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

Programmatically adding / removing selections

6 Answers 2298 Views
MultiSelect
This is a migrated thread and some comments may be shown as answers.
Keith
Top achievements
Rank 1
Keith asked on 28 Jun 2016, 08:12 PM

Hi

I've been working with the MultiSelect widget for a while now but this has led to a few questions....

Is there anyway to add or remove selections programmatically? I've implemented the following code in the select event but having tried lots of different methods, as suggested in the forums, I cannot get this to work (e.g. clearing the datasource filter and setting value seems to be the most popular). My multiselect is remote bound. My onSelect event is shown below.

Is there a better way of getting the dataItem rather than how I'm doing it in the first line?

Thanks

Keith

private checkSelection(e: kendo.ui.MultiSelectSelectEvent) {
            
    var dataItem = e.item.data().$$kendoScope.dataItem;
    var hidSelected = dataItem.hid;
    e.preventDefault();
    //check to see if adding this will change anything currently selected     
    _.find(<Array<any>>this.msSelector.dataItems(), (s) => {
          if (s.hid != hidSelected) {
              //check to see if item's ancestor has been selected
              if (_.startsWith(hidSelected, s.hid)) {
                   this.dialogService.showYesNo('Confirm selection',
                            'Adding <span class="text-bold">' + dataItem.name + '</span> will remove <span class="text-bold">' + s.name + '</span>. Do you want to continue?').promise.then((r) => {
                     if (r) {
                          //remove parent                                         
                     }
                     else {
                          //remove new selection
                     }
                     return;
                 });
             }
          }
     });
}

6 Answers, 1 is accepted

Sort by
0
Dimiter Topalov
Telerik team
answered on 30 Jun 2016, 03:17 PM
Hello Keith,

You can check out the following how-to article from our documentation that shows selecting/deselecting all items programmatically and adjust it to select/deselect specific items only:

http://docs.telerik.com/kendo-ui/controls/editors/multiselect/how-to/select-deselect-all-items

Let us know if you need further assistance.

Regards,
Dimiter Topalov
Telerik
Get started with Kendo UI in days. Online training courses help you quickly implement components into your apps.
0
Keith
Top achievements
Rank 1
answered on 01 Jul 2016, 10:36 AM

Hi Dimiter

Thanks for your response but I'd already looked at that How-To but it seems to work in a different way - all items are local and so already exist in the DataSource. I'm trying to do this using a service.

When I add an item into the selection, the server is called but the filter is blank and so since my service returns the top 100 items (and the selected item is not contained in this list) it doesn't get included in the data source. Having said all of that, I already have an instance of the item I would like to add, so having it going back to the server is not that important.

Since I have an instance of the item to add, manually adding into the data source and pushing its ID into the selection doesn't always seem to work. Here's some sample code which isn't exactly the same as I'm trying to do but is a good start...

<!DOCTYPE html>
<html>
<head>
    <style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
    <title></title>
    <link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.2.607/styles/kendo.metro.min.css" />
    <link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.2.607/styles/kendo.default.mobile.min.css" />
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
</head>
<body>
<div id="example" ng-app="KendoDemos">
    <div class="demo-section k-content" ng-controller="MyCtrl as ctrl">
      <h4>Refresh page after each test</h4>
        <ul>
          <li>Click Add - Works but selector only includes new item. How do you clear the filter?</li>
          <li>Click in selector (optionally select an item) and click Add - Works</li>
          <li>Click in selector, type Tom and select one. Click Add - Doesn't work</li>
      </ul>
        <h4>Select product</h4>
        <kendo-multi-select k-scope-field="ctrl.ms" k-options="ctrl.selectOptions" k-ng-model="ctrl.selectedIds"></kendo-multi-select>
        <p ng-show="ctrl.selectedIds.length" style="padding-top: 1em;">Selected: {{ ctrl.selectedIds }}</p>
       
      <button ng-click="ctrl.add()">Add</button>
    </div> 
</div>
<script>
  angular.module("KendoDemos", [ "kendo.directives" ])
    .controller("MyCtrl", function($scope){
        this.selectOptions = {
            placeholder: "Select products...",
            itemTemplate: '<span class="order-id">#= OrderID #</span> #= ShipName #, #= ShipCountry #',
            dataTextField: "ShipName",
            dataValueField: "OrderID",
            valuePrimitive: true,
            autoBind: false,
            dataSource: {
                type: "odata",
              pageSize: 10,
               serverPaging: true,
               serverFiltering: true,
                transport: {
                        read: "//demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
                },
                schema: {
                 model: {
                   fields: {
                     OrderID: { type: "number" },
                     Freight: { type: "number" },
                     ShipName: { type: "string" },
                     OrderDate: { type: "date" },
                     ShipCountry: { type: "string" }
                   }
                 }
              }
            }
        };
        this.selectedIds = [];
     
     this.add = function(e) {  
        var itemToAdd = {
          OrderID: 10926,
          Freight: 123,
          ShipName: 'Test',
          OrderDate: '2016-07-01',
          ShipCountry: 'Country',
        }
         
        this.ms.dataSource.add(itemToAdd);
        this.selectedIds.push(itemToAdd.OrderID);
      }
      })
