Programmatically adding / removing selections

7 posts, 0 answers
  1. Keith
    Keith avatar
    88 posts
    Member since:
    May 2007

    Posted 28 Jun 2016 Link to this post

    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;
                     });
                 }
              }
         });
    }

  2. Dimiter Topalov
    Admin
    Dimiter Topalov avatar
    570 posts

    Posted 30 Jun 2016 Link to this post

    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.
  3. Keith
    Keith avatar
    88 posts
    Member since:
    May 2007

    Posted 01 Jul 2016 Link to this post

    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


  4. Keith
    Keith avatar
    88 posts
    Member since:
    May 2007

    Posted 01 Jul 2016 in reply to Keith Link to this post

    I've created a Plunker using the above code so you can see the problem.

    Thanks

  5. Dimiter Topalov
    Admin
    Dimiter Topalov avatar
    570 posts

    Posted 05 Jul 2016 Link to this post

    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.
  6. Barry P
    Barry P avatar
    14 posts
    Member since:
    Aug 2006

    Posted 21 Feb in reply to Dimiter Topalov Link to this post

    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?

  7. Dimiter Topalov
    Admin
    Dimiter Topalov avatar
    570 posts

    Posted 23 Feb Link to this post

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