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

MultiSelect not updating view model

5 Answers 1314 Views
MultiSelect
This is a migrated thread and some comments may be shown as answers.
Stacy
Top achievements
Rank 1
Stacy asked on 16 Oct 2018, 06:44 PM

I am using the kendo.ui.MultiSelectwidget in a form with an Ajax.BeginForm wrapper.

The view model:

public class ContextViewModel
{
        public int Context_PK { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public List<int> OwnerPermissions { get; set; }
        public List<int> UserPermissions { get; set; }
 
}

 

Razor View Htmlhelper call:

@(Html.Kendo().MultiSelectFor(m => m.OwnerPermissions)
.DataTextField("Text")
.DataValueField("Value")
.DataSource(source =>
 {
      source.Read(read =>
      {
          read.Action("GetAppUsers", "Context");
      });
 })

 

AJAX binding action method:

[AllowAnonymous]
public JsonResult GetAppUsers()
{
     int applicationid = GetThisApplicationID();
 
     if (applicationid < 1) throw new Exception("Unable to determine application id");
     var adul = GetAllApplicationUsers(applicationid);
 
     var list = adul.Where(a => a.IsValidBadge)
       .Select(u => new
       {
         Text = (!String.IsNullOrEmpty(u.AltDisplayName) ? u.AltDisplayName : u.DisplayName)
                   + " (" + u.UsernameShort + ")",
         Value = u.AirportPersonID
       }).ToList();
 
     list.Insert(0, new  { Text = "Owner Not Set", Value = 0 });
 
     return Json(list, JsonRequestBehavior.AllowGet);
}

 

  •  Target Framework:  4.6.1
  •  ASP.NET MVC: 5.2.6
  •  Microsoft.AspNet.Razor: 3.2.6
  • Microsoft Visual Studio Enterprise 2017 15.8.7

debugging in chrome (Version 69.0.3497.100) but behavior is identical in Edge (Microsoft Edge 42.17134.1.0)

JQuery 1.12.4 (Attempts made with both Kendo included jquery.min.js and full nuget package for jquery)

Issue that is occurring is the deselect operation in the multiselect widget is not removing the entry, either programmatically or through a user event (selecting the 'X') from the model it is bound to. View is generated with view model OwnerPermissions property with one entry.

  1. When entry is removed and submitted to the forms POST action the view model OwnerPermissions property has the original value.
  2. When entry is removed and an entry added and submitted to the forms POST action the view model OwnerPermissions property contains original initial value along with new value.
  3. When an entry is added to the mutliselect and then the original entry is deleted, same as #3 results, submitted to the forms POST action the view model OwnerPermissions property contains original initial value along with new value.

If an attempt is made to programmatically remove the entry in javascript using the Deselect Event, by calling <kendo.ui.MultiSelect>.value() method with an empty array [] a javascript exception is throw (see below) when the <kendo.ui.MultiSelect>.trigger("change") is called.

function onDeselectOwnerPermissions(e) {
   var owmerMS =  $('#frm-context #OwnerPermissions').data("kendoMultiSelect");
   if(!owmerMS) {return;}
    var dataItem = e.dataItem;
 
    if(dataItem.Value && dataItem.Value > 0) {
         var selectapid = dataItem.Value;
         var selected = owmerMS.value();
 
          selected = jQuery.grep(selected, function(value) {
              return value != selectapid;
          });
          owmerMS.value(selected);
          owmerMS.trigger("change");
    }
 }

 

Exception thrown when <kendo.ui.MultiSelect>.value() is passed an empty array to clear selected.

kendo.all.js:41785 Uncaught TypeError: l.select(...).done is not a function
    at init._removeTag (kendo.all.js:41785)
    at init._tagListClick (kendo.all.js:41795)
    at HTMLSpanElement.r (jquery?v=JL596WEzEYSLK79KRL4It4N63VXpRlW4A824KHlhVLc1:1)
    at HTMLUListElement.dispatch (jquery?v=JL596WEzEYSLK79KRL4It4N63VXpRlW4A824KHlhVLc1:1)
    at HTMLUListElement.a.handle (jquery?v=JL596WEzEYSLK79KRL4It4N63VXpRlW4A824KHlhVLc1:1)
_removeTag @ kendo.all.js:41785
_tagListClick @ kendo.all.js:41795
r @ jquery?v=JL596WEzEYSLK79KRL4It4N63VXpRlW4A824KHlhVLc1:1
dispatch @ jquery?v=JL596WEzEYSLK79KRL4It4N63VXpRlW4A824KHlhVLc1:1
a.handle @ jquery?v=JL596WEzEYSLK79KRL4It4N63VXpRlW4A824KHlhVLc1:1

 

This is the Htmlhelper generated markup:

<div class="k-widget k-multiselect k-multiselect-clearable" unselectable="on" title="" style="">
   <div class="k-multiselect-wrap k-floatwrap" unselectable="on">
      <ul role="listbox" unselectable="on" class="k-reset" id="OwnerPermissions_taglist">
        <li class="k-button" unselectable="on">
          <span unselectable="on">Stacy (stacyp)</span>
          <span unselectable="on" aria-label="delete" class="k-select">
          <span class="k-icon k-i-close"></span></span>
        </li>
     </ul>
     <input class="k-input" style="width: 25px" accesskey="" autocomplete="off" role="listbox" title="" aria-expanded="false" tabindex="0" aria-describedby="OwnerPermissions_taglist" aria-owns="OwnerPermissions_taglist OwnerPermissions_listbox" aria-disabled="false" aria-busy="false">
        <span unselectable="on" class="k-icon k-clear-value k-i-close" title="clear" role="button" tabindex="-1"></span>
        <span class="k-icon k-i-loading k-hidden"></span>
   </div>
<select id="OwnerPermissions" multiple="multiple" name="OwnerPermissions" data-role="multiselect" aria-disabled="false" style="display: none;">
   <option value="0">Owner Not Set</option>
   <option value="15336">Brian (brianc)</option>
   <option value="62278" selected="">Stacy (stacyp)</option>
</select>
<span style="font-family: "Open Sans", sans-serif; font-size: 12px; font-stretch: 100%; font-style: normal; font-weight: 400; letter-spacing: normal; text-transform: none; line-height: 24.8571px; position: absolute; visibility: hidden; top: -3333px; left: -3333px;">
</span>

</div>

<script>
    kendo.syncReady(function(){jQuery("#OwnerPermissions").kendoMultiSelect({"select":onSelectOwnerPermissions,"dataSource":{"transport":{"read":{"url":"/Context/GetAppUsers","data":function() { return kendo.ui.MultiSelect.requestData(jQuery("#OwnerPermissions")); }},"prefix":""},"serverFiltering":true,"filter":[],"schema":{"errors":"Errors"}},"dataTextField":"Text","dataValueField":"Value","value":[62278]});});
</script>
 

Note: The logic of the onSelectOwnerPermissions function the select event is bound to commented out to isolate the issue to it was left out of this post for brevity.

 

5 Answers, 1 is accepted

Sort by
0
Stacy
Top achievements
Rank 1
answered on 16 Oct 2018, 06:54 PM

Additionally, when the only selected value is delete by user from the multiselect widget the html <ul> is emptied but the <select> <option> from the original view model selected view still has the selected attribute.

 

Resulting markup after the only selected entry of the multiselect is removed.

<div class="k-widget k-multiselect k-multiselect-clearable" unselectable="on" title="" style=""><div class="k-multiselect-wrap k-floatwrap" unselectable="on"><ul role="listbox" unselectable="on" class="k-reset" id="OwnerPermissions_taglist"></ul><input class="k-input k-readonly" style="width: 25px" accesskey="" autocomplete="off" role="listbox" title="" aria-expanded="false" tabindex="0" aria-describedby="OwnerPermissions_taglist" aria-owns="OwnerPermissions_taglist OwnerPermissions_listbox" aria-disabled="false" aria-busy="false"><span unselectable="on" class="k-icon k-clear-value k-i-close k-hidden" title="clear" role="button" tabindex="-1"></span><span class="k-icon k-i-loading k-hidden"></span></div><select id="OwnerPermissions" multiple="multiple" name="OwnerPermissions" data-role="multiselect" aria-disabled="false" style="display: none;"><option value="0">Owner Not Set</option><option value="15336">Brian (brianc)</option><option value="62278" selected="">Stacy  (stacyp)</option></select><span style="font-family: "Open Sans", sans-serif; font-size: 12px; font-stretch: 100%; font-style: normal; font-weight: 400; letter-spacing: normal; text-transform: none; line-height: 24.8571px; position: absolute; visibility: hidden; top: -3333px; left: -3333px;"></span></div>
0
Stacy
Top achievements
Rank 1
answered on 16 Oct 2018, 06:57 PM
Manually removing the selected attribute from the <option> element results in the correct state of the view model being posted when the form is submitted.
0
Ianko
Telerik team
answered on 18 Oct 2018, 01:05 PM
Hello Stacy,

I implemented a similar scenario with the MultiSelect in the attached project. And I was unable to reproduce the described issue. Can you check it out and see if I am missing something that might be relevant to the case?

Regards,
Ianko
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Stacy
Top achievements
Rank 1
answered on 18 Oct 2018, 04:57 PM

Thank you for the help Ianko . 

The issue was the GetAppUsers ajax call resulting data for dropdown list of the multiselect.  My test environment data had a duplicate entry resulting in a duplicate <option> in the <select> element probably causing the deselect kendo code that removes the "selected" attribute to fail.

It is unfortunate the kendo scripts aren't more robust to handle issues like this or make it easier to trouble shoot.

 

Thank you again for your help.

0
Ianko
Telerik team
answered on 19 Oct 2018, 04:43 AM
Hello Stacy,

Handling such a case in code would be a bad practice for an UI component. UI components should only show and handle the data that are bound to. Altering it because of duplication or any other reason would lead to harm instead of actual benefits. 

Regards,
Ianko
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
MultiSelect
Asked by
Stacy
Top achievements
Rank 1
Answers by
Stacy
Top achievements
Rank 1
Ianko
Telerik team
Share this question
or