DataGrid Editor - List properties in template

Jul 3, 2012 at 5:18 AM
Edited Jul 3, 2012 at 5:23 AM

Hi There,

Firstly, I haven't upgraded to the latest version of MVCControlsToolkit for a few months so please let me know if this issue is fixed.

 

I'm using a DataGrid and I have an Edit template which contains a List property. The ViewModel for the Edit template is CorporateActionAllocations which contains a List of SystemReferences.

So on the Edit Template I simply have 

 

@Html.EditorFor(model=>Model.SystemReferenceList)

 

There is a custom EditorTemplate for this which has the following 3 lines

@Html.HiddenFor(m=>m.CorporateActionAllocationId)
@Html.HiddenFor(m=>m.System_Reference)
@Html.HiddenFor(m=>m.Sequence)

 

The problem is that only the first list item is being returned on Postback. The input blocks look ok to me (included below minus their validation tags). Any ideas?

Note that the list is only referenced in the EditTemplate, not the display or editdeleteitem templates. Also note that I don't actually edit the line before posting back the page. 

<input 
id="CorporateActionAllocations___0___Item_Value_SystemReferenceList_0__CorporateActionAllocationId" 
name="CorporateActionAllocations.$$0.$.Item.Value.SystemReferenceList[0].CorporateActionAllocationId" type="hidden" value="318" />

<input 
id="CorporateActionAllocations___0___Item_Value_SystemReferenceList_0__System_Reference" 
name="CorporateActionAllocations.$$0.$.Item.Value.SystemReferenceList[0].System_Reference" type="hidden" value="AM002942" />

<input 
id="CorporateActionAllocations___0___Item_Value_SystemReferenceList_0__Sequence" 
name="CorporateActionAllocations.$$0.$.Item.Value.SystemReferenceList[0].Sequence" type="hidden" value="1" />

<input 
id="CorporateActionAllocations___0___Item_Value_SystemReferenceList_1__CorporateActionAllocationId" 
name="CorporateActionAllocations.$$0.$.Item.Value.SystemReferenceList[1].CorporateActionAllocationId" type="hidden" value="318" />

<input 
id="CorporateActionAllocations___0___Item_Value_SystemReferenceList_1__System_Reference" 
name="CorporateActionAllocations.$$0.$.Item.Value.SystemReferenceList[1].System_Reference" type="hidden" value="AM002988" />

<input
id="CorporateActionAllocations___0___Item_Value_SystemReferenceList_1__Sequence" 
name="CorporateActionAllocations.$$0.$.Item.Value.SystemReferenceList[1].Sequence" type="hidden" value="2" />

<input
id="CorporateActionAllocations___0___Item_Value_SystemReferenceList_2__CorporateActionAllocationId" 
name="CorporateActionAllocations.$$0.$.Item.Value.SystemReferenceList[2].CorporateActionAllocationId" type="hidden" value="318" />

<input
id="CorporateActionAllocations___0___Item_Value_SystemReferenceList_2__System_Reference" 
name="CorporateActionAllocations.$$0.$.Item.Value.SystemReferenceList[2].System_Reference" type="hidden" value="AM002989" />

<input
id="CorporateActionAllocations___0___Item_Value_SystemReferenceList_2__Sequence" 
name="CorporateActionAllocations.$$0.$.Item.Value.SystemReferenceList[2].Sequence" type="hidden" value="3" />

<input
id="CorporateActionAllocations___0___Item_Value_SystemReferenceList_3__CorporateActionAllocationId" 
name="CorporateActionAllocations.$$0.$.Item.Value.SystemReferenceList[3].CorporateActionAllocationId" type="hidden" value="318" />

<input
id="CorporateActionAllocations___0___Item_Value_SystemReferenceList_3__System_Reference" 
name="CorporateActionAllocations.$$0.$.Item.Value.SystemReferenceList[3].System_Reference" type="hidden" value="AM002990" />

<input
id="CorporateActionAllocations___0___Item_Value_SystemReferenceList_3__Sequence" 
name="CorporateActionAllocations.$$0.$.Item.Value.SystemReferenceList[3].Sequence" type="hidden" value="4" />



Coordinator
Jul 3, 2012 at 8:27 PM

Maybe it is a problem of am old version...however, it is not a bug. The grid do changes tracking an remember the oldvalues. Now since you DONT edit the line what you get on post is just the old value. Now in past versions the routine in charge for saving the old values ...Did not go though IEnumerables for performace reason! NOW WE CHANGES THIS BEHAVIOUR. HOWEVER, in any case you can force storing your list by using the toTrack argument. the toTrack argument let youy specify explicitely all properties whose values MUST BE STORED.

See below its usage:

<%: Html.DataGridFor(m => m.ToDoList, ItemContainerType.tr,
                                "ToDoEditItem", "ToDoDisplayItem", null, "ToDoInsertItem", "ToDoUndeleteItem",
                     itemCss: "normalRow", altItemCss: "alternateRow",
                     toTrack: new FieldsToTrack<ToDoItem>().
                                   Add(f => f.Code).Add(f => f.Name).Add(f => f.Description).Add(m => m.Important)
                                   .Add(f => f.ToDoRoles).Add(f => f.ToDoRole))
                                   %>

If you don't use the master detail helpers you can also simply do 

new FieldsToTrack<ToDoItem>(). Add(f => f)

This will force the jSon serialization of the whole row. This way ALL CONTENT OF EACH ITEM WILL BE STORED. The use of toTrack increase efficiency, since reduce the space needed to store the oldvalues. let me know if the toTrack solves. If toTrack solve, the probably also passing the the last version will solve

Jul 3, 2012 at 10:35 PM
Edited Jul 3, 2012 at 10:37 PM

Thanks for the tips, unfortunately it made it worse for me. It didn't seem to return anything in the OldValue and Value properties.

Not quite sure why it ended up blanking out all the fields upon post but it did.

In the end I've decided to reload the System Reference Lists from the database.

They are read only on the UI, but they control what is accessible to the user so are critical. This problem only occurs if there is an issue on Postback.

Here's my datagrid for statement.

@Html.DataGridFor(model => model.CorporateActionAllocations, 
ItemContainerType.tr, "RightsIssue\\RIAllocEditItem", "RightsIssue\\RIAllocEditDeleteItem", 
"RightsIssue\\RIAllocGrid", "RightsIssue\\RIAllocInsertItem",
toTrack: new FieldsToTrack<ViewModel.GL.CorporateActionAllocation>().Add(ca=>ca.SystemReferenceList) )
Coordinator
Jul 3, 2012 at 10:46 PM

You used it in the wrong way! Either you DON'T SPECIFY ANY FIELDS, in which case the fileds are autodetected, or you specify ALL FIELDS TO SAVE. Now you just specified ONE FIELD. If you want to add ALL FILEDS it is enough to write :

toTrack: new FieldsToTrack<ViewModel.GL.CorporateActionAllocation>().Add(ca=>ca) )

Tell me also wich version are you using

Jul 6, 2012 at 3:08 AM

Apologies for the late reply, I've got it working by reloading on the server. I tried it the way you have suggested (i.e. ca=>ca) but that didn't seem to work either.

 

I think we are on version 1.8.

 

Cheers

Coordinator
Jul 6, 2012 at 8:41 AM

It is quite strange...because I use lists inside grids regularly...There was no change from the 1.8 in that part of code, so it should not be a problem of version.

Maybe you found a bug ...or there is some simple stupid error somwhere that for some reason  reflects into this behaviou :)

Are you able to arrange a self-contained (with no DB) working project showing the issue? 

You can send it to me on the contact form of my blog or to my email (You should have it...).