restoreRow problem while using formatter and unformat #819

Closed
wqbill opened this Issue Nov 3, 2016 · 5 comments

Comments

Projects
None yet
2 participants
@wqbill

wqbill commented Nov 3, 2016

colModel: [{ name: "staffCode", index: "staff_code", editable:true, formatter: function (cellvalue, options, rowObject) { return "["+rowObject.staffCode+"] " + rowObject.staffName; }, unformat:function(cellvalue, options, cell){ return cellvalue.split('[')[1].split(']')[0]; } },
I used two parameters of rowObject in the formatter function,and I did set the unformat function.
But it still got wrong after restoreRow,the cellvalue changed from '[A001]bob' to '[A001]undefined' coz the new rowObject had parameter named 'staffCode' only(found out in chrome F12 mode).

@tonytomov

This comment has been minimized.

Show comment
Hide comment
@tonytomov

tonytomov Nov 4, 2016

Owner

Hello,

Can you please post the full code related to the grid - I mean everything. The best is if you prepare a test case with demo data.

Thank you.

Kind Regards

Owner

tonytomov commented Nov 4, 2016

Hello,

Can you please post the full code related to the grid - I mean everything. The best is if you prepare a test case with demo data.

Thank you.

Kind Regards

@wqbill

This comment has been minimized.

Show comment
Hide comment
@wqbill

wqbill Nov 7, 2016

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

        if( $.type(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=-1, ind, ares={}, k;
            if (!$t.grid ) { return; }
            ind = $($t).jqGrid("getInd",rowid,true);
            if(ind === false) {return;}
            var bfcr = $.isFunction( o.beforeCancelRow ) ?  o.beforeCancelRow.call($t, o, rowid) :  undefined;
            if( bfcr === undefined ) {
                bfcr = true;
            }
            if(!bfcr) { return; }
            for(k=0;k<$t.p.savedRow.length;k++) {
                if( String($t.p.savedRow[k].id) === String(rowid)) {fr = k; break;}
            }
            if(fr >= 0) {
                if($.isFunction($.fn.datepicker)) {
                    try {
                        $("input.hasDatepicker","#"+$.jgrid.jqID(ind.id)).datepicker('hide');
                    } catch (e) {}
                }
                $.each($t.p.colModel, function(){
                    if(this.editable === true && $t.p.savedRow[fr].hasOwnProperty(this.name)) {
                        ares[this.name] = $t.p.savedRow[fr][this.name];
                    }
                });
                $($t).jqGrid("setRowData",rowid,ares);

Variable 'ares' here contains the edited cell value only.
Here is part of my code.

    $("#duty_list").jqGrid({
        url: "/duty/list",
        datatype: "json",
        height: "auto",
        autowidth: true,
        shrinkToFit: true,
        rowNum: 15,
        rowList: [15, 50, 100],
        rownumbers: false,
        multiselect: false,
        viewrecords: true,
        hidegrid: false,
        colNames: ["staff"],
        colModel: [
            {
                name: "staffCode",
                index: "staff_code",
                align: "left",
                width: 35,
                editable:true,
                formatter: function (cellvalue, options, rowObject) {
                    return "["+rowObject.staffCode+"] " + rowObject.staffName;
                },
                unformat:function(cellvalue, options, cell){
                    return cellvalue.split('[')[1].split(']')[0];
                }
            }
        ],
        pager: "#duty_pager",
        gridComplete: function(){
            var ids = jQuery("#duty_list").jqGrid('getDataIDs');
            for(var i=0;i < ids.length;i++){
                var cl = ids[i];
                var edit='<a class="btn btn-xs btn-default" href="javascript:void(0);" onclick="jQuery(\'#duty_list\').editRow(\''+cl+'\');">edit<i class="fa fa-pencil"></i></a>';
                var save='<a class="btn btn-xs btn-success" href="javascript:void(0);" onclick="jQuery(\'#duty_list\').saveRow(\''+cl+'\',successfunc);">save<i class="fa fa-save"></i></a>';
                var restore='<a class="btn btn-xs btn-danger" href="javascript:void(0);" onclick="jQuery(\'#duty_list\').restoreRow(\''+cl+'\');">cancel<i class="fa fa-close"></i></a>';
                jQuery("#duty_list").jqGrid('setRowData',ids[i],{act:edit+save+restore});
            }
        },
        editurl: "/duty/inline"
    });
<table id="duty_list"></table>
<div id="duty_pager"></div>

json sent back from server like this.

{"rows":[{"id":6,"staffCode":"A074","startDate":"20161103","endDate":"20161104","createTime":1478154884000,"staffName":"aa","staffPhone":"12345678901","staffQq":null,"staffEmail":"aa@aa.me"},{"id":7,"staffCode":"A021","startDate":"20161110","endDate":"20161111","createTime":1478154899000,"staffName":"bb","staffPhone":"12345678901","staffQq":"1234","staffEmail":"bb@bb.com"}],"page":1,"records":5,"total":3,"userdata":null}

The first row should be like '[A074]aa',but after calling restoreRow function it changes to '[A074]undefined' instead.The corresponding 'ares' here is 'Object {staffCode: "A074"}'.

wqbill commented Nov 7, 2016

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

        if( $.type(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=-1, ind, ares={}, k;
            if (!$t.grid ) { return; }
            ind = $($t).jqGrid("getInd",rowid,true);
            if(ind === false) {return;}
            var bfcr = $.isFunction( o.beforeCancelRow ) ?  o.beforeCancelRow.call($t, o, rowid) :  undefined;
            if( bfcr === undefined ) {
                bfcr = true;
            }
            if(!bfcr) { return; }
            for(k=0;k<$t.p.savedRow.length;k++) {
                if( String($t.p.savedRow[k].id) === String(rowid)) {fr = k; break;}
            }
            if(fr >= 0) {
                if($.isFunction($.fn.datepicker)) {
                    try {
                        $("input.hasDatepicker","#"+$.jgrid.jqID(ind.id)).datepicker('hide');
                    } catch (e) {}
                }
                $.each($t.p.colModel, function(){
                    if(this.editable === true && $t.p.savedRow[fr].hasOwnProperty(this.name)) {
                        ares[this.name] = $t.p.savedRow[fr][this.name];
                    }
                });
                $($t).jqGrid("setRowData",rowid,ares);

Variable 'ares' here contains the edited cell value only.
Here is part of my code.

    $("#duty_list").jqGrid({
        url: "/duty/list",
        datatype: "json",
        height: "auto",
        autowidth: true,
        shrinkToFit: true,
        rowNum: 15,
        rowList: [15, 50, 100],
        rownumbers: false,
        multiselect: false,
        viewrecords: true,
        hidegrid: false,
        colNames: ["staff"],
        colModel: [
            {
                name: "staffCode",
                index: "staff_code",
                align: "left",
                width: 35,
                editable:true,
                formatter: function (cellvalue, options, rowObject) {
                    return "["+rowObject.staffCode+"] " + rowObject.staffName;
                },
                unformat:function(cellvalue, options, cell){
                    return cellvalue.split('[')[1].split(']')[0];
                }
            }
        ],
        pager: "#duty_pager",
        gridComplete: function(){
            var ids = jQuery("#duty_list").jqGrid('getDataIDs');
            for(var i=0;i < ids.length;i++){
                var cl = ids[i];
                var edit='<a class="btn btn-xs btn-default" href="javascript:void(0);" onclick="jQuery(\'#duty_list\').editRow(\''+cl+'\');">edit<i class="fa fa-pencil"></i></a>';
                var save='<a class="btn btn-xs btn-success" href="javascript:void(0);" onclick="jQuery(\'#duty_list\').saveRow(\''+cl+'\',successfunc);">save<i class="fa fa-save"></i></a>';
                var restore='<a class="btn btn-xs btn-danger" href="javascript:void(0);" onclick="jQuery(\'#duty_list\').restoreRow(\''+cl+'\');">cancel<i class="fa fa-close"></i></a>';
                jQuery("#duty_list").jqGrid('setRowData',ids[i],{act:edit+save+restore});
            }
        },
        editurl: "/duty/inline"
    });
<table id="duty_list"></table>
<div id="duty_pager"></div>

json sent back from server like this.

{"rows":[{"id":6,"staffCode":"A074","startDate":"20161103","endDate":"20161104","createTime":1478154884000,"staffName":"aa","staffPhone":"12345678901","staffQq":null,"staffEmail":"aa@aa.me"},{"id":7,"staffCode":"A021","startDate":"20161110","endDate":"20161111","createTime":1478154899000,"staffName":"bb","staffPhone":"12345678901","staffQq":"1234","staffEmail":"bb@bb.com"}],"page":1,"records":5,"total":3,"userdata":null}

The first row should be like '[A074]aa',but after calling restoreRow function it changes to '[A074]undefined' instead.The corresponding 'ares' here is 'Object {staffCode: "A074"}'.

tonytomov added a commit that referenced this issue Dec 1, 2016

Fix restoreRow to restore all the data saved into the savedRow array …
…and not only the editable. This fixes calling of depended formatter custom function. See here: #819
@tonytomov

This comment has been minimized.

Show comment
Hide comment
@tonytomov

tonytomov Dec 1, 2016

Owner

Thank you very much for the test case where I was able to localize the problem.

This is a very interesting bug. Now it is fixed. See here: 71f25da

Note: Since you use server data and in order to work this properly you will need to add the field staffName in the colModel and set to hidden (it can be not editable) if you do not want to show it.

Please test with the new build and let me know if the problem is fixed (in this case close the issue)

Thank you.

Kind Regards,
Tony

Owner

tonytomov commented Dec 1, 2016

Thank you very much for the test case where I was able to localize the problem.

This is a very interesting bug. Now it is fixed. See here: 71f25da

Note: Since you use server data and in order to work this properly you will need to add the field staffName in the colModel and set to hidden (it can be not editable) if you do not want to show it.

Please test with the new build and let me know if the problem is fixed (in this case close the issue)

Thank you.

Kind Regards,
Tony

@wqbill

This comment has been minimized.

Show comment
Hide comment
@wqbill

wqbill Dec 2, 2016

Before this fix.I overrided the restoreRow function and added hidden fields that I need.
Coz I didn't read this function through and needed to make it work ASAP.

$.jgrid.extend(
    {
        restoreRow:function(id){
            var rowObject=$('#duty_list').getRowData(id);
            $('#duty_list').setRowData(id,rowObject);
            var ind=$('#duty_list').getInd(id,true);
            $(ind).attr("editable","0").off("keydown");
        }
    });

(Not extendable.Not all conditions considered.But works for me.)
After your fix,I update jqrid in my project and finally I can remove this.The new version works fine.
Thank you for your work.
Kind Regards,
Bill

wqbill commented Dec 2, 2016

Before this fix.I overrided the restoreRow function and added hidden fields that I need.
Coz I didn't read this function through and needed to make it work ASAP.

$.jgrid.extend(
    {
        restoreRow:function(id){
            var rowObject=$('#duty_list').getRowData(id);
            $('#duty_list').setRowData(id,rowObject);
            var ind=$('#duty_list').getInd(id,true);
            $(ind).attr("editable","0").off("keydown");
        }
    });

(Not extendable.Not all conditions considered.But works for me.)
After your fix,I update jqrid in my project and finally I can remove this.The new version works fine.
Thank you for your work.
Kind Regards,
Bill

@tonytomov

This comment has been minimized.

Show comment
Hide comment
@tonytomov

tonytomov Dec 2, 2016

Owner

Glad to hear this. I will close the issue.

Owner

tonytomov commented Dec 2, 2016

Glad to hear this. I will close the issue.

@tonytomov tonytomov closed this Dec 2, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment