6

My grid works fine in firefox and chrome but it shows 'Loading' icon in IE9 when gridview is set to true. This is using jqgrid 4.7.0

var setGrid = $("#recordSetsGrid");
var gridView=false; //setting this to true in IE9 causes grid not to show with only message 'Loading'.

setGrid.jqGrid(
        {
            ajaxGridOptions: {cache: false},
            url : getUrlContext()+loadUrl,
            postData : {
                searchText : function() {
                    return $("#" + setSearchTextId)
                            .val();
                }
            },
            datatype : "json",
            editurl : setGrid_editUrl,
            colNames : ["","Record Set", "Origin",
                    "Origin", "Organization",
                    "Sharing", "Active?",
                    "Comments" ],
            editCaption : "Edit Record Set",
            colModel : [
                    {
                        name : "crud",
                        width : 10,
                        fixed : true,
                        editable : false,
                        search : false
                    },
                    {
                        name : "recordSet",
                        width : 65,
                        fixed : true,
                        editable : false,
                        search : false
                    },
                    {
                        name : "origin",
                        width : 90,
                        editable : true,
                        hidden : true,
                        editrules : {
                            required : false,
                            edithidden : true
                        },
                        search : true,
                        editoptions : {
                            size : "30"
                        }
                    },
                    {
                        name : "domainName",
                        width : 90,
                        editable : false,
                        search : true,
                        searchoptions : {
                            caption : "Search in record sets",
                            sopt : [ 'cn' ]
                        },
                        formatter : originFormatter,
                        editrules : {
                            required : true,
                            edithidden : false
                        }
                    },
                    {
                        name : "org",
                        width : 80,
                        align : "left",
                        editable : true,
                        search : false,
                        formatter : orgFormatter,
                        editoptions : {
                            value : orgChoices
                        },
                        edittype : "select",
                    },
                    {
                        name : "sharing",
                        width : 65,
                        fixed : true,
                        align : "left",
                        editable : true,
                        search : false,
                        editoptions : {
                            value : sharingChoices
                        },
                        edittype : "select",
                    },
                    {
                        name : "active",
                        width : 45,
                        fixed : true,
                        align : "center",
                        editable : true,
                        search : false,
                        edittype : "checkbox",
                        editoptions:{value:"Yes:No", defaultValue: "Yes"}       
                    }, 
                    {
                        name : "comments",
                        width : 80,
                        align : "left",
                        editable : true,
                        search : false,
                        editoptions : {
                            size : "60"
                        }
                    } ],
            pager : "#recordSetsGridPager",
            gridview: gridView,
            rowNum : getRecordSetInitialPageSize(),
            rowList : getRecordSetPageSizes(),
            sortname : "origin",
            sortorder : "desc",
            viewrecords : true,
            autoencode : true,
            rownumbers: true,
            height : 100,
            width : 700,
            multiselect : false,
            caption : "Record Sets",
            onSelectRow : function(ids) 
            {
                var rowData = setGrid.jqGrid("getRowData",ids);
                var origin=rowData["domainName"];
                var caption="Resource Records: "+ origin;
                if (ids == null) {
                    ids = 0;
                    if (jQuery("#recordsGrid").jqGrid('getGridParam','records') > 0) {
                        recGrid.jqGrid('setGridParam',{url:getUrlContext()+"" +
                                "/ZoneEditManaged.action?_eventName=getResourceRecords&isInit",page:1});
                        //recGrid.jqGrid('setCaption',caption).trigger('reloadGrid');
                        recGrid.trigger('reloadGrid');
                    }
                } else {
                    recGrid.jqGrid('setGridParam',{url:getUrlContext()+
                        "/ZoneEditManaged.action?_eventName=getResourceRecords&&isInit=1",page:1});
                        //"/ZoneEditManaged.action?_eventName=getResourceRecords&&isInit=1&setId="+ids,page:1});
                    //recGrid.jqGrid('setCaption',caption).trigger('reloadGrid');
                    recGrid.trigger('reloadGrid');
                }

                $("#captionOriginId").html(origin);

                //drawResourceRecordSearchBox(recGrid,caption); 
            },
            ondblClickRow : function(rowid) {
                var p = setGrid[0].p;
                if (p.selrow !== rowid) {
                    grid.jqGrid('setSelection',
                            rowid);
                }
                setGrid.jqGrid('editGridRow',
                        rowid, editProps);
            },
            loadComplete : function() {
                logMessage("In recordSetsGrid load complete");
                applyContextMenu();
                highlightFilteredData.call(this,setSearchTextId);
            },
            loadError : function(jqXHR, textStatus,
                    errorThrown) {
                handleAjaxError(jqXHR, textStatus,
                        errorThrown);
            }
        }).navGrid('#recordSetsGridPager', {
    add : true,
    edit : true,
    del : true,
    search : false
}, editProps, addProps, delProps);

