3

The Model:

public class MyObject
{
    public IList<Entry> Entries;
}

public class Entry
{
    public string Name { get; set; }
}

If I use the default EditorFor(model => model.Entries) the name/id values are:

<input type="text" value="" name="Entries[0].Name" id="Entries_0__Name">

If instead I want to create an EditorFor template like this:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<List<CMS.Models.MyObject>>" %>

<div class="list">
<%
    for (int i = 0; i < Model.Count; i++)
    { %>
    <div class="object" id="<%: i %>">
        <%: Html.EditorFor(model => Model[i]) %>
        <%: Html.ValidationMessageFor(model => Model[i]) %>
    </div>
<%  } %>
</div>

The emitted name/id values are:

<input type="text" value="" name="Entries.[0].Name" id="Entries__0__Name">

So the name has a period between the property name and [0] and the id has an extra underscore to the left of the index number. This doesn't work with the default model binder. Is there a way to do this that does work with the default model binder?

Cymen
  • 14,079
  • 4
  • 52
  • 72
  • 1
    Why do you want to do this? Are you just looking to get the validation message included or is there really a requirement to have the div tag with the ID set? – Shea Daniels Feb 11 '11 at 01:13
  • I am doing it so that I can have a generic jQuery-based "add" option at the end of the list to add another element. Emitting the list with that HTML makes it much easier to make "add" generic. Think a form where one section requires N references (each reference having multiple properties), another part requires N details about something else (each part having multiple properties), etc... – Cymen Feb 11 '11 at 01:16

1 Answers1

3

I think you can do most of this using templates without having to explicitly iterate over the list, which seems to be causing your problems with the model binder.

Try making these shared editor templates:

MyObject Editor Template

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<CMS.Models.MyObject>" %>

<div class="list">
    <%: Html.EditorFor(m => m.Entries) %>
</div>

Entry Editor Template

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<CMS.Models.Entry>" %>

<div class="object" id="<%: ??? %>">
    <%: Html.EditorFor(m => m.Name) %>
    <%: Html.ValidationMessageFor(m => m.Name) %>
</div>

The only thing I haven't figured out yet is how to get the correct value in the id attribute of the div, hence the question marks. Final caveat is that I'm at home so I haven't actually tried this.

Shea Daniels
  • 3,232
  • 3
  • 23
  • 27
  • This worked and I was able to leave the id off and accomplish what I needed to. I think it is actually invalid HTML anyway (can have duplicate ids if have multiple lists) so better this way in the end! Thanks! – Cymen Feb 11 '11 at 18:54
  • Most helpful , clean and simple. Thanks! – Menahem Dec 07 '11 at 15:11