Use dropdownlist in grid column filter

18 posts, 1 answers
  1. Rich
    Rich avatar
    2 posts
    Member since:
    Feb 2009

    Posted 14 Dec 2012 Link to this post

    I would like the column filter to display a dropdownlist instead of a text box so the user can filter the grid based on pre-defined values.  For example, I have a column in my grid called, "Status".  The values can only be "New", "Open", or "Closed".  When I set this column to filterable, the user has to type the word "New" and I would like them to choose the value from a dropdownlist instead.  Is there a way to do this?  I can't find it in the documentation.  Thanks.
  2. Marcin Butlak
    Marcin Butlak avatar
    26 posts
    Member since:
    Dec 2012

    Posted 14 Dec 2012 Link to this post

    The grid doesn't provide any nice way to hook-up a custom filter in the column header but you can customize the column header template to imitate a filter http://docs.kendoui.com/api/web/grid#columnsheadertemplate-string or you can create a filter in the toolbar like in this example: http://demos.kendoui.com/web/grid/toolbar-template.html
  3. Kendo UI is VS 2017 Ready
  4. Answer
    John DeVight
    John DeVight avatar
    209 posts
    Member since:
    Jan 2010

    Posted 14 Dec 2012 Link to this post

    Hi Rich,

    Yes it is possible to do this with a bit of extra code.  After you create the grid, get a reference to the filter menu.  Locate the textbox in the filter menu and initialize it as a dropdownlist.

    I've actually done something very similar and have a jsFiddle demonstrating it.  The jsFiddle is located at: http://jsfiddle.net/jddevight/wGjCZ/

    I have the following code to create a grid:

    // Define the datasource for the grid.
    var _peopleDataSource = new kendo.data.DataSource({
        data: [
            { id: 1, name: "John", roleId: 1, roleTitle: "Software Engineer" },
            { id: 2, name: "Dave", roleId: 2, roleTitle: "Quality Assurance Engineer" },
            { id: 3, name: "Aaron", roleId: 3, roleTitle: "Team Lead" }
        ]
    });
      
    // Create the grid.
    var _grid = $("#grid").kendoGrid({
        dataSource: _peopleDataSource,
        filterable: { extra: false },
        columns: [
            {
                field: "name",
                title: "Name"
            },{
                field: "roleTitle",
                title: "Role"
            }
        ],
        editable: true
    }).data("kendoGrid");

    Here is the code to get the filter menu for the "Role" column (the CSS query assumes that the filtermenu that I want is for the last column):
    // Find the Role filter menu.
    var filterMenu = _grid.thead.find("th:not(.k-hierarchy-cell,.k-group-cell):last").data("kendoFilterMenu");
    If you need to get the filter menu for a different column, lets say, the 2nd column, then the code would look like this:
    // Find the filter menu for the second column.
    var filterMenu = $(_grid.thead.find("th:not(.k-hierarchy-cell,.k-group-cell)")[1]).data("kendoFilterMenu");

    And finally, here is the code to convert the textbox to a dropdownlist:
    // Change the text field to a dropdownlist in the Role filter menu.
    filterMenu.form.find(".k-textbox:first")
        .removeClass("k-textbox")
        .kendoDropDownList({
            dataSource: new kendo.data.DataSource({
                data: [
                    { title: "Software Engineer" },
                    { title: "Quality Assurance Engineer" },
                    { title: "Team Lead" }
                ]
            }),
            dataTextField: "title",
            dataValueField: "title"
        });
    Hope this helps...

    Regards,

    John DeVight
  5. Marcin Butlak
    Marcin Butlak avatar
    26 posts
    Member since:
    Dec 2012

    Posted 14 Dec 2012 Link to this post

    Nice hack but still kendui team should provide a nice way to hook-up our custom filter, nevertheless thanks for sharing :)
  6. Rich
    Rich avatar
    2 posts
    Member since:
    Feb 2009

    Posted 17 Dec 2012 Link to this post

    Thanks for both of your responses!  John, I ended up using your solution and it works great.  One more question:  Is there a way I can hide the dropdownlist with the conditional values ("is equal to", "contains", etc.)?

    thanks for your help.
  7. John DeVight
    John DeVight avatar
    209 posts
    Member since:
    Jan 2010

    Posted 28 Dec 2012 Link to this post

    Hi Rich,

    Yes, you can hide the dropdownlist with the conditional values with the following:

    filterMenu.form.find("span.k-dropdown:first").css("display", "none");

    You can also change the text that appears in the filter menu so that it makes a bit more sense with how you are using it:

    filterMenu.form.find("div.k-filter-help-text").text("Select an item from the list:");
    I've updated the jsFiddle to demonstrate: http://jsfiddle.net/jddevight/wGjCZ/

     Regards,

    John DeVight

  8. Michael
    Michael avatar
    4 posts
    Member since:
    Jan 2013

    Posted 21 Mar 2013 Link to this post

    I was using this solution and it was working great with Kendo version 2012.3.1315, but when I upgraded to version 2013.1.319 the "filterMenu.form" object is undefined.  So, when I execute this code:

    var grid = $("#BartSelectedProjectsGrid");
    // Get the filter menu for the third column in the grid
    var filterMenu = $(grid.find("th:not(.k-hierarchy-cell,.k-group-cell)")[2]).data("kendoFilterMenu");
    //modify the default help text
    filterMenu.form.find("div.k-filter-help-text").text("Select an item from the list:");

    It gives me this error (on the last line of code):

    Microsoft JScript runtime error: Unable to get value of the property 'find': object is null or undefined

    Again, this code worked fine with version 2012.3.1315 but now it's broken in version 2013.1.319.  Any suggestions on how to modify this code to get it to work in the new version?

  9. John DeVight
    John DeVight avatar
    209 posts
    Member since:
    Jan 2010

    Posted 21 Mar 2013 Link to this post

    Hi Michael,

    I'll look into it now and get back to you shortly....

    Regards,

    John DeVight
  10. John DeVight
    John DeVight avatar
    209 posts
    Member since:
    Jan 2010

    Posted 21 Mar 2013 Link to this post

    Hi Michael,

    I looked at the source code for 2013.1.319 and it appears that with this release, the kendo framework is not creating the filter form until it is actually needed.  The kendo grid raises a "filterMenuInit" event when any of the filter forms are initialized.  In the parameter passed in is the field associated with the filter and a reference to the form which is referred to as "container".

    I was unable to get the example working on jsFiddle, but I was able to get the example working on my local workstation.  Here is the entire code:

    <!DOCTYPE html>
    <html>
    <head>
    </head>
    <body>
        <div class="title">Instructions</div>
        <div id="instructions">The first textbox in the Role filter menu has been converted to a Kendo DropDownList.  Click on the filter icon in the Role column heading to see.</div>
        <div class="title">Person Grid</div>
        <div id="grid"></div>
     
        <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
        <script>
            $(document).ready(function() {
                // Define the datasource for the grid.
                var _peopleDataSource = new kendo.data.DataSource({
                    data: [
                        { id: 1, name: "John", roleId: 1, roleTitle: "Software Engineer" },
                        { id: 2, name: "Dave", roleId: 2, roleTitle: "Quality Assurance Engineer" },
                        { id: 3, name: "Aaron", roleId: 3, roleTitle: "Team Lead" }
                    ]
                });
     
                // Create the grid.
                var _grid = $("#grid").kendoGrid({
                    dataSource: _peopleDataSource,
                    filterable: { extra: false },
                    columns: [
                        {
                            field: "name",
                            title: "Name"
                        },{
                            field: "roleTitle",
                            title: "Role"
                        }
                    ],
                    editable: true
                }).data("kendoGrid");
     
                // The filterMenuInit event is raised when the filter menu is initialized.
                _grid.bind("filterMenuInit", function (e) {
                     
                    // If the filter is for the "Role" column...
                    if (e.field == "roleTitle") {
                        e.container.find("div.k-filter-help-text").text("Select an item from the list:");
                        e.container.find("span.k-dropdown:first").css("display", "none");
                     
                        // Change the text field to a dropdownlist in the Role filter menu.
                        e.container.find(".k-textbox:first")
                            .removeClass("k-textbox")
                            .kendoDropDownList({
                                dataSource: new kendo.data.DataSource({
                                    data: [
                                        { title: "Software Engineer" },
                                        { title: "Quality Assurance Engineer" },
                                        { title: "Team Lead" }
                                    ]
                                }),
                                dataTextField: "title",
                                dataValueField: "title"
                            });
                    }
                });
            });
        </script>
    <body>
    </html>

    Let me know if you have any questions / problems with this.

    Regards,

    John DeVight

  11. Michael
    Michael avatar
    4 posts
    Member since:
    Jan 2013

    Posted 22 Mar 2013 Link to this post

    Yes!  That worked great.  Thanks for the quick response!

    Mike
  12. Dilshan
    Dilshan avatar
    2 posts
    Member since:
    Jul 2012

    Posted 26 Mar 2013 Link to this post

    Hey John:

    your example works perfect except one thing.

    If you open the page and do not change any filter,  just click "Filter" button,  It should filter by "Software Engineer" since that is the default value of drop down, but it actually does not filter by that.  if you change to another filter and click "Filter" button, and then change back to "Software Engineer" and click "Filter" again, it will work.

    Can you tell us how to fix this issue?
     
    Thanks.
  13. Michael
    Michael avatar
    4 posts
    Member since:
    Jan 2013

    Posted 26 Mar 2013 Link to this post

    That's a great question.  I had the same problem.  I got around it by adding a blank value in my dropdown list, so the blank value is the default value of the list and if the user wants to filter on a "real" value then they would choose it and click "Filter".  That works, but it's not ideal and it would be great to figure out how to fix the underlying problem.

    Thanks,

    Mike
  14. John DeVight
    John DeVight avatar
    209 posts
    Member since:
    Jan 2010

    Posted 27 Mar 2013 Link to this post

    I'll take a look at that now and see what I can figure out...

    Regards,

    John DeVight
  15. John DeVight
    John DeVight avatar
    209 posts
    Member since:
    Jan 2010

    Posted 27 Mar 2013 Link to this post

    At the bottom of this post is an updated solution that will set the filter value to the first item in the dropdownlist ("Software Engineer") when the filter dialog is displayed.

    When filtering is enabled, each column heading has a kendoFilterMenu object associated with it.  The kendoFilterMenu has a filterModel object with a filters array.  There are 2 objects in the filter array, the first object for the first filter field and the second object for the second filter field.  In my example, I've hidden the second filter field, so I'm only concerned with the first filter object (kendoFilterMenu.filterModel.filters[0]).

    I got the kendoFilterMenu object for the last column in the grid with the following code:
    _grid.thead.find("th:last").data("kendoFilterMenu")
    I then set the filterModel.filters[0].value to the title of the first item in the kendoDropDownList with the following code:
    _grid.thead.find("th:last").data("kendoFilterMenu").filterModel.filters[0].value = dropDownList.dataSource.data()[0].title;
    Here is the entire solution.
    <!DOCTYPE html>
    <html>
    <head>
    </head>
    <body>
        <div class="title">Instructions</div>
        <div id="instructions">The first textbox in the Role filter menu has been converted to a Kendo DropDownList.  Click on the filter icon in the Role column heading to see.</div>
        <div class="title">Person Grid</div>
        <div id="grid"></div>
     
        <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
        <script>
            $(document).ready(function() {
                // Define the datasource for the grid.
                var _peopleDataSource = new kendo.data.DataSource({
                    data: [
                        { id: 1, name: "John", roleId: 1, roleTitle: "Software Engineer" },
                        { id: 2, name: "Dave", roleId: 2, roleTitle: "Quality Assurance Engineer" },
                        { id: 3, name: "Aaron", roleId: 3, roleTitle: "Team Lead" }
                    ]
                });
     
                // Create the grid.
                var _grid = $("#grid").kendoGrid({
                    dataSource: _peopleDataSource,
                    filterable: { extra: false },
                    columns: [
                        {
                            field: "name",
                            title: "Name"
                        },{
                            field: "roleTitle",
                            title: "Role"
                        }
                    ],
                    editable: true
                }).data("kendoGrid");
     
                // The filterMenuInit event is raised when the filter menu is initialized.
                _grid.bind("filterMenuInit", function (e) {
                     
                    // If the filter is for the "Role" column...
                    if (e.field == "roleTitle") {
                        e.container.find("div.k-filter-help-text").text("Select an item from the list:");
                        e.container.find("span.k-dropdown:first").css("display", "none");
                     
                        // Change the text field to a dropdownlist in the Role filter menu.
                        var dropDownList = e.container.find(".k-textbox:first")
                            .removeClass("k-textbox")
                            .kendoDropDownList({
                                dataSource: new kendo.data.DataSource({
                                    data: [
                                        { title: "Software Engineer" },
                                        { title: "Quality Assurance Engineer" },
                                        { title: "Team Lead" }
                                    ]
                                }),
                                dataTextField: "title",
                                dataValueField: "title"
                            }).data("kendoDropDownList");
                         
                        // Get the FilterMenu object for the roleTitle column.
                        // Set the FilterMenu.filterModel.filters[0] to the
                        // title of the first item in the dropdownlist.
                        _grid.thead.find("th:last")     /* roleTitle is the last column */
                            .data("kendoFilterMenu")    /* Get the FilterMenu for the last column */
                                .filterModel.filters[0].value = dropDownList.dataSource.data()[0].title;
                    }
                });
            });
        </script>
    <body>
    </html>

    Hope that helps :-)

    Regards,

    John DeVight
  16. Dilshan
    Dilshan avatar
    2 posts
    Member since:
    Jul 2012

    Posted 27 Mar 2013 Link to this post

    Thanks a lot John. This works perfect.

    There is still a bug with the code, if you click "clear" button first, and then click "Filter" button again, it won't filter properly. I think the same code needs to be set when "Clear" button gets clicked.


    So I changed last part of code to be:


                        // Get the FilterMenu object for the roleTitle column.
                        // Set the FilterMenu.filterModel.filters[0] to the
                        // title of the first item in the dropdownlist.
                        var filterMenu = _grid.thead.find("th:last")     /* roleTitle is the last column */
                            .data("kendoFilterMenu");    /* Get the FilterMenu for the last column */
                        filterMenu.filterModel.filters[0].value = dropDownList.dataSource.data()[0].title;
                                
                        filterMenu.form.bind('reset', function() {
                        filterMenu .filterModel.filters[0].value = dropDownList.dataSource.data()[0].title;
                    });

    This will fix the bug.
      
  17. John DeVight
    John DeVight avatar
    209 posts
    Member since:
    Jan 2010

    Posted 27 Mar 2013 Link to this post

    Thanks for catching that issue and posting a solution :-)
  18. Tom
    Tom avatar
    9 posts
    Member since:
    Mar 2013

    Posted 27 Sep Link to this post

    Have there been any updates since this old thread to support custom column filters?
  19. Alex Hajigeorgieva
    Admin
    Alex Hajigeorgieva avatar
    115 posts

    Posted 30 Sep Link to this post

    Hi Tom,

    Please accept my apology for the delay in responding.

    Indeed, there is an update. The Kendo UI Team has created a nice and easy way for our clients to implement a DropDown List as a Filter Menu among other features which provide more freedom as far as filter customizations as concerned.

    All you have to do now is add the columns filterable UI configuration setting and initialize the UI of your preference:

    http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#configuration-columns.filterable.ui

    A live demo is available at: http://demos.telerik.com/kendo-ui/grid/filter-menu-customization

    Kind Regards,
    Alex
    Telerik by Progress
     
    Get started with Kendo UI in days. Online training courses help you quickly implement components into your apps.
Back to Top
Kendo UI is VS 2017 Ready