Values clearing from multiselect UI, but still sent to controller in a custom grid edit

1 Answer 36 Views
Editor Grid MultiSelect
Eric
Top achievements
Rank 1
Eric asked on 02 May 2025, 03:43 AM | edited on 02 May 2025, 03:44 AM

I have a grid with custom editors and they are bound to the grid as such.

columns.Bound(x => x.Parent).EditorTemplateName("ParentEditor").ClientTemplate("#= Parent === undefined || Parent === null ? '' : parentTemplate(Parent)#");
columns.Bound(x => x.Child).EditorTemplateName("ChildEditor").ClientTemplate("#= Child === undefined || Child === null ? '' : childTemplate(Child)#");

The two editor templates look like this:

@model List<ParentViewModel>  
@(Html.Kendo()  
     .MultiSelectFor(m => m)  
     .DataTextField("Name")  
     .DataValueField("Id")  
     .Placeholder("Select one or more parents")  
     .AutoBind(true)  
     .TagMode(MultiSelectTagMode.Multiple)   
     .DataSource(source =>  
     {  
         source  
         .Read(read =>  
         {  
             read.Action("GetParent", "Lookup");  
         });  
     })  
     .Events(events => events.Change("onParentChange"))  
)  


@model List<ChildViewModel>
@(Html.Kendo()
      .MultiSelectFor(m => m)
      .DataTextField("Name")
      .DataValueField("Id")
      .Placeholder("Select one or more children")
      .AutoBind(true)
      .TagMode(MultiSelectTagMode.Multiple)
      .DataSource(source =>
      {
          source
          .Read(read =>
          {
              read.Action("GetChild", "Lookup").Data("getCurrentParents");
          })
          ;
      })
)

The UI is properly populating when the grid loads and looks like this:

Coumn Parent|Column Child
A           |A1
B           |B1, B2

When the user edits the row and removes item B from Column Parent, this code is invoked (which I got from Kendo UI Snippet | Kendo UI Dojo)

function onParentChange(e) {
    var selectedonParentChange = this.value();
    let dataItems = e.sender.dataItems();

	var multiSelect = $("#Child").data("kendoMultiSelect");
	var value = multiSelect.value();
	multiSelect.dataSource.filter(getFilterObj(dataItems));
	multiSelect.dataSource.filter({});  // Adding or removing has no effect
    multiSelect.refresh();
	multiSelect.value(value);
	console.log("Second value: " + multiSelect.value());
    var dataSource = multiSelect.dataSource;
    dataSource.read();
}

function getFilterObj(dataItems){
  let filtObj = {
    logic: "or",
    filters: [],
  };

  if(dataItems.length > 0){
    for (var i = 0; i < dataItems.length; i++) {
      filtObj.filters.push({
        field: "ParentId",
        operator: "eq",
        value: dataItems[i].Id
      });
    }
  } else {
    filtObj.filters.push({
        field: "ParentId",
        operator: "eq",
        value: ""
      });
  }

  return filtObj;
}

After the code runs, the UI looks like this:
Coumn Parent|Column Child
A           |A1

So far so good.  The problem is that when the user hits save this ends up on the Network in the form data:

Parent[0].Id: ParentIdA
Parent[0].Name: A
Child[0].Id: ChildId1
Child[0].Name: A1
Child[0].ParentId: ParentIdA
Child[1].Id: ChildId2
Child[1].Name: B1
Child[1].ParentId: ParentIdB
Child[2].Id: ChildId3
Child[2].Name: B2
Child[2].ParentId: ParentIdB
Although B1 and B2 no longer display in the UI, they are still being sent to the controller when the item is saved.  I'm not sure how to prevent them from being sent when they are no longer in the UI.

Kendo Version: 2024.4.1112

1 Answer, 1 is accepted

Sort by
0
Eyup
Telerik team
answered on 06 May 2025, 07:12 PM

Hi Eric,

 

Thank you for reaching out.

I have gone through the provided code snippets and noticed that the javascript logic uses the filter() method:
https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/configuration/filter

Since the filter() method hides the items only visually, the method you should use instead is called remove():
https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/methods/remove

Depending on your binding specifics, you might also need to call sync():
https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/methods/sync

Please follow this suggestion and let me know about the result.

 

Regards,
Eyup
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Eric
Top achievements
Rank 1
commented on 07 May 2025, 03:22 AM | edited

I tried modifying the code as follows and sadly still got the same results.  As a side note:  The read of the child will populate the datasource with only those values that are valid for the Parent, so I would think it would be the same as removing the items from the datasource.  I would think the sync essentially does the same thing as rereading and getting just the values that should be there.


var selectedonParentChange = this.value();
    let dataItems = e.sender.dataItems();

	var multiSelect = $("#Child").data("kendoMultiSelect");
	var value = multiSelect.value();
	multiSelect.dataSource.filter(getFilterObj(dataItems));
	multiSelect.dataSource.filter({});  

var
previous = this._savedOld; var current = this.value(); var diff = []; if (previous) { diff = $(previous).not(current).get(); } this._savedOld = current.slice(0); var dataSource = multiSelect.dataSource; if(diff.length > 0){ var items = dataSource.data(); // Get all items for (var i = items.length - 1; i >= 0; i--) { if (items[i].ParentId === diff) { dataSource.remove(items[i]); } } } dataSource.read();

Eyup
Telerik team
commented on 09 May 2025, 09:06 AM

Hi Eric,

Can you please show your entire configuration in a standalone live REPL sample and send the URL to us so we can analyze it deeper on our side?
https://www.telerik.com/aspnet-core-ui/documentation/knowledge-base/repl-isolate-sample

Eric
Top achievements
Rank 1
commented on 14 May 2025, 02:27 AM

OK.  I'll work on that this week and post back when I get it up there.
Eric
Top achievements
Rank 1
commented on 16 May 2025, 05:13 AM

I've been working to create the sample.  I've been unable to get ClientTemplate and EditorTemplateName to work in the REPL.  I suspect the EditorTemplate is a critical part of the problem.  Are those functions supported?  I need to have change events and pretend to load different data on the Bind for one of the EditorTemplates.
Anton Mironov
Telerik team
commented on 16 May 2025, 08:23 AM

Hi Eric,

Yes, the EditorTemplates should be added in the ~Views/Shared/EditorTemplates folder of a project. In a REPL we can not place these files.

If you need to represent the functionality of the EditorTemplate/s, feel free to send us a sample project where the issue is represented:

If no changes are needed in the EditorTemplates, feel free to use this REPL example:

Kind Regards,
Anton Mironov

 

Tags
Editor Grid MultiSelect
Asked by
Eric
Top achievements
Rank 1
Answers by
Eyup
Telerik team
Share this question
or