1

I 've two problems in jqGrid

1) Suppose there is 91 records in table with rownum set to 10, now when i navigate to last page and delete the record number 91, it does not reload the grid automatically, when i use ReloadGrid explicitly it went to reload the whole data from controller which increases the network load. This is the Screen shot of last page Now I am deleting the last Record It does not redirect to 1st page

2) In my grid there are 10 pages and when I enter the page number greater than the max page in text box it gives the blank grid, ideally it should dispaly some message.

Here I've given page no = 50 though max page = 1

any solution?

ADDED CODE FOR BETTER UNDERSTANDING OF PROBLEM

$(document).ready(function () {
        $('#jqgCars').jqGrid({
            //url from wich data should be requested
            url: '@Url.Action("CarsListing", "Car")?Carid=' + getID(),
            //event for inline edit
            onSelectRow: function (currentSelectedRow) {
                if (currentSelectedRow && currentSelectedRow != $.lastSelectedRow) {
                    //save changes in row 
                    $('#jqgCars').jqGrid('saveRow', $.lastSelectedRow, false);
                    $.lastSelectedRow = currentSelectedRow;
                }
            },
            //type of data
            datatype: 'json',
            //url access method type
            mtype: 'POST',
            //columns names
            colNames: ['ID','Number','Name'],
            //columns model
            colModel: [
                            { name: 'ID', index: 'ID', align: 'left', editable: false },
                            { name: 'Number', index: 'Number', align: 'left', editable: true, formatter: "text", edittype: 'text', editrules: { required: true}, editoptions:{maxlength:"25"}},
                            { name: 'Name', index: 'Name', align: 'left', editable: true, formatter: "text", edittype: 'text', editrules: { required: false} , editoptions:{size:"35",maxlength:"255"}},
                          ],
            //pager for grid
            pager: $('#jqgpCars'),
            //number of rows per page
            rowNum: 2,
            //initial sorting column
            sortname: 'name',
            //initial sorting direction
            sortorder: 'asc',
            //display total records count
            viewrecords: true,
            //grid height
            height: '100%' 
        });
        $('#jqgCars').jqGrid('navGrid', '#jqgpCars', { add: true, del: true, edit: true, search: false });
        $('#jqgCars').jqGrid('hideCol', "ID");
        $('#jqgCars').setGridWidth(600 , true);
        var dialogPosition = $(this).offset();
    });

UPDATE -- SOLUTION

Solution to problem#1

$.extend($.jgrid.del, {
            afterComplete: function () {
                var p = $('#jqgCars')[0].p;
                var newPage = p.page; // Gets the current page
                if (p.reccount === 0 && newPage > p.lastpage && newPage > 1) {
                    // if after deleting there are no rows on the current page and lastpage != firstpage than
                    newPage--; // go to the previous page
                }
                // reload grid to make the row from the next page visable.
                $(p.pager + " input.ui-pg-input").val(newPage); //Here setting the new page into textbox before loading in case of longer grid it would look nice
                $('#jqgCars').trigger("reloadGrid", [{page: newPage}]); // reloading grid to previous page
            } 
        });

Solution of problem#2 is exact as posted by Oleg

This works fine with jqGrid v4.1.2

IT ppl
  • 2,626
  • 1
  • 39
  • 56
  • Could you post the code which you use? By the way, to send me a message you should write comment with @Oleg on the page where I pasted something. So I didn't have any notification from you last comment. – Oleg Jun 06 '12 at 13:42

3 Answers3

2

It's good question! In the old answers this and this you will find the answer on your first question. Because the answers are long and you need to use delete of data on the server I repeat the same idea here.

It's not good to ask two separate questions inside of one question. Such questions are not good for searching engine. The users which have the problem from the part 2 of your question will be have to read unneeded information. So please don't do this in the future.

I start the answer with your second question. If the user type in the input part of the pager any value and press Enter the rows for the page will be requested from the server or from the local dataset. If the user choosed to large page number the grid will be successfully reloaded, but with no data. Absolutely the same results one will have in case of deleting the last row from the last page. The page with the same number will be reloaded and the user will see empty grid.

To fix the problem one can use the following onPaging callback:

onPaging: function (pgButton) {
    var p = this.p;
    if (pgButton === "user" && p.page > p.lastpage) {
        alert ("You can't choose the page " + $(p.pager + " input.ui-pg-input").val());
        p.page = p.currentPage; // restore the value of page parameter
        return 'stop';
    }
},
loadComplete: function () {
    // because on enter in the pager input the value of this.p.page
    // will be changed BEFORE calling of the onPaging the original
    // (current) page number will be overwritten. To save the problem
    // we can save somewhere the copy of the this.p.page. To be able
    // easy to maintain multiple grids on the page we can save the
    // copy as new jqGrid option:
    this.p.currentPage = this.p.page;
}

Not we go back to the first part of your question. To solve the problem one can use afterComplete callback of delGridRow method to do additional actions after the last row will be deleted. The code can be the following:

