Search code examples
jquerykendo-uikendo-listview

Filter Kendo ListView with search bar and dropdowns


I have a Kendo ListView on my page and I would like to be able to use a custom search bar and two Kendo DropDownLists to allow the user to filter the ListView.

I have no problem filtering while just using the search bar or just using the dropdowns but I am running into issues trying to figure out how to be able to filter the data using all three at the same time.

For example, I want to be able to type something into the search and have it filter the search term. Then with the results that are shown, I want to be able to filter those results down by using either dropdown.

I've got a full example here: https://codepen.io/anon/pen/eRpoag

To test it out, type into the search bar "test". You'll notice that it filters down to one result. Now expand the "Product Type" dropdown and select "Type 1". Notice how it then shows all products with that type? It should show no results because I only want to apply that filter on top of the current ones.


Solution

  • Thanks to Sandman for providing me with a link to his question which was very similar to mine and which he was able to find a solution for. I have changed his solution a little bit so that it would work for me. Original Solution.

    function applyClientFilters() {
        var listView = $("#ProductsList").data("kendoListView");
        var listViewDataSource = listView.dataSource;
        // clear existing datasource
        listViewDataSource.filter([]);
        // extract selected items from each of the dropdown controls and the search box
        var productType = $("#ProductTypeDropDown").data("kendoDropDownList").value();
        var therapeuticClass = $("#TherapeuticClassDropDown").data("kendoDropDownList").value();
        var searchString = $(".search-filter").val();
        // setup filter object (using and logic)
        var filter = {
            logic: "and",
            filters: [] // ready for filter from each of the dropdowns and search bar
        };
        // push new filter into array of filters with or logic on each filter
        if (productType.length > 0) {
            var productTypeFilter = {
                logic: "or",
                filters: [
                    { field: "ProductTypeId", operator: "equals", value: productType }
                ]
            };
            filter.filters.push(productTypeFilter);
        }
    
    
        if (therapeuticClass.length > 0) {
            var therapeuticClassFilter = {
                logic: "or",
                filters: [
                    {
                        field: "TherapeuticClasses",
                        operator: function (itemValue, value) {
                            return itemValue &&
                                itemValue.find(function (item) {
                                    if (item.Name.toLowerCase().indexOf(value.toLowerCase()) !== -1) {
                                        return true;
                                    } else {
                                        return false;
                                    }
                                });
                        },
                        value: therapeuticClass
                    }
                ]
            };
            filter.filters.push(therapeuticClassFilter);
        }
    
        if (searchString.length > 0) {
            var searchFilter = {
                logic: "or",
                filters: [
                    { field: "Name", operator: "startswith", value: searchString },
                    { field: "ProductTypeDisplay", operator: "startswith", value: searchString },
                    { field: "NdcCode", operator: "startswith", value: searchString },
                    {
                        field: "TherapeuticClasses",
                        operator: function(itemValue, value) {
                            return itemValue &&
                                itemValue.find(function(item) {
                                    // If a therapeutic class name matches search then return true
                                    if (item.Name.toLowerCase().indexOf(value.toLowerCase()) !== -1) {
                                        return true;
                                    } else {
                                        return false;
                                    }
                                });
                        },
                        value: searchString
                    }
                ]
            };
            filter.filters.push(searchFilter);
        }
    
        // apply filter query to datasource
        listViewDataSource.query({
            filter: filter
        });
    }
    

    Then I just call the applyClientFilters() function in the change event of each dropdown and search box and the filtering works great.