2

I have a JQuery grid which I am reloading everytime when some event occurs on the server (i.e. update in the data set) and display the latest set of data in the grid. This grid has also got checkboxes in it's first column. What's happening is let's say user is selecting some checkboxes and in the meantime if the grid gets reloaded due to update in the data on the server, my grid gets reloaded with the latest set of data but all my previous checkbox selection gets lost. How can I mark these selected checkboxes again after grid reload?

Please suggest.

function PushData() {
    // creates a proxy to the Alarm hub
    var alarm = $.connection.alarmHub;
    alarm.notification = function () {
        $("#jqTable").trigger("reloadGrid",[{current:true}]); 
    };
    // Start the connection and request current state
    $.connection.hub.start(function () {
        BindGrid();
    });
}
function BindGrid() {
    jqDataUrl = "Alarm/LoadjqData";
    var selectedRowIds;
    $("#jqTable").jqGrid({
        url: jqDataUrl,
        cache: false,
        datatype: "json",
        mtype: "POST",
        multiselect: true ,
        postData: {
            sp: function () { return getPriority(); },
            },
        colNames: ["Id", "PointRef", "Value", "State", "Ack State", "Priority", "AlarmDate", "", ""],
        colModel: [
            //{ name: 'alarmId_Checkbox', index: 'chekbox', width: 100, formatter: "checkbox", formatoptions: { disabled: false }, editable: true, edittype: "checkbox" },
            { name: "AlarmId", index: "AlarmId", width: 70, align: "left" },
            { name: "PointRef", index: "PointRef", width: 200, align: "left" },
            { name: "Value", index: "Value", width: 120, align: "left" },
            { name: "AlarmStateName", index: "AlarmStateName", width: 150, align: "left" },
            { name: "AcknowledgementStateName", index: "AcknowledgementStateName", width: 200, align: "left" },
            { name: "Priority", index: "Priority", width: 130, align: "left" },
            { name: "AlarmDate", index: "AlarmDate", width: 250, align: "left" },
            { name: "TrendLink", index: "Trends", width: 100, align: "left" },
            { name: "MimicsLink", index: "Mimics", width: 100, align: "left" }
            ],
        // Grid total width and height
        width: 710,
        height: 500,
        hidegrid: false,
        // Paging
        toppager: false,
        pager: $("#jqTablePager"),
        rowNum: 20,
        rowList: [5, 10, 20],
        viewrecords: true, // "total number of records" is displayed
        // Default sorting
        sortname: "Priority",
        sortorder: "asc",
        // Grid caption
        caption: "Telemetry Alarms",
        onCellSelect: function (rowid, icol, cellcontent, e) {
            var cm = jQuery("#jqTable").jqGrid('getGridParam', 'colModel');
            var colName = cm[icol];
            //alert(colName['index']);
            if (colName['index'] == 'AlarmId') {
                if ($("#AlarmDialog").dialog("isOpen")) {
                    $("#AlarmDialog").dialog("close");
                }
                AlarmDialogScript(rowid)
            }
            else if (colName['index'] == 'Trends') {
                TrendDialogScript(rowid)
            }
            else if (colName['index'] == 'Mimics') {
                MimicsDialogScript(rowid)
            }
            else {
                $("#jqTable").setCell(rowid, "alarmId_Checkbox", true); //Selects checkbox while clicking any other column in the grid
            }
        },
        recreateFilter: true,
        emptyrecords: 'No Alarms to display',
        loadComplete: function () {
            var rowIDs = jQuery("#jqTable").getDataIDs();
            for (var i = 0; i < rowIDs.length; i++) {
                rowData = jQuery("#jqTable").getRowData(rowIDs[i]);
                //change the style of hyperlink coloumns
                $("#jqTable").jqGrid('setCell', rowIDs[i], "AlarmId", "", { 'text-decoration': 'underline', 'cursor': 'pointer' });
                $("#jqTable").jqGrid('setCell', rowIDs[i], "TrendLink", "", { 'text-decoration': 'underline', 'cursor': 'pointer' });
                $("#jqTable").jqGrid('setCell', rowIDs[i], "MimicsLink", "", { 'text-decoration': 'underline', 'cursor': 'pointer' });
                if ($.trim(rowData.AcknowledgementStateName) == 'Active') {
                    $("#jqTable").jqGrid('setCell', rowIDs[i], "AcknowledgementStateName", "", { 'background-color': 'red', 'color': 'white' });
                }
                else if ($.trim(rowData.AcknowledgementStateName) == 'Acknowledged') {
                    $("#jqTable").jqGrid('setCell', rowIDs[i], "AcknowledgementStateName", "", { 'background-color': 'Navy', 'color': 'white' });
                }
            }
            //$("#jqTable").jqGrid('hideCol', "AlarmId") //code for hiding a particular column
        },
        gridComplete: function () {
            $('#jqTable input').bind('mouseover', function () {
                var tr = $(this).closest('tr');
                if ($("#AlarmDialog").dialog("isOpen")) {
                    $("#AlarmDialog").dialog("close");
                }
                AlarmDialogScript(tr[0].id);
            }
            );
        }
    }).navGrid("#jqTablePager",
    { refresh: true, add: false, edit: false, del: false },
    {}, // settings for edit
    {}, // settings for add
    {}, // settings for delete
    {sopt: ["cn"]} // Search options. Some options can be set on column level
    )
    .trigger('reloadGrid', [{page:1, current:true}]);
}
binu
  • 337
  • 2
  • 5
  • 16

