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

Apply the saved grid settings

9 Answers 1152 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Dinesh
Top achievements
Rank 1
Dinesh asked on 11 Jun 2013, 04:30 PM
Hi,
My goal is to save the grid settings (filter, sort, group,page, pagesize) in a cache or in a database and restore it.
I am able to save the grid setting but not able to apply it back. 
I save the grid setting on grid databound call

var grid = $("#DocumentGrid").data().kendoGrid;
var dataSource = grid.dataSource;

var state = {
                page: dataSource.page(),
                pageSize: dataSource.pageSize(),
                sort: dataSource.sort(),
                group: dataSource.group(),
                filter: dataSource.filter()
            };

            $.ajax(
                 "/controller/SaveGridSettings", {
                     data: dataSource.transport.parameterMap(state, "read")
                 });
In the controller, i am saving it in a dictionary where "string" is a GUID and saving the setting as a Kendo.Mvc.UI.DataSourceRequest

Dictionary<string, Kendo.Mvc.UI.DataSourceRequest>

For testing purpose, i created a button click event to apply the settings.
To read the grid setting and apply it, i tried the following and it didn't work
var grid = $("#DocumentGrid").data().kendoGrid;
        var dataSource = grid.dataSource;
        $.get("/controller/GetGridSettings", {
            Id:  id <-- Passed in during the call
        }).done(function (data) {
                         dataSource.query(data);
                      //dataSource.filter(data.Filters);  <-- Also tried this way
                     //dataSource.sort(data.Sorts);
        });
I want to apply the saved setting when the users navigate to different page and come back to the page with the grid and when they log out and log back in.

Any help is appreciated.

Thanks,
Dinesh

9 Answers, 1 is accepted

Sort by
0
Vladimir Iliev
Telerik team
answered on 13 Jun 2013, 09:57 AM
Hi Dinesh,

 
There is already such example of preserving the Grid state in our CodeLibrary which you can use as a baseline to achieve the desired behavior.

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!
0
Dinesh
Top achievements
Rank 1
answered on 13 Jun 2013, 01:46 PM
Hello Vladimir,
I have tried that too but it is not working. The grid does not set the filter or go to the last page i was in. I don't get any errors.
 Here is the more detailed code.

Here is how we are creating the grid:
_DocumentGrid.CSHTML (partial view)

@model System.Data.DataTable

@(Html.Kendo().Grid(Model)
    .Name("DocumentGrid")    
    .Columns(columns =>
    {
        foreach (System.Data.DataColumn column in Model.Columns)
        {
            string strFormat = "", strTitle = column.Caption;
            if (column.DataType == typeof(System.DateTime))
                strFormat = "{0:" + System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern + "}";

            if (column.ColumnName == "Name")
                strTitle = Web.Resources.Labels.Name;
            else if (column.ColumnName == "DocumentType")
                strTitle = Web.Resources.Labels.DocumentType;
            else if (column.ColumnName == "owner")
                strTitle = Web.Resources.Labels.Owner;
            else if (column.ColumnName == "CreateDate")
                strTitle = Web.Resources.Labels.DateCreated;
            else if (column.ColumnName == "LastModifyDate")
                strTitle = Web.Resources.Labels.LastModified;

            columns
                .Bound(column.ColumnName)
                .Groupable(column.ColumnName != "Id")
                .Title(strTitle)
                .Hidden(column.ColumnName == "Id")
                .Format(strFormat)
                .Width(200);
        }
    })
    .Pageable(paging=>paging.PageSizes(new int[]{10, 20 , 30, 50} ))
    .Sortable()
    .Navigatable()
    .Filterable()
    .Groupable()
    .Selectable(selectable => selectable
            .Mode(GridSelectionMode.Multiple)
            .Type(GridSelectionType.Row))
    .ColumnMenu()

        .Resizable(resize => resize
                    .Columns(true))
    .DataSource(dataSource => 
        dataSource  
            .Ajax()          
            .Model(model =>
                {
                    foreach (System.Data.DataColumn column in Model.Columns)
                    {
                        model.Field(column.ColumnName, column.DataType);
                    }                
                })
            .Read(read => read.Action("GetDocuments", "controller"))
            .PageSize(20)
    )        
    .HtmlAttributes(new { style = "height:100%" })
    .Scrollable() 
    )
)

