Telerik blogs

You know that a platform has become truly ubiquitous when it starts creating UI components that bleed into everyday computing. You can see examples of this everywhere. Twitter gave us the "pull to refresh" interaction on mobile ListViews. That one was so popular that Apple put it into their default Mail application in iOS 6 and many other mobile apps such as the Facebook App have adopted it as well. Kendo UI additionally provides this feature in the Mobile ListView as it's become the way that people expect to refresh data in on mobile devices.

This latest release of Kendo UI includes another very common UI component made famous by Facebook: The Multi Select. At it's most basic level, the MultiSelect is an enhancement on the standard HTML <select> element. It allows the user to pick multiple items, each of which are represented by an autonomous element within the select. The AutoComplete behviour can be added to further tame very large lists. This is often seen in the context of messaging since you might be trying to message more than one person, and your list of contacts is likely very very large. It's also often seen in a blog editor where you are adding or selecting from existing tags.

A Simple MultiSelect

You can create a simple MultiSelect by using a standard HTML select, then using jQuery to transform it into a suped-up Kendo UI MultiSelect.

A Simple MultiSelect

<select multiple="multiple" id="friends">
  <option value="0">Derick Bailey</option>
  <option value="1">Todd Anglin</option>
  <option value="2">Jim Cowart</option>
  <option value="3">Atanas Korchev</option>
  <option value"4">Rob Lauer</option>
  <option value="5">Flint Lockwood</option>
</select>

<script>

  $(function() {
    $("#friends").kendoMultiSelect({
      placeholder: "Select friends..."
    });
  });

</script>

Interactive Sample

Notice that the "multiple" attribute is set on the select. This must be set on a static list of items in order for the MultiSelect to function properly. I've also set a placeholder. If you wanted to have a few of the names show up by default, you would use the selected attribute on the required option items.

Setting Default Selected Values

<select multiple="multiple" id="friends">
  <option value="0">Derick Bailey</option>
  <option value="1" selected>Todd Anglin</option>
  <option value="2">Jim Cowart</option>
  <option value="3">Atanas Korchev</option>
  <option value"4">Rob Lauer</option>
  <option value="5">Flint Lockwood</option>
</select>

