JQGrid toolbar filter and restoring a row in edit state with formatted columns

1.4k views Asked by At

I have noticed the behavior that when using inline row editing (putting the row into edit state via $grid.jqGrid('editRow', rowId, ...etc)) and then restoring the row ($grid.jqGrid('restoreRow',rowToRestore);) without actually editing the row will set a formatted column's $grid.p.data[{indexofrowrestored}][{columnname}] to the formatted value rather than the original value of the column.

The consequences of this is that the restored row's toolbar filter input will filter the row based on the formatted value rather than the unformatted value (as it does all the other rows).

I went through the JQGrid source and have come up with a solution for this issue (JQGrid v4.3.1). I changed some code in the restoreRow function that solves my issue:

Staring with line 9038 of jquery.jqGrid.src.js (see comments for added code):

restoreRow : function(rowid, afterrestorefunc) {
    // Compatible mode old versions
    var args = $.makeArray(arguments).slice(1), o={};

    if( $.jgrid.realType(args[0]) === "Object" ) {
        o = args[0];
    } else {
        if ($.isFunction(afterrestorefunc)) { o.afterrestorefunc = afterrestorefunc; }
    }
    o = $.extend(true, $.jgrid.inlineEdit, o );

    // End compatible

    return this.each(function(){
        var $t= this, fr, d, ind, ares={};  //UPDATED: added the variable 'd'
        if (!$t.grid ) { return; }
        ind = $($t).jqGrid("getInd",rowid,true);
        if(ind === false) {return;}
        for( var k=0;k<$t.p.savedRow.length;k++) {
            if( $t.p.savedRow[k].id == rowid) {fr = k; break;}
        }
        //----------------------------------------------------------------------------
        //ADDED: added this for-loop
        //      get a hold of the $t.p.data array row with the ID of the
        //      row being restored; this row contains the original, unformatted
        //      data that came from the server while $t.p.savedRow contains
        //      what appears to be formatted column data; this is messing
        //      up the toolbar filter accuracy (which filters on original, unformatted
        //      data) when the row is restored
        for( var k=0;k<$t.p.data.length;k++) {
            if( $t.p.data[k].id == rowid) {d = k; break;}
        }
        //END EDIT
        //----------------------------------------------------------------------------
        if(fr >= 0) {
            if($.isFunction($.fn.datepicker)) {
                try {
                    $("input.hasDatepicker","#"+$.jgrid.jqID(ind.id)).datepicker('hide');
                } catch (e) {}
            }
            $.each($t.p.colModel, function(i,n){
                if(this.editable === true && this.name in $t.p.savedRow[fr] && !$(this).hasClass('not-editable-cell')) {
                    //EDIT: this line was edited to set ares[this.name] to
                    //the original, unformatted data rather than the saved row data
                    //so, below, when setRowData method is called, it is being set
                    //to original data rather than formatted data
                    ares[this.name] = $t.p.data[d][this.name];
                    //END EDIT
                }
            });
            $($t).jqGrid("setRowData",rowid,ares);
            $(ind).attr("editable","0").unbind("keydown");
            $t.p.savedRow.splice(fr,1);
            if($("#"+$.jgrid.jqID(rowid), "#"+$.jgrid.jqID($t.p.id)).hasClass("jqgrid-new-row")){
                setTimeout(function(){$($t).jqGrid("delRowData",rowid);},0);
            }
        }
        if ($.isFunction(o.afterrestorefunc))
        {
            o.afterrestorefunc.call($t, rowid);
        }
    });
},

Basically, instead of using the $grid.p.savedRow data to set the row data as, I use the $grid.p.data to set the row data as when restoring the row.

I guess I am looking for feedback on my fix- are there any unintended consequences I may run in to by changing the source code in this way? Is there a way that I can achieve this fix without changing the source code (easier for my team to maintain and update JQGrid)? Am I not understanding something correctly? :)

Thank you so much for any help! If a demo of the bug would be helpful, I could create one. I do not have access to my personal webserver here.

1

There are 1 answers

1
Oleg On BEST ANSWER

One important problem with your suggestion is that $grid.p.data exists not always. If you use "classical" grid with datatype: 'json' or datatype: 'xml' and you don't use loadonce: true you will have undefined data parameter. I suggested Tony to modify the code of addJSONData and addXmlData to fill the data parameter too (see the part of code) but in any way the current implementation of the jqGrid don't always fill data. So $t.p.data can't be used in the case.