</script>
</body>
</html>


Thanks
Keith


0
Keith
Top achievements
Rank 1
answered on 01 Jul 2016, 11:45 AM
I've created a Plunker using the above code so you can see the problem.

Thanks

0
Dimiter Topalov
Telerik team
answered on 05 Jul 2016, 07:56 AM
Hello Keith,

The described issue is caused by the following known limitation of server filtering in the context of the Kendo UI dropdown widgets:

http://docs.telerik.com/kendo-ui/controls/editors/combobox/serverfiltering#known-limitations

To be able to add items that are not in the current page of data to the MultiSelect's value, you should utilize the Virtualization functionality of the widget, as described in the following documentation article:

http://docs.telerik.com/kendo-ui/controls/editors/combobox/virtualization#virtualization

You can also check out our MultiSelect Virtualization demo for a sample implementation of the required configuration and valueMapper:

http://demos.telerik.com/kendo-ui/multiselect/virtualization

I hope this helps, but if I am missing something, please describe the scenario, and the desired functionality in further details, so we can provide further, and more to-the-point suggestions.

Regards,
Dimiter Topalov
Telerik
Get started with Kendo UI in days. Online training courses help you quickly implement components into your apps.
0
Barry P
Top achievements
Rank 1
answered on 21 Feb 2017, 08:57 PM

I have a related problem with this.

I have a successfully virtualized MultiSelect working.

As a user types in to the field searching for a specific record, they find there isn't one.  Through a separate button on the page, they execute a function to add to the list of options.  This triggers an Ajax call that updates the lookup table adding a new record, and it returns the key for that record. Upon success, it updates the value of the MultiSelect to add the newly created record to the list of selected records.

The problem I'm running into is that the server's mapper function is returning (for example) 1267 for the index into the dataset where the newly created record is found.  Since the dataset is sorted alphabetically, this is not going to be the last record.  When the control reads the return from the mapper, it says, "Hey, I've already retrieved the record at position 1267, and it displays it without going back to the server to update the list of options.  The problem is that this is what WAS at 1267 (and is now at 1268) is being selected - sometimes. 

I had the following records in my database.  ..., test, theory, ...  I typed test into the MultiSelect, and saw that (of course) test1 wasn't in there.  So, I clicked on the button I added, entered my new value (test1) and saved.  The MultiSelect successfully selected test1.  I then clicked on the button again, and I entered another new value (test2) and saved.  The MultiSelect showed test1 and theory.  If I clicked on the MultiSelect to view the items, I indeed saw test1 followed by theory.  However, if I typed "test" in for searching and the virtualization kicked in and started talking to the server, I saw test1 and test2.  Now, if I cleared my search text, I saw ..., test, test1, test2, theory, ...

I think what I'm looking for is a way to manually clear or reset the data already retrieved for pages of selections the MultiSelect has seen.  When I successfully add a new lookup value, I want to call a method that tells the MultiSelect, "Hey, your cached data isn't quite accurate anymore.  You're going to need to go to the server to get current selections.

Is there a way to do this?

0
Dimiter Topalov
Telerik team
answered on 23 Feb 2017, 02:19 PM
Hello Barry,

Unfortunately, any manual data operations, such as add, filter, remove, page, read, etc. can lead to undesired behavior, and is not supported in scenarios with virtualization (this applies to all Dropdown widgets that share common virtualization functionality):

http://docs.telerik.com/kendo-ui/controls/editors/combobox/virtualization#known-limitations

You can try creating a new DataSource after adding the item to the remote service via the described AJAX call, and use the setDataSource() method to set it to the MultiSelect, but I cannot guarantee this would yield the desired effect in the specific scenario.

In general, non-supported scenarios and/or feature customization fall outside the scope of our support service, but if you send us an isolated runnable project, similar to the ones in our online demos, we can take a look, and try to provide a relevant suggestion, if one is available, and the desired functionality can be achieved with our API.

Regards,
Dimiter Topalov
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
MultiSelect
Asked by
Keith
Top achievements
Rank 1
Answers by
Dimiter Topalov
Telerik team
Keith
Top achievements
Rank 1
Barry P
Top achievements
Rank 1
Share this question
or