How to improve performance of jqGrid - jqgrid

I have more than 1000 rows to populate data through jqGrid. When I populate data through jqGrid, jqGrid takes more than 20 seconds to populate data. This time is taken only by jqGird (query execution time and other time is excluded). I have a requirement to populate 1000 rows by using jqGrid and I don't want to use Pagination. Please help me how to increase the performance of jgGrid.
The versions we are using are:
jgGrid: 3.6.4
jQuery:1.4.2
jQuery UI:1.7.2
Browser: IE 7
Following is the code:
jQuery("#displayItemPerformanceGrid").jqGrid({
//datatype: displayItemPerformanceGridData, //json
url:'/DISMGMT/StandardProxy/displayItemPerformanceService?userRole='+userRole+
'&userName='+userName+'&duration='+displayDuration+'&userId='+userId,
datatype: 'json',
colNames: ["CM","Display Location","Display Name","Item","Item Description",
"Store","DC","Date","Type","Promo Retail","Reg. Retail 50" "Units",
"Sales $", "Profit $"],
// $("#load_navGrid").html("Loading...").show();
colModel: [
{name:"cmName",index:"cmName",classes:"metric",width:130,resizable:true,
align:"left"},
{name:"displayLocation",index:"displayLocation",width:80,align: "left"},
{name:"displayName",index:"displayName",width:225,align:"left"},
{name:"item",index:"item",sorttype:"int",width:60,align:"left"},
{name:"itemDescription",index:"itemDescription",width:230,align:"left"},
{name:"store",index:"store",sorttype:"int",width: 70,align: "right"//,
//unformat : spaceFormatter
},
{name: "dc", index: "dc", sorttype: "int",width: 60,align: "right"//,
//unformat : spaceFormatter
},
{name:"date",index:"date",sorttype:"date",datefmt:"mm-dd-yy",width:80,
align: "left"},
{name: "type",index: "type",width: 45,align: "left"},
{name: "price",index: "price",width: 70,align: "left"},
{name: "regRetail",index: "regRetail",width: 70,align: "left"},
{name:"units",index:"units",sorttype:"int",width:45,align:"right",
unformat : spaceFormatter},
{name:"sales",index:"sales",sorttype:"int",width:45,align:"right",
unformat : spaceFormatter},
{name:"profit1",index:"profit1",sorttype:"int",width:40,align:"right",
unformat : spaceFormatter}
],
width: 982,
height: 137,
toolbar: [true, "top"],
viewrecords: true,
rowNum: 1500,
// gridview:true,
loadonce:true
});
Please suggest me how to improve performance of jqGrid

Use virtual scrolling (look at the demo, New in version 3.7 -> Virtual scrolling).

You question look like another question from trirand forum which I recently answered. To be sure I can repeate the information here.
In general for jqGrid is not a problem to display 1000 rows. The demo example which has 15 columns and 1000 rows will be displayed on my computer quickly enough. I have no IE7, but in IE8, IE9 beta, Chrome, Firefox, Opera and Safari (all in the last versions) the time to display the table is very quickly. In the example I use the modified jQuery UI, where .ui-widget :active { outline: none; } is removed. See here and here for more detailes.
So to be able to help you one need have possible full definition of your jqGrid inclusive the HTML code and test JSON data. You can capture the data with respect of Fiddler or Firebug. Probably you has some datatypes, don't use gridview:true option and use afterInsertRow method which make jqGrid working slower espetially for lagre pages. It can be also that you do many work inside of gridComplete or loadComplete event handler. So without having the code I can only guess. It can be also important which column you use for the sorting of the data and how you inserts the data in the grid (with data parameter, loadonce:true or using addRowData).
Another point of view is the usage of local paging. If you prefer to return all 1000 rows at once from the server it disturbs you not to use local paging of the 1000 rows of data. On the next example I demonstrate this. The problem is easy: all 1000 rows can not be displayed for the user at once. The user have to scroll the rows either in web browser or with respect fo jqGrid local paging. The advantage of the local paging is: only the data for one page will be placed in the table. All other data will be only hold in the sorted form internally. It can improve the performance and don't change almost anything from the users point of view.
More then that, having intelligent local filtering of data with respect of toolbar filtering or single field/advanced searching can help the user very much to analyse a lot of information from the 1000 rows which will be displayed him. Local filtering and local paging can be used very native together.

Related

Using JQgrid beforesearch and aftersearch for a loading dialog

