This has been perplexing me for a couple of days. It took me awhile to track down where this out of sync was happening.
I have jquery sortable dragging and dropping to determine the order of some images. My override of the stop (drag) of sortable I loop through and assign an ordinal to a hidden value to submit the value:
$.each(parent.children(), function (i, v) {
var newOrdinal = $(v).index();
$(v).find('.product-img-ordinal').val(newOrdinal);//hidden value
});
submitChagnes();
Next my controller:
public async Task<ActionResult> EditDetails(IEnumerable<ProductImage> images, Guid? productId)
{
//save to database
//get sorted list of images
return PartialView("_ProductImagesList", sortedImages);
}
Breakpoints at this point shows the images in the right order as they were dragged.
Then _ProductImagesList.html:
@foreach(var item in Model)
{
<div class="img-container-wrapper clearfix pull-left">
@Html.DisplayFor(n => n[Model.IndexOf(item)])
</div>
}
Followed by a DisplayTemplate for the DisplayFor:
@Html.Partial("_ProductImage", Model)
@Html.HiddenFor(model=>model.Ordinal, new { @class="product-img-ordinal"})
@Html.HiddenFor(model=>model.Id, new { @class = "product-img-id" })
And finally the partial:
<div class="img-container pull-left">
<div>
<img class="product-img" width="240" height="336" src='@Url.Content(string.Format("~/PathToMyImages/GetImage?size=240x337&id={0}", Model.Id))' title="@Model.Description" />
</div>
<div class="img-descr">
<div class="img-descr1">@Model.Description</div>
<div class="img-descr2">Test Desc2</div>
</div>
</div>
@Html.HiddenFor(model=>model.Description, new { @class = "product-img-desc" })
Some of this may seem chopping, but it's from moving things around trying to identify the problem. But what happens is @Html.Partial("_ProductImage", Model) somehow has the wrong value for the Id in it and @Html.HiddenFor(model=>model.Id, new { @class = "product-img-id" }) has the wrong one for the src of the image (which should be the Id of the image). I'm not understanding how there can be 2 different models in these, even though they are both passed the same model. I can even put breakpoints on them and see them be 2 different values on the same iteration of the loop. So I will end up with one divs containing one img src with one id and a hidden field for the Id with another Id. It's always right the first time, then all subsequent posts it gets out of sync, so like something after the first ajax call mixes things up. Even looking at the network traffic coming back you can see the information mixed up:
Simplified return from partials/ajax:
<div>
<img src='1234.jpg'> <!-- Wrong, should match Id below -->
<input type='hidden' name='[0].Id' value='abcd' /> <!-- src should have this name -->
</div>
<div>
<img src='abcd.jpg'> <!-- Wrong, should match Id below -->
<input type='hidden' name='[1].Id' value='1234' />
</div>
Where the src filename should match the Id value. It's almost like the something is server-side cached, or something happening I don't understand. The DisplayTemplate has the correct information in the hidden field, the Partial has the wrong information, which is odd, the foreach loop has not even gotten to that item yet and it's getting it's id in the partial.
One more piece of information, if I comment out the submit and just let jquery sortable move around the panels, everything stays together correctly, it's actually somehow getting mixed up between the DisplayTemplate and the Partial view iterations during the ajax call.
I can see the value go in as a certain Id (GUID) and be one thing in the partial and another in the DisplayTemplate.
Any thoughts?
Thanks!