tags:

views:

258

answers:

2

I would like to know people's thoughts on the best way to do the opposite to Phil Haack's Model Binding To A List. I have a form which contains several individual fields as well as form fields which are created dynamically using JQuery. This means that when I query the database for something to edit, it will return an object which in itself will have n number of objects (each the same) attached to it.

I would like to know what people would suggest as the best way to create the "dynamic" parts of the forms and, in particular, ensure that the correct items are selected for the drop down lists. I have a vague idea that it will involve View User Controls but I am struggling with how to put it all together.

The form:

<form action="/MyItems/Edit" method="post">
   Title: <input type="text" name="Title" value="" /><br />
   Description <input type="text" name="Description" value="" /><br /><br />

   <input type="hidden" name="myItem.Index" value="0" />
   <input id="item[0].Amount" name="item[0].Amount" type="text" value="" />
   <select id="item[0].selectA"><option value="1">1</option>
   <option value="2">2</option><option value="3">3</option></select>
   <select id="item[0].selectB"><option value="1">1</option>
   <option value="2">2</option><option value="3">3</option></select>

   <input type="hidden" name="myItem.Index" value="1" />
   <input id="item[1].Amount" name="item[1].Amount" type="text" value="" />
   <select id="item[1].selectA"><option value="1">1</option>
   <option value="2">2</option><option value="3">3</option></select>
   <select id="item[1].selectB"><option value="1">1</option>
   <option value="2">2</option><option value="3">3</option></select>

   <input type="hidden" name="myItem.Index" value="2" />
   <input id="item[2].Amount" name="item[2].Amount" type="text" value="" />
   <select id="item[2].selectA"><option value="1">1</option>
   <option value="2">2</option><option value="3">3</option></select>
   <select id="item[2].selectB"><option value="1">1</option>
   <option value="2">2</option><option value="3">3</option></select>
</form>

Everything from the hidden input to the end of the second select list could be repeated n times. The DTO that is being hydrated from the database query looks like the following:

public class MyItem
{
    public string Name { get; set; }
    public string Description { get; set; }
    public IEnumerable<SelectItem> SelectItems { get; set; }
}

Each SelectItem then looks like:

public class SelectItem
{
    public int SelectA { get; set; }
    public int SelectA { get; set; }
}

I hope I have explained this ok, thanks in advance for anyone taking the time to have a look at this.

+1  A: 

Wrapping this up in either a UserControl or your own HtmlHelper extension method would tidy up the view, but essentially you want something like this:

<%  int idx = 0;
    foreach (SelectItem item in myItem.SelectItems) { %>
<input type="hidden" name="myItem.Index" value="<%= idx %>" />
<input id="item[<%= idx %>].Amount" name="item[<%= idx %>].Amount" type="text" value="" />
<select id="item[<%= idx %>].selectA">
  <option <%= item.selectA == 1 ? "selected" : "" %> value="1">1</option>
  <option <%= item.selectA == 2 ? "selected" : "" %> value="2">2</option>
  <option <%= item.selectA == 3 ? "selected" : "" %> value="3">3</option>
</select>
<select id="item[<%= idx %>].selectB">
  <option <%= item.selectB == 1 ? "selected" : "" %> value="1">1</option>
  <option <%= item.selectB == 2 ? "selected" : "" %> value="2">2</option>
  <option <%= item.selectB == 3 ? "selected" : "" %> value="3">3</option>
</select>
<%  idx++;
    } %>

Have that wrapped up in your form tags and it should render just fine, assuming that your MyItem instance is called myItem. You could wrap the repeated option tags in another loop if you had your values held in a collection as well.

Giraffe
Thanks Giraffe, I am going to take a good look at that tomorrow morning and will be sure to report back.
dave
A: 

To complete this I ended up creating a while loop to loop through the form items and then query my data source to hydrate my objects. I have since changed this so that the same code now sits inside a custom modelbinder. Very neat.

dave