I wanted to allow the user to edit a list of items while also enabling the user to sort them, and to post that back in a meaningful way without parsing on the server side. This does the trick:
public class SortableModel { public List<CustomItem> CustomItems { get; set; } } public class CustomItem { public int Order { get; set; } public string Description { get; set; } } var model = new SortableModel { CustomItems = new List<CustomItem> { new CustomItem { Order = 0, Description = "Test 1"}, new CustomItem { Order = 1, Description = "Foo 2"}, new CustomItem { Order = 2, Description = "Bar 3"} } };
View:
<script src="@Url.Content("Scripts/jquery-1.9.1.js")"></script> <script src="@Url.Content("Scripts/jquery-ui-1.10.1.js")"></script> <script type="text/javascript"> $(function () { $("#sortMe").sortable({ stop: function (event, ui) { $("#sortMe li").each(function (index, element) { // find the hidden input in each <li> and set it to its current index, according to the DOM var hiddenInput = $(element).children(".order").first(); hiddenInput.val(index); }); } }); }); </script> @using (Html.BeginForm()) { <ul id="sortMe"> @for (int i = 0; i < Model.CustomItems.Count; i++) { <li>@Html.HiddenFor(m => m.CustomItems[i].Order, new { @class = "order" }) @Html.TextBoxFor(m => m.CustomItems[i].Description) <span>Drag me!</span></li> } </ul> <input type="submit" value="Save" /> }
Now my action can accept a SortableModel parameter, where we can loop through the list of CustomItems in order to determine their order!
[HttpPost] public ActionResult CustomFieldsForPort(SortableModel model) { // do your thing with model! return View(model); }
Up next: adding and deleting items.