Reputation: 23
I've read a bunch of articles now, from Phil Haacks "model binding to a list" to Steve Sanderson's "Editing a variable length list" and now trying to solve my problem - however I couln't really get it working.
I have two models - Order and Article. An order has many articles. The order view contains an articles table.
Currently, I'm creating the first table row using EditorFor(model => model.Articles) from within my Order View Model.
It recognizes that Articles is a list and returns the right list items. So far so good.
Now I want a link that adds an article to the table row but by using an AJAX Request to the Controller, which then returns a partial view (only containing the article table row). I already got that working using this tutorial: http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/
However, my problem is that I don't know how i can continue the article row sequence in ASP.NET MVC "style", so that it will get recognized on submit. (e.g. Articles[1].Number Articles[2].Number etc.)
Here's my code. The "add article" link should add an article and send an ajax request to /orders/BlankArticleRow
public ActionResult BlankArticleRow(int pos)
{
Article article = new Article()
{
Position = pos
};
return View(article);
}
The partial view for BlankArticleRow looks like this:
@model Bestellinterface.Models.Article
@{
Layout = null;
}
@Html.EditorFor(model => model)
Works fine. When i click the "add article" link the row gets added, however the attributes of the text fields etc. do not have the right format. What i want is that it continues the numbering of the html elements, Articles[0].Number, Articles[1].Number, Articles[2].Number ...
Is that possible with EditorFor? Is there a way to simulate a list so that it will keep numbering?
Upvotes: 0
Views: 1431
Reputation: 9453
I think you are missing the extension Steve created
If you look at the article it is used like this:
<% using(Html.BeginCollectionItem("gifts")) { %>
Item: <%= Html.TextBoxFor(x => x.Name) %>
Value: $<%= Html.TextBoxFor(x => x.Price, new { size = 4 }) %>
<% }
Upvotes: 0
Reputation: 34800
Yes you can use EditorFor
for this:
@{ int i = 0; }
@foreach (var article in Model.Articles)
{
@Html.EditorFor(model => Model.Articles[i])
i++;
}
Assuming the editor template contains fields Title, Description we would end up with Articles[i].Title, Articles[i].Description.
One solution for you may be to return a partial containing all the Articles for the Order which would then ensure your indexes are correct.
Alternatively you can update the indexes of your inputs with javascript.
To keep the indexes correct when removing items from a dynamic table I wrote the following:
//reset index values
$('#links-table tbody tr').each(function (index, value) {
$(this).find('input[type=text]').prop('name', function (i, e) { return e.replace(/(\d+)/g, index) });
});
This looks for the index in each input's name e.g. Articles[2].Title and replaces it with the new index. You could potentially do something similar on the success of your ajax call.
Hope that helps Ben
Upvotes: 2