Search code examples
c#asp.net-mvcmodel-view-controllermvc-editor-templates

Mvc EditorTemplate for List<string> with dynamic amount


I've made a simple EditorTemplate for a list in my Model (Views/Shared/EditorTemplates/List.cshtml):

@model List<string>
foreach (var str in Model)
{
    <li>
        @Html.LabelFor(m => str, "My Label")
        @Html.TextBoxFor(m => str)
        @Html.ValidationMessageFor(m => str)
    </li>
}

Called like this in my view (Views/Profile.cshtml):

@using (Html.BeginRouteForm(MvcSettings.SitecoreRouteName, FormMethod.Post, new { data_abide = "true", id = "myForm", enctype = "multipart/form-data" }))
{
    @Html.Sitecore().FormHandler("User", "UpdateProfile")
    @Html.ValidationSummary()

    @Html.EditorFor(x => x.ListTest, new { htmlAttributes = new { id = "listTestId" } })

    <input type="submit" value="Submit" />
}

Controlled Action:

public ActionResult UpdateProfile(IntranetContactViewModel formModel)
{
    // Save information to DB
}

Model:

public class IntranetContactViewModel
{
    public List<string> ListTest { get; set; }

    public IntranetContactViewModel()
    {
        ListTest = new List<string>{"abc","def","ghi"};
    }
}

When the list contains 3 strings then the view will render me 3 text-boxes.

<input class="text-box single-line" id="listTestId" name="ListTest[0]" type="text" value="abc">
<input class="text-box single-line" id="listTestId" name="ListTest[1]" type="text" value="def">
<input class="text-box single-line" id="listTestId" name="ListTest[2]" type="text" value="ghi">

But, the amount of options the user can insert should be unlimited. If all 3 text-boxes are filled in a 4th should appear (And, ideally, if more than 2 text-boxes are empty, 1 should be deleted).

I tried doing this myself by adding a text-box with the same signature ( added 1 to the counter inside the name attribute )

<input class="text-box single-line" id="listTestId" name="ListTest[3]" type="text" value="TEST">

But when I submit this, this doesn't get recognized by the Model and isn't returned to the Controller. Is there a way to let my Model know that it now also needs to keep track of this new text-box? Or is this simply not possible?

Please advise.


Solution

  • @Html.EditorFor(x => x.ListTest, new { htmlAttributes = new { id = "listTestId" } })
    

    Should have been:

    @Html.EditorFor(x => x.ListTest)
    

    I forced all my text-boxes to get the same id, and this screwed up the system. Thanks to everyone in the comments for helping out!