I am using a kendo grid and one of the columns uses a MultiSelectFor. I am also using a Sortable with the multiselect so users can change the ordering of the multiselect values but when I click out of the multiselect and it goes to write back to the grid it doesn't write back in the selected order but only the order in which I selected the values. I attached some images to show what I mean.
@using Models;@using DAL;@model IEnumerable<object>@{ string uniqueName = Util.GetUniqueName(); string onSelect = "onSelect_" + uniqueName; string onChange = "onChange_" + uniqueName; string selectedValueVariable = "selectedValueVar_" + uniqueName; string selectedValueFunction_default = "selectedValueFunction_" + uniqueName; string builtParamFunction = "builtParamFunction_" + uniqueName; bool isCascadingFrom = false; bool isRequired = ViewData.ModelMetadata.IsRequired; string onChangeRestrictValues = "onChangeRestrictValues" + uniqueName; string onSortChange = "onSortChange" + uniqueName; bool ShowLabel = ViewData.GetBoolValue("ShowLabel"); string selectedValueFunction = ViewData.GetValue("SelectedValueFunction", selectedValueFunction_default); string ParamFunction = ViewData.GetValue("ParamFunction"); string id = ViewData.GetValue("FieldID", uniqueName); string Param1 = ViewData.GetValue("Param1"); string Param2 = ViewData.GetValue("Param2"); string Param3 = ViewData.GetValue("Param3"); string CascadeFromField = ViewData.GetValue("CascadeFromField"); string CascadeFromField_SelectedValueFunction = ViewData.GetValue("CascadeFromField_SelectedValueFunction"); bool allowCustomEdit = ViewData.GetBoolValue("AllowCustomEdit"); string defaultValue = ViewData.GetValue("DefaultValue"); isCascadingFrom = string.IsNullOrWhiteSpace(CascadeFromField) == false; ListType ListType = ViewData.GetEnumValue<IEnumerable<object>, ListType>("ListType"); string DataTextField = ListService.GetDataTextField(ListType); string DataValueField = ListService.GetDataValueField(ListType); if (string.IsNullOrWhiteSpace(CascadeFromField_SelectedValueFunction) == false && string.IsNullOrWhiteSpace(CascadeFromField)) { throw new Exception("CascadeFromField_SelectedValueFunction was specified, but CascadeFromField was not specified"); } if (string.IsNullOrWhiteSpace(ParamFunction) == false && string.IsNullOrWhiteSpace(CascadeFromField_SelectedValueFunction) == false) { throw new Exception("ParamFunction was specified as well as CascadeFromField_SelectedValueFunction, only one of these can be used"); } if (string.IsNullOrWhiteSpace(CascadeFromField_SelectedValueFunction) == false) //we want to use the CascadeFromField_SelectedValueFunction to populate a parameter value and pass it to server { if (string.IsNullOrWhiteSpace(Param1)) //if first param is unspecified { Param1 = CascadeFromField_SelectedValueFunction + "()"; } else if (string.IsNullOrWhiteSpace(Param2)) //if 2nd param is unspecified { Param1 = "\"" + Param1 + "\""; //we need to add quotation marks so the value is seen as a string in javascript and not a variable or method Param2 = CascadeFromField_SelectedValueFunction + "()"; } else if (string.IsNullOrWhiteSpace(Param3)) //if 3rd param is unspecified { Param1 = "\"" + Param1 + "\""; //we need to add quotation marks so the value is seen as a string in javascript and not a variable or method Param2 = "\"" + Param2 + "\""; //we need to add quotation marks so the value is seen as a string in javascript and not a variable or method Param3 = CascadeFromField_SelectedValueFunction + "()"; } ParamFunction = builtParamFunction; //param values will be converted into javascript and returned back to server as a function } string noDataTemplateID = "noDataTemplateID" + uniqueName;}<script id="@noDataTemplateID" type="text/x-kendo-tmpl"> <div> No data found. Do you want to add new item - '#: instance.input.val() #' ? </div> <br /> <button class="k-button" onclick="addNew('#: instance.element[0].id #', '#: instance.input.val() #')">Add new item</button></script><script> function hint(element) { return element.clone().addClass("hint"); } function placeholder(element) { return element.clone().addClass("placeholder").text("drop here"); }</script>@if (ShowLabel){ @Html.LabelFor(x => x)}@(Html.Kendo().MultiSelectFor(m => m) .DataTextField(DataTextField) .DataValueField(DataValueField) .NoDataTemplateId(noDataTemplateID) .Value(defaultValue) .HighlightFirst(true) .Filter(FilterType.StartsWith) .DataSource(source => { source.Read(read => { read.Action("Read", "List", new { ListType = ListType, Param1 = Param1, Param2 = Param2, Param3 = Param3 }); }); }) .HtmlAttributes(new {id = id }))@(Html.Kendo().Sortable() .For("#" + id + "_taglist") .HintHandler("hint") .PlaceholderHandler("placeholder"))
@using Models;<script type="text/kendo" id="usersTemplate"> #for(var i = 0; i < data.length; i++){# #:data[i].Description# #if(i < (data.length - 1)) { # #:", "# #}# #}#</script><script type="text/javascript"> var usersTemplate = kendo.template($("#usersTemplate").html(), { useWithBlock: false });</script><div id="content"> <!-- .container-fluid --> @(Html.Kendo().Grid<ApprovalGroupViewModel>() .Name("grid_approvalGroups") .Columns(columns => { columns.Command(command => { command.Destroy(); }).Width(150); columns.Bound(e => e.GroupID).Visible(false); columns.Bound(e => e.GroupName); columns.Bound(e => e.Users).ClientTemplate("#=usersTemplate(Users)#").Sortable(false); }) .Pageable() //Enable the paging. .Sortable() //Enable the sorting. .Editable(editable => editable.Mode(GridEditMode.InCell)) .ToolBar(toolbar => { toolbar.Create(); toolbar.Save(); }) .DataSource(datasource => datasource .Ajax() .PageSize(10) .Batch(true) .Model(model => { model.Id(m => m.GroupID); model.Field(m => m.Users).DefaultValue(new List<UserIDViewModel>()); }) .Read(read => read.Action("Read", "WFApprovalGroup")) .Create(c => c.Action("Create", "WFApprovalGroup")) .Update(c => c.Action("Update", "WFApprovalGroup")) .Destroy(c => c.Action("Delete", "WFApprovalGroup")) ) )</div>