This is a migrated thread and some comments may be shown as answers.

Update multi checkbox filter in Column Menu.

1 Answer 146 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Matthias
Top achievements
Rank 1
Matthias asked on 23 Jul 2018, 03:36 PM
Hello.

I try to update the item list in the multi checkbox filter popup by a separate datasource defined by a read action:
therefore I followed the instructions from the forum entry on
https://www.telerik.com/forums/refresh-multi-checkbox-filter-options-when-grid-is-filtered

Here a code snippet (MVC/Razor) :

 columns
    .Bound(column.Field)
    .Filterable(f =>
    {

        // check if field shall use checkbox filter
        if (Array.IndexOf(checkboxFilterFields, column.Field) >= 0)
        //if (column.Field == "StateType" || column.Field == "PhaseShortText")
        {
            f.Multi(true); // activate multi checkbox filter

            // setup checkbox filter list
            f.DataSource(ds => ds.Read(r => r
                .Action("ContractFilterListRead", "Contract", new
                {
                    field = column.Field
                }).Data("getFilterListReadParameters")
                )
            );
        }
    });
    
    
with a Javascript part:
    
<script>
    $(document).ready(function () {
        contractsGridController = new GridController('@(gridId)', '@(gridName)');

        //  bind click event of filter popup for checkbox filter list update
        $(".k-grid-filter").click(function (event) {
            //console.log("Gridfilter clicked");

            var fmc = $(event.target).closest("th").data("kendoFilterMultiCheck");
            if (fmc) {
                // update filter popup content
                fmc.checkSource.read();
                fmc.container.empty();
                fmc.refresh();
            }
        });
    });

    // getFilterReaderParameters gets client side filter and sort string
    getFilterListReadParameters = function () {
        console.log("getFilterReaderParameters()");
        var filterAndSortString = contractsGridController.getGrid().dataItem($(".k-grid-content tr")[0]).PFilterAndSortStr; // get filter and sort string of first data item
        console.log("Contract.Index: getFilterReaderParameters() filter and sort string: " + filterAndSortString);
        return { "filterAndSortString": filterAndSortString };
    };
</script>
    
This works like a charm if I use the grid filter mode "GridFilterMode.Menu".
If I switch to "GridFilterMode.Row" and add a Column Menu that contains the checkbox filter menu,
and changing the $(".k-grid-filter").click(function (event) part to $(".k-header-column-menu").click(function (event)
it doesn't work any more since the corresponding "th" element seems not having a kendoFilterMultiCheck object.
How can I access that kendoFilterMultiCheck of the Column Menu to update the item list?

BR, Matthias

1 Answer, 1 is accepted

Sort by
0
Marin Bratanov
Telerik team
answered on 25 Jul 2018, 02:01 PM
Hi Matthias,

If we start from the multi check filtering demo (https://demos.telerik.com/aspnet-mvc/grid/filter-row) and the second grid with the server data source operations, below are some sample modifications so you can access the FilterMultiCheck (I changed the Country column with regard to the custom parameters).

When the grid has a columnMenu, the custom logic which attaches a click handler to ".k-grid-filter" no longer works because of the different rendering. The recommended approach is to use the columnMenuInit event which is triggered when the user clicks on the column menu icon. Only at this point, will the FilterMultiCheck be initialized.

    <h4>Server Operations</h4>
    @( Html.Kendo().Grid<Kendo.Mvc.Examples.Models.EmployeeViewModel>()
                    .Name("server")
                    .Columns(columns =>
                    {
                        //when ServerOperations of the Grid is enabled, dataSource should be provided for all the Filterable Multi Check columns
                        columns.Bound(e => e.FirstName).Width(220).Filterable(ftb => ftb.Multi(true)
                                        .DataSource(ds => ds.Read(r => r.Action("Unique", "Grid").Data("{ field: 'FirstName' }")))
                                    );
                        columns.Bound(e => e.LastName).Width(220).Filterable(ftb => ftb.Multi(true)
                            .DataSource(ds => ds.Read(r => r.Action("Unique", "Grid").Data("{ field: 'LastName' }")))
                        );
                        columns.Bound(e => e.Country).Width(220).Filterable(ftb => ftb.Multi(true).ItemTemplate("itemTemplate")
                            .DataSource(ds => ds.Read(r => r.Action("Unique", "Grid").Data("myFunc"/*"{ field: 'Country' }"*/)))
                        );
                        columns.Bound(e => e.City).Width(220).Filterable(ftb => ftb.Multi(true).CheckAll(false).BindTo(new[]{
                    new { City = "Seatle" },
                    new { City = "Tacoma" },
                    new { City = "Kirkland" },
                    new { City = "Redmond" },
                    new { City = "London" }
                        }));
                        columns.Bound(e => e.Title).Filterable(ftb => ftb.Multi(true)
                            .DataSource(ds => ds.Read(r => r.Action("Unique", "Grid").Data("{ field: 'Title' }")))
                        );
                    })
                    .Sortable()
                    .Pageable()
                    .Scrollable()
                    .ColumnMenu(menu => menu.Enabled(true).Filterable(true)) //this enables the header cell menus
                    .Filterable(ftb => ftb.Mode(GridFilterMode.Row))//this adds the filter row that is not relevant now
                    .Events(ev => ev.ColumnMenuInit("editMenu"))//attaches to the event you can use to access the checlist
                    .DataSource(dataSource => dataSource
                        .Ajax()
                        .ServerOperation(true)
                        .Read(read => read.Action("Filter_Multi_HierarchyBinding_Employees", "Grid"))
                    )
    )
</div>
 
 
 
<script>
    function myFunc() {
        var filterAndSortString = "aaaaaaaaaaa";//implement your logic for passing data
        return { "filterAndSortString": filterAndSortString };
    }
 
    function editMenu(e) {
        console.log(e.field);
            e.container.data("kendoPopup").bind("open", function () {
                console.log(e.container.find("[data-role='filtermulticheck']").data("kendoFilterMultiCheck"));
            });
    }
     
</script>

This lets you get an event when the column menu opens up, so you can see what field it is for, and get a reference to he multicheck in it to modify. Opening the menu in this scenario will automatically request the corresponding action from the column menu data source, and in this example the Country column will use the custom function to provide arguments to the action.

On a side note, you may also find useful the following snippet that shows how you can use the JS data source of the pure jQuery widget (without the wrapper) to render out only the distinct values from the data source: https://dojo.telerik.com/@bubblemaster/AFIRatop. The key difference with the setup above is that this has one data source in the browser memory and not separate data sources for different columns.

Regards,

Marin Bratanov
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
Grid
Asked by
Matthias
Top achievements
Rank 1
Answers by
Marin Bratanov
Telerik team
Share this question
or