2

I'm filling a jqGrid with initial data. Then what I'm trying to accomplish is that the user should be able to edit, insert and delete rows. After the user i finished, he should click a Save-button, which should send the changed data to the server for updating the db.

I have set the grid to cellsubmit: "clientArray", and getting the changed rows with $("#dagbok_grid").getChangedCells('all'). It seems to work. When I add rows, I give them the id of -1 so I know which ones are new.

When I try to implement delete, using jqGrid("delGridRow", rowid), it seems like it always wants to post to the server. Is there a way of doing the delete locally, and then sending it along with all the other changes?

kaze
  • 4,299
  • 12
  • 53
  • 74

1 Answers1

0

To delete row from the grid you can use delRowData, but the usage of delGridRow is also possible after some tricks. In the answer I posted the demo which shows how implement local form editing. The main idea of the solution is to use processing: true setting. You can delete local data with respect of delGridRow by adding additional options $("#dagbok_grid").jqGrid("delGridRow", rowid, delSettings) where the delSettings one can define as following:

var delSettings = {
        afterShowForm: function ($form) {
            var form = $form.parent()[0], dialog;
            // delete button: "#dData", cancel button: "#eData"
            $("#dData", form).attr("tabindex", "1000");
            $("#eData", form).attr("tabindex", "1001");
            setTimeout(function () {
                // set "Delete" button as default, so one can
                // confirm deliting by pressing "Enter" key
                $("#dData", form).focus();
            }, 50);
            dialog = $form.parent().parent();
            dialog.position({
                my: "center",
                //at: 'center center',
                of: grid.closest('div.ui-jqgrid')
            });
        },
        // 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) {
            var gridId = $(options.gbox).attr("id").substr(5),
                gridIdSelector = $.jgrid.jqID(gridId),
                $grid = $("#" + gridIdSelector);
                p = $grid[0].p, // jqGrid parameters
                newPage = p.page,
                rowids = p.multiselect ? p.selarrrow : [p.selrow];

            // reset the value of processing option to true
            // because the value can be changed by jqGrid
            options.processing = true;

            // delete the row
            $.each(rowids, function () {
                $grid.jqGrid('delRowData', this);
            });
            $.jgrid.hideModal("#delmod" + gridIdSelector,
                                { 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 -= 1; // go to the previous page
                }
                // reload grid to make the row from the next page visable.
                $grid.trigger("reloadGrid", [{page: newPage}]);
            }

            return true;
        },
        processing: true
    };

I would warn you about the problems in the batch modifications of data which you get from the server. The problem which you can have is the concurrency error. In other words if two persons edit the same information. The user can first load the information and edit the information much later without refreshing grid from the server. In the time another user can modify part of the information. Detection of such errors is not so easy, but even more complex to create good error message. If the user will have to make all the modifications one more time it will make the user of your program very angry. See here and here for more information.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Thanks for an amazing answer as always! I was not aware of delRowData, it does exactly what I want. However, the problem getChangedCells is that I dont get the deleted rows through that call, only inserted and edited. It there a way for solving that? – kaze Mar 30 '12 at 08:55
  • @kaze: You are welcome! You can use any callback of `delRowData` to save the list of deleted ids in a variable after you delete a row. For example you can add in the code of `onclickSubmit` the statement `deletedIds.push(this);` after the line `$grid.jqGrid('delRowData', this);`. The variable `deletedIds` you can initialize just as `var deletedIds = [];`. If you want you can any additional parameter in the jqGrid like `deletedIds: []`. In the case you can use `p.deletedIds.push(this);`. There are many other possibilities. You should just choose what is the most convenient for your case. – Oleg Mar 30 '12 at 09:14
  • An excellent idéa! I would never have solved my grid woes without your help! – kaze Mar 30 '12 at 09:17
  • Hallå! Another unexpected issue, when I thought I had it all figured out! getChangedCells gives me other data than I had an editurl. All foreign key stuff is lost, before, I got the id, now the acutal text, for example, I get "Some value 2" istead of "332". It was the other way around before. Is that possible to configure? This is for the columns with select-option. – kaze Mar 30 '12 at 10:48
  • @kaze: do you call `getChangedCells` with `'dirty'` parameters? In general if some cell is changed the class `"edited"` is added to row (``) and `'dirty-cell'` will be added to the cell (''). So you can get the information which you need yourself. The look in [the code](https://github.com/tonytomov/jqGrid/blob/v4.3.1/js/grid.celledit.js#L452-487) of `getChangedCells` can help you to understand all. – Oleg Mar 30 '12 at 11:04
  • I call it with 'all'. I was surprised to not getting the ids, but instead the text. I was excpecting an array with the changed rows, in the same format as with editurl. I'll look into the soruce to see what I can find. – kaze Mar 30 '12 at 11:09
  • @kaze: If you would call `getChangedCells` with `'dirty'` parameter you would get array of items which described modifications and one from the property of the item is `id`. I think it's what you need. – Oleg Mar 30 '12 at 11:13
  • I found the problem, by debug-tracing the source as you suggested. My mistake was that I had not formatter:'select' in the colModel, only edittype:'select'. Adding the formatter option, got me the right data back (id instead of textvalue)! – kaze Mar 30 '12 at 11:40
  • @kaze: OK! You never posted the grid definition which you use. In any way you last comment sound as the problem is solved now. Is it so? – Oleg Mar 30 '12 at 11:46
  • Could you bare with me for one more detail? I thought I had solved it, but when I added formatter:'select', all the cells for that column became blank. The already existing data is not rendering. If I remove formatter:'select', they render fine, but then I get back the other problem. I think I'm loosing my mind! – kaze Mar 30 '12 at 13:13
  • @kaze: Sorry, but I can't really help you because I didn't seen any code. It's difficult to debug the code having only short descriptions of what you do. :-( – Oleg Mar 30 '12 at 13:23