New to Telerik UI for ASP.NET Core? Download free 30-day trial

Using Both Multi-Checkbox and Default Grid Filtering

Environment

Product Progress® Telerik® UI Grid for UI for ASP.NET Core
Progress Telerik UI version 2021.3.1207

Description

By design, the Grid column does not support the multi-checkbox and the default menu filter. How can I modify the Grid to use both multi-checkbox and default filtering?

Solution

  1. Enable the Filterable() option of the Grid.
  2. Handle the FilterMenuInit event of the Grid that fires when the column filter menu is initialized and opens for the first time.
  3. Within the FilterMenuInit event handler, check the name of the filtered column and append a Kendo UI for jQuery ListView to the default filter menu that will display the checkboxes.
  4. Handle the submit event of the column filer menu, prevent its default action, and filter the Grid manually based on the selected checkboxes and filter menu values.
    @(Html.Kendo().Grid<OrderViewModel>()
        .Name("grid")
        .Columns(columns =>
        {
            columns.Bound(p => p.ShipName);
            columns.Bound(e => e.ShipCity).Filterable(ftb => ftb.Multi(true).Search(true));
        })
        .Filterable()
        .Events(ev => ev.FilterMenuInit("onFilterMenuInit"))
        ... // Other configuration.
        .DataSource(dataSource => dataSource
            .Ajax()
            .PageSize(10)
            .Read(read => read.Action("Read", "Grid"))
        )
    )
    @addTagHelper *, Kendo.Mvc

    <kendo-grid name="grid" on-filter-menu-init="onFilterMenuInit">
        <datasource type="DataSourceTagHelperType.Ajax" page-size="10">
            <transport>
                <read url="@Url.Action("Read","Grid")"/>
            </transport>
        </datasource>
        <columns>
            <column field="ShipName"/>
            <column field="ShipCity">
                <filterable enabled="true" multi="true" search="true"/>
            </column>
        </columns>
        <filterable enabled="true"/>
        <!-- Other configuration-->
    </kendo-grid>
    <script>
        function onFilterMenuInit(e) {
            if (e.field == "ShipName") { // Check if the "ShipName" column filter menu opens.
                initCheckboxFilter.call(this, e); // Initialize the ListView widget to display the checkboxes.
            }
        }

        function initCheckboxFilter(e) {
            var popup = e.container.data("kendoPopup");
            var dataSource = this.dataSource;
            var field = e.field;
            var checkboxesDataSource = new kendo.data.DataSource({ // Set up the DataSource for the ListView by using the "ShipName" column data.
                data: uniqueForField(dataSource.data(), field)
            });


            var helpTextElement = e.container.children(":first").children(":first");
            // Define the ListView and insert it to the filter menu container element.
            var element = $("<div class='checkbox-container'></div>").insertAfter(helpTextElement).kendoListView({
                dataSource: checkboxesDataSource,
                template: "<div><input type='checkbox' class='k-checkbox k-checkbox-md k-rounded-md' value='#:" + field + "#'/> #:" + field + "#</div>"
            });
            // Handle the "submit" event of the column filter menu.
            e.container.find("[type='submit']").click(function (e) {
                e.preventDefault();
                e.stopPropagation();
                var filter = dataSource.filter() || { logic: "or", filters: [] };
                var fieldFilters = $.map(element.find(":checkbox:checked"), function (input) {
                    return {
                        field: field,
                        operator: "eq",
                        value: input.value
                    };
                });


                // Default filter menu options.
                var defaultFilters = {};
                var defaultFilterValue1 = $(".k-filter-menu-container").find("input[title='Value']").val();
                var defaultFilterValue2 = $(".k-filter-menu-container").find("input[title='Additional value']").val();
                var operator1 = $(".k-filter-menu-container").find("[data-role='dropdownlist']").eq(0).getKendoDropDownList().value();
                var operator2 = $(".k-filter-menu-container").find("[data-role='dropdownlist']").eq(2).getKendoDropDownList().value();
                var defaultFilterLogic = $(".k-filter-menu-container").find("[data-role='dropdownlist']").eq(1).getKendoDropDownList().value();

                if (defaultFilterValue1 != "") {
                    defaultFilters = {
                        logic: defaultFilterLogic,
                        filters: [
                            { field: "ShipName", operator: operator1, value: defaultFilterValue1 }
                        ]
                    };
                };
                if (defaultFilterValue2 != "") {
                    defaultFilters.filters.push({ field: "ShipName", operator: operator2, value: defaultFilterValue2 });
                }


                if (fieldFilters.length || defaultFilters.filters) {
                    removeFiltersForField(filter, field);

                    if (fieldFilters.length) {
                        filter.filters.push({
                            logic: "or",
                            filters: fieldFilters
                        });
                    }

                    if (defaultFilters.filters) {
                        filter.filters.push({
                            logic: defaultFilters.logic,
                            filters: defaultFilters.filters
                        });
                    }

                    dataSource.filter(filter);
                }
                popup.close();
            });
        }

        function removeFiltersForField(expression, field) {
            if (expression.filters) {
                expression.filters = $.grep(expression.filters, function (filter) {
                    removeFiltersForField(filter, field);
                    if (filter.filters) {
                        return filter.filters.length;
                    } else {
                        return filter.field != field;
                    }
                });
            }
        }

        function uniqueForField(data, field) {
            var map = {};
            var result = [];
            var item;
            for (var i = 0; i < data.length; i++) {
                item = data[i];
                if (!map[item[field]]) {
                    result.push(item.toJSON());
                    map[item[field]] = true;
                }
            }
            return result;
        }
    </script>
<style>
    .checkbox-container {
        max-height: 200px;
        overflow:auto;
    }
</style>

For a runnable example based on the code above, refer to the following REPL samples:

More ASP.NET Core Grid Resources

See Also

In this article