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

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

6 Answers 330 Views
Grid
This is a migrated thread and some comments may be shown as answers.
John
Top achievements
Rank 1
John asked on 22 May 2014, 12:04 AM
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?

6 Answers, 1 is accepted

Sort by
0
Nikolay Rusev
Telerik team
answered on 26 May 2014, 05:51 AM
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.

 
0
Ken
Top achievements
Rank 1
answered on 13 Aug 2015, 01:27 PM
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>
0
Nikolay Rusev
Telerik team
answered on 14 Aug 2015, 12:09 PM

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
0
Ken
Top achievements
Rank 1
answered on 14 Aug 2015, 12:30 PM

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);
}

0
Ken
Top achievements
Rank 1
answered on 14 Aug 2015, 03:16 PM

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);
}

0
Dimo
Telerik team
answered on 18 Aug 2015, 03:53 PM
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
Tags
Grid
Asked by
John
Top achievements
Rank 1
Answers by
Nikolay Rusev
Telerik team
Ken
Top achievements
Rank 1
Dimo
Telerik team
Share this question
or