-1

I have a MVC controller action with inputModel parameter which have list type property and , I ,m using $('form').serialize() to serialize the form content and append some of my custom data to serialized string, but inside the action method input model object the list property is empty, Can any one help me , below is the code samples

My controller

[HttpPost]
public ActionResult Edit(ALDS.Web.Areas.Direct2M3.Models.ItemInputModel collection)
{   }

ItemInputModel class

 public class ItemInputModel
    {
        //......Some property here..
        public List<FabricCompositionInputModel> FabricCompositions { get; set; }
    }

FabricCompositionInputModel class

 public class FabricCompositionInputModel
    {
        public int ItemID { get; set; }
        public string CompositionCode { get; set; }
        public decimal Value { get; set; }

    }

Ajax call

function save() {

    var compositionData = generateCompositionForSave(); //Returns array
    var data = $('form').serialize();
    var d2 = JSON.stringify(compositionData);

    var data2 = data + '&FabricCompositions=' + d2;

    $.ajax({
        type: 'POST',
        dataType: 'json' ,
        cache: false,
        url: '/ItemMaster/Edit',
        data: data2,
        success: function (data, textStatus, jqXHR) {
            sucess(data);
        },
        error: function (jqXHR, textStatus, errorThrown) {
            failed(jqXHR);
        }

    });

}

Array generating function

function generateCompositionForSave() {
    var arr = [];
    var delClassList = $('#compositionContainer').find('.btnRemoveCompositions');
    for (var c = 0; c < delClassList.length; c++) {
        var row = $(delClassList[c]).closest('.row');
        var code = row.find('.compositionCode').val();
        var value = parseInt(row.find('.compositionValue').val());
        arr.push({ItemID:0, CompositionCode:code, Value:value});
    }

    return arr;
}
Roshan
  • 3,236
  • 10
  • 41
  • 63
  • You cannot combine the data from `.serialize();` and an array like that. If you have generated you form controls from the collection items correctly in the first place, the `.serialize()` is all that is required. Show the part of the view that is generating those form controls –  Feb 14 '17 at 05:18

1 Answers1

1

Your not building the data correctly, and it needs to be

var compositionData = generateCompositionForSave();
var data = $('form').serializeObject(); // see function below
data['FabricCompositions'] = compositionData; // add the array to the serialized data
var data2 = JSON.stringify({ collection: data }), // stringify it

$.ajax({
    type: 'POST',
    contentType: "application/json; charset=utf-8", // add contentType
    dataType: 'json' ,
    cache: false,
    url: '@Url.Action("Edit", "ItemMaster")', // don't hard code your url's
    data: data2,
    success: function (data, textStatus, jqXHR) {
        ....

And add the following function (warning: this will not work correctly for a <select multiple> element)

$.fn.serializeObject = function () {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function () {
        if (o[this.name] === undefined) {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

Note that if you generate your form controls correctly using a for loop or custom EditorTemplate for typeof FabricCompositionInputModel (refer Post an HTML Table to ADO.NET DataTable), for example

for(int i = 0; i < Model.FabricCompositions.Count; i++)
{
    @Html.TextBoxFor(m => m.FabricCompositions[i].CompositionCode)
    @Html.TextBoxFor(m => m.FabricCompositions[i].Value)
}

then all that is required is

var data = $('form').serialize();
$.ajax({
    type: 'POST',
    dataType: 'json' ,
    cache: false,
    url: '@Url.Action("Edit", "ItemMaster")',
    data: data,
    success: function (data, textStatus, jqXHR) {
Community
  • 1
  • 1
  • And the output of `console.log(data2);` would be something like `{"collection":{"ID":1.....","FabricCompositions":[{"ItemID":0,"CompositionCode":"xxx","Value":"yyy"},{....}]}}` –  Feb 14 '17 at 05:58
  • Nope.! Can u please explain what the purpose of this line data['FabricCompositions'] = compositionData; when I debug the code data1 does not contain any information about the composition data. – Roshan Feb 14 '17 at 06:06
  • Then you have not followed my instructions. And you may possibly have a problem if the form controls you are generating are inside the `
    ` tag, because `form.serialize()` will serialize those 2 (and they would have no relationship to your model and could cause a problem, particularly if they include `FabricCompositions` in their `name` attributes. If that is the case - move them outside the `
    ` tag
    –  Feb 14 '17 at 06:10
  • `var data = $('form').serialize();` generates a javascript object of your form controls name/value pairs - so it might be `{ ID: 1, Name: 'xx' }` the `data['FabricCompositions'] = compositionData` add the array to that object, and you now have `{ ID: 1, Name: 'xx', FabricCompositions: [ { ItemID: 0, CompositionCode:‌ ​'xxx', Value: yy }, { .... } ]}` which you finally stringify with the name of the parameter in the method. –  Feb 14 '17 at 06:14
  • is `$('form').serialize();` generate javascript object or just a text , when I debug the `$('form').serialize(); ` it is just a text with `property name = property value` – Roshan Feb 14 '17 at 06:17
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/135648/discussion-between-stephen-muecke-and-roshan). –  Feb 14 '17 at 06:18