<script>

  $(function() {
    $("#friends").kendoMultiSelect();
  };

</script>

Interactive Sample

Also, you cannot just enter free text into this field. If it's not an item in the list, it's not accepted by the control.

Remote Data

Of course you it's more likely that you will be hooking into some data in a database or in a remote service. The MultiSelect uses the Kendo UI DataSource just like all other Kendo UI Widgets.

MultiSelect With Remote Data

// use select as the multiselect
<select id="friends" ></select>
<script>

  $(function() {

        // a multiselect hooked up to a remote endpoint
    $("#friends").kendoMultiSelect({
      dataTextField: "ContactName",
      dataValueField: "CustomerID",
      dataSource: {
        transport: {
          read: {
            dataType: "jsonp",
            url: "http://demos.kendoui.com/service/Customers"
          }
        }
      }
    });

  }(jQuery));

</script>

Interactive Sample

Server Filtering

Just like the AutoComplete, the MultiSelect will delegate the filtering operation to the server. This can be toggled on simply by setting serverFiltering: true on the DataSource. If you have been working with Kendo UI for any amount of time, this should all be quite familiar. When you toggle the server paging on, the MultiSelect will fire a request for data once you reach the minLength, which is by default 1.

In this example I connect to the StackExchange API to search for users. A minimum of 3 characters is required for each search.

Remote Data With Filtering

$(function() {

    // URL to StackExchange API
    var soURL = "https://api.stackexchange.com/2.1/users?sitte=stackoverflow&order=desc&sort=reputation&filter=default";

    $("#users").kendoMultiSelect({
      placeholder: "Select A User..",
      minLength: 3,
      dataTextField: "display_name",
      dataValueField: "user_id",
      dataSource: {
        serverFiltering: true,
        transport: {
          dataType: "jsonp",
          read: soURL,
          parameterMap: function(options, operation) {
            // if there is a value in the autocomplete...
            if (options.filter) {
              return {
                // this will append "inname" to the querystring set to
                // the current value of the multiSelect
                inname: options.filter.filters[0].value  
              }
            }
          }
        },
        schema: {
          data: "items"
        }
      }
    });

});

Interactive Sample

Also notice that I set autoBind to false. Be default, the MultiSelect reads the remote data source when it loads the control. I don't want it to read until I trigger it by typing so I'm telling it NOT to autoBind.

Templates

This is the beautiful thing about HTML. You are virtually unrestricted in what you can show as both the the item that appears in the dropdown, and the tag that appears in the select box after an item is selected.

In the example above, StackOverflow actually returns a profile image along with each user. This image is set to either their Gravatar, or a StackOverflow generated image if they don't have a Gravatar set. I can use that image not only in the dropdown list, but also in the tag that appears in the select box.

Custom Templates

<script type="text/x-kendo-template" id="item-template">
  <div class="item row">
    <div class="profile">
      <img width="50" height="50" src="#: profile_image #" >
    </div>
    <div class="info">
      <span>#: display_name # <b>#: reputation #</b></span>
    </div>
  </div>
</script>

<script type="text/x-kendo-template" id="tag-template">
  <img src="#: profile_image #" width="20" height="20"> #: display_name #
</script>

<script>

$(function() {

  var soURL = "https://api.stackexchange.com/2.1/users?site=stackoverflow&order=desc&sort=reputation&filter=default";

  $("#users").kendoMultiSelect({
    placeholder: "Select A User...",
    autoBind: false,
    minLength: 3,
    // set the template for each item
    itemTemplate: kendo.template($("#item-template").html()),
    // set the template for the item tags
    tagTemplate: kendo.template($("#tag-template").html()),
    dataValueField: "user_id",
    dataSource: {
      serverFiltering: true,
      transport: {
        dataType: "jsonp",
        read: soURL,
        parameterMap: function(options, operation) {
          if (options.filter) {
            return {
              inname: options.filter.filters[0].value || "" 
            }
          }
        }
      },
      schema: {
        data: "items"
      }
    }
  });

});

</script>

Interactive Sample

Interacting With Events

The MultiSelect has several events and methods that allow you to interact with it programatically.

I can use the value method to get the value of the items that are currently in the MultiSelect. Remember that I set the value of the items in the MultiSelect to be the user id, so that's what is returned by the value() method.

In this example, I display the selected value(s) below the buttons to show what the user selected.

Getting The Value Of The MultiSelect

// on the "send" button click
$("#send").on("click", function() {

  var selected = "<h3>You Selected</h3>";

  // get a reference to the MultiSelect
  var users = $("#users").getKendoMultiSelect();

  // iterate through the value array and create a p tag
  // which will be appended as the content of the popup window
  $.each(users.value(), function() {
    selected += "<p>" + this + "</p>"
  });

  // show the selected values
  $("#output").html(selected);
});

You might want to get a reference to the actual items in the list. In this case, you want to use the dataItems method. This gets you a list of the actual data items which are in the list, and all of their properties. That means that you could then rewrite the above value code as such:

Getting The Data items In The MultiSelect

// on the send button click
$("#send").on("click", function() {

  var selected = "<h4>You Selected</h4>";

  // get a reference to the MultiSelect
  var users = $("#users").getKendoMultiSelect();

  // iterate through all the data items and create a p tag
  // with the display_name property
  $.each(users.dataItems(), function() {
    selected += "<p>" + this.display_name + "</p>"
  });

  // show the selected values
  $("#output").html(selected);
});

Interactive Sample

A Welcome Addition

The MultiSelect is a welcome addition to the Kendo UI Web widget suite. The AutoComplete has always been capable of allowing multiple values, but a "Facebook" like MultiSelect was highly requested on the UserVoice forums. You spoke, we heard. Grab Kendo UI and checkout the new MultiSelect widget for yourself.


Comments

Comments are disabled in preview mode.