If I change the gridView=false, it works well in IE9. I will have large amount of the data in this grid so I read that gridView=true speeds up the performance in case of large data. Any ideas to get gridView to work in IE9 is appreciated.

Thanks

Sannu
  • 1,202
  • 4
  • 21
  • 32
  • 2
    You should *debug* the code. Just press F12 button of IE9 to start Developer Tools and choose "Script" and press "Start debugging" button. You will see exactly *where* in your code the problem exist. The reason of the most errors during loading of the grid is the code of `loadComplete`. You calls `logMessage`, `applyContextMenu` and `highlightFilteredData` inside. I suppose some from the function have an error. One should debug the code. – Oleg Jan 22 '15 at 13:53
  • I commented out all the code in loadComplete and tried again with gridView=true, same issue, grids don't load. I saw the error in grid.base.js at line 1641 at "ts.firstElementChild.innerHTML += rowData.join(''); // append to innerHTML of tbody which contains the first row (.jqgfirstrow)". I am sure i have something configured incorrectly. I will write a new grid from scratch and see if i can get it to work in IE but that is when i make some time. – Sannu Jan 29 '15 at 13:05
  • Let me ask you this. I do not have cell edits in my grid. All edits are done using the edit form. Does setting gridView=true still buy me performance incentives? I read in the documentation that gridView=true speeds up the performance of ajax edits. Does it mean ajax cell edits or form edits. – Sannu Jan 29 '15 at 13:09

4 Answers4

3

After your comments to your question I understand the problem. The reason of the problem is the bug in jqGrid. It uses firstElementChild (see the lines) property:

} else {
    //$("#"+$.jgrid.jqID(ts.p.id)+" tbody:first").append(rowData.join(''));
    ts.firstElementChild.innerHTML += rowData.join(''); // append to innerHTML of tbody which contains the first row (.jqgfirstrow)
    ts.grid.cols = ts.rows[0].cells; // update cached first row
}

I fixed the bug some time before in my fork of jqGrid (see the lines currently):

} else if (self.firstElementChild) {
    self.firstElementChild.innerHTML += rowData.join(''); // append to innerHTML of tbody which contains the first row (.jqgfirstrow)
    self.grid.cols = self.rows[0].cells; // update cached first row
} else {
    // for IE8 for example
    $tbody.html($tbody.html() + rowData.join('')); // append to innerHTML of tbody which contains the first row (.jqgfirstrow)
    self.grid.cols = self.rows[0].cells; // update cached first row
}

So I can suggest to to make the same changes in jquery.jqGrid.src.js or to download modified jquery.jqGrid.src.js, jquery.jqGrid.min.js and jquery.jqGrid.min.map files from my repository (see js folder). I should warn you that the code is in developing stadium and I plan to publish the first release in the next month, but the current code is stable and it contains many other fixes which I found and some new features (described shortly in the readme).

UPDATED: The code above which fixes the problem are get from my new code, so it contains self and $tbody defined above in my code. If you want modify the code of jqGrid 4.7 you can use

} else if (ts.firstElementChild) {
    ts.firstElementChild.innerHTML += rowData.join('');
    ts.grid.cols = ts.rows[0].cells;
} else {
    // use for IE8 for example
    var $tbody = $(ts.tBodies[0]);
    $tbody.html($tbody.html() + rowData.join(''));
    ts.grid.cols = ts.rows[0].cells;
}

UPDATED 2: The current code of the fragment of free jqGrid look as the following

