7

I was wondering whether there is a better way to load large Json data set from the server.

I am using jqgrid as loadonce:true. i need to load around 1500 records at once and also i don't use pagination options. is there any better way to achieve this? Thank you in advance.

This is my Grid code -

  $(function(){
        $("#testgrid").jqGrid({
            url:getGridUrl,
            datatype: 'json',
            mtype: 'GET',
            height: 250,
            colNames:['Inv No','Date', 'Client', 'Amount','Tax','Total','Notes'],
            colModel:[
                {name:'id',index:'id', width:60, sorttype:"int",search:false},
                {name:'invdate',index:'invdate', width:90, sorttype:"date",search:false},
                {name:'name',index:'name', width:100,search:false},
                {name:'amount',index:'amount', width:80, align:"right",sorttype:"float"},
                {name:'tax',index:'tax', width:80, align:"right",sorttype:"float",search:false},        
                {name:'total',index:'total', width:80,align:"right",sorttype:"float",search:false},     
                {name:'note',index:'note', width:150, sortable:false,search:false}      
            ],
            multiselect: true,
            multiboxonly:true,
            caption: "Manipulating Array Data",
            pager: '#testgridpager',
            //Auto load while scrolling
            //scroll: true,
            //to hide pager buttons
            pgbuttons:false,
            recordtext:'',
            pgtext:'',
            loadonce: true,
            sortname: 'id',
            sortorder: 'asc',
            viewrecords: true,
            multiselect: true,

            jsonReader : {
                root: "rows",
                //page: "page",
                //total: "total",
                records: "records",
                repeatitems: false,
                cell: "cell",
                id: "id"
            },
            loadComplete: function(data) {
            var rowId;
            //alert(data.length);
            //alert('load complete'+data.rows.length);
            //set checkboxes false if mode is set to true
            if(mode){
                for(var i=0;i<data.rows.length;i++){
                    rowId=data.rows[i].id;
                    disableRow(rowId);
                    var searchVal =  $("#gs_amount").val().trim();
                    if(searchVal ==data.rows[i].amount){
                        jQuery("#testgrid").jqGrid('setSelection',rowId);
                        //heighlightSearch();
                    }
                }
            }
        }
     });
        //toolbar search
        $("#testgrid").jqGrid('filterToolbar',{stringResult:true,searchOnEnter:false});
    });

    function disableRow(rowId){
    $("#testgrid").jqGrid('setRowData', rowId, false, {color:'gray'});
    var trElement = jQuery("#"+ rowId,$('#testgrid'));
    trElement.removeClass("ui-state-hover");
    trElement.addClass('ui-state-disabled');
    trElement.attr("disabled",true);
}
Sam
  • 2,055
  • 6
  • 31
  • 48
  • Could you include the javascript code which you currently use? Do you use local paging of the data? Do you use `gridview:true` parameter? – Oleg Apr 14 '11 at 14:38
  • @Oleg - Thanks oleg. i used gridView parameter. please find the updated question. – Sam Apr 14 '11 at 15:14
  • @Sam: I am very busy now, but if your problem will not be solved till Saturday I'll write you some suggestions. What do `disableRow`? I am not sure that I understand what you do inside of `loadComplete`. If in the filter bar for `amount` no data exist you should do nothing. If in `amount` the data exist the data are filtered and you should select all rows. Is it so? Moreover I don't see `gridview:true` parameter. Is the example which you posted the real example which you tested? How long time is the loading in your tests? Which browser is the most important for you? – Oleg Apr 14 '11 at 16:47
  • @Oleg - Thanks for your valuable time Oleg. this is the grid i used to test jqgrid. i just removed `gridview` param to check the consequences. inside loadComplete if the `amount` match the grid value `amount` it needs to get selected. you are right i do need to put empty check in loadComplete. I am still searching the better ways to do this(load large data). IE 8 will be my most important browser. Thanks for your response Oleg. I will looking forward to your thoughts among this.Appreciate it. – Sam Apr 14 '11 at 17:42
  • @Oleg - If you have some time can you please send me some directions about any approach for this? if you have time to spare only..Appreciate your help. – Sam Apr 16 '11 at 16:13
  • @Sam: I am preparing the demo for you at the time. By the way in the example you forget to include `rowNum` with some value greater or equal to 1500. After this you will see that your grid is mostly slow because of the actions which you do inside of `loadComplete`. If you commented th part and use `gridview: true` and `hoverrows: false` the grid construction will be acceptable. What is unclear for me is the following: Your current code disable **all rows** (in many ways) and then try to select all the rows. What you really want to do? – Oleg Apr 16 '11 at 17:12
  • @Sam: rows having 'ui-state-disabled' class can not be selected. – Oleg Apr 16 '11 at 17:18
  • @Oleg - Thanks for your response.according to the `mode` i need to disable the filtered rows.that rows cannot be selected. else i need to filter whatever value typed in the `amount` search box must be filtered. i assume there may be a unique `amount` for each and every row. so if the `amount` match the particular amount in the grid that row needs to be automatically checked. thats what i am trying to do. if my approach is wrong please let me know what needs to be change. Thank you. – Sam Apr 16 '11 at 17:33
  • @Sam: I don't quite understand what you mean. If you use `searchOnEnter:false`, then the grid start be filtered almost immediately after starting the typing in the "#gs_amount". So **all** rows which will be displayed in the grid are the filtered rows. So if you write "i need to disable the filtered rows" it means that **all rows of grid will be disabled**. I don't quite understand which matching you need. If you define [searchoptions](http://www.trirand.com/jqgridwiki/doku.php?id=wiki:search_config#colmodel_options) with `sopt:["eq"]` for 'amount' column only exact matching will be done. – Oleg Apr 16 '11 at 19:00
  • @Sam: you can use `defaultSearch` parameter of `filterToolbar` to specify the default matching operations. I use almost everywhere for the integer and 'select' columns the exact matching 'eq' and case insensitive (`ignoreCase:true` parameter of jqGrid) contain searching ('cn') for the columns having strings. – Oleg Apr 16 '11 at 19:04
  • @Oleg - Thank you very much oleg for the advices. i will follow those. is there any clue regarding large data set loading? – Sam Apr 17 '11 at 14:45
  • @Sam: In my answer I included an example which loads 1500 rows and the performance is not bad. I recommend only better to use more compact packing of data as with `repeatitems:false` in `jsonReader`. If one column can be interpret as the id one can use `cell:""` instead (see my answer). Much more important is how to work with the data. Simple loop where you find row by rowid is too slow. Moreover would recommend you to use local data paging. 1500 rows can not be displayed at once. If you will use local paging by setting rowNum to some small value the performance will be much much better. – Oleg Apr 17 '11 at 16:59

2 Answers2

10

On example of this demo you can see the time of loading 1500 rows for your grid in case of usage of gridview: true.

The most performance problem of your example are inside of loadComplete function. If you do need to make some modifications on the grid you should use jQuery to manipulate the grid contain. The best performance you can archive if you use DOM elements of the grid directly like in the example

loadComplete: function() {
    var i=0, indexes = this.p._index, localdata = this.p.data,
        rows=this.rows, rowsCount = rows.length, row, rowid, rowData, className;

    for(;i<rowsCount;i++) {
        row = rows[i];
        className = row.className;
        //if ($(row).hasClass('jqgrow')) { // test for standard row
        if (className.indexOf('jqgrow') !== -1) {
            rowid = row.id;
            rowData = localdata[indexes[rowid]];
            if (rowData.amount !== "200") {
                // if (!$(row).hasClass('ui-state-disabled')) {
                if (className.indexOf('ui-state-disabled') === -1) {
                    row.className = className + ' ui-state-disabled';
                }
                //$(row).addClass('ui-state-disabled');
            }
        }
    }
}

You can see the corresponding example live here.

In the implementation of loadComplete function I use the fact, that jqGrid having loadonce:true parameter use internal parameters _index and data which can be used to access the contain of the grid. In the example I disabled the rows which not contain "200" in the amount column.

UPDATED: The answer describes how to use rowattr callback to simplify the solution and to have the best performance (in case of gridview: true of cause).

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • @Oleg- Thank you very much oleg. now I got the base line from **The best performance you can archive if you use DOM elements** phrase. examples are really helpful. Thanks for your knowledge sharing and the kind guidance.Greatly appreciate your time & the effort. – Sam Apr 18 '11 at 00:29
1

I would be tempted to look into the Autoloading on scroll feature of jqGrid. I would never load 1500 rows upfront. Any reason you cannot page?

redsquare
  • 78,161
  • 20
  • 151
  • 159
  • thanks for the turn over. Requirement is not to use pagination. i used to look at scroll:true function and i found [this](http://jollyroger.kicks-ass.org/grid_test/) article. Thats why i wonder what will be the best way to use. – Sam Apr 14 '11 at 14:41
  • @Sam - the issue maybe his js/php who knows. I would test for myself. I am sure others would have mentioned and it is upto version 4.0 now. – redsquare Apr 14 '11 at 15:42