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.
One important problem with your suggestion is that
$grid.p.data
exists not always. If you use "classical" grid withdatatype: 'json'
ordatatype: 'xml'
and you don't useloadonce: true
you will have undefineddata
parameter. I suggested Tony to modify the code ofaddJSONData
andaddXmlData
to fill thedata
parameter too (see the part of code) but in any way the current implementation of the jqGrid don't always filldata
. So$t.p.data
can't be used in the case.