3 Answers3

3

If I understand you correct you need just use additional parameter i

$("#list").trigger("reloadGrid", [{current:true}]);

or

$("#list").trigger("reloadGrid", [{page: 1, current: true}]);

(See the answer). It do almost the same what Justin suggested.

Depend from what you want exactly mean under reloading of the grid it can be that waht you need is to save the grid state inclusive the list of selected items in localStorage and reload the state after loading the grid. This answer describes in details the implementation. The corresponding demo from the answer could be simplified using new jqGrid events which are introduced in version 4.3.2.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Thanks Oleg. My grid gets reloaded automatically with the latest set of data whenever the data changes on the server and I wanted to maintain the selected checkboxes during the relaods. I still need to sort out the maintaining the selection while paginating the grid. Thanks again for pointing me to valueable answers.. – binu Apr 19 '12 at 14:37
  • @user535189: You are welcome! What you mean under "grid gets reloaded automatically"? Do you call somewhere `.trigger("reloadGrid")`? In the case you can just use additional parameters which I described to hold the selection. If you reload the page instead of reloading the grid data you can use `localStorage`. – Oleg Apr 19 '12 at 14:45
  • Thanks again Oleg. My web server sends notification (using SignalR) to the browser when data changes on the server and in response to the notification I simply call a method (BindGrid) for creating the grid with the latest data. BindGrid() method has the code .trigger("reloadGrid"). I tried the additional parameter but it is not helping. I have declared the checkbox in the colModel as follows : { name: 'checkbox', index: 'chekbox', width: 100, formatter: "checkbox", formatoptions: { disabled: false }, editable: true, edittype: "checkbox" },. Am I doing something wrong? – binu Apr 19 '12 at 15:11
  • @user535189: Why you not use the `multiselect: true` option? It will create the 'cb' column with checkboxes automatically. Moreover I don't understand why you recreate the grid `BindGrid()` instead of just using `.trigger("reloadGrid")` only? Which `datatype` you has ('json', 'local')? Do you have a simple grid or probably TreeGrid? – Oleg Apr 19 '12 at 15:20
  • Hi Oleg, How can I send you the code for my BindGrid () method. I might be doing something seriously wrong as I am using JQuery grid for the first time but I am really amazed with the fetures of this powerful plugin. Please see this: function PushData() { // creates aproxy to the Alarm hub var alarm = $.connection.alarmHub; alarm.notification = function () { BindGrid(); }; // Start the connection and request current state //$.connection.hub.start(); $.connection.hub.start(function () { //alarm.getAlarms(); BindGrid(); }); } – binu Apr 19 '12 at 15:30
  • Oleg, Thanks, You are great....It worked with $("#list").trigger("reloadGrid", [{current:true}]); with multiselect:true option.. cheers.. – binu Apr 19 '12 at 15:39
  • @user535189: I think that you can just append the code to your current question. You have much more place as in comment and you can better format the code (see [here](http://meta.stackexchange.com/a/22189/147495)). I suppose that you use *separate* Ajax call and then use `datatype: 'local'` instead of the usage of `datatype: 'json'` and allow jqGrid to do the Ajax call for you whenever its needed. – Oleg Apr 19 '12 at 15:41
  • Hi Oleg, I have updated my question with the exact code. This PushData function which is binded on the page under document.ready function triggers the data refresh in the grid. Please suggest if I need to change something for automatically remembering the selected checkboxes while grid paging. – binu Apr 19 '12 at 15:56
  • @user535189: The code looks not bad. It's very good for the first grid. I suppose that `PushData` function will be called **once**, so `$.connection.hub.start` will be called once too. Some small parts of code can be a little better, but the most important problem in your code is *very slow* code in `loadComplete`. Another problem is: you should **always** add `gridview: true` to the grid option. If you would rewrite your current code from `loadComplete` to the usage of `cellattr` (see [here](http://stackoverflow.com/a/8022860/315935) for example) you can improve performance in many times. – Oleg Apr 19 '12 at 16:33
  • @user535189: Additionally you can consider to use [showLink](http://www.trirand.com/jqgridwiki/doku.php?id=wiki:predefined_formatter#predefined_format_types) formatter or [dynamicLink](https://github.com/OlegKi/jqGrid-plugins) formatter. See [the answer](http://stackoverflow.com/a/9048483/315935). The main advantage of the usage of `cellattr` or formatters compared with `setCell` in `loadComplete` is the following. Every `setCell` change one element on the page so position of **all** other elements should be recalculated by web browser. `cellattr` and formatters allow to do in singe operation. – Oleg Apr 19 '12 at 16:40
2

You could save the selections before reloading the grid, for example in the beforeRequest event:

selectedRowIDs = jQuery('#myGrid').getGridParam('selarrrow');

Then after the grid has been reloaded, you can loop over selectedRowIDs and reselect each one using setSelection. For example:

for (i = 0, count = selectedRowIDs.length; i < count; i++) {
    jQuery('#myGrid').jqGrid('setSelection', selectedRowIDs[i], false);
}

You might run this code in the loadComplete event.

Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
  • Justin, thanks a lot, it worked like a charm. The only change I had to make was while reading the checkeboxes in the beforeRequest, I did following: var selectedRowIds = []; $('#jqTable input:checked').each(function () { var tr = $(this).closest('tr'); selectedRowIds .push(tr[0].id); }); and for setting the checkboxes for (i = 0; i < selectedRowIds.length; i++) { $("#jqTable").setCell(selectedRowIds[i], "checkbox", true); }, How can I maintain these selection while paging? Please let me know.. – binu Apr 19 '12 at 14:14
  • `How can I maintain these selection while paging` - If you are maintaining this data client-side you would need to store them in a data structure such as an array. Then when the page changes (in `loadComplete` perhaps) you would need to scan the grid and select any rows that are in your data structure. – Justin Ethier Apr 19 '12 at 14:19
  • 1
    @user535189: I suppose you didn't know that you have right to [vote up](http://stackoverflow.com/faq#howtoask) about 30 answers and questions **per day** (see [here](http://meta.stackexchange.com/a/5213/147495)) which you find *helpful*. The main goal of voting is to help searching engine. One can combine "accepting" of answers and voting. So if you want *to help other visitors of stackoverflow* you should use your right of voting. – Oleg Apr 19 '12 at 14:34
  • Thanks Oleg, I didn't knew this before – binu Apr 19 '12 at 15:17
0

use

recreateFilter: true 

and you should be done

Satya
  • 8,693
  • 5
  • 34
  • 55
  • But, this option is only for modal dialogs. I believe the op was asking about the selection checkboxes in the grid itself. – Justin Ethier Apr 19 '12 at 13:46