0

Have setup a grid that actually gets the records from a java back-end.The data is sent in json format and hence I use the datatype as json in jqgrid. I have already used the suggestions in forums , i.e., have already tried including all the properties but still the performance is drastic when the records count that are retrieved from java are > 500 rows. And this is slow only in IE but in FF the rendering is pretty fast and work fine.

Please not that I don't want pagination but all the records should be shown with the vertical scroll bar available within the grid.

Have pasted the important properties/functions I have used, kindly suggest on this.

    type: "POST",
    cache: false,
    url: '............', 
    datatype: "json",
    viewrecords: false,
    gridview: true, // tried false as well
    pgtext: "",
    ignoreCase: true,
    rownumbers: true,
    pginput: false,
    loadonce: true, // tried setting the loadonce:false as well , no luck
    pager: false,
    cellEdit: true,
    pgbuttons: false,
    editurl: 'clientArray',
    beforeProcessing: function (data) {
//setting the rownum, if not set it always shows only 20 records as its the default
      $(this).setGridParam({rowNum: data.length}).trigger("reloadGrid");
    },
    loadComplete: function (data) {
        if (data.length > 0) {
            if (data.length <= 10) {
                $(this).setGridHeight('auto');
            }
            else {
                $(this).setGridHeight(200); //setting vertical scroll bar within the grid and not for browser
            }
        }
        else if (data.length == 0) {
            ..............
        }
    }