I'm using jqgrid with a lot of data and, as the filter is taking too long, I'd like to show a dialog before the search and close it after the search.
The thing that's happening to me, is that when I run the filter in debug mode I see the methods that open and close the dialog get called before the search and after the search, but when I run the filter without interruptions I can't see the dialog, my filter waits 10 seconds or more to refresh the table but the dialog isn't shown.
is it a syncronous problem? or why isn't my dialog showing up?
Here's my code:
jQuery("#mytable").jqGrid('filterToolbar',{
searchOnEnter : false,
stringResult : true,
defaultSearch:'cn',
beforeSearch: openDialogLoading,
afterSearch: closeDialogLoading
}
);
function openDialogLoading(){
$( "#DialogLoading" ).dialog({
resizable: false,
autoOpen: false,
height: 110,
width: 50,
title: 'Loading...',
modal: true,
bgiframe: true
});
$( "#DialogLoading" ).dialog('open');
}
function closeDialogLoading(){
if ($( "#DialogLoading" ).dialog('isOpen')) {
$( "#DialogLoading" ).dialog('close');
}
}
Thanks
It's really important to know the details of the grid (options which you use). It's important to use local paging to have good performance with large number of rows. I created some demos for you which you can try and the the time of loading/sorting/filtering:
the demo1 uses 13 columns, 400 rows and the page size 20.
the demo2 uses 13 columns, 400 rows and the page size 400 (no local paging).
the demo3 uses 13 columns, 4000 rows and the page size 20.
the demo4 uses 13 columns, 40000 rows and the page size 20.
the demo5 uses 13 columns, 1000 rows and the page size 1000 (no local paging).
You can see that the performance of the grid depends very havy from the page size. You can play more with differnet values of columns, rows and the page size using the JSFiddle demo http://jsfiddle.net/OlegKi/1rmmyeLh/ where I used
rowNum: 20
UPDATED: The demo http://jsfiddle.net/1rmmyeLh/7/ which you posted later in the comment some important problems. Modifing the code so that it do displays the "Loading" gif with anymation is realtively easy, see http://jsfiddle.net/OlegKi/1rmmyeLh/8/.
I included the call of closeDialogLoading(); inside of loadComplete and modified beforeSearch so that it returns true instead of false, which prevent reloading of grid by jqGrid. Additionally I trigger reloadGrid inside of setTimeout manually:
.jqGrid("filterToolbar", {
beforeSearch: function () {
var $self = $(this);
openDialogLoading();
setTimeout(function () {
$self.jqGrid("setGridParam", { search: true })
.trigger("reloadGrid", [{ page: 1 }]);
}, 0);
startTime = new Date();
measureTime = true;
return true; // SKIP filtering
}
})
Such modification of the code solves the issue with displaying of the "Loading" div. On the other side I stay on my opinion, that the main problem which you have is in ingoring the usage of local paging of data (rowNum option).
I want to stress that it's better, in my opinion, to make the application quickly as to display some "Loading" massage and to hold the application slow. You use in the demo rowNum: 4000 with 4000 rows of data. On the other side I can see on my display about 35 rows of data only. If I just change rowNum from 4000 to 30 I see the peformance improvement in about 20 times!!! Now you should set clear your priorities. One can speak long about the difficulty for very stupid user to undesrtand the meaning of pager buttons, but in my opinion the difference in performance in 20 times makes any discussions unneeded. Practically every user have used already applications with pagers. So I strictly recommend you to use local data paging. You will be able to work in the style with much more large dataset (see the demo with 40000 rows and the page size 20, which responsibility is more as 3 times better in IE11 as the responsibility of the demo with 400 rows and no paging).

jqGrid loses edits when you reorder or filter

