0

I've been using this post as the basis for my code to allow allow the state of the grid to be saved by clicking a Save button, and loaded by clicking a Load button.

I have it almost working, in that it is saving and re-loading any Filter data, however if I change the order or visibility of any columns, these changes are not being saved when the save button is clicked.

I don't understand this comment in the source code

// the ID of the filterToolbar text-input is "gs_" + colModel.name

if(col_arr[i].search && $("#gs_" + col_arr[i].name).val().length) { toolbar_search_array.push({ name: col_arr[i].name, value: $("#gs_" + col_arr[i].name).val() }); }

As a result, I'm getting a console error when clicking save. If I comment this section out, then I am able to save the Filter criteria without the column orders and visibility.

Below is a working example of my code.

$(function() {
 "use strict";
    $.jgrid.defaults.guiStyle = "bootstrap";
    $.jgrid.defaults.iconSet = "fontAwesome";
    var template1 = {
        "groupOp": "AND",
        "rules": [{
            "field": "r",
            "op": "eq",
            "data": "YES"
        }]
    };

    var template2 = {
        "groupOp": "AND",
        "rules": [{
            "field": "hz",
            "op": "eq",
            "data": "YES"
        }]
    };
 
   var mygrid = jQuery("#jqGrid").jqGrid({
    url: 'https://dl.dropboxusercontent.com/s/nh7rcwcimxljjr2/data.json',
    datatype: "json",
    cmTemplate: {
     autoResizable: false,
     align: "center",
        searchoptions: {
            searchOperMenu: true,
            sopt: ["bw" ,"eq", "ne" , "lt", "le" ,"gt" ,"ge" , "bn" ,"in" ,"ni" ,"ew" ,"en" ,"cn" ,"nc" ,"nu" ,"nn"]
        }
    },
    colModel: [{
            label: 'Position',
            name: 'p',
            width: 100
        }, {
            label: 'Equipment Nbr',
            key: true, // ??? only if e is unique in the input data
            name: 'e'
        }, {
            label: 'Length',
            name: 'l',
            width: 95
        }, {
            label: 'Height',
            name: 'ch',
            width: 90
        }, {
            label: 'ISO Code',
            name: 'i',
            width: 110
        }, {
            label: 'Carrier',
            name: 'c',
            width: 95
        }, {
            label: 'Bay',
            name: 'ba',
            width: 75
        }, {
            label: 'Row',
            name: 'ro',
            width: 75
        }, {
            label: 'Tier',
            name: 'ti',
            width: 75
        }, {
            label: 'Type',
            name: 'ty',
            width: 90
        }, {
            label: 'Status',
            name: 's',
            width: 90
        }, {
            label: 'Bundle?',
            name: 'b',
            width: 100
        }, {
            label: 'Attached Nbr',
            name: 'a',
        }, {
            label: 'Pos Format',
            name: 'pf',
            width: 125
        }, {
            label: 'VGM',
            name: 'wv',
            width: 100
        }, {
            label: 'Weight',
            name: 'w',
            width: 100
        }, {
            label: 'OOG',
            name: 'o',
            width: 75
        }, {
            label: 'Dimensions',
            name: 'dn',
            width: 200
        }, {
            label: 'Hazardous',
            name: 'hz',
            width: 120
        }, {
            label: 'IMDG Code',
            name: 'im',
            width: 125
        }, {
            label: 'UN Number',
            name: 'un',
            width: 125
        }, {
            label: 'Reefer',
            name: 'r',
            width: 90
        }, {
            label: 'Temp',
            name: 'tp',
        }, {
            label: 'Range',
            name: 'ra',
            width: 130
        }, {
            label: 'Description',
            name: 'd',
            width: 125
        }, {
            label: 'Handling',
            name: 'h',
            width: 125
        }, {
            label: 'Load Remarks',
            name: 'lr',
            width: 140
        }, {
            label: 'POL',
            name: 'pl',
            width: 80
        }, {
            label: 'POD',
            name: 'pd',
            width: 80
        }, {
            label: 'Optional POD',
            name: 'op',
            width: 140
        }, {
            label: 'Destination',
            name: 'de',
            width: 125
        }, {
            label: '1st POD',
            name: 'p1',
            width: 110
        }, {
            label: '2nd POD',
            name: 'p2',
            width: 110
        }, {
            label: '3rd POD',
            name: 'p3',
            width: 110
        }, {
            label: '4th POD',
            name: 'p4',
            width: 110
        }, {
            label: '5th POD',
            name: 'p5',
            width: 110
        }, {
            label: 'Transhipment Port',
            name: 'pt',
            width: 175
        }, {
            label: 'Next POD',
            name: 'np',
            width: 115
        }, {
            label: 'Ref Code',
            name: 'rc',
            width: 110
        }, {
            label: 'Ref',
            name: 'ref',
            width: 80
        }],
 
    viewrecords: true, 
        autowidth: true,
        sortable: true,
        height: 400,
        rowNum: 17,
        shrinkToFit: false,
        autoresizeOnLoad: false,
        loadonce: true,
    colMenu : true,
        sortname: 'p',
        hoverrows: true,
        iconSet: "fontAwesome",
    rowNum: 250,
    autoResizing: { compact: true },
    rowList: [250, 1000, 2500, "10000:All"],
        rownumbers: true,
      rownumWidth: 60,
        multiselect: true,
        multiPageSelection: true,
        pager: true,
        groupingView: {
            groupOrder: ["desc"],
            groupText: ["<b>{0}</b> - {1} record(s) found"],
            groupColumnShow: [true],
    groupCollapse: true
        },
        searching: {
            stringResult: true,
            searchOperators: true,
            loadDefaults: false,
            multipleSearch: true,
            caption: "Advanced Query Builder",
            Find: " Filter",
            Reset: " Reset",
            multipleGroup: true,
            showQuery: false,
            tmplNames: ["Reefers", "Hazardous"],
            tmplFilters: [template1, template2]
        }
    }).jqGrid('filterToolbar')
     .jqGrid("gridResize")
     .jqGrid("navGrid", {
    iconsOverText: true,
    addtext: "Add",
    edittext: "Edit",
    deltext: "Delete",
    searchtext: "Search",
    refreshtext: "Refresh",
    viewtext: "View",
    view: true
   })
   .jqGrid("navButtonAdd", {
                caption: "Show/Hide Filters",
                id: "toggleToolbar",
                //buttonicon: "ui-icon-calculator",
                //commonIconClass: "ui-icon",
                buttonicon: "ui-pg-button-text ui-pg-button-icon-over-text fa-toggle-off",
                title: "Toggle toolbar",
                onClickButton:function(){
         mygrid[0].toggleToolbar()
        } 
            })
   .jqGrid("navButtonAdd", {
                caption: "Clear Filters",
                id: "clearFilters",
                //buttonicon: "ui-icon-calculator",
                //commonIconClass: "ui-icon",
                buttonicon: "ui-pg-button-text ui-pg-button-icon-over-text fa-eraser",
                title: "Clear Filters",
                onClickButton:function(){
         mygrid[0].clearToolbar()
        } 
            })
   .jqGrid("navButtonAdd", {
       caption: "Show/Hide Columns",
       buttonicon: "ui-pg-button-text ui-pg-button-icon-over-text fa-table",
       title: "Choose columns",
       onClickButton: function () {
           $(this).jqGrid("columnChooser", {
               done: function (perm) {
                   if (perm) {
                       this.jqGrid("remapColumns", perm, true);
                       saveColumnState.call(this);
                   }
               }
           });
       }
   })
   .jqGrid("navButtonAdd", {
                caption: "Default Settings",
                buttonicon: "ui-pg-button-text ui-pg-button-icon-over-text fa-times",
                title: "Clear saved grid's settings",
                onClickButton: function () {
                    window.location.reload();
                }
            });
   
   

    $("#dynamicGrouping").change(function() {
        var groupingName = $(this).val();
        if (groupingName) {
            $("#jqGrid").jqGrid("setGridParam", {rowNum: 9999})
             .jqGrid('groupingGroupBy', groupingName);
        } else {
            $("#jqGrid").jqGrid("setGridParam", {rowNum: 250})
             .jqGrid('groupingRemove');
             $('#jqGrid').trigger( 'reloadGrid' );
        }
    });
    $("#getSelectedRows").click(function() {
  var selectedIDs = $("#jqGrid").getGridParam("selarrrow");
  alert(selectedIDs.length === 0 ? "No rows are selected" : selectedIDs.join());
    });
    
    
}),
 

    $("#savestate").click(function(){
     saveState();
    });
    $("#loadstate").click(function(){
     loadState();
    });
 
    function navigateToLang(lng) {
            $.jgrid.setRegional('jqGrid',{regional: lng});
        }
        
        function getSelectedRows() {
            var grid = $("#jqGrid");
            var rowKey = grid.getGridParam("selrow");

            if (!rowKey)
                alert("No rows are selected");
            else {
                var selectedIDs = grid.getGridParam("selarrrow");
                var result = "";
                for (var i = 0; i < selectedIDs.length; i++) {
                    result += selectedIDs[i] + ",";
                }

                alert(result);
            }                
        }
 

