This is a migrated thread and some comments may be shown as answers.

MultiSelect in Grid

2 Answers 336 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Bernhard
Top achievements
Rank 1
Bernhard asked on 05 Sep 2013, 04:00 AM
I am currently trying out kendo.ui for asp.net mvc

I have a model

public class RegionViewModel 
{
  public int Id { get; set; }
  public string Name { get; set; }
   public IList<VillageViewModel> Villages {get; set; }
}

public class VillageViewModel
{
 public int Id {get; set; }
   public string Name {get; set; }
}

Basically its a many to many relationship .. the model is built using entity framework.
But that is not really the problem.

I am trying to select multiple Villages from a huge list and assign them to a region. The region is the main row entity for a grid.
I am using the MultiSelect widget in an editor template.

This works fine, selection works and everything. But on clicking update no ajax request is sent to the server ( i am using inline edit mode ) 
I have tried everything, looked at the sample provided here: http://www.kendoui.com/code-library/mvc/grid/using-multiselect-in-grid.aspx

But i cannot get this to work apparently.
One requirement that i have btw is that the multiselect has to be using ajax as well since for exampel there are 17.000 possible villages in our database right now
and loading them all on creating the editor takes to long, and also makes the editor basically unusable.

Here is my field and column setup code:

 fields.Field(Accessor).DefaultValue(new List<VillageViewModel>());
columns.Bound(t => t.Villages).EditorTemplateName("MultiReference");

My editor template: ( not using the html helper ,since that does not allow for using serverpaging right now )

select id="Villages">
</select>

<script>

    jQuery(function() {
        jQuery("#Villages").kendoMultiSelect(
            {
                "dataSource":
                {
                    "transport":
                    {
                        "prefix": "",
                        "read":
                        {
                            "url": "/admin/regions/villages",
                            "data": function() {
                                return kendo.ui.MultiSelect.requestData("#Villages");
                            }
                        }
                    },
                    "serverFiltering": true,
                    "serverPaging": true,
                    "pageSize": 20,
                    "filter": [],
                    "schema": {
                        "errors": "Errors"
                    }
                },
                "dataTextField": "Name",
                "dataValueField": "Id",
                "value": []
            });
    });
</script>

And here is the final grid script that gets rendered:

jQuery(function () {
    jQuery("#regionsGrid").kendoGrid({
        "columns": [{
            "title": "Name",
            "field": "Name",
            "filterable": {},
            "encoded": true,
            "editor": "\u003cinput class=\"k-textbox\" id=\"Name\" name=\"Name\" type=\"text\" value=\"\" /\u003e\u003cspan class=\"field-validation-valid\" data-valmsg-for=\"Name\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e"
        }, {
            "title": "Villages",
            "template": "#for(var i = 0; i\u003c data.length; i  ){#\u003cspan\u003e#:data[i].Name#\u003c/span\u003e#}#",
            "field": "Villages",
            "filterable": {},
            "encoded": true,
            "editor": "\r\n\r\n\u003cselect id=\"Villages\"\u003e\r\n\u003c/select\u003e\r\n\r\n\u003cscript\u003e\r\n\r\n    jQuery(function() {\r\n        jQuery(\"#Villages\").kendoMultiSelect(\r\n            {\r\n                \"dataSource\":\r\n                {\r\n                    \"transport\":\r\n                    {\r\n                        \"prefix\": \"\",\r\n                        \"read\":\r\n                        {\r\n                            \"url\": \"/Admin/regions/Villages\",\r\n                            \"data\": function() {\r\n                                return kendo.ui.MultiSelect.requestData(\"#Villages\");\r\n                            }\r\n                        }\r\n                    },\r\n                    \"serverFiltering\": true,\r\n                    \"serverPaging\": true,\r\n                    \"pageSize\": 20,\r\n                    \"filter\": [],\r\n                    \"schema\": {\r\n                        \"errors\": \"Errors\"\r\n                    }\r\n                },\r\n                \"dataTextField\": \"Name\",\r\n                \"dataValueField\": \"Id\",\r\n                \"value\": []\r\n            });\r\n    });\r\n\u003c/script\u003e\r\n\r\n\u003cspan class=\"field-validation-valid\" data-valmsg-for=\"Villages\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e"
        }, {
            "title": "Commands",
            "width": "200px",
            "command": [{
                "name": "edit",
                "buttonType": "ImageAndText",
                "text": "Edit"
            }, {
                "name": "destroy",
                "buttonType": "ImageAndText",
                "text": "Delete"
            }]
        }],
        "pageable": {
            "buttonCount": 10
        },
        "sortable": true,
        "scrollable": false,
        "editable": {
            "confirmation": "Are you sure you want to delete this record?",
            "mode": "inline",
            "create": true,
            "update": true,
            "destroy": true
        },
        "toolbar": {
            "command": [{
                "name": null,
                "buttonType": "ImageAndText",
                "text": "Add new record"
            }]
        },
        "dataSource": {
            "transport": {
                "prefix": "",
                "read": {
                    "url": "/Admin/regions/List"
                },
                "update": {
                    "url": "/Admin/regions/Update",
                    "data": gridSerialize
                },
                "create": {
                    "url": "/Admin/regions/Create",
                    "data": gridSerialize
                },
                "destroy": {
                    "url": "/Admin/regions/Destroy"
                }
            },
            "pageSize": 10,
            "page": 1,
            "total": 0,
            "serverPaging": true,
            "serverSorting": true,
            "serverFiltering": true,
            "serverGrouping": true,
            "serverAggregates": true,
            "type": "aspnetmvc-ajax",
            "filter": [],
            "schema": {
                "data": "Data",
                "total": "Total",
                "errors": "Errors",
                "model": {
                    "id": "Id",
                    "fields": {
                        "Villages": {
                            "type": "object",
                            "defaultValue": []
                        },
                        "Id": {
                            "editable": false,
                            "type": "number"
                        },
                        "Name": {
                            "type": "string"
                        },
                        "Slug": {
                            "type": "string"
                        }
                    }
                }
            },
            "autoSync": true
        }
    });
});

Or are there any other recommended options to edit many to many relationships in a grid ? 









2 Answers, 1 is accepted

Sort by
0
Petur Subev
Telerik team
answered on 06 Sep 2013, 03:20 PM
Hello Bernhard,

I think you just miss the name="Villages" (and/or try to add the data-bind="value:Villages") attribute added on your select element. Also you need to use the serialize that array and send it on update/create, other way the MVC model binder wont recognize the records on the server.

code from the code library:

        .Read(read => read.Action("Read", "Home"))
        .Update(update => update.Action("Update", "Home").Data("serialize"))
        .Create(create => create.Action("Create", "Home").Data("serialize")))
)
 
 
<script type="text/javascript">
 
    function serialize(data) {
        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>


Can you please check if this is the case?

If not can you modify the code library project and share it so we can investigate further the case?

Kind Regards,
Petur Subev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Bernhard
Top achievements
Rank 1
answered on 06 Sep 2013, 09:59 PM
That was it.. Thank you so much .

Now its getting the existing selection to sync with the widget, but that should not be too bad.
Tags
Grid
Asked by
Bernhard
Top achievements
Rank 1
Answers by
Petur Subev
Telerik team
Bernhard
Top achievements
Rank 1
Share this question
or