Preserving the setting
Controller
public ActionResult GetDocuments([DataSourceRequest]DataSourceRequest request)
        {
            var model = new ourModel();
           //For now, we are storing the grid settings in session but we are going to change this later
            UserSettings _settings = (UserSettings)System.Web.HttpContext.Current.Session["Setting"];
            if (_settings == null) _settings = new UserSettings();
           string id = _settings.Id;
            if (_settings.GridSettings == null)
                _settings.GridSettings = new Dictionary<string, Kendo.Mvc.UI.DataSourceRequest>();

            _settings.GridSettings[id] = request;
             System.Web.HttpContext.Current.Session["Setting"] = _settings;
            if (id == "0")
                id = null;

            var result = <getting data from a table>

            var retVal = result.ToDataSourceResult(request);
            
            return Json(retVal, JsonRequestBehavior.AllowGet);            
        }

Get Grid Setting
Controller
public ActionResult GetGridSettings([DataSourceRequest] DataSourceRequest request, string Id)
        {
            UserSettings _settings = (UserSettings)System.Web.HttpContext.Current.Session["Setting"];
            if (_settings == null) _settings = new UserSettings();
            var gridSettings = _settings.GridSettings;

            Kendo.Mvc.UI.DataSourceRequest result = null;
            
            if (gridSettings != null)
                result = (gridSettings.ContainsKey(Id)) ? gridSettings[Id] : new Kendo.Mvc.UI.DataSourceRequest();

            return Json(result, JsonRequestBehavior.AllowGet);
        }

Index.CSHTML
function setGridSettings(id) {
        var grid = $("#DocumentGrid").data().kendoGrid;
        var dataSource = grid.dataSource;
        $.get("/Controller/GetGridSettings", {
            Id: id
        }).done(function (data) {
            alert(JSON.stringify(data)); <-- Value seems to be correct. page, pageSize, filter, group, sort values are set
            var state = data;          
            if (state) {
                if (state.filter) {
                    parseFilterDates(state.filter, dataSource.options.schema.model.fields);
                }
                dataSource.query(state);  <-- This calls the GetDocuments in the controller. When i put a break point in this method in the controller, the page and pageSize values are correct but the filter, sort, and group values are empty eventhough i see it in the above alert call.
            }
        });
    }

function treeView_onChange(e) {
        var data = treeview.dataItem(e.node);
        var id = data.id;
        var url = window.location.pathname + "/DocumentGrid";
        if (id == "0")
            id = null;
        var splitter = $("#splitter").data("kendoSplitter");
        //Refresh the detail pane
        splitter.ajaxRequest("#detail-pane", url, { id: id }); <--Refreshes the pane that contains the grid so the grid is destroyed and recreated. To find out why i am doing this, please look at http://www.kendoui.com/forums/mvc/grid/recreate-the-grid-on-demand.aspx

        setGridSettings(id);
    };

Thanks,
Dinesh
0
Vladimir Iliev
Telerik team
answered on 17 Jun 2013, 05:52 AM
Hi Dinesh,

 
In current scenario when the DataSourceRequest object is directly serialized and sent as JSON to the client side you should implement custom solution which to format correctly the sort / filter objects, however such solution is out of scope of our support service as it covers the build in functionality of the controls only. For more information about how the sort / filter objects should be formatted I would suggest to check the examples in the KendoUI API documentation

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!
0
Bob
Top achievements
Rank 1
answered on 22 Nov 2013, 05:15 PM
Is there still no built in way to do this?

Like a configuration setting:

cacheState: true

???

BOb
0
Dinesh
Top achievements
Rank 1
answered on 22 Nov 2013, 06:27 PM
Bob,
There is no built in way to do it. I had to save the DataSourceRequest object in the session and send the object back to the view in a Tuple model.
In the view, you could do this:

@model Tuple<System.Data.DataTable,DataSourceRequest >

