0
votes

I'm replicating the functionality very close to what's seen here. https://onabai.wordpress.com/2013/07/17/kendoui-multiselect-in-a-grid-yes-we-can/

I have Kendo grid with an inline multiselect editor field. I have a datasource.sync() event kicked off on change of that multiselect. The issue I'm having is how the data is arranged in the post variables.

I'm using FireBug in FireFox. I can set a function to view the values in my multiselect field like this at the sync() event.

console.log(this.value());

This would be for a string array field I have called "RoleCode". Anyway, the console log displays the values as they should, for example

A, OU

However, when I look in the Post call to my controller and at the parameters, I see the RoleCode field is duplicated, which is why my controller doesn't recognize the method signature. For example, this is what I see in FireBug...

ID  123
Field1  TextFromField1
RoleCode[1][RoleCode]  OU
RoleCode[]  A

Any idea how I should set this up so the post parameters are usable?

UPDATE

For now I just altered the update function to send the multiselect values as a comma separated string. I can deal with them in the controller. I don't really like this setup, but until I find how to get the posted values to send correctly, this is what I'm going with.

    update: {
            url: "Home/GridUpdate",
            type: "POST",
            dataType: "json",
            data: function () {
                //Grid does not post multiselect array correctly, need to convert to a string
                var rolesString = $("#gridRoleList").data("kendoMultiSelect").value().toString();
                return { rolesString: rolesString };
            },
            complete: function (e) {
                setTimeout(function () {
                    refreshGrid();
                }, 300);
            },
            success: function (result) {
                // notify the data source that the request succeeded
                options.success(result);
            },
            error: function (result) {
                // notify the data source that the request failed
                options.error(result);
            }
        },

UPDATE 2

Actually that's not a good idea because if I edit another field in the grid, I get a js error because the multiselect is not found.

2

2 Answers

0
votes

Looks like your issue can be resolved by sending the data after serializing it

Read action - using MVC Wrapper

.Create(create => create.Action("Create", "Home").Data("serialize"))

JS Code

<script type="text/javascript">

function serialize(data) {
    debugger;
    for (var property in data) {
        if ($.isArray(data[property])) {
            serializeArray(property, data[property], data);
        }
    }
}

function serializeArray(prefix, array, result) {
    for (var i = 0; i < array.length; i++) {
        if ($.isPlainObject(array[i])) {
            for (var property in array[i]) {
                result[prefix + "[" + i + "]." + property] = array[i][property];
            }
        }
        else {
            result[prefix + "[" + i + "]"] = array[i];
        }
    }
}


</script>

Please refer here for complete source code

0
votes

Here's how I solved it. On the change event of the editor function, I updated the value of the model with the value of the multiselect. Then the data posts correctly as a string array like this.

ID  123
Field1  TextFromField1
RoleCode[]  A
RoleCode[]  OU

My grid editor function

function roleMultiSelectEditor(container, options) {
    $('<input id = "gridRoleList" name="' + options.field + '"/>')
        .appendTo(container)
        .kendoMultiSelect({
            dataTextField: "RoleCode",
            dataValueField: "RoleCode",
            autoBind: true,    
            change: function (e) {
                //Applies the value of the multiselect to the model.RoleCode field
                //Necessary to correctly post values to controller
                options.model.RoleCode = this.value();
                processGridMultiSelectChange();
            },
            dataSource: {
                type: "json",
                transport: {
                    read: {
                        dataType: "json",
                        url: baseUrl + "api/DropDownData/RoleList",
                    },
                }
            },
            dataBound: function (e) {
            }
        });
}