Remember kendo grid state (current page, current sort, filter, selected record etc) while loading back grid

25 posts, 0 answers
  1. Anamika
    Anamika avatar
    147 posts
    Member since:
    Mar 2014

    Posted 20 Mar 2014 Link to this post

    Hi All,

    I have a Kendo grid which Displays data based on filter criteria in TextBox above clicking search button. The grid has edit and Detail Action links which take user to a different view (no popup or inline),  loading more fields than we Display in grid for edit.When done editing and user Comes back to grid it must retain old filter criteria, selected record, page etc. Which is the best way to achieve this using Kendo grid?

    Anamika
  2. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 24 Mar 2014 Link to this post

    Hi,

    This code library project shows a sample implementation: http://www.telerik.com/support/code-library/save-grid-state-in-session-on-server-side
    Regards,
    Atanas Korchev
    Telerik
     

    Build cross-platform mobile apps using Visual Studio and .NET. Register for the online webinar on 03/27/2014, 11:00AM US ET.. Seats are limited.

     
  3. Anamika
    Anamika avatar
    147 posts
    Member since:
    Mar 2014

    Posted 25 Mar 2014 in reply to Atanas Korchev Link to this post

    Hi,

    This is a good sample, but my Scenario is different. the grid has a Action link button in each row clicking which takes user to a different Controller showing Details from selected row . When back clicked we should come back to Display grid with old search criteria and old selected page and record. So i cannot have a load button to click and load the saved state, it should be invoked automatically after read Action i believe

  4. Anamika
    Anamika avatar
    147 posts
    Member since:
    Mar 2014

    Posted 25 Mar 2014 in reply to Anamika Link to this post

    When i run the sample Project i choose page 6 and click save state. Then i click page 2 and click load state, it invokes the load method in Controller but does not reload page 6 in view. I still see page 2 selected on grid.
  5. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 25 Mar 2014 Link to this post

    Hi Anamika,

    The project shows how to persists only the grid sate - page, sort, filter and grouping. You would need to save and restore any other page state separately. You can persist the grid state automatically by handling the dataBound event of the grid:
    @(Html.Kendo().Grid<TelerikMvcApp1.Models.Product>()
          .Name("grid")
          .DataSource(ds => ds.Ajax().Read("Read", "Home"))
          .Events(e => e.DataBound("grid_dataBound"))
          .Pageable()
          .Groupable()
          .Sortable()
          .Reorderable(r => r.Columns(true))
          .Resizable(r => r.Columns(true))
    )
     
    <script>
        function grid_dataBound() {
            var grid = $("#grid").data("kendoGrid");
     
            var dataSource = grid.dataSource;
     
            var state = {
                columns: grid.columns,
                page: dataSource.page(),
                pageSize: dataSource.pageSize(),
                sort: dataSource.sort(),
                filter: dataSource.filter(),
                group: dataSource.group()
            };
     
            $.ajax({
                url: "/Home/Save",
                data: {
                    data: JSON.stringify(state)
                }
            });
        }
    </script>

    You can restore the grid state when the page is loaded:
    <script>
    $(document).ready(function() {
        var grid = $("#grid").data("kendoGrid");
     
        var dataSource = grid.dataSource;
     
        $.ajax({
            url: "/Home/Load",
            success: function(state) {
                state = JSON.parse(state);
     
                var options = grid.options;
     
                options.columns = state.columns;
     
                options.dataSource.page = state.page;
                options.dataSource.pageSize = state.pageSize;
                options.dataSource.sort = state.sort;
                options.dataSource.filter = state.filter;
                options.dataSource.group = state.group;
     
                grid.destroy();
     
                $("#grid")
                   .empty()
                   .kendoGrid(options);
            }
        });
    });
     
    </script>




    I couldn't reproduce the problem you are observing. Please check this video which shows my experience - the 6th page is successfully restored after clicking the Load state button.

    Regards,
    Atanas Korchev
    Telerik
     

    Build cross-platform mobile apps using Visual Studio and .NET. Register for the online webinar on 03/27/2014, 11:00AM US ET.. Seats are limited.

     
  6. Anamika
    Anamika avatar
    147 posts
    Member since:
    Mar 2014

    Posted 25 Mar 2014 in reply to Atanas Korchev Link to this post

    When i debug the Project, everytime i click Save button the save method in Controller do not get hit. But if i click Load it hits Controller load method. i am testing in Safari browser. With teh databound Event also save method is never called in Controller. Any idea what is missing
  7. Anamika
    Anamika avatar
    147 posts
    Member since:
    Mar 2014

    Posted 25 Mar 2014 in reply to Anamika Link to this post

    On further debug if i save only page and pagesize to state and reload them then it works, the Moment i add columns, filter or Group it Fails. the following work. Any idea why
    $("#save").click(function() {
    var grid = $("#grid").data("kendoGrid");

    var dataSource = grid.dataSource;

    var state = {

    page: dataSource.page(),
    pageSize: dataSource.pageSize()
    };


    $.ajax({
    url: "/Home/Save",
    data: {
    data: JSON.stringify(state)
    }
    });
    });

    $("#load").click(function() {
    var grid = $("#grid").data("kendoGrid");

    var dataSource = grid.dataSource;

    $.ajax({
    url: "/Home/Load",
    success: function(state) {
    state = JSON.parse(state);
    var options = grid.options;

    options.dataSource.page = state.page;
    options.dataSource.pageSize = state.pageSize;


    grid.destroy();
    // grid.dataSource.query(state);
    $("#grid")
    .empty()
    .kendoGrid(options);
    }
    });
    });
  8. Anamika
    Anamika avatar
    147 posts
    Member since:
    Mar 2014

    Posted 25 Mar 2014 in reply to Anamika Link to this post

    everything except column works, if i add column to state save Fails
    $("#save").click(function() {
    var grid = $("#grid").data("kendoGrid");

    var dataSource = grid.dataSource;

    var state = {

    page: dataSource.page(),
    pageSize: dataSource.pageSize(),
    sort: dataSource.sort(),
    filter: dataSource.filter(),
    group: dataSource.group()
    };


    $.ajax({
    url: "/Home/Save",
    data: {
    data: JSON.stringify(state)
    }
    });
    });

    $("#load").click(function() {
    var grid = $("#grid").data("kendoGrid");

    var dataSource = grid.dataSource;

    $.ajax({
    url: "/Home/Load",
    success: function(state) {
    state = JSON.parse(state);
    var options = grid.options;

    options.dataSource.page = state.page;
    options.dataSource.pageSize = state.pageSize;
    options.dataSource.sort = state.sort;
    options.dataSource.filter = state.filter;
    options.dataSource.group = state.group;

    grid.destroy();
    // grid.dataSource.query(state);
    $("#grid")
    .empty()
    .kendoGrid(options);
    }
    });
    });

    </script>
  9. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 26 Mar 2014 Link to this post

    Hi,

    The column state should be persisted as expected. I recorded another video which shows the same.

    Could you please tell us the browser and operating system that you are using?

    Regards,
    Atanas Korchev
    Telerik
     

    Build cross-platform mobile apps using Visual Studio and .NET. Register for the online webinar on 03/27/2014, 11:00AM US ET.. Seats are limited.

     
  10. Anamika
    Anamika avatar
    147 posts
    Member since:
    Mar 2014

    Posted 26 Mar 2014 in reply to Atanas Korchev Link to this post

    My developement Environment is Windows 7 ultimate and browser where i test is Safari 5.1.7 with user agents to test for tablet and mobile Browsers.Also i test with IE 10 and it is the same. Even if i publish my Website and try it on actual device Browsers the result is same.
  11. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 26 Mar 2014 Link to this post

    Hi Anamika,

    Kendo UI doesn't support Safari on Windows. This browser hasn't been updated by Apple since 2012. We however fully support Safari on OSX.

    I tested the sample project on IE10 and it still works. Do you see any JavaScript errors when you click the load and save state buttons?

    Regards,
    Atanas Korchev
    Telerik
     

    Build cross-platform mobile apps using Visual Studio and .NET. Register for the online webinar on 03/27/2014, 11:00AM US ET.. Seats are limited.

     
  12. Anamika
    Anamika avatar
    147 posts
    Member since:
    Mar 2014

    Posted 26 Mar 2014 in reply to Atanas Korchev Link to this post

    no i do not see any Java script error, i click save and break Point never hits. if i put alert it does Show alert but the Server side save is never invoked. On load click Server side load breakpoint is hit. If i remove column in save click in Java script then the Controller save breakpoint will be hit. So something about column saving in state in Java script may be??
  13. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 27 Mar 2014 Link to this post

    Hello Anamika,

    This is very strange because this sample has been tested by many users on various browsers and operating systems. There seems to be something unique about your setup which we haven't encountered so far. I recommend checking with the browser debugger whether the $.ajax call is made when you click the "save state" button. If the browser successfully executes $.ajax then it should make a request to the action method. If it doesn't execute that code then there must be some runtime error preventing this.

    Regards,
    Atanas Korchev
    Telerik
     

    Build cross-platform mobile apps using Visual Studio and .NET. Register for the online webinar on 03/27/2014, 11:00AM US ET.. Seats are limited.

     
  14. Brent
    Brent avatar
    7 posts
    Member since:
    Apr 2015

    Posted 22 Feb 2016 Link to this post

    I wanted to reply to this since I had such a tough time getting it all working. I'm using an MVC grid with Ajax binding. Here is what I used to make it work. This way doesn't need the controller calls either, all just localstorage, and less code, so a combination of above and what I found on another topic.

    @section Scripts {
        <script>
            $(document).ready(function () {
                var grid = $("#grid").data("kendoGrid");
                var options = localStorage["kendo-grid-options"];
                if (options) {
                    grid.setOptions(JSON.parse(options));
                }
            });
     
            function grid_dataBound() {
                var grid = $("#grid").data("kendoGrid");
                localStorage["kendo-grid-options"] = kendo.stringify(grid.getOptions());
            }
        </script>
    }
  15. GoodGuysWin
    GoodGuysWin avatar
    1 posts
    Member since:
    Feb 2016

    Posted 08 Aug 2016 Link to this post

    For those trying to get grid persistence to work across sessions, browsers, and computers, here is the solution.   My project uses Kendo MVC Grid, but this JavaScript applies to any use of the Kendo Grid.   One of the keys is to ensure your grids have Autobind set to false, otherwise you get grids loading 2x on a page and create a chicken/egg scenario.

    The following is true

    1) All grids set AutoBind(false)
    2) document.ready looks for any grids on page and then calls the getGridPersistence method
    3) getGridPersistence reads the database and retrieves the persistence based on UserID/URL/GridID
    4) getGridPersistence then sets the grid by first destroying it, then providing the destroyed grid the persistence options in the getGridPersistenceOnSuccess method.
    5) if a user makes any changes to the grid, I have events listening on dataBound and various column events that will then call the setGridPersistence method.  The setGridPersistence calls getOptions() and saves out only the items I want to the db.

     

    CODE:

    001.//Called whenever model data and UI needs to be synchronized
    002.window.X.GGrid.onDataBound = function (e) {
    003.    var gridId = e.sender.wrapper.context.id;
    004. 
    005.    if (gridId != null) {
    006.        // Grid.AutoBind(false) must be set for this to work properly.   Other code in document.ready will fire
    007.        //  off the databind when window.X.GGrid.getGridPersistence is called.  This also has the wanted side effect of only loading
    008.        //  the grid 1x upon page load.
    009.        setGridPersistence(e);
    010. 
    011.        // If an active filter is set, change the css class to show a filter icon
    012.        var jqGridId = $("#" + gridId);
    013. 
    014. 
    015.        // Since our grids are using the menu widget and not the default grid header, normal filter icons and operations
    016.        //  are different.  This code manually cycles through the filtered columns and applies the correct class
    017.        //  that will apply the filter icon when the filter is set
    018.        var grid = jqGridId.data("kendoGrid");
    019.        var filter = grid.dataSource.filter();
    020. 
    021.        if (filter) {
    022.            grid.thead.find(".k-header-column-menu.k-state-active").removeClass("k-state-active");
    023.            var filteredMembers = {};
    024.            setFilteredMembers(filter, filteredMembers);
    025.        }
    026. 
    027.        this.thead.find("th[data-field]").each(function () {
    028.            var cell = $(this);
    029.            var filtered = null;
    030.            if (filter) {
    031.                filtered = filteredMembers[cell.data("field")];
    032.            }
    033. 
    034.            if (filtered != null) {
    035.                cell.find(".k-header-column-menu").addClass("k-state-active");
    036.                cell.find(".k-icon").removeClass("k-i-arrowhead-s").addClass("k-filter");
    037.            }
    038.            else {
    039.                cell.find(".k-icon").removeClass("k-filter").addClass("k-i-arrowhead-s");
    040.            }
    041.        });
    042. 
    043.    }
    044.}
    045. 
    046.   // Method to tell the UI that a column is filtered.  
    047.// Called from the onDataBound event code.
    048.function setFilteredMembers(filter, members) {
    049.    if (filter.filters) {
    050.        for (var i = 0; i < filter.filters.length; i++) {
    051.            setFilteredMembers(filter.filters[i], members);
    052.        }
    053.    }
    054.    else {
    055.        members[filter.field] = true;
    056.    }
    057.}
    058. 
    059.// Get's the grids persistence from the database and configures the grid appropriately
    060.window.X.GGrid.getGridPersistence = function (e, gridId) {
    061.    if ((e != null) || (gridId != null)) {
    062. 
    063.        // if gridId is passed in use it, otherwise get gridId from button custom attribute
    064.        if (gridId == null) {
    065.            gridId = e.target.attributes['gridId'].nodeValue;
    066.        }
    067. 
    068.        var relativeUrl = $(location).attr('pathname');
    069. 
    070.        $.ajax({
    071.            url: "/common/gridpersistence/GetGridPersistence",
    072.            type: "POST",
    073.            data: JSON.stringify({ 'gridId': gridId, 'relativeUrl': relativeUrl }),
    074.            contentType: "application/json",
    075.            success: function (data)
    076.            {
    077.                getGridPersistenceOnSuccess(data, gridId);
    078.            },
    079.            error: function () {
    080.                alert("An error has occured while getting Grid Persistence View!!!");
    081.            }
    082.        });
    083.    }
    084.}
    085. 
    086.// Seperated out of AJAX call to debug and follow process
    087.// This method can only ever get called if there is a grid on the page.
    088.function getGridPersistenceOnSuccess(state, gridId) {
    089.    var grid = $("#" + gridId).data("kendoGrid");
    090. 
    091.    // save the toolbar
    092.    var toolBar = $("#" + gridId + " .k-grid-toolbar").html();
    093. 
    094.    if (state != null && state !== '') {
    095.        // set options that were retreived
    096.        //grid.setOptions(JSON.parse(data));
    097.        state = JSON.parse(state);
    098.        var options = grid.options;
    099. 
    100.        options.columns = state.columns;
    101.        options.dataSource.page = state.page;
    102.        options.dataSource.pageSize = state.pageSize;
    103.        options.dataSource.sort = state.sort;
    104.        options.dataSource.filter = state.filter;
    105.        options.dataSource.group = state.group;
    106.        options.dataSource.aggregate = state.aggregate;
    107.         
    108.        // destroy current grid
    109.        grid.destroy();
    110. 
    111.        // set options into empty grid in DOM
    112.        var gridThatWasReset = $("#" + gridId);
    113.        gridThatWasReset
    114.           .empty()
    115.           .kendoGrid(options);
    116. 
    117.        // force a data read
    118.        grid = gridThatWasReset.data("kendoGrid");
    119.        grid.dataSource.read();
    120. 
    121.        // reset the toolbar
    122.        var toolBarSelector = $("#" + gridId + " .k-grid-toolbar");
    123.        toolBarSelector.html(toolBar);
    124.        toolBarSelector.addClass("k-grid-top");
    125.    }
    126.    else {
    127.        // just perform a read without resetting toolbar buttons when it's the first time viewing a grid
    128.        grid.dataSource.read();
    129.    }
    130.}
    131. 
    132.//  Saves the grids current configuration into the database
    133.function setGridPersistence(e) {
    134.    if (e != null ) {
    135.        var gridId = null;
    136.         
    137.        if (e.target == null)
    138.        {
    139.            // if coming from grid event
    140.            gridId = e.sender.wrapper.context.id;
    141.        }
    142.        else
    143.        {
    144.            // If coming from button click
    145.            gridId = e.target.attributes['gridId'].nodeValue;
    146.        }
    147.         
    148.        var grid = $("#" + gridId).data("kendoGrid");
    149.        var dataSource = grid.dataSource;
    150.        var relativeUrl = $(location).attr('pathname');
    151. 
    152.        // Set specific options
    153.        var state = {
    154.            columns: grid.columns,
    155.            page: dataSource.page(),
    156.            pageSize: dataSource.pageSize(),
    157.            sort: dataSource.sort(),
    158.            filter: dataSource.filter(),
    159.            group: dataSource.group(),
    160.            aggregate: dataSource.aggregate()
    161.        };
    162. 
    163. 
    164.        var options = JSON.stringify(state);
    165.        //var options = kendo.stringify(grid.getOptions());
    166. 
    167.        $.ajax({
    168.            url: "/common/gridpersistence/SetGridPersistence",
    169.            type: "POST",
    170.            data: JSON.stringify({ 'gridId': gridId, 'relativeUrl': relativeUrl, 'options': options }),
    171.            contentType: "application/json",
    172.            success: function (data) {
    173.                // alert('saved persistence');
    174. 
    175.            },
    176.            error: function () {
    177.                alert("An error has occured while saving Grid Persistence View!!!");
    178.            }
    179.        });
    180.    }
    181.};
    182. 
    183.// Resets the grids configuration by deleting persistence info from the database, then refreshing the entire page.
    184.function resetGridPersistence(e) {
    185.    if (e !== null && e !== undefined) {
    186.        var gridId = e.target.attributes['gridId'].nodeValue;
    187.        var grid = $("#" + gridId).data("kendoGrid");
    188.        var relativeUrl = $(location).attr('pathname');
    189. 
    190.        if (typeof grid !== "undefined") {
    191.            $.ajax({
    192.                url: "/common/gridpersistence/ResetGridPersistence",
    193.                type: "POST",
    194.                data: JSON.stringify({ 'gridId': gridId, 'relativeUrl': relativeUrl }),
    195.                contentType: "application/json",
    196.                success: function (data) {
    197. 
    198.                    if (data) {
    199.                        // only way to refresh the column widths is to reload page as other methods like data.read() don't do the trick
    200.                        location.reload();
    201.                    }
    202.                },
    203.                error: function () {
    204.                    alert("An error has occured while resetting Grid Persistence View!!!");
    205.                }
    206.            });
    207. 
    208. 
    209.        }
    210.    }
    211.};
    212. 
    213. 
    214.$(document).ready(function () {
    215.    // Find all grids in a page
    216.    var grids = $("div").find(".k-grid");
    217. 
    218.    if (grids != null && grids.length > 0) {
    219.        grids.each(function () {
    220.            var gridId = this.id;
    221.            if (gridId !== '') {
    222.                //fetch persistence settings for each grid
    223.                window.X.GGrid.getGridPersistence(null, gridId);
    224.            }
    225.        });
    226.    }

  16. Konstantin Dikov
    Admin
    Konstantin Dikov avatar
    2068 posts

    Posted 10 Aug 2016 Link to this post

    Hello,

    Thank you for sharing your solution with the community. 

    As a gesture of gratitude you will find your Telerik Points updated.


    Kind Regards,
    Konstantin Dikov
    Telerik by Progress
    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
  17. Imran
    Imran avatar
    1 posts
    Member since:
    Jun 2014

    Posted 11 Nov 2016 in reply to Brent Link to this post

    Thanks Brent. You made my life eaisy :-)
  18. Russ
    Russ avatar
    49 posts
    Member since:
    Sep 2006

    Posted 01 Dec 2016 in reply to GoodGuysWin Link to this post

    Do you have the server side code for this as well?
  19. Konstantin Dikov
    Admin
    Konstantin Dikov avatar
    2068 posts

    Posted 05 Dec 2016 Link to this post

    Hello Russ,

    The server-side code should contain the relevant part for saving the state in the database and having in mind that you need to save grid id, the URL and the options (as string), there should be nothing special about it.

    Nevertheless, the following forum thread should be helpful for retrieving the values in the controller:

    Best Regards,
    Konstantin Dikov
    Telerik by Progress
    Telerik UI for ASP.NET MVC is ready for Visual Studio 2017 RC! Learn more.
  20. Raj
    Raj avatar
    23 posts
    Member since:
    Nov 2016

    Posted 28 Dec 2016 in reply to Atanas Korchev Link to this post

    Hello Atanas 

    I have the same problem like Anamika, when i include columns it is not working else its working fine. on further debug in chrome developer tools, i found something if i include columns, data is not passed as string to controller. If i remove columns it works fine data is passed as string.

    Please find attached image.

  21. Konstantin Dikov
    Admin
    Konstantin Dikov avatar
    2068 posts

    Posted 28 Dec 2016 Link to this post

    Hi Raj,

    Most probably you are exceeding the max length of the query string when you include the columns structure. You could take a look at the following thread for a solution:

    Regards,
    Konstantin Dikov
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  22. Raj
    Raj avatar
    23 posts
    Member since:
    Nov 2016

    Posted 28 Dec 2016 in reply to Konstantin Dikov Link to this post

    Hello Dikov

    Thanks for your quick response.

    It didn't work adding max requests to web config.

    neither this <httpRuntime maxQueryStringLength="32768" maxUrlLength="65536"/> nor this

    <system.webServer><security><requestFiltering><requestLimits maxQueryString="32768"/></requestFiltering></security></system.webServer> or both didnt work

    Thanks

    Raj

     

  23. Konstantin Dikov
    Admin
    Konstantin Dikov avatar
    2068 posts

    Posted 29 Dec 2016 Link to this post

    Hi Raj,

    Could you please try setting higher values to the httpRuntime maxQueryStringLength and if the request fails again, click on the request and inspect the "Preview" tag to see what is the thrown error. Another option is to change the type of the request to "post":
    $.ajax({
        type: "post",


    Regards,
    Konstantin Dikov
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  24. Mike
    Mike avatar
    1 posts
    Member since:
    Sep 2015

    Posted 24 Jan in reply to GoodGuysWin Link to this post

    We get and set grid options the same.  We allow our users to save different grid setups with names though instead of saving through events.  My question have you or anyone else tried to update the json stored in the database when you make changes to the grid schema?  Like adding or removing columns and/or attributes.  We don't want to to have to reset the stored grid options and make our users recreate them all.

    Since I have access to the database, I use a PowerShell script to update the json but it's not robust enough to handle all scenarios.

  25. Dimo
    Admin
    Dimo avatar
    8401 posts

    Posted 26 Jan Link to this post

    Hello Mike,

    Theoretically, there should be a way to retrieve the JSON, convert (parse) it to an object (either client-side or server-side), make the desired changes and then stringify and save it back. All this can happen outside of the Kendo UI context and without using our APIs. As long as the modified object can be used by the Kendo UI as a valid configuration object, this approach should work.

    Regards,
    Dimo
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top