if (p.treeGrid === true && fpos > 0) {
    $(self.rows[fpos]).after(rowData.join(""));
} else if (p.scroll) {
    $tbody.append(rowData.join(""));
} else if (self.firstElementChild == null || (document.documentMode != undefined && document.documentMode <= 9)) {
    // for IE8 for example
    $tbody.html($tbody.html() + rowData.join("")); // append to innerHTML of tbody which contains the first row (.jqgfirstrow)
    self.grid.cols = self.rows[0].cells; // update cached first row
} else {
    self.firstElementChild.innerHTML += rowData.join(""); // append to innerHTML of tbody which contains the first row (.jqgfirstrow)
    self.grid.cols = self.rows[0].cells; // update cached first row
}
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Thank you. I downloaded forked code and ran it in under linux and I realized that there were lot of changes being made as my pager buttons were not showing up and also in couple of occasions i lost the selection state as well. Hence i am only going to apply the surgical patch and test it on Monday. Will post the result on Monday. Thanks again. – Sannu Jan 31 '15 at 14:17
  • 1
    @Sannu: Could you provide the demo which reproduces the problems which you described? Do you used `table.navgrid` selector somewhere in your code? If you use it you should just replace it to `.navgrid`. It's the only problem which I know in pager. Which selection mode you use (`multiselect: true` or not)? – Oleg Jan 31 '15 at 14:44
  • i got it to work, but i had to make some changes to the patch you provided. I was getting javascript errors for 'self' and fixed with the following code. It is working well but see if you find any issue with this code. – Sannu Feb 01 '15 at 22:24
  • 1
    @Sannu: I included some lines from **my fork of jqGrid** where `self` was defined before. If you want to use the same code in **old jqGrid** you should of cause use `ts` instead of `self`. The variable `$tbody` is just the body of the grid `var $tbody = $(ts.tBodies[0]);`. The expression `ts.tBodies[0]` can be calculated *very quickly*, but `$("#"+$.jgrid.jqID(ts.p.id)+" tbody:first")` is more slowly. – Oleg Feb 01 '15 at 23:39
3

The modifications by @Oleg were helpful for my similar issue, however I still received the error invalid target element for this operation in Internet Explorer 9 (no problem in 7, 8, 10, or 11) when attempting this line of code:

self.firstElementChild.innerHTML += rowData.join('');

However, after setting the jqGrid property...

gridview: false

... I no longer have the error in Internet Explorer 9. As I understand, setting gridview to true builds the table all at once giving faster performance, whereas setting gridview to false builds it row by row and is a bit slower.

I don't know how jqGrid is able to append table data to innerHTML, because, from MSDN:

The innerHTML property is read-only on the col, colGroup, frameSet, html, head, style, table, tBody, tFoot, tHead, title, and tr objects.

However, even with gridview:true, it somehow works for me in all versions of IE, except for IE9.

This isn't really an answer, but hopefully it helps someone. As always, thank you @Oleg for all of your contributions to jqGrid. You have helped me more than you can imagine.

Seph
  • 33
  • 5
1

I wrapped 'ts.firstElementChild' into $ rather the 'innerHTML' property.

 try {
        ts.firstElementChild.innerHTML += rowData.join(''); // append to innerHTML of tbody which contains the first row (.jqgfirstrow)
     } 
 catch (e) {
        //IE 9 bug-fix for exception "invalid target element for this operation"                    

       $(ts.firstElementChild).html($(ts.firstElementChild).html() + rowData.join(''));
     }

and it's working.

0

@Oleg, I had to make some changes to your patch as i was getting javascript errors at 'self'. I think if I had used complete script, it would have worked i guess. Here is my revised code and please let me know if it doesn't look right.

            } else if (ts.firstElementChild) { //Fix applied by Oleg for gridView=true in IE9.
                ts.firstElementChild.innerHTML += rowData.join(''); // append to innerHTML of tbody which contains the first row (.jqgfirstrow)
                ts.grid.cols = ts.rows[0].cells; // update cached first row
            } else {
                // for IE8 for example
                $("#"+$.jgrid.jqID(ts.p.id)+" tbody:first").append($("#"+$.jgrid.jqID(ts.p.id)+" tbody:first").html() + rowData.join('')); //Modified
                //$tbody.html($tbody.html() + rowData.join('')); // append to innerHTML of tbody which contains the first row (.jqgfirstrow) //doesn't work.
                ts.grid.cols = ts.rows[0].cells; // update cached first row
            }

It is working now. Thanks for your help. I will test my grid with your forked code tomorrow and let you know the result.

Sannu
  • 1,202
  • 4
  • 21
  • 32
  • 1
    If you use `$("#"+$.jgrid.jqID(ts.p.id)+" tbody:first").append` instead of `.html` then you should remove `$("#"+$.jgrid.jqID(ts.p.id)+" tbody:first").html()` from the right part and append just `rowData.join('')`. The current code seems to add the first line (`tr.jqgfirstrow`) **twice** which is wrong. – Oleg Feb 01 '15 at 23:47