.DataSource(dataSource => dataSource
            .PageSize((Model.Item2 != null && Model.Item2!= null) ? Model.Item2.PageSize : 20)            
            .Sort(st =>
                {
                    if (Model.Item2 == null || Model.Item2== null)
                        return;
                    
                    foreach (var sort in Model.Item2.Sorts)
                    {
                        st.Add(sort.Member).Order(sort.SortDirection);
                    }
                }
             )
             .Group(gp =>
                {
                    if (Model.Item2 != null && Model.Item2!= null)
                    {
                        foreach (var group in Model.Item2.Groups)
                        {
                            gp.Add(group.Member, group.MemberType, group.SortDirection);
                        }
                    }
                }
             )
             .Filter(fl =>
                 {
                     if (Model.Item2 != null && Model.Item2!= null)
                     {
                         fl.AddRange(Model.Item2.Filters);
                     }
                 }
             )

hope this helps
Dinesh
0
Brent
Top achievements
Rank 2
answered on 22 Feb 2016, 05:34 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
Vladimir Iliev
Telerik team
answered on 24 Feb 2016, 07:44 AM
Hello Brent,

Thank you for sharing this solution. Another option is to save the state in session on the server side as demonstrated in the following demo:
Regards,
Vladimir Iliev
Telerik
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
Terry
Top achievements
Rank 1
answered on 21 Sep 2016, 03:18 PM

Brent - if you're still out there - thanks.  Your answer is really helped me out.

For anyone else who reads this.  I did Brent's approach and it's exactly what I wanted.  The only difference is that I used sessionStorage instead of localStorage.  If anyone sees anything I could have done better then please let me know. 

My use case is that I have a view that has grid that opens another view when a row on the grid is clicked.  So when the user goes back to the grid view, then I want them to be on the same page.  Originally, I passed the page number to the controller and saved it in a View Model field.  That worked great, except that I wasn't saving the filtering.  So then I stumbled upon Brent's answer.  BTW - I tried the Kendo window.  I think the Kendo window is really cool.  But doesn't really work in my situation because I have a lot of data to show.  And also, that view can then open another view.

In my view, I have an onChange event in the grid that executes when a row is clicked.  This method saves the grid options to sessionStorage like Brent showed.

function onChange(arg) {
    var data = this.dataItem(this.select());
 
    YourRowID = data.PlannedProjectID;
    unit = data.PlannedProjectUnitID;
 
    var grid = $("#grid").data("kendoGrid");       
    sessionStorage["LRFPList"] = kendo.stringify(grid.getOptions());
 
    window.location.href('/PlannedProjects/LRFPInstances?PlannedProjectID=' + YourRowID + '&PlannedProjectUnitID=' + unit + '&LocationNo=' + '&backToView=LRFPList');
}

I also have a function that runs when the page loads.  This function reads the grid options saved in the onChange event.  My view is actually a partial view - so I look at a model field to know whether or not the grid is being displayed.

$(function () {
 
    if ('@Model.ShowGrid' == 'False') {
        return;
    }
 
    //Get the previous grid choices
    var grid = $("#grid").data("kendoGrid");
    var options = sessionStorage["LRFPList"];
    if (options) {
        grid.setOptions(JSON.parse(options));
    }
 
    dataSource = $('#grid').data().kendoGrid.dataSource;
 
    dataSource.query({
        page: dataSource.page(),
        group: dataSource.group(),           
        filter: dataSource.filter(),
        sort: dataSource.sort(),
        pageSize: dataSource.pageSize()
    })
 
})

 

0
Terry
Top achievements
Rank 1
answered on 21 Sep 2016, 04:21 PM

I ran into one small problem.  I have a view that contains Selection fields.  My grid is on a Partial view.  So I ran into an issue of when I changed the selection fields, then the previously saved grid options were being used instead of my selection fields.  So I added a statement to remove the grid options from sessionStorage when the button on the main view is clicked to rebuild the grid.

sessionStorage.removeItem("LRFPList");

Tags
Grid
Asked by
Dinesh
Top achievements
Rank 1
Answers by
Vladimir Iliev
Telerik team
Dinesh
Top achievements
Rank 1
Bob
Top achievements
Rank 1
Brent
Top achievements
Rank 2
Terry
Top achievements
Rank 1
Share this question
or