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

19 posts, 0 answers
  1. Anamika
    Anamika avatar
    124 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. UI for ASP.NET MVC is VS 2017 Ready
  4. Anamika
    Anamika avatar
    124 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

  5. Anamika
    Anamika avatar
    124 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.
  6. 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.

     
  7. Anamika
    Anamika avatar
    124 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
  8. Anamika
    Anamika avatar
    124 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);
    }
    });
    });
  9. Anamika
    Anamika avatar
    124 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>
  10. 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.

     
  11. Anamika
    Anamika avatar
    124 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.
  12. 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.

     
  13. Anamika
    Anamika avatar
    124 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??
  14. 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.

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

    Posted 22 Feb 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>
    }
  16. GoodGuysWin
    GoodGuysWin avatar
    1 posts
    Member since:
    Feb 2016

    Posted 08 Aug 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.    }

  17. Konstantin Dikov
    Admin
    Konstantin Dikov avatar
    1795 posts

    Posted 10 Aug 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
  18. Imran
    Imran avatar
    1 posts
    Member since:
    Jun 2014

    Posted 11 Nov in reply to Brent Link to this post

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

    Posted 4 days and 12 hours ago in reply to GoodGuysWin Link to this post

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

    Posted 16 hours ago 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.
Back to Top
UI for ASP.NET MVC is VS 2017 Ready