function saveState(){

    // i have to access the colModel in order to get the names of my columns
    // which i need to get the values of the filter-toolbar textboxes later:
    var col_arr = $("#jqGrid").jqGrid("getGridParam", "colModel");

    // my own array to save the toolbar data:
    var toolbar_search_array = [];
    /*
    for(var i = 0, max = col_arr.length; i < max; i++)
    {
        // only saving the data when colModel's "search" is set to true
        // and value of the filterToolbar textbox  got a length
        // the ID of the filterToolbar text-input is "gs_" + colModel.name
        if(col_arr[i].search && $("#gs_" + col_arr[i].name).val().length)
        {
             toolbar_search_array.push({ name: col_arr[i].name, value: $("#gs_" + col_arr[i].name).val() });
        }
    }*/

    // putting everything into one object
    var pref = {
        // 1. toolbar filter data - used to fill out the text-inputs accordingly
        toolbar :   toolbar_search_array,

        // 2. postData - contains data for the actual filtering 
        post :      $("#jqGrid").jqGrid("getGridParam", "postData"),

        // 3. settings - this data is also included in postData - but doesn't get applied 
        // when using 'setGridParam'
        sortname:   $('#jqGrid').jqGrid('getGridParam', 'sortname'),
        sortorder:  $('#jqGrid').jqGrid('getGridParam', 'sortorder'),
        page:       $('#jqGrid').jqGrid('getGridParam', 'page'),
        rowNum:     $('#jqGrid').jqGrid('getGridParam', 'rowNum')

    };

    //saving in localStorage
    localStorage.setItem("jqGrid",  JSON.stringify( pref ));
};

