Persisting Grid user customizations

5 posts, 2 answers
  1. Ian
    Ian avatar
    73 posts
    Member since:
    Jun 2013

    Posted 13 Aug 2013 Link to this post

    Using MVC I have a Grid which support column ordering, filtering etc.

    Once a user has customized their grid to the way they like it, is there a way to save those customization into perhaps a cookie so that when the form comes up again, they are kept?

  2. Answer
    Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 15 Aug 2013 Link to this post

    Hi Ian,

    Basically this feature is not supported out-of-the-box, however you can use for example the "jQuery-cookie" plugin and the grid API to save all user preferences to a cookie. For convenience I created small example which demonstrates such behavior which you can use as a baseline:


    Kind Regards,
    Vladimir Iliev
    Telerik
    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. Answer
    Ian
    Ian avatar
    73 posts
    Member since:
    Jun 2013

    Posted 15 Aug 2013 Link to this post

    This is very helpful.

    Below I have translated the answer to MVC.

    Step #1: Bind the MVC grid to the Column change event(s) only

    Step #2: Use this Javascript:

     
    var uniqueName = '@ViewContext.RouteData.Values["controller"]' + '_';
            var colState = uniqueName + "columnState";
            var gridState = uniqueName + "gridState";
            var gridRows = uniqueName + "gridRows";
     
            //On page ready, apply any exisiting cookie grid state
            $(function () {
                var grid = $("#NAMEOFYOURGRID").data("kendoGrid");
                var state = JSON.parse($.cookie(gridState));
                var currentColumnState = JSON.parse($.cookie(colState));
     
                if (currentColumnState && currentColumnState.length > 0) {
                    for (var i = 0; i < currentColumnState.length; i++) {
                        grid.hideColumn(currentColumnState[i]);
                    }
                }
     
                if (state) {
                    if (state.filter) {
                        parseFilterDates(state.filter, grid.dataSource.options.schema.model.fields);
                    }
                    grid.dataSource.query(state);
                } else {
                    grid.dataSource.read();
                }
                 
                //Bind the grid to dataBound so that changes the user make are sent to the save routine
                grid.bind("dataBinding", dataBoundKendo);
     
            });
     
     
            function parseFilterDates(filter, fields) {
                if (filter.filters) {
                    for (var i = 0; i < filter.filters.length; i++) {
                        parseFilterDates(filter.filters[i], fields);
                    }
                } else {
                    if (fields[filter.field].type == "date") {
                        filter.value = kendo.parseDate(filter.value);
                    }
                }
            }
     
     
            //When the grid is databound, or changes made, persist them
            function dataBoundKendo(e) {
                var grid = this;
                var dataSource = this.dataSource;
     
                var state = kendo.stringify({
                    page: dataSource.page(),
                    pageSize: dataSource.pageSize(),
                    sort: dataSource.sort(),
                    group: dataSource.group(),
                    filter: dataSource.filter()
                });
     
                var currentColumnState = [];
                for (var i = 0; i < grid.columns.length; i++) {
                    if (grid.columns[i].hidden) {
                        currentColumnState.push(grid.columns[i].field);
                    }
                }
                $.cookie(colState, JSON.stringify(currentColumnState));
     
                $.cookie(gridState, state);
     
                if ($.cookie(gridRows)) {
                    $.each(JSON.parse($.cookie(gridRows)), function() {
                        var item = dataSource.get(this);
                        var row = grid.tbody.find('[data-uid=' + item.uid + ']');
                        row.addClass('k-state-selected');
                    });
                }
            }
     
            function columnHideKendo(e) {
                setTimeout(function() {
                    e.sender.trigger("dataBoundKendo");
                });
            }
     
            function columnShowKendo(e) {
                setTimeout(function() {
                    e.sender.trigger("dataBoundKendo");
                });
            }
     
            function columnReorderKendo(e) {
                setTimeout(function () {
                    e.sender.trigger("dataBoundKendo");
                });
            }
             
            function changeKendo() {
                var grid = this;
                var ids = grid.select().map(function() {
                    return grid.dataItem($(this)).Id;
                }).toArray();
                $.cookie(gridRows, JSON.stringify(ids));
            }
  5. Benjamin
    Benjamin avatar
    5 posts
    Member since:
    Dec 2013

    Posted 06 Feb 2014 in reply to Ian Link to this post

    for the functions  columnHideKendo, columnShowKendo and columnReorderKendo the function dataBoundKendo is never called for some reason. The events are firing but the parameter e doesn't seem to be defined. How did you end up implementing this?
  6. Andrew
    Andrew avatar
    1 posts
    Member since:
    Feb 2014

    Posted 10 Mar 2014 Link to this post

    The previous posts helped me a lot, just in case anyone needs to record column positions along with this as I did, I made a slight alteration to this excellent bit of help.

    ​Basically what needs to happen is (as per the above) a delay in responding to the user event initially (so the grid has time to alter itself) and record the columns. When restoring the grid columns (and visibility), I perform the restore on $(window).Ready but then step through the current grid columns using a $map to the live grid.  I was previously saving the column order in a cookie and then replaying that back to the grid, using reorderColumn, which didn't go well!  Code below...

    @(Html.Kendo().Grid<[Model]>()
                  .Name("HelperGrid")
                  .Events(events => events.ColumnHide("colReorder").ColumnShow("colReorder").ColumnReorder("colReorder")))

    <script>
            $(window).ready(function () {
                 reorderCheck();
            });

            function colReorder(e) {
                setTimeout( function () {
                    $.cookie(colState, JSON.stringify($('#HelperGrid').data("kendoGrid").columns))
                });
            }

            function reorderCheck()
            {
            var grid = $("#HelperGrid").data("kendoGrid");
            var cols = grid.columns;
            var cs = getColumnsCookie();
            if (cs) {
                if (cs.length > 0) {
                    for (var i = 0; i < cs.length; i++) {
                        var curColState = cs[i];
                        $.map(grid.columns, function (elementOfArray, indexInArray) {
                            if (elementOfArray.field == curColState.field) {
                                grid.reorderColumn(i, grid.columns[indexInArray]);
                                if (curColState.hidden) {
                                    grid.hideColumn(i);
                                }
                            }
                        });
                    }
                }
            }
        }
     </script>
Back to Top
Kendo UI is VS 2017 Ready