Way to show/remind user that a column is applying a filter?

14 posts, 1 answers
  1. Jordon
    Jordon avatar
    20 posts
    Member since:
    Nov 2012

    Posted 15 May 2013 Link to this post

    Hi,

    I have a grid all setup and working the way I want. I think It's pretty slick, but i've noticed that if a user filters a column, there doesn't seem to be any indication that the data is being filtered once that menu is closed.

    Am I simply missing a 'is filtered' indicator, or is there not one?

    If there isn't can you suggest a good way to add one? I imagine either some text at the bottom or top stating its filtered on particular columns or an image on each column header that indicates a filter is being applied.
  2. Answer
    Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 16 May 2013 Link to this post

    Hi Jordon,


    When the Filter menu is used, the filter icon receives a white background, when the specified column is filtered as demonstrated in the following demo. It serves as an indicator for the user. You could override it's color, by specifying the following CSS styles.

    E.g.
    #Grid th a.k-state-active
    {
        background-color: green;
    }


    This functionality is not implemented out of the box, when a column menu is used. If this is the case in the current scenario, I would suggest you the following code snippet, which enables it in the dataBound event.

    E.g.
    function dataBound(e) {
        var filter = this.dataSource.filter();
        this.thead.find(".k-header-column-menu.k-state-active").removeClass("k-state-active");
        if (filter) {
            var filteredMembers = {};
            setFilteredMembers(filter, filteredMembers);
            this.thead.find("th[data-field]").each(function () {
                var cell = $(this);
                var filtered = filteredMembers[cell.data("field")];
                if (filtered) {
                    cell.find(".k-header-column-menu").addClass("k-state-active");
                }
            });
        }
    }
     
     
    function setFilteredMembers(filter, members) {
        if (filter.filters) {
            for (var i = 0; i < filter.filters.length; i++) {
                setFilteredMembers(filter.filters[i], members);
            }
        }
        else {
            members[filter.field] = true;
        }
    }

     

    Greetings,
    Dimiter Madjarov
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. Kendo UI is VS 2017 Ready
  4. Jordon
    Jordon avatar
    20 posts
    Member since:
    Nov 2012

    Posted 16 May 2013 Link to this post

    Thank you, this will do perfectly.
  5. Tyrone
    Tyrone avatar
    13 posts
    Member since:
    Feb 2014

    Posted 29 Aug 2014 Link to this post

    This was an awesome fix and ultra easy to implement... thank you...
    Quick follow on question, if the column is locked it does not seem to be working... Any thoughts?  the only difference is that the

    columns.Bound(o => o.FirstDayOfMonth).Format("{0:MMM - yyyy}").Width(100).Locked(true).Lockable(true).Title("Month").HeaderHtmlAttributes(new { style = "overflow: visible; white-space: normal" });


    vs...

    columns.Bound(o => o.FirstDayOfMonth).Format("{0:MMM - yyyy}").Width(100).Locked(false).Lockable(true).Title("Month").HeaderHtmlAttributes(new { style = "overflow: visible; white-space: normal" });
  6. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 29 Aug 2014 Link to this post

    Hi Tyrone,


    Indeed your observation is correct. At the time the code snippet was provided, the frozen columns feature was not available. Regarding the reason for the issue, it is that in the current case the Grid markup contains two tables and this.thead is referring to the head of the right one. Here is the updated version of the example.
    E.g.
    function dataBound(e) {
        var filter = this.dataSource.filter();
      
        this.thead.find(".k-header-column-menu.k-state-active").removeClass("k-state-active");
        this.wrapper.find(".k-grid-header-locked .k-header-column-menu.k-state-active").removeClass("k-state-active");
      
        if (filter) {
            var filteredMembers = {};
            setFilteredMembers(filter, filteredMembers);
      
            var heads = this.thead.find("th[data-field]");
            var frozenHeads = this.wrapper.find(".k-grid-header-locked th[data-field]");
      
            heads.add(frozenHeads).each(function () {
                var cell = $(this);
                var filtered = filteredMembers[cell.data("field")];
                if (filtered) {
                    cell.find(".k-header-column-menu").addClass("k-state-active");
                }
            });
        }
    }
      
      
    function setFilteredMembers(filter, members) {
        if (filter.filters) {
            for (var i = 0; i < filter.filters.length; i++) {
                setFilteredMembers(filter.filters[i], members);
            }
        }
        else {
            members[filter.field] = true;
        }
    }

    Have a great day!

    Regards,
    Dimiter Madjarov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  7. Tyrone
    Tyrone avatar
    13 posts
    Member since:
    Feb 2014

    Posted 29 Aug 2014 Link to this post

    It is a beautiful thing... thanks so much for the code snippet and insight...
    Have a great day...
  8. Renee
    Renee avatar
    15 posts
    Member since:
    Jan 2011

    Posted 11 Sep 2014 Link to this post

    A follow up question:  When using the "columnMenu: true: option (http://demos.telerik.com/kendo-ui/grid/column-menu), filtering, sorting, and optional columns functionality is all collapsed into one icon which means that now our users can no longer immediately see that the column is filtered.  This is problematic because we save the state of grids, so it may be that a user returns after some period of time to see a grid, but it *appears* as though the grid is showing 100% of the data when in fact a user would need to click through every column until they found that it had a filter (if they even knew to do that).  Thoughts?
  9. Tyrone
    Tyrone avatar
    13 posts
    Member since:
    Feb 2014

    Posted 11 Sep 2014 in reply to Renee Link to this post

    I had a very similar issue, but I think the solution that Dimiter proposed does a nice job of addressing your situation.

    I do use the column menu and apply filtering on the page load and as soon as the page is done rendering it highlights the column so you can see that it has changed in accordance with your CSS.
    .DataSource(dataSource => dataSource.Ajax()
                .Read(read => read.Action("Read", "WorkerAssignments"))
                .PageSize(1000)
                .Filter(filters =>
                    {
                        filters.Add(product => product.functional_area_owner_employee_id).Contains(ManagerID);
                    })
                 
                .ServerOperation(false)
                    .Model(model => model.Field("percenta_of_work_owned", typeof(decimal)))
                    .Model(model => model.Field("workstream_hours_owned", typeof(decimal)))
                    .Model(model => model.Field("first_check_date", typeof(DateTime)))
                    .Aggregates(aggregates =>
            {
                aggregates.Add(p => p.workstream_hours_owned).Min().Max().Count().Sum();
            }
             )
             )

  10. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 12 Sep 2014 Link to this post

    Hi Renee,


    Indeed, as Tyrone mentioned, I assume that the solutions proposed in my previous posts are targeting exactly the issue that you are referring too.

    Let me know if the information was sufficient enough.

    Regards,
    Dimiter Madjarov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  11. Renee
    Renee avatar
    15 posts
    Member since:
    Jan 2011

    Posted 16 Sep 2014 in reply to Dimiter Madjarov Link to this post

    Based on this answer, unfortunately we decided that we couldn't use use the "columnMenu: true" option.  The overall UX isn't intuitive anyway: (1) The fact that each single column lists all optional columns is a confusing UI (2) The out of the box integration with filtering is clunky at best (2a) Simply highlighting the background color a different color (without a "filter" icon) isn't enough of a clue for our users to understand that the color alone signifies filtered (2b) The menu itself doesn't highlight that filters are applied either

    The implementation suggestion to override the dataBound function for every standard grid would be a clunky solution for us. So, we'll instead choose to write a plug in that makes optional columns more easily discoverable and an improved UX.  Thanks all!


  12. Tyrone
    Tyrone avatar
    13 posts
    Member since:
    Feb 2014

    Posted 16 Sep 2014 in reply to Renee Link to this post

    Renee,
    I would love to see your solution when it is complete.  I am always looking to learn new stuff...
    Some thoughts about your issues with the grid.  Specifically 2a and 2b...

    Couldn't you use CSS to create an image at the top of your grid to indicate filtering has been applied.  I did mention color, but you could also use an image as the background for the table cell.

    Also, I think you could also have a trail that leads the user down to the filter.... maybe using the k-filter-item class on the <li> for the filter or something...  I am certainly not a jquery person so that may take some trial and error.

    As for overriding the dataBound, I was able to slip the jquery specified in an included file and just have it as part of the code I start with for each grid now.  Works like a charm.


  13. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 17 Sep 2014 Link to this post

    Hi Renee,


    Indeed the described behavior is by design and at the moment there is no other workaround that we could suggest. Nevertheless, if you have any suggestions, you could post them in our User Voice portal. If they become popular among the community, we will consider to implement them in future releases.

    Regards,
    Dimiter Madjarov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  14. Juan Jose
    Juan Jose avatar
    45 posts
    Member since:
    Jul 2013

    Posted 18 Sep 2014 Link to this post

    I have the same problem as Renee, ¿is there a way that i can show the user the columns to show/hide, but not using the columnMenu:true option? I mean, ¿can a have a single button somewhere in the UI that shows the optional columns the user can show/hide, instead of having every single column listing all optional columns?.
    That way, i would have filtering enabled and columnMenu disabled, so the user could apply column filters (and know when they are applied), and the user could chose the columns he want to see (using that single button).
    Thanks.
  15. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 18 Sep 2014 Link to this post

    Hello Juan,


    Yes, you could include custom UI on the page for hiding and showing the columns. The Grid API provides the following useful methods:
    hideColumn
    showColumn

    which accept the index of the column or the field that the column is bound to.

    Regards,
    Dimiter Madjarov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
Back to Top
Kendo UI is VS 2017 Ready