I have a jqGrid that has the following properties;
grid.jqGrid({
datatype: "local",
data: GRID.GridData,
colModel: GRID.availableGridColumns['columnModel'],
loadonce: true,
It loads the data just fine.
I then make an inline edit to one to the cells.
I then apply a filter, or a sort, and the edit I made to the cell is now gone and the value is back to its original value.
I also have this;
var rowData = $('#Grid').jqGrid('getRowData', "11332601");
rodData.State = "Open";
$('#Grid').setRowData("11332601", rowData)
The value in the cell is changed but when I apply a filter or a sort, the cell value is changed back to its original value.
This can also be demonstrated here http://www.trirand.com/blog/jqgrid/jqgrid.html and then opening "New in version 3.3" and selecting the "Cell Editing" link.
Sort the grid by "Amount", change the value of "50.00" to be say "51.00". Sort by amount again and then again and you will see that "51.00" has changed back to "50.00".
Is there a workaround for this behavior?

jqGrid dynamic columns

I use jqGrid v4.4.5 and I want to create it with dynamic columns.
It is filled by "jqGridHandler.ashx" file .
I want send all information(column name,data,...) by JSON .
I search for it in Google but can not find a good answer.
By Click on each node(child) change whole grid(actions and columns...).For example by click on node3 the grid has three columns 'A' and 'B' and 'actions' but by click on node2 grid has columns 'C' and 'D' and 'actions'.
One can use jqGrid to create many different grids, tree grids, subgrids and so on. It's very important to understand whether you want to display grid with 10 rows or with 100000 rows. If you have 100000 rows (or some other large number of rows) you will have to implement server side paging and sorting of data. So if the user would click on the "next page" button the next rows should be loaded from the server. Why you would need to send all colModel data on paging or sorting? So you should clear understand that in server side scenario one need create all structures of grid only once and then one need refresh only the body of grid. So it would be bad choice to send all information (column name, column model, data,... at once).
Only if you have some hundreds or some thousand of rows in the grid and you can use loadonce: true option them you can load once all information (column name, column model, data, ...) per separate jQuery.ajax call and then create jqGrid with datatype: "local" and using data parameter which contains all grid data.
UPDATED: If you need change
// in the example below the grid with id="list" will be created
// with column having name: "c4" in colModel
var $grid = $("#list"), columnName = "c4";
...
var $colHeader = $("#jqgh_" + $.jgrid.jqID($grid[0].id) + "_" + $.jgrid.jqID(columnName)),
$sortingIcons = $colHeader.find(">span.s-ico");
// change the text displayed in the column
$taxHeader.text("New header text");
// append sorting icons to the new text
$taxHeader.append($sortingIcons);
Before your initialize the jqGrid you will need to have the information for your colNames and colModel properties of the jqGrid.
So in short, you will request the information from your server, once you have successfully retrieved that information you can then build the jqGrid and then the jqGrid can go and fetch it's data.
The following post has some example code on the client side:
jqGrid and dynamic column binding

Sorting when two grids are on the same page

On my page I have two webGrids. When I click on one to sort that column, both of the grids are sorted on that column. Sorting on a column that is only in one, doesn't sort at all.
I noticed the sorting works by making the header a link to the same page with in the query string a column and a direction. This explains that both grids are affected. I was wondering if the webGrid has some functionality to solve my problem or should I fix it myself.
The way I am planning to "fix it myself" is to first add an id attributes to the table tags by setting the htmlAttributes. Then I will use jQuery to find this id for every webgrid and incorporate that id in the links parameters. Then when loading a page with a grid I will forcably set which column to sort on based on those parameters.
It seems to me the webGrid is not designed to be on a page with another webGrid. However, I feel that in my situation it is desired. I prefer to use some standard way (built in or just what everyone else uses).
So the question is, what is the best way to do it? And if there is no best way, is my way a good way (did I forget about something)?
Thanks in advance.
I think you need to set the following properties:
string fieldNamePrefix = null
//The value which prefixes the default querystring fields
string pageFieldName = null
//A value that replaces the default querystring page field
var grid1 = new WebGrid(canPage: true, canSort: true, ajaxUpdateContainerId: "grid1", fieldNamePrefix:"g1",pageFieldName: "p1");
var grid2 = new WebGrid(canPage: true, canSort: true, ajaxUpdateContainerId: "grid2", fieldNamePrefix:"g2",pageFieldName: "p2");

Hide expand/collapse symbol or deactivate spec. rows in jqGrid subgrid

I have a grid with a subgrid: Only the first row of the Main grid need to have a subgrid.
The solutions I found by Google and http://www.trirand.com/....i:subgrid&s[]=hidecol
doesn't work.
Is there a quick and dirty (hard coded) solution?
Hiding the 'subgrid' column with jQuery("#grid_id").hideCol('subgrid'); remove full column which can be used to expand or collapse the subgrid, so you can not use the way in your case.
I suggest you to clear contain of the 'subgrid' column and unbind the 'click' event for the cells inside of loadComplete event handle:
loadComplete: function() {
$("td.sgcollapsed:not(:first)","#list").unbind('click').html('');
}
you will have the following results:
(You can see the corresponding example live here). It's important to understand, that the loadComplete event will be called on any page, so on the second page you will have subrgid also only on the first row.
If you need to implement more complex logic in choosing of the rows which need have subgrids you can use following code
loadComplete: function() {
var grid = $("#list");
var subGridCells = $("td.sgcollapsed",grid[0]);
$.each(subGridCells,function(i,value){
if (i!==0) {
$(value).unbind('click').html('');
}
});
}
The code above do the same as the statement $("td.sgcollapsed:not(:first)","#list").unbind('click').html(''), but you can easy modify the last version of the code to implement more complex behavior.
UPDATED: If you need detractive subgrid only for some row identified by the rowid you can use
$("#"+rowid+" td.sgcollapsed",grid[0]).unbind('click').html('');
(see live here) inside of the loadComplete. If you need deactivate subgrid for all rows which id is not equal to rowid you can make something like following
$('td.sgcollapsed:not("#'+rowid+' td.sgcollapsed")',grid[0]).unbind('click').html('');
(see live here)
UPDATED: free jqGrid now have new feature described in the answer: hasSubgrid callback which can be specified in subGridOptions. It allows to inform jqGrid which rows should don't have subgrids.

Resources