Apply the saved grid settings

10 posts, 0 answers
  1. Dinesh
    Dinesh avatar
    6 posts
    Member since:
    Apr 2013

    Posted 11 Jun 2013 Link to this post

    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
  2. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 13 Jun 2013 Link to this post

    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!
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Dinesh
    Dinesh avatar
    6 posts
    Member since:
    Apr 2013

    Posted 13 Jun 2013 Link to this post

    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
  5. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 17 Jun 2013 Link to this post

    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!
  6. Bob
    Bob avatar
    138 posts
    Member since:
    Sep 2012

    Posted 22 Nov 2013 Link to this post

    Is there still no built in way to do this?

    Like a configuration setting:

    cacheState: true

    ???

    BOb
  7. Dinesh
    Dinesh avatar
    6 posts
    Member since:
    Apr 2013

    Posted 22 Nov 2013 Link to this post

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

  9. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 24 Feb Link to this post

    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
  10. Terry
    Terry avatar
    31 posts
    Member since:
    Jun 2016

    Posted 21 Sep in reply to Brent Link to this post

    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()
        })
     
    })

     

  11. Terry
    Terry avatar
    31 posts
    Member since:
    Jun 2016

    Posted 21 Sep in reply to Terry Link to this post

    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");

Back to Top
UI for ASP.NET MVC is VS 2017 Ready