MultiSelect not updating view model

6 posts, 0 answers
  1. Stacy
    Stacy avatar
    5 posts
    Member since:
    Sep 2015

    Posted 16 Oct 2018 Link to this post

    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.

     

  2. Stacy
    Stacy avatar
    5 posts
    Member since:
    Sep 2015

    Posted 16 Oct 2018 Link to this post

    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>
  3. Stacy
    Stacy avatar
    5 posts
    Member since:
    Sep 2015

    Posted 16 Oct 2018 in reply to Stacy Link to this post

    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.
  4. Ianko
    Admin
    Ianko avatar
    1898 posts

    Posted 18 Oct 2018 Link to this post

    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.
  5. Stacy
    Stacy avatar
    5 posts
    Member since:
    Sep 2015

    Posted 18 Oct 2018 in reply to Ianko Link to this post

    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.

  6. Ianko
    Admin
    Ianko avatar
    1898 posts

    Posted 18 Oct 2018 Link to this post

    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.
Back to Top