How can I customize the Filter UI to support check boxes or similar

7 posts, 0 answers
  1. John
    John avatar
    1 posts
    Member since:
    Jun 2011

    Posted 21 May 2014 Link to this post

    I'm evaluating the Grid control for use in a project. I've searched the documentation and demos and haven't been able to figure out whether it is possible to customize the Filter UI to look something similar to the first attached screenshot. It doesn't need to be exact, but I'd like to be able to remove the operators list and label text.

    I also tried using a multiselect (which might be ok as an alternative to check boxes), but I don't know how to wire it up so that it filters properly.

    @(
        Html.Kendo().Grid<User>()
        .Name("grid")
        .Pageable(config => config
            .Info(true)
        )
        .Sortable()
        .Filterable()
        .ColumnMenu(config =>
            config.Enabled(true))
        .Columns(config =>
        {
            config.Bound(user => user.Id);
            config.Bound(user => user.FirstName);
            config.Bound(user => user.LastName);
            config.Bound(user => user.UserName);
            config.Bound(user => user.Type)
                .ClientTemplate("#=Type#")
                .Filterable(filter => filter
                    .UI("typeFilter")
                    .Extra(false)
                );
        }
            )
        .DataSource(dataSourceBuilder => dataSourceBuilder
            .WebApi()
            .Read(config => config
                    .Url("/api/data/users")
            )
             
            )
          )
    ----
     
    <script type="text/javascript">
        function typeFilter(element) {
            element.kendoMultiSelect(
            {
                dataTextField: "name",
                dataValueField: "id",
                dataSource: {
                    data: [
                        { id: 1, name: "Builder"},
                        { id: 2, name: "Police Man"}
                    ]
                }
            });
        }
    </script>

    Is what I'm trying to achieve possible? Can someone point me in the right direction?
  2. Nikolay Rusev
    Admin
    Nikolay Rusev avatar
    2289 posts

    Posted 26 May 2014 Link to this post

    Hello John,

    The following example shows the built-in capabilities for customization of the filter menu: Filter menu customization. All additional changes in the look and feel of the filter menu are considered custom solutions and you will have to handle filterMenuInit event of the grid and tweak the UI per your needs.

    The following forum post contains sample implementation of Multiselect as filter UI: multiselect in grid filter.

    Regards,
    Nikolay Rusev
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  3. Ken
    Ken avatar
    3 posts
    Member since:
    Apr 2015

    Posted 13 Aug 2015 Link to this post

    Multi select checkbox filter popup does not refresh when the grid is reloaded or data updated. Here is a rewrite for multiselect filter by reloading the checkboxes on filter popup open...


    @(Html.Kendo().Grid<User>()
      ...
      .columns.Bound(user => user.FirstName).Filterable(filterable => filterable.​Multi(​true))
      ...
      .Events(e => e.FilterMenuInit("function(e) { initCheckboxFilter(e); }"))
     )

    <script>
    function initCheckboxFilter(e)
    {
        var ul = e.container.find("ul");
        var field = e.field;

        popup.bind("open", function ()
        {
            if (ul != undefined)
            {
                // get local data
                var data = $("#grid").data("kendoGrid").dataSource.data();

                // use linq.js from http://linqjs.codeplex.com/
                var result = Enumerable.From(data)
                .OrderBy(function (x)
                {
                    switch(field)
                    {
                        case "FirstName": return x.FirstName;
                        case "LastName": return x.LastName;
                        case "UserName": return x.UserName;
                    }
                })
                .Select("$." + field)
                .ToArray();

                if (result.length > 0)
                {
                    ul.empty(); // clear list first
                    
                    ul.append("<li class='k-item' style='border-bottom: 1px solid #E7E7E7'><label class='k-label'><input class='k-check-all' type='checkbox' value='Select All' onchange='selectAllCheckbox(this);'>&nbsp;Select All</label></li>")

                    var prev = null;
                    $.each(result, function (index, value)
                    {
                        if (prev != value) // handle distinct
                        {
                            var li = "<li class='k-item' style='border-bottom: 1px solid #E7E7E7'><label class='k-label'><input class='checkbox1' type='checkbox' value='" + value + "'>&nbsp;" + value + "</label></li>";
                            ul.append(li);
                            prev = value;
                        }
                    });
                }
            }
        });
    }

    function selectAllCheckbox(checkbox)
    {
        if (checkbox.checked)
        {
            // check select status
            $('.checkbox1').each(function ()
            {
                //loop through each checkbox
                this.checked = true;  //select all checkboxes with class "checkbox1"              
            });
        }
        else
        {
            $('.checkbox1').each(function ()
            { //loop through each checkbox
                this.checked = false; //deselect all checkboxes with class "checkbox1"                      
            });
        }
    }
    </script>
  4. Nikolay Rusev
    Admin
    Nikolay Rusev avatar
    2289 posts

    Posted 14 Aug 2015 Link to this post

    Hello Ken,

     

    Indeed the multi check will not update when Grid data is updated as filterMenuInit event is triggered only once on menu initialization.

     

    Regards,
    Nikolay Rusev
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  5. Ken
    Ken avatar
    3 posts
    Member since:
    Apr 2015

    Posted 14 Aug 2015 Link to this post

    I have updated my code to properly get existing filters from grid data source to set the checks in the filter box. I am sharing this code for future updates. I am hoping that you can release this in your next release.

     

    <script src="linq.js" type="text/javascript"></script>
     
    @(Html.Kendo().Grid<User>()
      ...
      columns.Bound(c => c.FirstName).Filterable(filterable => filterable.Multi(true));
      ...
      .Events(e => e.FilterMenuInit("function(e) { initCheckboxFilter(e); }"))
    )
     
    function initCheckboxFilter(e)
    {
      var popup = e.container.data("kendoPopup");
      var ul = e.container.find("ul");
      var field = e.field;
     
      popup.bind("open", function ()
      {
        if (ul != undefined)
        {
          ul.css({ "font-size": "9px", "padding": "0px 4px" });
          var filters = $("#gridRiskAlerts").data("kendoGrid").dataSource.filter();
          var filterArray = [];
          if (filters != undefined)
          {
            filterArray = Enumerable.From(filters.filters)
              .Select("$.value").ToArray();
          }
          var data = $("#grid").data("kendoGrid").dataSource.data();
          var dataArray = Enumerable.From(data)
            .Select("$." + field)
            .Distinct()
            .OrderBy()
            .ToArray();
     
          if (dataArray.length > 0)
          {
            ul.empty();
     
            // select all checkbox
            ul.append("<li class='k-item' style='border-bottom: 1px solid #E7E7E7'><label class='k-label' style='font-size: 9px'><input id='checkboxSelectAll' class='k-check-all' style='padding: 0px 4px' type='checkbox' value='Select All' onchange='selectAllCheckbox(this);'> Select All</label></li>");
     
            $.each(dataArray, function (index, value)
            {
              var checked = false;
              $.each(filterArray, function (index, filter)
              {
                if(value == filter)
                {
                  checked = true;
                }
              });
     
              var li = "<li class='k-item' style='background-color: white; color: black; border-bottom: 1px solid #E7E7E7'><label class='k-label' style='font-size: 9px'><input class='checkbox1' style='padding: 0px 4px' type='checkbox' onchange='checkboxOnchange();' checked='" + checked + "' value='" + value + "'> " + value + "</label></li>";
              ul.append(li);
           });
         }
       }
      });
    }
     
    function selectAllCheckbox(checkbox)
    {
      if (checkbox.checked)
      {
        // check select status
        $('.checkbox1').each(function ()
        { //loop through each checkbox
          this.checked = true//select all checkboxes with class "checkbox1"             
        });
      }
      else
      {
        $('.checkbox1').each(function ()
        { //loop through each checkbox
          this.checked = false; //deselect all checkboxes with class "checkbox1"                     
        });
      }
    }
     
    function checkboxOnchange()
    {
        $("#checkboxSelectAll").prop("checked",false);
    }

  6. Ken
    Ken avatar
    3 posts
    Member since:
    Apr 2015

    Posted 14 Aug 2015 Link to this post

    code update, checkbox checked='checked' for existing filter value.

    <script src="linq.js" type="text/javascript"></script>
     
    @(Html.Kendo().Grid<User>()
      ...
      columns.Bound(c => c.FirstName).Filterable(filterable => filterable.Multi(true));
      ...
      .Events(e => e.FilterMenuInit("function(e) { initCheckboxFilter(e); }"))
    )
     
    function initCheckboxFilter(e)
    {
      var popup = e.container.data("kendoPopup");
      var ul = e.container.find("ul");
      var field = e.field;
      
      popup.bind("open", function ()
      {
        if (ul != undefined)
        {
          ul.css({ "font-size": "9px", "padding": "0px 4px" });
          var filters = $("#grid").data("kendoGrid").dataSource.filter();
          var filterArray = [];
          if (filters != undefined)
          {
            filterArray = Enumerable.From(filters.filters)
              .Select("$.value").ToArray();
          }
          var data = $("#grid").data("kendoGrid").dataSource.data();
          var dataArray = Enumerable.From(data)
            .Select("$." + field)
            .Distinct()
            .OrderBy()
            .ToArray();
      
          if (dataArray.length > 0)
          {
            ul.empty();
            // select all checkbox
            ul.append("<li class='k-item' style='border-bottom: 1px solid #E7E7E7'><label class='k-label' style='font-size: 9px'><input id='checkboxSelectAll' class='k-check-all' style='padding: 0px 4px' type='checkbox' value='Select All' onchange='selectAllCheckbox(this);'> Select All</label></li>");
     
            $.each(dataArray, function (index, value)
            {
              var checked = "";
              $.each(filterArray, function (index, filter)
              {
                if(value == filter)
                {
                  checked = "checked='checked'";
                }
              });
     
              var li = "<li class='k-item' style='background-color: white; color: black; border-bottom: 1px solid #E7E7E7; padding: 0px 2px'><label class='k-label' style='font-size: 9px'><input class='checkbox1' style='padding: 0px 4px' type='checkbox' onchange='checkboxOnchange();' " + checked + " value='" + value + "'> " + value + "</label></li>";
     
              ul.append(li);
           });
         }
       }
      });
    }
     
    function selectAllCheckbox(checkbox)
    {
      if (checkbox.checked)
      {
        // check select status
        $('.checkbox1').each(function ()
        { //loop through each checkbox
          this.checked = true//select all checkboxes with class "checkbox1"             
        });
      }
      else
      {
        $('.checkbox1').each(function ()
        { //loop through each checkbox
          this.checked = false; //deselect all checkboxes with class "checkbox1"                     
        });
      }
    }
     
    function checkboxOnchange()
    {
        $("#checkboxSelectAll").prop("checked",false);
    }

  7. Dimo
    Admin
    Dimo avatar
    8457 posts

    Posted 18 Aug 2015 Link to this post

    Hello Ken,

    Thanks for your contribution to the community.

    Regards,
    Dimo
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top