function loadState(){
  var localsave = JSON.parse(localStorage.getItem("jqGrid"));
  
  // these settings are also saved in postData, 
  // but they don't get applied to the grid when setting the postData:
  $('#jqGrid').jqGrid('setGridParam', {
      sortname: localsave.sortname,
      sortorder: localsave.sortorder,
      page: localsave.page,
      rowNum: localsave.rowNum
  });
  
  // this applies the filtering itself and reloads the grid. 
  // it's important that you don't forget the "search : true" part:
  $("#jqGrid").jqGrid("setGridParam", { 
      search : true,
      postData : localsave.post
  }).trigger("reloadGrid");
  
  // this is loading the text into the filterToolbar 
  // from the array of objects i created:
  console.log(localsave.toolbar);
  for(i = 0, max = localsave.toolbar.length; i < max; i++)
  {
      $("#gs_" + localsave.toolbar[i].name).val( localsave.toolbar[i].value );
  } 
 
}
a.soptclass {
  border: 2px;
}
th {
  background-color: #aaa;
}
.two-col {
  overflow: hidden;
  /* Makes this div contain its floats */
}
.two-col .col1,
.two-col .col2 {
  width 49%;
}
.two-col .col1 {
  float: left;
}
.two-col .col2 {
  float: right;
}
.two-col label {
  display: block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.13.5/css/ui.jqgrid.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.13.5/js/jquery.jqgrid.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />


 <div style="margin-left:20px; margin-right:20px;">

<div class="two-col">
    <div class="col1">
        <div class="form-group">
      <label for="dynamicGrouping">Group Data By:</label>
      <select id="dynamicGrouping" class="form-control" style="width:auto;">
            <option value="">No Grouping</option>
            <option value="c">Carrier</option>
            <option value="l">Length</option>
            <option value="h">Height</option>
            <option value="i">ISO Code</option>
            <option value="ba">Bay</option>
            <option value="s">Status</option>
            <option value="o">Is OOG?</option>
            <option value="hz">Is Hazardous?</option>
            <option value="r">Is Reefer?</option>
        </select>
    </div>
    </div>


</div>

    <table id="jqGrid"></table>
    <div id="jqGridPager"></div>
 <br>
 <button id="savestate" class="btn btn-default">Save Table State</button>

 <button id="loadstate" class="btn btn-default">Load Table State</button>
 </br>
  <input class="btn btn-default" type="button" value="Get Selected Container Numbers" onclick="getSelectedRows()" />   
</div>
Community
  • 1
  • 1
MarkT
  • 81
  • 7

1 Answers1

0

The answer is already old. The code fragment which you included is from refreshSerchingToolbar function, which is not more needed because free jqGrid 4.13.5 should automatically fills the input/select elements of the filter toolbar (see the answer). You don't posted full working demo and I can't point you exact changes in the code, but you need just remove unneeded call of refreshSerchingToolbar from the loadComplete and remove the code of the function refreshSerchingToolbar.

About other problems: I can't reproduce any problem with saving/restoring the visibility or the column order on the demo. If some problems do exist, please describe the exact test case.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • I have used your demo to get my table almost working. The state of the table is now correctly saving both columnChooser and Filter criteria, however when refreshing the page, the filter is not being used. Please see my **[demo](https://test.baplieviewer.com/userareajqGrid/?filetoload=../JSON/mtrayn01/Elaine.json)** Please can you take a look and let me know what I need to add to make this work? I see it is working ok in your demo so I must have done something wrong. – MarkT Dec 07 '16 at 20:39
  • @MarkT: Could you describe the exact test case to reproduce the problem. If one set some filters and press ENTER one can see the filtered results. One ca After that one can press F5 to reload the page. One can see that the page will be loaded **with the last filter applied**. I used Chrome 55 in my test. – Oleg Dec 07 '16 at 22:58
  • If you load the demo, then input SEGU in the Equipment Nbr filter and press Enter, you will see the records filtered down to 61. If you then press F5, you see the Filter still has SEGU but the results are no longer filtered and you have 2273 records. I am testing on a Mac with Safari, Firefox and Chrome. – MarkT Dec 07 '16 at 23:27
  • @MarkT: You should add `forceClientSorting: true` option to fix the problem. It applies the filter (from `postData.filters`) and sort the data on the client side *before* displaying the grid. Mostly it's recommended to use `forceClientSorting: true` option at the same time with `loadonce: true`. – Oleg Dec 07 '16 at 23:38