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

Persist State - Kendo Grid

17 Answers 652 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Suresh
Top achievements
Rank 1
Suresh asked on 07 Jan 2015, 06:30 PM
Hi,

I have a kendo grid that can be sorted, filtered, grouped, etc. via bound columns. I have action links in each row. If the user wants to filter the grid (sort, group, etc), then perform an edit action (navigates to another view), and then return back to the index page, the filtered records need to be preserved. I have tried the coding that is presented in the demo, but those are for situations within the index page (Save & Load buttons). I want to navigate from the index page and return back and keep the grid state preserved.

Thanks,
Suresh

17 Answers, 1 is accepted

Sort by
0
Bob
Top achievements
Rank 1
answered on 07 Jan 2015, 10:36 PM
I've done this by adding the event on the grid

.Events(events => events.DataBound("onDataBound"))

Here's the javascript.  It saves the options whenever a databound event happens which should occur when you page, filter, or sort.  Then when user comes back, the settings are pulled and applied.
var localStorageKey = "UserAdministrationUserGridOptions";
 
function onDataBound(arg)
{
    var grid = $("#UserAdministrationUserGrid").data("kendoGrid");
    localStorage[localStorageKey] = kendo.stringify(grid.getOptions());
}
 
$(function () {
    // pull client grid state and apply to grid (filters, current page, sorts, etc).
});
 
function setGridOptions() {
    var options = localStorage[localStorageKey];
 
    if (options) {
        $("#UserAdministrationUserGrid").data("kendoGrid").setOptions(JSON.parse(options));
    }
}

0
Bob
Top achievements
Rank 1
answered on 07 Jan 2015, 10:43 PM
Here's what I did:

Set databound event: .Events(events => events.DataBound("onDataBound"))

Then in javascript, save the state on every databind automatically, then pull the state when the page is re-loaded.
   
var localStorageKey = "UserAdministrationUserGridOptions";
 
function onDataBound(arg) {
    var grid = $("#UserAdministrationUserGrid").data("kendoGrid");
    localStorage[localStorageKey] = kendo.stringify(grid.getOptions());
}
 
function setGridOptions() {
    var options = localStorage[localStorageKey];
 
    if (options) {
        $("#UserAdministrationUserGrid").data("kendoGrid").setOptions(JSON.parse(options));
    }
}
0
Bob
Top achievements
Rank 1
answered on 07 Jan 2015, 10:44 PM
I love how this forum tells me there's an error, then I re-type post and find I double-posted.
0
Suresh
Top achievements
Rank 1
answered on 08 Jan 2015, 04:21 PM
Thanks Bob. I implemented your code, but the grid state is not being applied when I return back from the edit page. Here is my code.

<script type="text/javascript">
var localStorageKey = "UserAdministrationUserGridOptions";
function dataBound() {
var grid = $("#grid").data("kendoGrid");
localStorage[localStorageKey] = kendo.stringify(grid.getOptions());
}
$(function () {
setGridOptions();
});

function setGridOptions() {

var options = localStorage[localStorageKey];
if (options) {

$("#grid").data("kendoGrid").setOptions(JSON.parse(options));

}

}
</script>
0
Bob
Top achievements
Rank 1
answered on 08 Jan 2015, 05:32 PM
Hmmm...have you tried debugging (or JavaScript alerts) to make sure options are getting set on databound and pulled on page load?
0
Suresh
Top achievements
Rank 1
answered on 08 Jan 2015, 11:02 PM
Yes, I did. Attached are screenshots.
GetOptions_Alert.jpg is after grid.getOptions()
SetOptions.jpg is after

I filtered by FirstName = 'Bob' but I don't see this filter in the alert message

Is the databound event being saved?

Thanks.
‚Äč
0
Suresh
Top achievements
Rank 1
answered on 08 Jan 2015, 11:58 PM
Ok, I changed the code like this.

function 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()
};
localStorage[localStorageKey] = kendo.stringify(state);
alert(localStorage[localStorageKey]);

The alert shows the filter that I applied (filter_bob.jpg)


