views:

23

answers:

1

I am banging my head against this wall for some time, some help will be highly appreciated:

Let's say I we have a simple Model:

public class Contact {
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

And a simple editor temple:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Rpdc.Models.Contact>" %>
FirstName: <% = Html.TextBoxFor(x => x.FirstName)%><br />
SecondName: <% = Html.TextBoxFor(x => x.LastName)%><br />

What I want to accomplish, is do display a list of editable Contacts, each with his own "save" button. If I do it this way:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IList<Rpdc.Models.Contact>>" %>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
    <% foreach(Contact c in Model) { %>
        <% using(Html.BeginForm("UpdateContact", "Home")) { %>
            <%=Html.EditorFor(x => c) %>
            <input type="submit" value="save" />
        <% } %>
    <% } %>
</asp:Content>

It renders a list of editors for each object, but all the textboxes have identical id's ("c_FirstName" and "c_LastName" for each "Contact" object).

And this way:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IList<Rpdc.Models.Contact>>" %>
<asp:Content ID="Content4" ContentPlaceHolderID="MainContent" runat="server">
    <% using(Html.BeginForm("UpdateContact", "Home")) { %>
        <%=Html.EditorForModel() %>
        <input type="submit" value="save" />
    <% } %>
</asp:Content>

It renders a list of objects, but with only one save button that submits all the objects. (Works, but it's not what I need)

Is there a clean way to display a list of editors for a list of objects, with a separate "save" button for each of them and without elements having repeating id's?

Thanks

A: 

Here's one way of doing it. You could put the form in the editor template and override the id to some custom value so that it is unique:

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

<% using(Html.BeginForm("UpdateContact", "Home")) { %>
    FirstName: <%= Html.TextBoxFor(x => x.FirstName, new { id = Guid.NewGuid() }) %><br />
    SecondName: <%= Html.TextBoxFor(x => x.LastName, new { id = Guid.NewGuid() }) %><br />        
    <input type="submit" value="save" />
<% } %>

And in your main view include the editor template for each element of the model:

<% foreach (var contact in Model) { %>
    <%= Html.EditorFor(x => contact) %>
<% } %>

This will generate the following HTML:

<form action="/Home/UpdateContact" method="post">
    FirstName: <input id="4fe9e2cd-042d-4648-a7e7-5eca866fc6b4" name="contact.FirstName" type="text" value="fn1" /><br />
    SecondName: <input id="d28916ec-81a3-45f1-8bea-8aef7715ab86" name="contact.LastName" type="text" value="ln1" /><br />
    <input type="submit" value="save" />
</form>
<form action="/Home/UpdateContact" method="post">
    FirstName: <input id="d8131dfa-2476-43f7-ad85-8e52d0b047bc" name="contact.FirstName" type="text" value="fn2" /><br />
    SecondName: <input id="4060649e-491d-4781-8108-5ba69ad4cea7" name="contact.LastName" type="text" value="ln2" /><br />
    <input type="submit" value="save" />
</form>

As you can see different ids are used for each input element but proper names so that the default model binder could get the values in the POST action:

[HttpPost]
public ActionResult UpdateContact(Contact contact)
{
    return View();
}

Obviously with this approach you might need to add some hidden input field in the editor template containing an unique identifier of the contact so that in your POST controller action you know which contact is being updated.

Darin Dimitrov
Darin, thanks for your reply, but there is a problem: after the form is submitted, the framework restores input controls' values from ModelState. Now because all textboxes' names are identical, they all receive the value of that textbox from a submitted form. Also I'd like to avoid having a form inside an editor template, I think a plain usercontrol will suit it better.
Vladikk