0
votes

Having issues persisting state in mvc grid when using custom command columns. Here is the grid's wrapper

 @(Html.Kendo().Grid < Weighmaster_Web.Data.Entity.Destination > ()
   .Name("grid")
   .Columns(columns => {
     columns.Bound(c => c.Description);
     columns.Bound(c => c.CODE);
     columns.Command(c => {
       if (bUpdate) c.Custom("Edit").Click("editItem");
       if (bDelete) c.Custom("Delete").Click("deleteItem");
     }).Width(175);
   })
   .Scrollable()
   .Groupable()
   .Sortable()
   .ToolBar(toolbar => {
     if (bCreate) {
       toolbar.Create().HtmlAttributes(new {
         id = "addDestination"
       }).Text("Add Destination");
     }
   })
   .ToolBar(t => t.Excel())
   .Excel(excel => excel
     .FileName("Destinations.xlsx")
     .Filterable(true)
     .AllPages(true)
     .ProxyURL(Url.Action("Excel_Export_Save", "MaterialTransaction"))
   )
   .Filterable(filterable => filterable.Extra(false))
   .Resizable(resize => resize.Columns(true))
   .Reorderable(reorder => reorder.Columns(true))
   .Pageable(pageable => pageable
     .Refresh(true)
     .PageSizes(true)
     .ButtonCount(5))
   .DataSource(dataSource => dataSource
     .Ajax()
     .Events(events => events.Error("error_handler"))
     .Read(read => read.Action("DestinationIndex", "Destination").Type(HttpVerbs.Post))
     .Model(model => model.Id(p => p.Id))
     .PageSize(20)
     .Create(update => update.Action("DestinationSave", "Destination").Type(HttpVerbs.Post)))
 )

Here i define a click event handler in the wrapper for both edit and delete buttons. i am using custom commands so that i may define custom edit template.

When you look at the actual jquery for this wrapper , i can see the event handler defined.

Then when you leave the page , this code is ran to save the grid's state in a cookie :

$(window).unload(function () {
    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()
    };

    $.cookie(username + "DestinationGridState", JSON.stringify(state), { expires: 365 });


})

The grid's state is read from cookie in $(document).ready like this :

$(document).ready(function () {     

     var grid = $("#grid").data("kendoGrid");      
     var toolbar = $("#grid").find(".k-grid-toolbar").html();
     var state = $.cookie(username +  "DestinationGridState");
    if (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;
        if (grid) {
            grid.destroy();
            //grid.wrapper.html("");
        }

        $("#grid").empty().kendoGrid(options).find(".k-grid-toolbar").html(toolbar);
    }





});

After the grid's state is read from the cookie, no click event handler is defined for the custom edit command button. So , i guess my question is; How do i correctly save the state of the grid so that my custom command buttons will retain their event handlers?

2

2 Answers

0
votes

As mentioned in the kendo documentation:

JSON.stringify() cannot serialize function references (e.g. event handlers), so if stringification is used for the retrieved Grid state, all configuration fields, which represent function references, will be lost.

I once had the same issue, when I was trying to save the filters values in session. I was doing just like you, but then I realized that I didn't need to restore the columns state. If you remove the row options.columns = state.columns; the custom command will work just as expected.

Hope it helps.

0
votes

I had a similar problem. After loading the settings my custom delete button stopped working. This was the solution that I came up with:

Save the original grid options. After parsing the saved settings, restore the original values, in this case the column where my delete buttons was placed.

Hope this helps.

$("#Grid").on("click",
    ".loadsetting",
    function(e) {
        var grid = $("#Grid").data("kendoGrid");
        var originalOptions = grid.options; // Save original options

        e.preventDefault();

        var options = localStorage["msettings"];
        if (options) {
            var parsedOptions = JSON.parse(options);
            parsedOptions.toolbar = [
                {
                    template: $("#toolbarTemplate").html()
                }
            ];

            // Restore values
            parsedOptions.columns[30] = originalOptions.columns[30];

            grid.setOptions(parsedOptions);
        }
    });