Search code examples
asp.net-mvcasp.net-mvc-4kendo-uikendo-multiselect

How do I create Kendo ComboBox with multiple selected items using server filtering


I'm creating an email client, where I'd like the name/address lookup to work the same way it does in, say, Gmail.

Kendo offer a ComboBox which will allow user to write free-form text, or to select an item from the filtered list.

Kendo also offer a Multiselect which allows user to select multiple items from the list.

What I need is a combination of both...


Solution

  • The best approach is to use Multiselect box, and if the search item cannot be found in database, add it to the resultset. You'll need to pass in a separate search field "search" (or whatever you want to call it) to the action.

    Initialise the Multiselect in you .shtml

    $('#recipient').kendoMultiSelect({
            placeholder: "Type name or email address...",
            dataTextField: "Name",
            dataValueField: "Email",
            template: "#: Name # <#: Email #>",
            autoBind: false,
            filter: "contains",
            dataSource: {
                type: "json",
                serverFiltering: true,
                transport: {
                    read: {
                        url: "/Email/Contacts",
                        dataType: "json",
                        data: function () {
                            return { // THIS IS YOUR SEARCH FIELD
                                search: $('#recipient').data("kendoMultiSelect").input.val()
                            }
                        }
                    }
                },
                schema: {
                    type: "json",
                    data: "Data",
                    model: {
                        fields: {
                            Name: { field: "Name", type: "string" },
                            Email: { field: "Email", type: "string" }
                        }
                    }
                }
            }
        });
    

    Your controller will have this code:

        public ActionResult Contacts(string search, [DataSourceRequest]DataSourceRequest request)
        {            
            if(search == null || search.Length == 0) // Only query once user types stuff in to avoid unnecessary db load
            {
                return Json((new List<EmailNamePair>()).ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
            }
    
            var PeopleList = from moc in db.MeansOfContacts
                             orderby moc.Firstname, moc.LastName, moc.Email
                             select new EmailNamePair()
                             {
                                 Email = moc.Email,
                                 Name = moc.Firstname + " " + moc.LastName
                             };
    
            // Check that the searched value exists
            var ds = PeopleList.ToDataSourceResult(request);
            if (ds.Total != 0)
            {
                return Json(ds, JsonRequestBehavior.AllowGet);
            }
    
            // Custom value that doesn't exist
            var result = PeopleList.ToList();
            result.Add(new EmailNamePair() {
                Email = search,
                Name = search
            });
            return Json(result.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
        }
    

    The newly added items will stay in the MultiSelect box, and will be treated exactly the same as the rest of the items (i.e. removed by clicking on the little cross etc).

    You can also add extra validation to see if the email address is valid before adding it to the datasource. But you get the gist.

    Hope this helps!