SetGridOptions
function setGridOptions() {

var options = localStorage[localStorageKey];


if (options) {
alert(options);
$("#grid").data("kendoGrid").setOptions(JSON.parse(options));

}

This alert shows the original state of the grid, not the state through setoptions.

Thanks.
0
Petur Subev
Telerik team
answered on 09 Jan 2015, 01:11 PM

Hello Suresh,

Here is an example which you can try in action - resize, hide / show column, reorder or lock column, or any dataBinding action and then refresh the page. The page should look the same as it was left.

http://runner.telerik.io/fullscreen/@pesho/oQOwo/3

You can check the code by editing the example:

http://dojo.telerik.com/@pesho/oQOwo/3

 

Kind Regards,

Petur Subev

Telerik

 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Bob
Top achievements
Rank 1
answered on 09 Jan 2015, 01:34 PM
Thanks for example Petur as there was several events I wasn't capturing
0
Suresh
Top achievements
Rank 1
answered on 09 Jan 2015, 10:37 PM
Thanks Bob and Petur.

This what I ended up doing. On the Edit action link I call:

function LinkEdit() {
var grid = $("#grid").data("kendoGrid");
localStorage["kendo-grid-options"] = kendo.stringify(grid.getOptions());
}

and on page load I call:

$(document).ready(function () {
var grid = $("#grid").data("kendoGrid");
var options = localStorage["kendo-grid-options"];
if (options) {
grid.setOptions(JSON.parse(options));
}
})


This works, except when I load the page from the menu, the persists state is restored. So, in the menu onclick, I set
localStorage["kendo-grid-options"] = null;

Works fine for now.

Thanks for your help.

Suresh
0
DHHS
Top achievements
Rank 1
answered on 03 Sep 2015, 04:43 PM

Hi Suresh,

Is your custom command is working after coming back? 

 

Hi Petur,

 

I have used the solution given by suresh. Everything is working fine and the grid is setting the options back. But next time my custom command buttons are not working. On click function is not working on edit or view buttons. I think it is because the custom command buttons are not binding properly while setting options.

   <div class="row">
       <div class="col-xs-18 col-md-12">
           @(Html.Kendo().Grid<BHEBS.Areas.Admin.Models.ContractorModel.contractor>()
       .Name("contractorGrid")
       .Columns(columns =>
       {
           //columns.Bound(p => p.Id).Filterable(false).Width(50);
           columns.Bound(p => p.ContractorName).Width(150);
           columns.Bound(p => p.ContractorType).Title("Type").Width(40);
           columns.Bound(p => p.BHSISNum).Width(100); ;
           columns.Bound(p => p.ContractorIsAlsoRegion).Width(50).Title("Is Region").ClientTemplate("<input type='checkbox' disabled='disabled' #= ContractorIsAlsoRegion ? checked='checked': '' # class='chkbx' />").HtmlAttributes(new { style = "text-align: center" });
           columns.Bound(p => p.IsParent).Width(50).Title("Is Parent").ClientTemplate("<input type='checkbox' disabled='disabled' #= IsParent ? checked='checked': '' # class='chkbx' />").HtmlAttributes(new { style = "text-align: center" });
           columns.Bound(p => p.AddressBkNum).Width(60);
           columns.Bound(p => p.StartDate).Format("{0:MM/dd/yyyy}").Width(60);
           columns.Bound(p => p.EndDate).Format("{0:MM/dd/yyyy}").Width(60); ;
           columns.Bound(p => p.ISAT).Width(50);
           columns.Bound(p => p.MHS).Width(50);
           columns.Bound(p => p.ParentName).Width(100);
           columns.Command(command =>
           {
               command.Custom("Edit").SendDataKeys(true).Click("editClick");
               command.Custom("View").SendDataKeys(true).Click("viewClick");
               //command.Custom("Delete").SendDataKeys(true).Click("deleteClick");
           }).Width(120);
       })
          .Events(e => e.DataBound("onDataBound"))
          .Pageable(pageable => pageable.Refresh(true).PageSizes(true).ButtonCount(5))
          .Sortable()
          .Scrollable()
          .Filterable()
          .Selectable()
          .AutoBind(true)
          .Resizable(resize => resize.Columns(true))
          .HtmlAttributes(new { style = "height:600px;" })
          .DataSource(dataSource => dataSource.Ajax().Read(read => read.Action("Contractors_Read", "Contractor")).Model(model => model.Id(p => p.Id)))
          .ToolBar(toolbar =>
          {
              toolbar.Template(@<text><div class="toolbar pull-right tbheight">
                   <a class="k-button k-button-icontext k-grid-excel" href="#"><span class="k-icon k-i-excel"></span></a>
               </div></text>);
              toolbar.Excel().HtmlAttributes(new { @class = "pull-right" }).Text(" Export to Excel");
          })
                  .Excel(excel => excel.FileName("Contractor.xlsx").Filterable(true).AllPages(true).ProxyURL(Url.Action("Excel_Export_Save", "Contractor")))
           )
       </div>
   </div>
 
 
function editClick(e) {
       var grid = $("#contractorGrid").data("kendoGrid");
       localStorage["kendo-grid-options"] = kendo.stringify(grid.getOptions());
       //saveGridOptions("contractorGrid", '@Url.Action("SaveGridOptions")');
       e.preventDefault();
       var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
       var Id = dataItem.Id;
       var element = $(document.body);
       kendo.ui.progress(element, true);
       $.ajax({
           url: '@Url.Action("Edit")',
           type: 'GET',
           data: {
               'id': Id
           },
           success: function (data) {
               kendo.ui.progress(element, false);
               $('#ContractorIndexDiv').html(data);
           },
           error: function () {
               kendo.ui.progress(element, false);
               console.log("error in saving the record");
           }
       });
       //window.location.href = '@Url.Action("Edit","Contractor")/' + Id;
   }
 
 
  $(document).ready(function () {
       var grid = $("#contractorGrid").data("kendoGrid");
       var options = localStorage["kendo-grid-options"];
       alert(options);
      
       if (options) {
           alert(JSON.parse(options));
           grid.setOptions(JSON.parse(options));
       }
      // loadGridOptions("contractorGrid", '@Url.Action("LoadGridOptions")');
   });

0
Kiril Nikolov
Telerik team
answered on 07 Sep 2015, 08:43 AM

Hello DHHS,

 

Please check the important section of the following documentation article, that explains what happens in your case:

 

http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#methods-setOptions

 

you can also find a possible solution there.

 

Regards,
Kiril Nikolov
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
Adrian Segovia
Top achievements
Rank 1
answered on 10 Sep 2015, 02:20 PM

Hi DHHS,

Did you get a solution for this? I'm having the same problem with the custom command.

0
DHHS
Top achievements
Rank 1
answered on 14 Sep 2015, 06:27 PM

Hi Adrian,

 

Yes I did some workaround. I was not using columns or group by, so i removed those and kept only i want. This is how I am doing. Hope this helps :) Ley me know if you have any other issues. I really spent lot of time on this :(

 

   function editClick(e) {
var grid = $("#contractGrid").data("kendoGrid");
        var dataSource = grid.dataSource;
        var state = {
            page: dataSource.page(),
            pageSize: dataSource.pageSize(),
            sort: dataSource.sort(),
            filter: dataSource.filter()
        };
        localStorage["kendo-grid-options"] = kendo.stringify(state);
}
 
  $(document).ready(function () {
        var grid = $("#contractGrid").data("kendoGrid");
        var state = localStorage["kendo-grid-options"];
        //  alert(state);
        if (state) {
            data = JSON.parse(state);
            //alert(data.page);
            var options = grid.options;
            options.dataSource.page = data.page;
            options.dataSource.pageSize = data.pageSize;
            options.dataSource.sort = data.sort;
            options.dataSource.filter = data.filter;
            grid.destroy();
            $("#contractGrid")
           .empty()
           .kendoGrid(options);
        }       
    });
 
On menu click I am clearing the localstorage
 
  $(".nav-stacked").click(function () {
        window.localStorage.clear();
    });

0
DD101
Top achievements
Rank 1
answered on 14 Oct 2015, 10:21 AM
Big thanks to DHHS for this work around :)
0
Heiko
Top achievements
Rank 1
answered on 03 Jul 2017, 02:15 PM

