Jqgrid: Load data after Grid load? - jqgrid

I am using jqgrid 4.0 .The grid is loaded on page load using 'local' datatype , loadonce:'true' and I don't want to use pagination. Since the data that is to be loaded is huge, it takes lot of time to get loaded. How can I
load the grid only first with headers, displaying a load text as 'loading....' and then load the data? Right now, both the grid and data loads together and page doesnt appear until this is complete.
Load the data faster in grid?
Below is my code snippet where 'data' is the json encoded array formed server side.
<script type="text/javascript">
jQuery("#list9").jqGrid({
data: data,
datatype: "local",
colNames:[...],
colModel:[...],
sortname: 'fld_name',
rowNum: '-1',
loadonce:true,
mtype: "GET",
gridview: true,
viewrecords: true,
sortorder: "asc",
pager: '#pager9',
rownumbers: true,
multiselect: false,
width: '100%',
pgbuttons:false,
pgtext:'',
loadtext: 'loading....',
ignoreCase: true
});
jQuery("#list9").jqGrid('filterToolbar', {stringResult: true,searchOnEnter : false});
$('.ui-widget-header').css("background", "#7B9FBC");
$('.ui-jqgrid-sortable').css("text-align", "left");
</script>

What I do is:
First, render the grid without any data.
var grid = $('#myGrid');
grid.jqGrid({
data: [],
datatype: "local",
colModel: [ ...
Then, add the data to the grid using addRowData.
var grid = $('#myGrid');
grid.jqGrid('addRowData', 'ContactID', newRowData, 'first');
It sounds like you have your data already in memory when you build the grid, and it's just taking a long time to render the grid. This might be because of all the DOM objects being created when rendering the grid. There isn't much you can do about that other than paging, or decrease the complexity of your cells if you are using heavy formatting.

Related

Mapping data to JQGrid with Ajax call

I'm just trying to display a very simple JQGrid with data from an ajax call to a controller. All I'm seeing is the grid headers, no data. Can someone please help me figure out what I'm doing wrong? Thanks in advance!
Here's the Ajax call and JQGrid setup..
$("#grid").jqGrid({
url: '#Url.Action("GetLoanReport", "Report")',
datatype: "json",
height: "auto",
colNames: ['Name', 'Random Stuff'],
colModel: [
{ name: 'Name', index: 'Name', width: 150, sortable: true },
{ name: 'RandomStuff', index: 'RandomStuff', width: 500, sortable: false }
],
jsonReader: {
repeatitems: true,
root: 'rowdata',
page: 'currpage',
total: 'totalpages',
records: 'totalrecords'
},
rowNum: 10,
rowList: [5, 10, 30],
rownumbers: false,
gridview: true,
loadonce: true,
pager: "#page",
caption: "Flat Data Example"
});
Here's the controller code...
Function GetLoanReport() As JsonResult
ViewData("Ribbon") = "partials/_statsRibbon"
Dim response As New Response
Dim model As New ReportModel
model.Name = "Mark"
model.RandomStuff = "Highfield"
response.currpage = 1
response.totalpages = 1
response.totalrecords = 1
response.rowdata = model
Return Json(response, JsonRequestBehavior.AllowGet)
End Function
The main problem: rowdata should be array of items (array of objects) instead of one object only with Name and RandomStuff properties.
Additionally you should decide whether you implement server side paging of data or you want to return all the data from GetLoanReport at once and jqGrid should make local paging, sorting and filtering/sorting the data? In the case you should use loadonce: true option. Additionally it's important to choose the fork of jqGrid, which you use: free jqGrid, commercial Guriddo jqGrid JS or an old jqGrid in version <=4.7. I develop free jqGrid fork, which I can recommend you. If you use it, then I would recommend you to add forceClientSorting: true option additionally to loadonce: true. It will allows you to use sortname and sortorder options to sort the data returned from the server before it will be displayed.

JQGrid rendering performance

We have performance issues with JQgrid rendering. Please advise.
JQGrid v4.3.2, jquery-1.7.2.min.js, jquery-ui-1.8.1.sortable.min.js, jquery-ui-1.8.20.custom.min.js
Browser: IE6,7
Every user is shown data in 2 grids - actions and fyi's. Typical data range is ~300 rows in each grid. The list of columns could vary for user groups and hence the colModel structure is dynamic. After getting data we apply conditional styles to each row (to be bold or not etc) and change the number formatting.
Code sample for grid is as below:
jQuery('#ActionItems').jqGrid({
url: 'http://actionsurl',
mtype: 'GET',
datatype: 'json',
page: 1,
colNames: actionsColNames,
colModel: actionsColModel,
viewrecords: true,
loadonce: true,
scrollrows: false,
prmNames: { id: "PrimaryID" },
hoverrows: false,
jsonReader: { id: "PrimaryID" },
sortname: 'CreateDt',
sortorder: 'desc',
gridComplete: function () {
fnActionsGridComplete();
},
recordtext: "Displaying {1} of {2} Records",
emptyrecords: "No data to view",
emptyDataText: "No data found.",
loadtext: "Loading...",
autoWidth: true,
rowNum: 1000,
grouping: true,
groupingView: groupingViewOp
});
Formatting code in fnActionsGridComplete():
Set column widths in %
Iterate thru rows to apply conditional css styles
$("#Actions").find("tbody tr").each(function () {
if ($(this)[0].id != '') {
var data = $(this).find('.IsItemNew').html();
if(data == "Y") {
$(this).css("fontWeight", "bold");
}
}
});
Formatting for specific columns.
Currently we have performance issues for >200 rows of data in any grid. After analysis we found that formatting and rendering is taking most time.
Can you suggest any optimal way to improve performance here. (paging is no-no)
Regards,
Rajani
- We did testing on IE9 and its lot better. But users cant immediately upgrade.
The reason is the code fnActionsGridComplete. I recommend you to read the answer which explains why it's very important to use gridview: true and reduce the number of changes of DOM elements of the page.
What you try to do seems could be implemented by adding cellattr to the column "IsItemNew". The code could be about the following
cellattr: function (rowId, value) {
// additional parameter of cellattr: rawObject, cm, rdata are optional
if (value === "Y") {
return ' style="font-weight:bold;"';
}
}
Alternatively you can add class attribute instead of style and define font-weight: bold in the class.
I recommend you to read the answer, this one, this one etc. If you would need to set some properties on the whole row instead of the cell only you can use rowattr (see the answer).
If you would include gridview: true and use cellattr, rowattr or custom formatters you would see that the performance of the grid will be on absolutely another level.

How to delete selected rows from server and reload grid?

Im trying to implement a jqgrid in my web page but not able to handle delete; if the user selects multiple values, and clicks on delete, I want to invoke a servlet that will handle the delete and return to the page.
The code snippet is as below:
<script type="text/javascript">
function fillGridOnEvent(){
$("#jQGrid").html("<table id=\"list\"></table><div id=\"page\"></div>");
jQuery("#list").jqGrid({
url:'<%=request.getContextPath()%>/MyServletGrid?q=1&action=fetchData',
datatype: "xml",
mtype: 'POST',
height: 423,
colNames:['##','Keyword','Category','ViewType',"Action"],
colModel:[
{name:'srNo',index:'srNo', width:30,sortable:true,align:'center'},
{name:'Keyword',index:'Keyword', width:200,sortable:true},
{name:'Category',index:'Category', width:100,sortable:true,align:'center'},
{name:'ViewType',index:'ViewType', width:100,sortable:true,align:'center'},
{name:'view',index:'view', width:113,sortable:false,align:'center'}
],
multiselect: true,
paging: true,
rowNum:18,
pager: $("#page"),
loadonce:true,
caption: "Test JQGrid"
}).navGrid('#page',{edit:false,add:false,del:true});
}
jQuery().ready(function (){
//fillGrid(); rowList:[10,20,30],
});
Get the row id of the row to be deleted as follows
var rowid = jQuery("#tableid").jqGrid('getGridParam', 'selrow');
Get the row data using the following
var rowdata = jQuery("#tableid").jqGrid('getRowData', rowid);
rowdata will have your data like rowdata.srNo, rowdata.Keyword etc.,
Issue an ajax call to your servlet for the delete from your database. Then call the following to reload your grid
jQuery("#tableid").trigger('reloadGrid');

JQGrid 'undefined' error

I am getting a JavaScript error when trying to use the JQGrid:
"Message: 'undefined' is null or not an object"
When I debug on my server, I see that my JSON output looks like this: (does it matter that the "id" value is not inside double quotes?)
{
"page":"1",
"total":"20",
"records":"5",
"rows":[
{"id":1,"name":"Sam","phone":"732-333-2222"},
{"id":2,"name":"Dan","phone":"000-222-1111"},
{"id":6,"name":"George","phone":"333333"},
{"id":4,"name":"Jerry","phone":"332-333-4444"},
{"id":7,"name":"John","phone":"666666"},
{"id":8,"name":"Tom","phone":"3333"}]
}
.. and my page looks like this:
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("#list").jqGrid({
url:'/myUrlPage',
datatype: 'json',
mtype: 'GET',
colNames:['Id', 'Name', 'Phone'],
colModel :[
{name:'id', index:'id', width:55},
{name:'name', index:'name', width:90},
{name:'phone', index:'phone', width:150, sortable:false} ],
pager: jQuery('#pager'),
rowNum:10, rowList:[10,20,30],
sortname: 'id',
sortorder: "desc",
viewrecords: true,
imgpath: 'themes/basic/images',
caption: 'My first grid' }); });
</script>
You main problem will be solved if you include
jsonReader: { repeatitems: false }
parameter in your jqGrid. See details in the jqGrid documentation.
Moreover I modified a little your demo. You can see it here. I recommend you remove deprecated imgpath parameter. Instead of that I recommend you to use height: 'auto' which gives you good results in the most cases. Instead of jQuery('#pager') is better to use just '#pager'. You should additionally increase the value of the width for some columns in case of the usage of pager and viewrecords: true. I included in my demo the jQuery("#pager_left").hide(); statement which hide some block of the pager which you not use now. If you will start to use navigator buttons you should remove the line.
One more remarks about the JSON data which you use. The values of id, page, total and records properties can be either strings or integers, so "id":1 will gives you the same results as "id":"1".
It's important to understand how you should fill page, total and records. You current values are page=1, total=20, records=5 and you data contain 6 rows. All the data has no sense. The jqgrid asked the server with respect of additional parameters which it appended to the URL to gives one page of the data with 10 rows per page (rowNum:10). Your answer from the server means that your data contain 5 items (records=5) totally. If you order the data (the 5 items) in pages (10 items per page) you will have 20 pages (total=20) and the first one from there (page=1) you are filled with the data (6 items). The strange values of page, total and records from your JSON data follows to strange values in the pager on the demo:
I would recommend you to read the answer where I tried to describe why jqGrid need so strange format of JSON data.

jqrid generate xml from grid data

I'm trying for a few hours now to generate an xml string from my grid's data , when the columns names will be the tag names and the content of the grid will be inside of them.
my grid is initialized with xmlReader.
I tried using:
var dataFromGrid = {row: grid.jqGrid('getGridParam', 'data') };
var xmldata = xmlJsonClass.json2xml (dataFromGrid, '\t');
alert(xmldata);
but it did not work for me.
how can this be done? it will be better not using json, if it's possible.
Thank's In advance.
Update:
This is my code: I'm using datatype xml.
Query("#signatory2_payment").jqGrid({
url:'loadgrid.jsp?type=3',
datatype: "xml",
direction:"rtl",
height: '100%',
width: '100%',
colNames:['group_order','claim','beneficiary_description','insurance_code_description'],
colModel:[
{name:'group_order',xmlmap:'group_order', width:80, align:"right",sorttype:"int"},
{name:'claim',xmlmap:'claim', width:70, align:"right",sorttype:"int"},
{name:'beneficiary_description',xmlmap:'beneficiary_description', width:120, align:"right",sorttype:"string"},
{name:'insurance_code_description',xmlmap:'insurance_code_description', width:120, align:"right",sorttype:"string"}},
],
xmlReader: {
root:"payments",
row:"payment",
page:"payments>page",
total:"payments>total",
records:"payments>records",
repeatitems:false
},
multiselect: false,
autowidth: true,
forceFit: false,
shrinkToFit: false,
caption: " xxxxxx "
});
If i understood you correctly it will work only on local data?
What is the solution for data that is not local?
Thank's again.
Look at the answer. You will find here a working demo which do what you need.
UPDATED: It is important, that you include definition of jqGrid in your question. The data parameter will be filled only in case of local data (for example if you use datatype:"local", datatype:"xmlstring" or use loadonce:true additional parameter which changes the datatype to datatype:"local" after the first load of data. So if my old answer will help you not you should append your question with additional informations.

Resources