Faz
  • 534
  • 1
  • 9
  • 27
  • Please **write in all questions** about jqGrid, which version of jqGrid you use and from which fork ([free jqGrid](https://github.com/free-jqgrid/jqGrid), [Guriddo jqGrid JS](http://guriddo.net/?page_id=103334) or an old jqGrid in version <= 4.7). Free jqGrid is the fork which I develop. You can try to change (temporary) the URLs to the URLs describe in [the wiki article](https://github.com/free-jqgrid/jqGrid/wiki/Access-free-jqGrid-from-different-CDNs). If you still have the same problem you can prepare the demo (wit non-minimized free jqGrid), which reproduce the problem and I'll debug it. – Oleg Feb 05 '16 at 21:22
  • The setting of `rowNum` inside of `beforeProcessing` is unneeded. You can use any large enough value instead. The usage of `.trigger("reloadGrid")` inside of `beforeProcessing` is **definitively wrong**. You should remove it. After upgrade to free jqGrid you can use `maxHeight` option: `maxHeight: 200` in combination with `height: "auto"`, which is default for free jqGrid. After that you can remove `loadComplete`, which you use. – Oleg Feb 05 '16 at 21:24
  • It's unclear why you want to display more as 500 rows **at once** instead of usage **local** paging. The monitor allows to display about 25 rows. By filling 500 rows instead of 25 your reduce dramatically the performance of the page independent from jqGrid. Try [the demo](http://www.ok-soft-gmbh.com/jqGrid/OK/performane-13-4000-20-free-jqgrid.htm) and [another one](http://www.ok-soft-gmbh.com/jqGrid/OK/performane-13-40000-20-free-jqgrid.htm) with 4000 and 40000 rows **with** local paging. You can try sorting, paging and filtering of the data and decide whether you need to use it. – Oleg Feb 05 '16 at 21:30
  • Thanks Oleg, the version am using is **jqGrid 4.9.0-beta1 - free jqGrid**. Also its a requirement to avoid the pagination so I dont have any other option. Also the reason I set the rowNum is to ensure that the height of the grid will have to adjusted according in the load complete . Let me know HOW I can make use of maxHeight here to avoid the usage of load complete in this version. – Faz Feb 06 '16 at 12:24
  • 1
    You are welcome! First of all you should use the latest jqGrid 4.12.1 or the current code from GitHub. The `maxHeight` is just new jqGrid option like `datatype` or `loadonce`. Just include `maxHeight: 200`. The value `height: "auto"` is default. I think that the requirement to avoid the pagination is wrong if you have to display more as 500 rows. You can show your customer the performance of scrolling pure HTML table with 1000 rows or free jqGrid with 1000 rows (see [the demo](http://www.ok-soft-gmbh.com/jqGrid/OK/performane-13-1000-1000-free-jqgrid.htm)) and compare with the demo with paging – Oleg Feb 06 '16 at 12:37
  • 1
    By the way free jqGrid set **automatically** `rowNum` to `maxRowNum` (it's 10000 by default) if you don't specified any `rowNum` or if `pager: ""` (it's default value). – Oleg Feb 06 '16 at 12:40
  • 1
    You should **remove** `pager: false`, which break the test for `pager === ""`. `cache: false` is not exist, `type: "POST"` have wrong name (you want probably to use `mtype: "POST"`). If you don't specify any `pager`, then the options `viewrecords: false`, `pgtext: ""`, `pgbuttons: false` are unneeded. `editurl: 'clientArray'` is default in free jqGrid and `gridview: true` will be default too. Thus you can simplify your code. By the way `forceClientSorting: true` is important option which can be used in combination with `loadonce. true` to sort **locally** the data returned from the server. – Oleg Feb 06 '16 at 12:59
  • Thanks again Oleg, that's a lot of useful information :). I will take a look at these in detail and will get back to you for any further questions. By the way, are all the above options (eg. maxHeight) available under **jqGrid 4.9.0-beta1 - free jqGrid**? – Faz Feb 06 '16 at 17:14
  • Also I removed the setting of rowNum inside of beforeProcessing and also the trigger stuff, but looks like on removing this I always see a default of only **20 rows** even though the rows returned from server is more than 20 rows. Is it due to the jqGrid 4.9.0-beta1 - free jqGrid version am using or any other issue ? – Faz Feb 06 '16 at 17:56
  • You are welcome! I don't understand why you use some preliminary version of 4.9.0 if many other versoins are published later. I recommend you update every time to the latest version if it will be published. You can just use the URLs from CDN described in [the wiki artickle](https://github.com/free-jqgrid/jqGrid/wiki) or download the latest version from GiThub. You can in [the readme](https://github.com/free-jqgrid/jqGrid/blob/master/README.md) to every version which features are implemented and which bugs are fixed. – Oleg Feb 06 '16 at 18:09
  • Ok Let me check if I can download the latest minified version of the jquery.jgrid.js. Please let me know if 4.12.1 is the latest stable version. I believe that this link https://github.com/free-jqgrid/jqGrid/archive/master.zip will contain the required source..? – Faz Feb 06 '16 at 20:00
  • One last thing, just getting the jquery.jgrid.min.js should be sufficient right? As i'm planning not to change the existing code base, so will pulling in and referring to only the jquery.jgrid.min.js be sufficient?? – Faz Feb 06 '16 at 20:03
  • Also, could you please point me a demo which actually has a multiselect and an.option to send all the required rowdata that are selected to the server.. Pls suggest – Faz Feb 06 '16 at 21:18
  • Sorry, I'm not sure that I understand your question. Which options you use? Do you downloaded the files or you use the files from CDN? Do you use `iconSet: "fontAwesome"` option or not? – Oleg Feb 06 '16 at 21:25
  • Sorry, but I don't understand your last question too. You wrote "to send all the required rowdata that are selected to the server". What you mean? If you want to edit server data you should use `editurl` with the server method and the **row** will be send to the server. Do you need to send *additional* non-editable data? In the case you can add `editable: "hidden"` property to not editable columns which values you need to send to the server. Sorry, but I'm not sure that I understand your last question. – Oleg Feb 06 '16 at 21:26
  • Sorry for not being clear. Queries 1 Are jquery.jqgrid.min.js and ui.jqgrid.min.css only sufficient, IF I upgrade to 4.12 version?(I'm not using iconSet) 2 Currently onclick of button, I send all the grid rows to the server & parse the JSOn object in server layer using JSON.stringify($("#grid").getRowData()) Now I need to introduce checkbox column with multiselect option to enable user to select required rows & then on click of the button, I just need to send all the columns(including hidden columns) of the selected rows to server. (ANY ALTERNATIVE TO JSON.stringify($("#grid").getRowData())) – Faz Feb 07 '16 at 10:42
  • You can use `JSON.stringify($("#grid").getGridParam("data"))`. It returns the data from **all local pages**. If you use local free jqGrid files then `jquery.jqgrid.min.js` and `ui.jqgrid.min.css` are enough. In general I would still recommend you to include `jquery.jqgrid.src.js` and `jquery.jqgrid.min.map` in the same directory with `jquery.jqgrid.min.js` and `ui.jqgrid.css` and `ui.jqgrid.min.css.map`, which could be used only *during debugging* of solution which uses minimized files. The min-files have reference (at the end of the file) to map file and the map file to src. – Oleg Feb 07 '16 at 11:17
  • @Oleg , what do you mean by all local pages? Could you please throw some light? Does it depict the use of loadonce:true? – Faz Feb 07 '16 at 12:20
  • And what does **getGridParam("data")** do? Is it similar to getRowData because rowdata will get me all the columns even the hidden ones. if I use multiselect along with pagination, how can I maintain the state of multiple selected rows between different pages? say I select rows 1,3,5 in page 1 and rows 11,16,27 in page 2, how do I ensure that I send all these records to server? Hope am not bothering with many questions :( – Faz Feb 07 '16 at 12:31
  • I tried to answer on all your questions in my answer. I tried to explains in details the advantages of the usage of CDN as the main source of free jqGrid files. – Oleg Feb 07 '16 at 15:18

1 Answers1

0

I'd recommend you to upgrade to the latest free jqGrid 4.12.1 or to the current code from GitHub (jqGrid 4.12.2-pre). Free jqGrid is the fork of jqGrid, which I develop since the end of 2014. It could improve the performance of your application and simplify the code, because I implemented many features which seems be useful for you.

Free jqGrid support maxHeight option. You need just include maxHeight: 200, which could be good combined with height: "auto" (the default value in free jqGrid). I think that the requirement to avoid the pagination, which you have, is wrong if you have to display more as 500 rows. You can show your customer the performance of scrolling pure HTML table with 1000 rows or free jqGrid with 1000 rows (see the demo) and compare with the demos with paging. The first demo displays 4000 rows with 13 columns using the page size 20. If works much quickly as the demo with 1000 rows. Moreover you can try to sort by any column or to filter the data. The performance is very good. Even the next demo with 40000 rows works more quickly as the demo with 1000 rows without paging. The main goal for the user: to have quick grid, which displays the results almost immediately. JavaScript works quickly enough in modern web browsers and the usage of local paging is understandable intuitive for every user.

The next new free jqGrid options, which could be helpful for you are:

  • forceClientSorting: true, which can be used in combination with loadonce: true if the server don't returns data sorted based on sortname and sortorder. The usage of forceClientSorting: true informs jqGrid to sort the data from the server response before displaying there.
  • multiPageSelection: true option can be used in combination with well-known multiselect: true option. Typically jqGrid supports selarrrow parameter (which holds the ids of selected rows) only for one page. The array will be reset to empty array [] during initial loading, during changing to another page and during sorting. The option multiPageSelection: true allows "pre-select" some rows by usage selarrrow (you can set it from the server response inside of beforeProcessing, for example) and to hold selection over all pages. The demo created for the answer demonstrates the feature.
  • hidden columns increase the size of the page and make the page slowly because the data will be hold on DOM of the page instead of simple holding the data inside of JavaScript arrays/objects. The option additionalProperties is the new feature of free jqGrid, which solves the problem. Old versions of jqGrid loads and saves in local data parameter only the data for columns (for colModel), but the colModel creates the columns in the resulting grid. Thus one uses typically hidden: true property for such data. The option additionalProperties hold the array of additional properties of input data, which needed be read and saved locally. The option additionalProperties: ["taskId", "isFinal"] for example read and saves locally taskId and isFinal properties from every item of input data. The properties can be used inside of custom formatters, cellattr, rowattr, for sorting and filtering. Another form of usage would be additionalProperties: [{ name: "taskId", sorttype: "integer"}, "isFinal"], where the item of additionalProperties have the same format like colModel item. It inform free jqGrid that the field taskId should be interpreted as integer during sorting or filtering. The demo shows the usage of additionalProperties in the searching dialog.

Another thing which you asked in the comment to your question. The method getRowData is helpful for reading the data from the current page (you will see the difference if you use pager: true and set rowNum to the value which less as the number of items in the grid). Moreover getRowData use unformatter to decode the formatted data from the page to convert to initial format of data. The getRowData without rowid parameters can be used to get all data from the page. On the other side getGridParam just return the reference to internal data parameter with all data read from the server. $("#grid").jqGrid("getGridParam", "data") works very quickly and contains all data from all pages.

Another common question which ask many developers: should I download free jqGrid and uses the references to local copy of jqGrid files (jquery.jqgrid.min.js and ui.jqgrid.min.css) or to use URLs to CDN described in the wiki article? I recommend everybody to use CDN. You can use local copy as fallback path for the case that internet is not available. There are many ways to implement fallback behavior if it's really required. If you provide public web site available from Internet, then you really should use CDN. I can try to explain below why it's so.

First of all some specific version of jqGrid, jQuery or other common files are not changeable. The new version of the files will have another version and so another path on CDN. Thus the data loaded from http://cdn.jsdelivr.net/free-jqgrid/4.12.1/js/jquery.jqgrid.min.js for example will be always the same.

The recommended way for the usage of jqGrid, like jQuery and other common JavaScript libraries and CSS frameworks is the usage from CDN. Here you can find the code example and here the working demo, which uses all dependent files from CDN. The main advantage: the required files will be used from the local cache mostly and when one really need to download the files, the files will be loaded very quickly from any location on the world. I try to explain the reason.

Let us you load free jqGrid file from http://cdn.jsdelivr.net/free-jqgrid/4.12.1/css/ui.jqgrid.min.css and from http://cdn.jsdelivr.net/free-jqgrid/4.12.1/js/jquery.jqgrid.min.js. You can examine the HTTP headers of the severer response to understand the reason. Let us we examine the headers of jquery.jqgrid.min.js. It looks like

HTTP/1.1 200 OK
Date: Sun, 07 Feb 2016 11:46:33 GMT
Content-Type: application/javascript; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Last-Modified: Tue, 19 Jan 2016 13:22:55 GMT
Vary: Accept-Encoding
ETag: W/"569e38af-4d806"
Access-Control-Allow-Origin: *
Timing-Allow-Origin: *
Cache-Control: public, max-age=31536000
Server: NetDNA-cache/2.2
X-Cache: MISS
Content-Encoding: gzip

The total number of initially loaded data are 121.791 bytes (headers:418; body:121.373).

I don't want to comment all the HTTP headers, only some the most important:

  • The initial loaded data are compressed.
  • The header Cache-Control: public, max-age=31536000 allows to cache the loaded data in cache of web browser or the proxy during 365 days (356*24*60*60). If the user loads the same page next time that no request to the server will be done.
  • The header ETag: W/"569e38af-4d806" and Last-Modified: Tue, 19 Jan 2016 13:22:55 GMT are very important to re-validating the data. If the user press F5 to reload the data, but it hold still the data locally, then the request to the server to get jquery.jqgrid.min.js will contains the ETag from the cached version of the file. The request will contains HTTP headers

    If-Modified-Since: Tue, 19 Jan 2016 13:22:58 GMT If-None-Match: W/"569e38b2-acbef"

You can verify that response from http://cdn.jsdelivr.net/free-jqgrid/4.12.1/js/jquery.jqgrid.min.js will contains only 320 bytes, which starts with

HTTP/1.1 304 Not Modified

It means that the server confirms that the previously loaded version of jquery.jqgrid.min.js can be used. Thus jquery.jqgrid.min.js will be "reloaded" very quickly.

Finally I should remark that both the initial loading of data and response on the re-validation request will be get from cdn.jsdelivr.net really quickly. The web site have mirror servers in many locations on the word and the servers are optimized for re-validation responses.

I hope that it's clear now why I recommend to use CDN like cdn.jsdelivr.net as the primary source for loading free jqGrid files.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Thanks, Great explanation :) – Faz Feb 07 '16 at 17:14
  • I was just trying out something with $("#grid").jqGrid("getGridParam", "data") ; as you mentioned it returns all the data from all pages. But what should I be using when I select few rows (from different pages)) and then want to get the selected rows data?? i.e, say I select 5, 6 ,7 ,20,25 from 2 pages and when I clikc a button I need to get all the data for the above selected rows? I remeber using selrows before is this the same now also? – Faz Feb 08 '16 at 08:45
  • 1
    @Faz: The parameter `selarrrow` contains array of selected rowids. `var selIds = $("#grid").jqGrid("getGridParam", "selarrrow");`. The method `getLocalRow` provides simple way to get item of `data` by id. Thus you can push all the data elements in an empty array to get what you need: `var $grid = $("#grid"), p = $grid.jqGrid("getGridParam"), i, selData = [];` and then `for (i = 0; i < p.selarrrow.length; i++) { selData.push($grid.jqGrid("getLocalRow", p.selarrrow[i])); }` – Oleg Feb 08 '16 at 09:50
  • Does the above(selarrrow and getLocalRow) work even for the rows in multiple pages? I was under the impression that selarrrow only works for the current page. – Faz Feb 08 '16 at 11:11
  • @Faz: If you use `multiPageSelection: true, multiselect: true` then the `selarrrow` is consistent over all pages. The `data` and `getLocalRow` allows you get information from *internal* `data` array which is independent from displayed page. Thus you can use the above code to access any data from any local page. – Oleg Feb 08 '16 at 11:21
  • I was trying to perform this **$grid.jqGrid("setGridParam", { data: parsedData , loadonce: true}).trigger("reloadGrid");** and when I try to use $grid.jqGrid("getLocalRow", p.selarrrow[i]), am getting false. Any idea? – Faz Feb 11 '16 at 12:48
  • @Faz: Sorry, but you should provide the demo which demonstrate what you do or at least post more full code which demonstrate **where** and **when** you execute above code. One can no answer whether "it" or "are" correct or not. Both are correct in general, but "it are" is wrong. The same is with the code which you posted. – Oleg Feb 11 '16 at 13:33
  • opened a new question here http://stackoverflow.com/questions/35341926/jqgrid-getlocalrow-returning-false-when-data-property-is-set – Faz Feb 11 '16 at 14:27