DHHS: this is a nice solution. The problem is that this way the Grid is loading its data twice, at least in my solution (using Ajax() in DataSource). First load is initial load when the page is loading, second one is a reload when filter, sort etc. get applied.

Any idea how to solve this?

0
Alex Hajigeorgieva
Telerik team
answered on 05 Jul 2017, 10:22 AM
Hello Heiko,

If you are experiencing the same issue with the function references as a result of the JSON.stringify() method, another way would be to reattach them before passing them to the grid:

var grid = $("#grid").data("kendoGrid");
$("#save").click(function (e) {
  e.preventDefault();
  localStorage["kendo-grid-options"] = kendo.stringify(grid.getOptions());
});
$("#load").click(function (e) {
  e.preventDefault();
  var options = localStorage["kendo-grid-options"];
  if (options) {
    var optionsParsed = JSON.parse(options);
    optionsParsed.columns[4] = {
      command: {
        text: "View Details",
        click: showDetails
      },
    };
    grid.setOptions(optionsParsed);
  }
});

I have a runnable demo with grouping, paging, locked columns, filtering and custom command that you can test with:

http://dojo.telerik.com/eCuCE

Kind Regards,
Alex Hajigeorgieva
Progress Telerik
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 (charts) and form elements.
Tags
Grid
Asked by
Suresh
Top achievements
Rank 1
Answers by
Bob
Top achievements
Rank 1
Suresh
Top achievements
Rank 1
Petur Subev
Telerik team
DHHS
Top achievements
Rank 1
Kiril Nikolov
Telerik team
Adrian Segovia
Top achievements
Rank 1
DD101
Top achievements
Rank 1
Heiko
Top achievements
Rank 1
Alex Hajigeorgieva
Telerik team
Share this question
or