This is a migrated thread and some comments may be shown as answers.

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

24 Answers 4450 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Anamika
Top achievements
Rank 1
Anamika asked on 20 Mar 2014, 03:38 PM
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

24 Answers, 1 is accepted

Sort by
0
Atanas Korchev
Telerik team
answered on 24 Mar 2014, 08:30 AM
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.

 
0
Anamika
Top achievements
Rank 1
answered on 25 Mar 2014, 09:44 AM
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

0
Anamika
Top achievements
Rank 1
answered on 25 Mar 2014, 10:30 AM
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.
0
Atanas Korchev
Telerik team
answered on 25 Mar 2014, 12:02 PM
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.

 
0
Anamika
Top achievements
Rank 1
answered on 25 Mar 2014, 12:47 PM
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
0
Anamika
Top achievements
Rank 1
answered on 25 Mar 2014, 03:05 PM
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);
}
});
});
0
Anamika
Top achievements
Rank 1
answered on 25 Mar 2014, 03:26 PM
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>
0
Atanas Korchev
Telerik team
answered on 26 Mar 2014, 07:22 AM
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.

 
0
Anamika
Top achievements
Rank 1
answered on 26 Mar 2014, 07:38 AM
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.
0
Atanas Korchev
Telerik team
answered on 26 Mar 2014, 07:56 AM
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.

 
0
Anamika
Top achievements
Rank 1
answered on 26 Mar 2014, 10:38 AM
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??
0
Atanas Korchev
Telerik team
answered on 27 Mar 2014, 07:57 AM
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.

 
0
Brent
Top achievements
Rank 2
answered on 22 Feb 2016, 05:30 PM

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>
}
0
GoodGuysWin
Top achievements
Rank 2
answered on 09 Aug 2016, 02:00 AM

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.    }

0
Konstantin Dikov
Telerik team
answered on 10 Aug 2016, 01:12 PM
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
0
Imran
Top achievements
Rank 1
answered on 11 Nov 2016, 08:24 AM
Thanks Brent. You made my life eaisy :-)
0
Russ
Top achievements
Rank 1
answered on 01 Dec 2016, 05:02 PM
Do you have the server side code for this as well?
0
Konstantin Dikov
Telerik team
answered on 05 Dec 2016, 01:37 PM
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.
0
Raj
Top achievements
Rank 1
answered on 28 Dec 2016, 04:04 PM

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.

0
Konstantin Dikov
Telerik team
answered on 28 Dec 2016, 04:22 PM
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.
0
Raj
Top achievements
Rank 1
answered on 28 Dec 2016, 04:51 PM

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

 

0
Konstantin Dikov
Telerik team
answered on 29 Dec 2016, 06:29 AM
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.
0
Mike
Top achievements
Rank 1
answered on 24 Jan 2017, 04:50 PM

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.

0
Dimo
Telerik team
answered on 26 Jan 2017, 03:53 PM
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.
Tags
Grid
Asked by
Anamika
Top achievements
Rank 1
Answers by
Atanas Korchev
Telerik team
Anamika
Top achievements
Rank 1
Brent
Top achievements
Rank 2
GoodGuysWin
Top achievements
Rank 2
Konstantin Dikov
Telerik team
Imran
Top achievements
Rank 1
Russ
Top achievements
Rank 1
Raj
Top achievements
Rank 1
Mike
Top achievements
Rank 1
Dimo
Telerik team
Share this question
or