afterComplete: function () {
    var p = this.p, newPage = p.page;
    if (p.lastpage > 1) {// on the multipage grid reload the grid
        if (p.reccount === 0 && newPage === p.lastpage) {
            // if after deliting there are no rows on the current page
            // which is the last page of the grid
            newPage--; // go to the previous page
        }
        // reload grid to make the row from the next page visable.
        $(this).trigger("reloadGrid", [{page: newPage}]);
    }
}

So we just decrease the page number in case of empty grid and reload the grid one more time.

In case of deleting of data in the local grid (datatype: "local") one can use the following settings:

$.extend($.jgrid.del, {
    // because I use "local" data I don't want to send the changes to the server
    // so I use "processing:true" setting and delete the row manually in onclickSubmit
    onclickSubmit: function(options, rowid) {
        var gridId = $.jgrid.jqID(this.id),
            p = this.p,
            newPage = p.page,
            $this = $(this);

        options.processing = true;

        // delete the row
        $this.jqGrid("delRowData", rowid);
        $.jgrid.hideModal("#delmod" + gridId,
            { gb: options.gbox, jqm: options.jqModal, onClose: options.onClose});

        if (p.lastpage > 1) {// on the multipage grid reload the grid
            if (p.reccount === 0 && newPage === p.lastpage) {
                // if after deliting there are no rows on the current page
                // which is the last page of the grid
                newPage--; // go to the previous page
            }
            // reload grid to make the row from the next page visable.
            $this.trigger("reloadGrid", [{page: newPage}]);
        }
        return true;
    },
    processing: true
});

The corresponding demo you can see live here.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Problem 2 is solved with your suggested code, but in problem#1 it didn't fetch the this.p, i've tried and failed to alert that part – IT ppl Jun 07 '12 at 10:30
  • @ITppl: Could you describe more clear which problem you have currently. If `this.p` is undefined in `afterComplete` then you use some old version of jqGrid where `this` are not yet set to DOM of the grid. You can use `$('#jqgCars')[0].p` instead for example. – Oleg Jun 07 '12 at 10:40
  • it worked great, Thank you sir for your time and effort, i've to do some minor changes in solution#1's if conditon **if (p.reccount === 0 && newPage === p.lastpage)** to **if (p.reccount === 0 && newPage > p.lastpage)** cause every time server deletes the record, it also updates the lastpage too. – IT ppl Jun 07 '12 at 11:39
  • @ITppl: You are welcome! I just wrote the code of `afterComplete` without testing it. So some changes could be really required. I tried mostly to explain the *origin* of the problem and at least one way to solve it. It would be good if you append the text of your question with the final solution which you use. It could be important if you mention additionally the version of jqGrid in which the solution work. Best wishes! – Oleg Jun 07 '12 at 11:47
1

I have same issues. This is my solution for this issue:

$("#jqgCars").clearGridData(true).trigger(
   "reloadGrid", [{ current: true }]
);
Ashley Lee
  • 3,810
  • 1
  • 18
  • 26
0

Regarding #1, you stated:

use ReloadGrid explicitly it went to reload the whole data from controller which increases the network load.

But I think this is what you have to do, since the jqGrid is only retrieving a page of data at a time. If you do not reload from the server, how would the grid ever repopulate itself? Or perhaps I am missing something?


Regarding #2, after an AJAX call the grid uses the page number from the XML/JSON response. You can see this in the source code to grid.base.js:

ts.p.page = $.jgrid.getXmlData( xml,xmlRd.page ) || 0;

...

ts.p.page = $.jgrid.getAccessor(data,dReader.page) || 0;

Both functions also include a call to update the page number in the pager:

if (!more) { ts.updatepager(false,true); } // Note: More is true if pageNum > 0

So one solution is for your server code to detect if the given page number is greater than the max, and set it back to the max in your response. If you do this before you query for the actual data, you can also adjust that query to return data for the last page, preventing you from having to display an error message.

Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
  • About #1 :- so i've to write custom code to reload (lastpage-1) page at controller side? About #2 :- I've thought of similiar solution of checking page number at controller side, not any other solution ? Cause i've to change the code at many place – IT ppl Jun 06 '12 at 14:02
  • Hmmm... I was trying to understand how you had worked around the problem. Did you use your controller to detect that the last row was deleted, and then did you refresh the entire page? If so, I agree (or would hope) there must be a better way... – Justin Ethier Jun 06 '12 at 14:05
  • Regarding #2, this is how the grid is designed to work. For example, under the jqGrid demos see `Manipulating` | `Grid Data` and try to set the page number to 3. That said, the demo uses the limit/count numbers from the request to determine `total_pages`, probably a more convenient solution for you than reorganizing your queries. This is better from a user perspective too, since the grid automatically takes care of the problem instead of forcing them to read an error message and update the page number again. – Justin Ethier Jun 06 '12 at 14:09
  • Currently I don't check for that, thought there must be some solution, even after deleting the last record i've to go back to maxpage-1 page, and it would update the maxpage also, hence network load will increase significantly...am I right? – IT ppl Jun 06 '12 at 14:09
  • @ITppl - Not sure I understand why network load will increase, because when jqGrid requests a page of data it *always* makes a request to the server. Ideally that is how you solve #1, by making a request for page `maxpage - 1`. How else would you do it? – Justin Ethier Jun 06 '12 at 14:18