Miki Watts
Miki Watts

Reputation: 1756

jqGrid sends duplicate ajax request for page number while scrolling

I'm using jqGrid version 4.5.2 and jquery 1.9.1 as well as MVC 4.

The grid I'm using has about 2000 rows total, and I'm displaying 100 of them at a time. I'm using virtual grid scroll, not pagination, with the following grid definition:

$("#colorsGrid").jqGrid({
            url: '@Url.Action("Colors")',
            //datatype: 'xml',
            datatype: 'json',
            colNames: ['id', 'RGB', 'FS', 'RAL', 'Humbrol', 'Revell', 'Tamiya', 'RLM', 'Vallejo', 'Testors / Model Master','ANA','Games Workshop / Citadel'],
            colModel: [
                { name: 'id', index: 'id', hidden: true },
                { name: 'RGB', sorttype: rgbColorSorter, formatter: rgbColumnFormatter, width: 70 },
                { name: 'FS', sorttype: colorSorter, formatter: colorFormatter, width: 200 },
                { name: 'RAL', sorttype: colorSorter, formatter: colorFormatter, width: 200 },
                { name: 'Humbrol', sorttype: colorSorter, formatter: colorFormatter, width: 200 },
                { name: 'Revell', sorttype: colorSorter, formatter: colorFormatter, width: 200 },
                { name: 'Tamiya', sorttype: tamiyaColorSorter, formatter: colorFormatter, width: 200 },
                { name: 'RLM', sorttype: colorSorter, formatter: colorFormatter, width: 200 },
                { name: 'Vallejo', sorttype: colorSorter, formatter: colorFormatter, width: 200 },
                { name: 'Testors / Model Master', sorttype: colorSorter, formatter: colorFormatter, width: 200 },
                { name: 'ANA', sorttype: colorSorter, formatter: colorFormatter, width: 200 },
                { name: 'GamesWorkshop', sorttype: colorSorter, formatter: colorFormatter, width: 200 }
            ],
            rowNum: 50,
            scroll: 1,
            emptyrecords: "No colors found",
            loadonce: false,
            autowidth: false,
            sortable: true,
            afterInsertRow: afterInsertRowFunction,
            multipleSearch: true,
            ignoreCase: true,
            postData: { filterText: function () { return $('#colorFilter').val(); }},
            loadComplete: function () {
                if (!resizeGridOnLoadComplete) {
                    resizeGridOnLoadComplete = true;
                    resizeGrid();
                }
            }

The function afterInsertRowFunction only sets some css style for the row. The resizeGrid function only calls setGridHeight on the grid to dynamically fix the height.

On the controller side i'm returning just the number of rows and not the entire dataset as requested in the Request.QueryString parameters, along with the total number of records and pages. Abbreviated example:

{"page":1,"total":38,"records":1918,"rows":[{"id":1,"cell":["1","654037","^10075^10075^^~","","","","","","","","4F2E26^510^510 - Maroon^gloss^Pre/Early WWII~",""]},{"id":2,"cell":["2","7c3925","^10076^10076 - Coast Guard Deck Red, Metallic Red-Brown^^~","","","","","","","","",""]},

My problem is that the following happens: 1. On loading the page, jqGrid sends get an ajax request for page no.1 2. After scrolling past the initial 50 rows, jqgrid sends an ajax request for page no. 2 3. After scrolling past the next 50 rows, jqgrid sends an ajax request for page no.2 again instead of page no.3

If I keep scrolling, then jqGrid will send a request for page no.3 (which should have been page no.4 by now).

Due to the duplicate request and sending back the same data, it messes up the grid.

Things I've tried: Either xml or json format. Leaving the minimum settings on the jqGrid element. Different number of rows in rowNum. Scroll parameter as "true".

I've seen people mention something very similar but it was two years and two versions ago of jqGrid, and was fixed.

Why is jqGrid sending duplicate requests for the same page ?

Upvotes: 0

Views: 2048

Answers (1)

Oleg
Oleg

Reputation: 221997

First of all sending of two requests to the server is by design in case of usage virtual scrolling (scroll: 1 option).

I personally don't like the implementation of virtual scrolling in jqGrid. I find that it has some bugs (inclusive some bugs in design of the implementation of virtual scrolling). So I don't use the feature myself and don't recommend the feature to other. Standard scrolling could be a little strange for some users, but the users need to spend just some minutes to study the scrolling with buttons in the navigator bar. You can consider to use toppager: true option which create the pager on the top of grid. One can use additionally pager option to have two pagers. You can use navGrid with cloneToTop: true options to add navigator buttons in both pager.

In general it has not much sense to display unfiltered data with 2000 rows. One uses typically filterToolbar additionally. So the user could filter the data to see the subset of data which he really look for. If one think about the feature then the kind of paging will be not really important. The data which need the user will be typically displayed on one page.

I have more important remarks to your code which not directly concerned with your question, but which I find very important. First of all you should not use afterInsertRow. It make filling of grid slowly. I recommend you to read the answer where I describe the problem detailed. Instead of that you should use rowattr, cellattr or custom formatters and use gridview: true option. If I understand correctly what you do inside of afterInsertRowFunction you can use rowattr in the way close to described in the answer. You should take in consideration that the first parameter of rowattr in your case will be array instead of objects with named properties. So you should use integer indexes to access properties of the row.

After the above changes you can consider to use loadonce: true option. In the case the server shoould return all 2000 rows of data. The data should be still sorted corresponds to sortname option which you use (if you use it). I think that you could have very good performance in local paging and sorting. You server code could be simplified. By the way you will don't need return "page":1,"total":38,"records":1918 part in the server response. The returned data could be just array of items which represent the rows. The row can be array of items which represent the columns or object of named properties (the same as values of name properties in colModel).

Another remark. You should change name: 'Testors / Model Master' to some name without special character. You should understand the value as the name of variable or like the value of id attribute.

The last remark: you can remove id column. The value of id attribute of every row (id of <tr>) will be assigned based on "id" property of JSON response from the serevr.

Upvotes: 1

Related Questions