如何实现的Azure移动服务表的内联编辑(编辑)。如何处理错误处理 [英] How to implement inline editing (Edit) of Azure Mobile Services Tables. How to process errors handling

查看:193
本文介绍了如何实现的Azure移动服务表的内联编辑(编辑)。如何处理错误处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的jqGrid与蔚蓝的服务和兴趣了解行内编辑和错误天青移动服务表处理。

数据( inlineNav

请分享想法。

code更新1 :根据奥列格商建议使用的方式code更新 ondblClickRow ,<大骨节病>输入和<大骨节病>逃生机理

$(#list4)。jqGrid的({
    网址:myTableURL,
    数据类型:JSON
    高度:自动,
    colNames:['RowNo','RouteId','地区'],
    colModel:
        {名称:'身份证',宽度:70,编辑:假},
        {名称:'RouteId',宽度:70},
        {名称:'区',宽度:150}}
    ]
    cmTemplate:{编辑:真的,editrules:{要求:真正}},
    rowList:[10,20,30],
    的rowNum:10,
    sortname:ID,
    prmNames:{搜索:空,第二:空},
    ondblClickRow:功能(ROWID){
        变量$自我= $(本);        $ self.jqGrid(editRow,ROWID,{
            MTYPE:补丁,
            键:真实,
            网址:myTableURL +/+
                $ .jgrid.strip preF($ self.jqGrid(getGridParam,ID preFIX),ROWID)
        });
    },
    ajaxGridOptions:{
        的contentType:应用/ JSON
        标题:{
            X-谟 - 应用:的myKey
        }
    },
    serializeGridData:功能(POSTDATA){
        如果(postData.sidx){
            返回{
                $顶部:postData.rows,
                $跳过:(parseInt函数(postData.page,10) - 1)* postData.rows,
                $排序依据:postData.sidx ++ postData.sord,
                $ inlinecount:所有页
            };
        }其他{
            返回{
                $顶部:postData.rows,
                $跳过:(parseInt函数(postData.page,10) - 1)* postData.rows,
                $ inlinecount:所有页
            };
        }
    },
    serializeRowData:功能(POSTDATA){
        VAR dataToSend = $ .extend(真{} POSTDATA);
        如果(dataToSend.hasOwnProperty(OPER)){
            删除dataToSend.oper;
        }
        如果(dataToSend.hasOwnProperty(ID)){
            删除dataToSend.id;
        }
        返回JSON.stringify(dataToSend);
    },
    beforeProcessing:功能(数据,textStatus,jqXHR){
        变种行= parseInt函数($(本).jqGrid(getGridParam,的rowNum),10);
        data.total = Math.ceil(data.count /行);
    },
    jsonReader:{
        repeatitems:假的,
        根:结果
        记录:算
    },
    loadError:功能(jqXHR,textStatus,errorThrown){
        警报('HTTP状态code:'+ jqXHR.status +的'\\ n'+
            textStatus:'+ textStatus +的'\\ n'+
            errorThrown:'+ errorThrown);
        警报('HTTP消息体(jqXHR.responseText):'+'\\ n'+ jqXHR.responseText);
    },
    呼叫器:#pager1',
    viewrecords:真实,
    标题:计划数据
    GridView控件:真实,
    AUTOEN code:真
});

在线编辑和服务器端分页联合code:

 变量$电网= $(#list4),
azureHeaders = {X-谟 - 应用:的myKey},
myTableURL =htt​​ps://mohit.azure-mobile.net/tables/Schedules
inlineNavParams = {
    保存:假的,//我们要手工添加保存按钮。所以,我们需要的不是没有标准按钮
    编辑:真,地址:真的,德尔:真实,
    editParams:{MTYPE:补丁},
    addParams:{
        addRowParams:{
            // MTYPE:POST,//默认值
            aftersavefunc:功能(ROWID,响应){
                VAR rowData = $ .parseJSON(response.responseText)
                    NEWID = rowData.id,
                    $自我= $(本),
                    ID preFIX = $ self.jqGrid(getGridParam,ID preFIXNEWID)
                    selrow = $ self.jqGrid(getGridParam,selrow,NEWID),
                    selArrayRow = $ self.jqGrid(getGridParam,selarrrow,NEWID),
                    OLDID = $ .jgrid.strip preF(ID preFIX,的rowid)
                    dataIndex = $ self.jqGrid(getGridParam,_index,NEWID),
                    一世;
                在_index //更新ID
                如果(dataIndex = NULL&放大器;!&安培;!dataIndex [OLDID] ==未定义){
                    dataIndex [NEWID] = dataIndex [OLDID]
                    删除dataIndex [OLDID]
                }
                //更新id属性上述&lt; TR&GT;
                $(#+ $ .jgrid.jqID(ROWID))ATTR(ID,ID preFIX + NEWID)。
                //选择行的更新标识
                如果(selrow === ROWID){
                    $ self.jqGrid(setGridParam,{selrow:ID preFIX + NEWID});
                }
                在selarrrow阵列//更新ID
                //在使用多选的情况下:true选项
                如果($ .isArray(selArrayRow)){
                    I = $ .inArray(ROWID,selArrayRow);
                    如果(ⅰ&GT; = 0){
                        selArrayRow [I] = ID preFIX + NEWID;
                    }
                }
                //如果我们使用ajaxRowOptions需要下一个行:{异步:真正}
                $ self.jqGrid(showAddEditButtons);
            }
        }
    }
};//设置我们希望直接编辑使用常用选项
                  $ .extend(真,$ .jgrid.inlineEdit,{
键:真实,
afterrestorefunc:功能(){
    $(本).jqGrid(showAddEditButtons);
},
aftersavefunc:功能(){
    $(本).jqGrid(showAddEditButtons);
},
                });               $ grid.jqGrid({
colNames:['RouteId','地区'],
        colModel:
                      {名称:'RouteId',索引:RouteId',宽度:70},
                      {名称:'区',索引:'区',宽度:150}
                  ]
        cmTemplate:{编辑:真的,editrules:{要求:真正}},
//下面的参数都需要从服务器加载网格数据
//我们使用loadonce:下面true选项。人们可以使用服务器端,而不是pading。
//看到http://stackoverflow.com/a/15979809/315935的变化
网址:myTableURL,
rownumbers:真实,
数据类型:JSON
的rowNum:10,
rowList:[10,20,30],
prmNames:{搜索:空,ND:空,排序:空,行:空},
ajaxGridOptions:{的contentType:应用/ JSON,标题:azureHeaders},
                 // jsonReader:{
               // repeatitems:假的,
                   //根:函数(OBJ){返回OBJ; }
                   //},
                  jsonReader:{
            repeatitems:假的,
            根:结果
            记录:算
        },
loadError:功能(jqXHR,textStatus,errorThrown){
            警报('HTTP状态code:'+ jqXHR.status +的'\\ n'+
                textStatus:'+ textStatus +的'\\ n'+
                errorThrown:'+ errorThrown);
            警报('HTTP消息体(jqXHR.responseText):'+'\\ n'+ jqXHR.responseText);
        },
GridView控件:真实,
AUTOEN code:真的,
高度:自动,
                   //我们落实双击还内嵌编辑。
                  //它在使用的情况下,可选步骤inlineNav
                ondblClickRow:功能(ROWID){
    变量$自我= $(本);    $ self.jqGrid(editRow,ROWID,{
        MTYPE:补丁,
        键:真实,
        网址:myTableURL +/+
            $ .jgrid.strip preF($ self.jqGrid(getGridParam,ID preFIX),ROWID)
    });
},
                     //下一个选项是行内编辑重要
                     ajaxRowOptions:{的contentType:应用/ JSON,标题:azureHeaders},
editurl:myTableURL,
serializeRowData:功能(POSTDATA){
            VAR dataToSend = $ .extend(真{} POSTDATA);
            如果(dataToSend.hasOwnProperty(OPER)){
                删除dataToSend.oper;
            }
            如果(dataToSend.hasOwnProperty(ID)){
                删除dataToSend.id;
            }
            返回JSON.stringify(dataToSend);
        },serializeGridData:功能(POSTDATA){
    如果(postData.sidx){
        返回{
            $顶部:postData.rows,
            $跳过:(parseInt函数(postData.page,10) - 1)* postData.rows,
            $排序依据:postData.sidx ++ postData.sord,
            $ inlinecount:所有页
        };
    }其他{
        返回{
            $顶部:postData.rows,
            $跳过:(parseInt函数(postData.page,10) - 1)* postData.rows,
            $ inlinecount:所有页
        };
    }
},beforeProcessing:功能(数据,textStatus,jqXHR){
            变种行= parseInt函数($(本).jqGrid(getGridParam,的rowNum),10);
            data.total = Math.ceil(data.count /行);
        },viewrecords:真实,
rownumbers:真实,
高度:自动,
呼叫器:#pager1
标题:Windows Azure的移动服务REST API
           })的jqGrid(navGrid,#pager1,{编辑:假的,加:假的,德尔:假的,搜索:假});             $ grid.jqGrid(inlineNav,#pager1,inlineNavParams);                $ grid.jqGrid(navButtonAdd,#pager1,{
标题:$ .jgrid.nav.savetext || ,
标题:$ .jgrid.nav.savetitle || 保存排
buttonicon:UI图标盘
ID:$电网[0] .ID +_ilsave
onClickButton:功能(){
    变量$自我= $(本),
        gridIdSelector = $ .jgrid.jqID(this.id)
        savedRow = $ self.jqGrid(getGridParam,savedRow),
        prmNames = $ self.jqGrid(getGridParam,prmNames),
        editUrl = $ self.jqGrid(getGridParam,editurl),
        ROWID = savedRow!= NULL? savedRow [0] .ID:,
        ID = $ .jgrid.strip preF($ self.jqGrid(getGridParam,ID preFIX),ROWID)
        tmpParams = {};    如果(ROWID!= NULL){
        如果($(#+ $ .jgrid.jqID(ROWID),#+ gridIdSelector).hasClass(jqGrid的新行)){
            如果(!inlineNavParams.addParams.addRowParams.extraparam){
                inlineNavParams.addParams.addRowParams.extraparam = {};
            }
            inlineNavParams.addParams.addRowParams.extraparam [prmNames.oper] = prmNames.addoper;
            tmpParams = inlineNavParams.addParams.addRowParams;
        }其他{
            如果(!inlineNavParams.editParams.extraparam){
                inlineNavParams.editParams.extraparam = {};
            }
            inlineNavParams.editParams.extraparam [prmNames.oper] = prmNames.editoper;
            inlineNavParams.editParams.url = editUrl +/+ ID;
            tmpParams = inlineNavParams.editParams;
        }
        如果($ self.jqGrid(saveRow,ROWID,tmpParams)){
            $ self.jqGrid(showAddEditButtons);
        }
    }其他{
        $ .jgrid.viewModal(#alertmod,{GBOX:#gbox_+ gridIdSelector,JQM:真});
        $(#jqg_alrt)专注()。
    }
}
                });
                 $(#+ $电网[0] .ID +_ilsave)addClass(UI-国家已禁用)。

code更新3:

 变量$电网= $(#list4);
    VAR myTableURL ='https://mohit.azure-mobile.net/tables/Schedules';
    VAR azureHeaders = {X-谟 - 应用:,的myKey};    $ grid.jqGrid({
        网址:myTableURL,
        editurl:myTableURL,
        数据类型:JSON
        高度:自动,
        colNames:['RowNo','RouteId','区域','巴士站就','西特','纬度,长,时间,的FromTo','关键点'],
        colModel:
                      {名称:'身份证',索引:'ID',宽度:70,编辑:假},
                      {名称:'RouteId',索引:RouteId',宽度:70}
                                            ]
        cmTemplate:{编辑:真的,editrules:{要求:真正}},
        rowList:[10,20,30],
        的rowNum:10,
        sortname:ID,
        prmNames:{搜索:空,第二:空},
        ondblClickRow:功能(ROWID){
            变量$自我= $(本);            $ self.jqGrid(editRow,ROWID,{
                MTYPE:补丁,
                键:真实,
                网址:myTableURL +/+ $ .jgrid.strip preF($ self.jqGrid(getGridParam,ID preFIX),ROWID)
            });
        },        ajaxGridOptions:{的contentType:应用/ JSON,标题:azureHeaders},
        ajaxRowOptions:{的contentType:应用/ JSON,标题:azureHeaders},        serializeGridData:功能(POSTDATA){
            如果(postData.sidx){
                返回{
                    $顶部:postData.rows,
                    $跳过:(parseInt函数(postData.page,10) - 1)* postData.rows,
                    $排序依据:postData.sidx ++ postData.sord,
                    $ inlinecount:所有页
                };
            }
            其他{
                返回{
                    $顶部:postData.rows,
                    $跳过:(parseInt函数(postData.page,10) - 1)* postData.rows,
                    $ inlinecount:所有页
                };
            }
        },
        serializeRowData:功能(POSTDATA){
            VAR dataToSend = $ .extend(真{} POSTDATA);
            如果(dataToSend.hasOwnProperty(OPER)){
                删除dataToSend.oper;
            }
            如果(dataToSend.hasOwnProperty(ID)){
                删除dataToSend.id;
            }
            返回JSON.stringify(dataToSend);
        },
        beforeProcessing:功能(数据,textStatus,jqXHR){
            变种行= parseInt函数($(本).jqGrid(getGridParam,的rowNum),10);
            data.total = Math.ceil(data.count /行);
        },
        jsonReader:{
            repeatitems:假的,
            根:结果
            记录:算
        },
        loadError:功能(jqXHR,textStatus,errorThrown){
            警报('HTTP状态code:'+ jqXHR.status +的'\\ n'+
                                                                    textStatus:'+ textStatus +的'\\ n'+
                                                                    errorThrown:'+ errorThrown);
            警报('HTTP消息体(jqXHR.responseText):'+'\\ n'+ jqXHR.responseText);
        },
        呼叫器:#pager1',
        viewrecords:真实,
        标题:巴士时间表数据
        GridView控件:真实,
        AUTOEN code:真
    });inlineNavParams = {
    保存:假的,//我们要手工添加保存按钮。所以,我们需要的不是没有标准按钮
    编辑:真,地址:真的,德尔:真实,
    editParams:{MTYPE:补丁},
    addParams:{
        addRowParams:{
                            aftersavefunc:功能(ROWID,响应){
                VAR rowData = $ .parseJSON(response.responseText)
                    NEWID = rowData.id,
                    $自我= $(本),
                    ID preFIX = $ self.jqGrid(getGridParam,ID preFIXNEWID)
                    selrow = $ self.jqGrid(getGridParam,selrow,NEWID),
                    selArrayRow = $ self.jqGrid(getGridParam,selarrrow,NEWID),
                    OLDID = $ .jgrid.strip preF(ID preFIX,的rowid)
                    dataIndex = $ self.jqGrid(getGridParam,_index,NEWID),
                    一世;
                                    如果(dataIndex = NULL&放大器;!&安培;!dataIndex [OLDID] ==未定义){
                    dataIndex [NEWID] = dataIndex [OLDID]
                    删除dataIndex [OLDID]
                }
                                    $(#+ $ .jgrid.jqID(ROWID))ATTR(ID,ID preFIX + NEWID)。
                                    如果(selrow === ROWID){
                    $ self.jqGrid(setGridParam,{selrow:ID preFIX + NEWID});
                }
                                    如果($ .isArray(selArrayRow)){
                    I = $ .inArray(ROWID,selArrayRow);
                    如果(ⅰ&GT; = 0){
                        selArrayRow [I] = ID preFIX + NEWID;
                    }
                }
                                    $ self.jqGrid(showAddEditButtons);
            }
        }
    }
};    $ grid.jqGrid(navGrid,#pager1,{编辑:假的,加:假的,德尔:假的,搜索:假});
    $ grid.jqGrid(inlineNav,#pager1,inlineNavParams);    $ grid.jqGrid(navButtonAdd,#pager1,{
        标题:$ .jgrid.nav.savetext || ,
        标题:$ .jgrid.nav.savetitle || 保存排
        buttonicon:UI图标盘
        ID:$电网[0] .ID +_ilsave
        onClickButton:功能(){
            变量$自我= $(本),
                gridIdSelector = $ .jgrid.jqID(this.id)
                savedRow = $ self.jqGrid(getGridParam,savedRow),
                prmNames = $ self.jqGrid(getGridParam,prmNames),
                editUrl = $ self.jqGrid(getGridParam,editurl),
                ROWID = savedRow!= NULL? savedRow [0] .ID:,
                ID = $ .jgrid.strip preF($ self.jqGrid(getGridParam,ID preFIX),ROWID)
                tmpParams = {};        如果(ROWID!= NULL){
            如果($(#+ $ .jgrid.jqID(ROWID),#+ gridIdSelector).hasClass(jqGrid的新行)){
                如果(!inlineNavParams.addParams.addRowParams.extraparam){
                    inlineNavParams.addParams.addRowParams.extraparam = {};
                }
                inlineNavParams.addParams.addRowParams.extraparam [prmNames.oper] = prmNames.addoper;
                tmpParams = inlineNavParams.addParams.addRowParams;
            }其他{
                如果(!inlineNavParams.editParams.extraparam){
                    inlineNavParams.editParams.extraparam = {};
                }
                inlineNavParams.editParams.extraparam [prmNames.oper] = prmNames.editoper;
                inlineNavParams.editParams.url = editUrl +/+ ID;
                tmpParams = inlineNavParams.editParams;
            }
            如果($ self.jqGrid(saveRow,ROWID,tmpParams)){
                $ self.jqGrid(showAddEditButtons);
            }
        }其他{
            $ .jgrid.viewModal(#alertmod,{GBOX:#gbox_+ gridIdSelector,JQM:真});
            $(#jqg_alrt)专注()。
        }
    }
});
    $ .extend(真,$ .jgrid.inlineEdit,{
        键:真实,
        afterrestorefunc:功能(){
            $(本).jqGrid(showAddEditButtons);
        },
        aftersavefunc:功能(){
            $(本).jqGrid(showAddEditButtons);
        },
    });


解决方案

jqGrid的内嵌编辑模式提供所需的编辑实现三个基本方法:的 editRow ,的 restoreRow saveRow 。该方法 addRow添加空行,然后在内部使用 editRow 为开始编辑。如果一个人使用键:真正的 editRow 的选项,然后有没有需要调用 saveRow 明确。 editRow 做内部,如果用户preSS <大骨节病>输入在编辑领域的关键。用户可以使用<大骨节病> ESC 键取消编辑。 editRow 内部 restoreRow 的情况下,而不是 saveRow 调用。

的jqGrid后来推出格式:动作 addRow 和的 inlineNav 它简化了一个小行内编辑的使用,如果一个人需要具有启动编辑和保存数据一些按钮。 动作和的使用格式的大多数问题3ainline_editing#inlinenav相对=nofollow> inlineNav 是参数的正确用法,并因为这些方法为您提供的参数使用较少的控制。此外 inlineNav 有很多错误,这些错误只在固定的版本4.4.5。

对不起,这么久了常见的文字,但我只想解释一下为什么我要在的首的回答你的问题的使用 inlineNav ,然后提供解决方案,它使用的方法。

用于编辑现有的行内编辑的最简单的方法如下。一开始只是 editRow ondblClickRow 的。用户可以preSS键<大骨节病>输入保存在服务器或preSS的主要编辑的行<大骨节病> ESC 放弃更改。相应的code将大约如下:

VAR azureHeaders = {X-谟 - 应用:myApplicationKey},
    myTableURL =htt​​ps://oleg.azure-mobile.net/tables/Products;$(#电网)。jqGrid的({
    网址:myTableURL,
    数据类型:JSON
    prmNames:{搜索:空,ND:空,排序:空,行:空},
    ajaxGridOptions:{的contentType:应用/ JSON,标题:azureHeaders},
    jsonReader:{repeatitems:假的,根:函数(OBJ){返回OBJ; }},
    ondblClickRow:功能(ROWID){
        变量$自我= $(本);        $ self.jqGrid(editRow,ROWID,{
            MTYPE:补丁,
            键:真实,
            网址:myTableURL +/+
                $ .jgrid.strip preF($ self.jqGrid(getGridParam,ID preFIX),ROWID)
        });
    },
    ajaxRowOptions:{的contentType:应用/ JSON,标题:azureHeaders},
    serializeRowData:功能(POSTDATA){
        VAR dataToSend = $ .extend(真{} POSTDATA);
        如果(dataToSend.hasOwnProperty(OPER)){
            删除dataToSend.oper;
        }
        如果(dataToSend.hasOwnProperty(ID)){
            删除dataToSend.id;
        }
        返回JSON.stringify(dataToSend);
    },
    GridView控件:真实,
    loadonce:真实,
    AUTOEN code:真的,
    jqGrid的的... //其他参数
});

(为了使code更容易我删除的任何错误数据的加载过程中处理或编辑结果的保存)

上面的例子工程。用户可的视图的数据,选择行,使局部分页等在另一边就行的用户可以通过双击来编辑它。要明白,设计联编辑允许的是很重要的同方的编辑多行。用户可以双击一行,做了一些修改,然后做另一行双击,使得一些其他修改。最后,用户可以通过pressing在完成每一行的编辑或者<大骨节病>输入或<大骨节病> ESC 键保存或放弃行的电流变化。

目前我们设定每一行的编辑年初网​​址 editRow 这将是的有关的选项与格的行的。如果用户preSS <大骨节病>输入键方法 editRow 内部调用 saveRow 使用相同的参数

在你明白我的编辑如何直列工作可以解释如何在使用的情况下,所有的作品 inlineNav 。如果检查 inlineNav 的code(见的这里),那么你会看到,它主要使用该方法的 navButtonAdd 其中添加自定义按钮,导航器栏。在 onClickButton 的回调调用 addRow editRow saveRow restoreRow 。版本4.4.5修复了 inlineNav 很多bug(见<一href=\"http://www.trirand.com/blog/?page_id=393/bugs/cancel-button-of-inlinenav-uses-callback-of-edit-options-on-canceling-add-operation/#p28553\"相对=nofollow>这里,<一个href=\"http://www.trirand.com/blog/?page_id=393/bugs/jgrid-inlineedit-be-changed-by-restorerow/#p28552\"相对=nofollow>这里,<一个href=\"http://www.trirand.com/blog/?page_id=393/bugs/resetting-of-inlinenav-toolbar-buttons-required-in-case-of-saving-error/#p28528\"相对=nofollow>这里,<一个href=\"http://www.trirand.com/blog/?page_id=393/bugs/class-jqgrid-new-row-will-be-added-by-addrow-but-never-removed/#p28527\"相对=nofollow>这里和<一个href=\"http://www.trirand.com/blog/?page_id=393/bugs/save-button-of-inlinenav-uses-editparams-instead-of-addparams-addrowparams-on-add-new-row/#p28525\"相对=nofollow>这里),但它仍然没有没有解决所有存在的问题。例如,如果您允许同时编辑多个行(如果使用当前无证选项 restoreAfterSelect:假 inlineNav ),那么,因为使用的 $ tpsavedRow [0] .ID 前pression得到ROWID的jqGrid的code可以使用的错误的ROWID 的保存或行作废。因此,您不应使用选项 restoreAfterSelect:假 在jqGrid的当前版本的

inlineNav 的在我看来,主要的问题是一个未使用的用于保存或丢弃哪一个行编辑初始化过程中具有相同的选项。我的意思是 inlineNav 要求 saveRow restoreRow *不这是用于 editRow 呼叫相同的选项。如果一个人改变,例如 editRow 网​​址属性,使REST风格网​​址 ID 排将使用 saveRow 将不若相同的选项发出的呼吁用户点击保存按钮。

此外还有存在的没有回调可以用来修改当前的选项(修改网​​址居多)如果用户点击 saveRow 。幽冥 inlineNav 也不 saveRow 目前有(在4.4.5的jqGrid或更低),这样的回调。

来解决,我看这个问题的唯一方法是:


  1. 从不使用 restoreAfterSelect:假选项

  2. 使用保存:选项=htt​​p://www.trirand.com/jqgridwiki/doku.php?id=wiki%3ainline_editing#inlinenav 相对=nofollow> inlineNav

  3. 添加自定义的保存按钮,看起来像 inlineNav 相应的按钮,并修改网​​址手动选项的的调用某个 saveRow 。换句话说应该重新实现保存按钮 inlineNav

相应的实施可以在下面找到的一个例子。我用 loadonce:真正的选项。如果一个人有很大的表,preFER服务器端分页,然后一会需要做一些参数的变化与对应 previous答案的对您的问题。另外我删除错误处理,简化了code一点:

变量$电网= $(#清单),
    azureHeaders = {X-谟 - 应用:myApplicationKey},
    myTableURL =htt​​ps://oleg.azure-mobile.net/tables/Products
    inlineNavParams = {
        保存:假的,//我们要手工添加保存按钮。所以,我们需要的不是没有标准按钮
        editParams:{MTYPE:补丁},
        addParams:{
            addRowParams:{
                // MTYPE:POST,//默认值
                aftersavefunc:功能(ROWID,响应){
                    VAR rowData = $ .parseJSON(response.responseText)
                        NEWID = rowData.id,
                        $自我= $(本),
                        P = $ self.jqGrid(getGridParam)//获取所有参数的对象
                        ID preFIX = p.id preFIX,
                        OLDID = $ .jgrid.strip preF(ID preFIX,的rowid)
                        selrow = p.selrow,
                        selArrayRow = p.selarrrow,
                        dataIndex = p._index,
                        keyIndex = p.keyIndex,
                        colModel = p.colModel,
                        localRowData = $ self.jqGrid(getLocalRow,ROWID)
                        一世;
                    在_index //更新ID
                    如果(dataIndex = NULL&放大器;!&安培;!dataIndex [OLDID] ==未定义){
                        dataIndex [NEWID] = dataIndex [OLDID]
                        删除dataIndex [OLDID]
                    }
                    //更新值数据ID
                    如果(localRowData.hasOwnProperty(_ ID_)){
                        localRowData._id_ = NEWID;
                    }
                    如果(keyIndex!== FALSE){
                        对于(i = 0; I&LT; colModel.length;我++){
                            如果(colModel [I] .KEY){
                                如果(localRowData.hasOwnProperty(colModel [我]。名称)){
                                    //更新列的值
                                    localRowData [colModel [我]。名称] = ID preFIX + NEWID;
                                    $ self.jqGrid(setCell,ROWID,我,NEWID);
                                }
                                打破; //你也可以拥有只有一个键列:真
                            }
                        }
                    }                    //更新id属性上述&lt; TR&GT;
                    $(#+ $ .jgrid.jqID(ROWID))ATTR(ID,ID preFIX + NEWID)。
                    //选择行的更新标识
                    如果(selrow === ROWID){
                        $ self.jqGrid(setGridParam,{selrow:ID preFIX + NEWID});
                    }                    在selarrrow阵列//更新ID
                    //在使用多选的情况下:true选项
                    如果($ .isArray(selArrayRow)){
                        I = $ .inArray(ROWID,selArrayRow);
                        如果(ⅰ&GT; = 0){
                            selArrayRow [I] = ID preFIX + NEWID;
                        }
                    }
                    //如果我们使用ajaxRowOptions需要下一个行:{异步:真正}
                    $ self.jqGrid(showAddEditButtons);                }
            }
        }
    };//设置我们希望直接编辑使用常用选项
$ .extend(真,$ .jgrid.inlineEdit,{
    键:真实,
    afterrestorefunc:功能(){
        $(本).jqGrid(showAddEditButtons);
    },
    aftersavefunc:功能(){
        $(本).jqGrid(showAddEditButtons);
    },
});$ grid.jqGrid({
    colModel:
        {名:ID键:真,宽度:100} //可选列
        {名:姓名,宽度:450,可编辑:真正}
    ]
    //下面的参数都需要从服务器加载网格数据
    //我们使用loadonce:下面true选项。人们可以使用服务器端,而不是pading。
    //看到http://stackoverflow.com/a/15979809/315935的变化
    网址:myTableURL,
    数据类型:JSON
    prmNames:{搜索:空,ND:空,排序:空,行:空},
    ajaxGridOptions:{的contentType:应用/ JSON,标题:azureHeaders},
    jsonReader:{
        repeatitems:假的,
        根:函数(OBJ){返回OBJ; }
    },
    GridView控件:真实,
    AUTOEN code:真的,
    loadonce:真实,
    //我们落实双击还内嵌编辑。
    //它在使用的情况下,可选步骤inlineNav
    ondblClickRow:功能(ROWID){
        变量$自我= $(本);        $ self.jqGrid(editRow,ROWID,{
            MTYPE:补丁,
            键:真实,
            网址:myTableURL +/+
                $ .jgrid.strip preF($ self.jqGrid(getGridParam,ID preFIX),ROWID)
        });
    },
    //下一个选项是行内编辑重要
    ajaxRowOptions:{的contentType:应用/ JSON,标题:azureHeaders},
    editurl:myTableURL,
    serializeRowData:功能(POSTDATA){
        VAR dataToSend = $ .extend(真{} POSTDATA); //使后数据副本
        如果(dataToSend.hasOwnProperty(OPER)){
            删除dataToSend.oper;
        }
        如果(dataToSend.hasOwnProperty(ID)){
            删除dataToSend.id;
        }
        返回JSON.stringify(dataToSend);
    },
    的rowNum:2,
    rowList:[2,5,10],
    sortname:姓名,
    排序顺序:递减,
    viewrecords:真实,
    rownumbers:真实,
    高度:自动,
    呼叫器:#pager
    标题:Windows Azure的移动服务REST API
})的jqGrid(navGrid,#pager,{编辑:假的,加:假的,德尔:假的,搜索:假});
$ grid.jqGrid(inlineNav,#pager,inlineNavParams);
$ grid.jqGrid(navButtonAdd,#pager,{
    标题:$ .jgrid.nav.savetext || ,
    标题:$ .jgrid.nav.savetitle || 保存排
    buttonicon:UI图标盘
    ID:$电网[0] .ID +_ilsave
    onClickButton:功能(){
        变量$自我= $(本),
            gridIdSelector = $ .jgrid.jqID(this.id)
            savedRow = $ self.jqGrid(getGridParam,savedRow),
            prmNames = $ self.jqGrid(getGridParam,prmNames),
            editUrl = $ self.jqGrid(getGridParam,editurl),
            ROWID = savedRow!= NULL? savedRow [0] .ID:,
            ID = $ .jgrid.strip preF($ self.jqGrid(getGridParam,ID preFIX),ROWID)
            tmpParams = {};        如果(ROWID!= NULL){
            如果($(#+ $ .jgrid.jqID(ROWID),#+ gridIdSelector).hasClass(jqGrid的新行)){
                如果(!inlineNavParams.addParams.addRowParams.extraparam){
                    inlineNavParams.addParams.addRowParams.extraparam = {};
                }
                inlineNavParams.addParams.addRowParams.extraparam [prmNames.oper] = prmNames.addoper;
                tmpParams = inlineNavParams.addParams.addRowParams;
            }其他{
                如果(!inlineNavParams.editParams.extraparam){
                    inlineNavParams.editParams.extraparam = {};
                }
                inlineNavParams.editParams.extraparam [prmNames.oper] = prmNames.editoper;
                inlineNavParams.editParams.url = editUrl +/+ ID;
                tmpParams = inlineNavParams.editParams;
            }
            如果($ self.jqGrid(saveRow,ROWID,tmpParams)){
                $ self.jqGrid(showAddEditButtons);
            }
        }其他{
            $ .jgrid.viewModal(#alertmod,{GBOX:#gbox_+ gridIdSelector,JQM:真});
            $(#jqg_alrt)专注()。
        }
    }
});
$(#+ $电网[0] .ID +_ilsave)addClass(UI-国家已禁用)。

怎么可以看到最复杂的是的aftersavefunc 实施 addRowParams 参数的回调。我打算张贴后,我的建议,trirand延伸行内编辑的code,但简化 aftersavefunc 回调code,以便它可能只是

aftersavefunc:功能(ROWID,响应){
    返回response.responseText?
        $ .parseJSON(response.responseText).ID:
        不确定的;
}

所有其他的事情应该在内部的jqGrid做,如果通过 aftersavefunc 返回值的类型不是未定义。

I am using jqGrid (inlineNav) with data from azure service and interested in learning about inline editing and error handling with azure mobile service table.

Please share thoughts.

Code update 1: Code update based on Oleg's suggested way of using ondblClickRow, Enter and Escape machanism

$("#list4").jqGrid({
    url: myTableURL,
    datatype: "json",
    height: "auto",
    colNames: ['RowNo', 'RouteId', 'Area'],
    colModel: [
        { name: 'id', width: 70, editable: false },
        { name: 'RouteId', width: 70 },
        { name: 'Area', width: 150 }}
    ],
    cmTemplate: { editable: true, editrules: { required: true} },
    rowList: [10, 20, 30],
    rowNum: 10,
    sortname: "id",
    prmNames: { search: null, nd: null },
    ondblClickRow: function (rowid) {
        var $self = $(this);

        $self.jqGrid("editRow", rowid, {
            mtype: "PATCH",
            keys: true,
            url: myTableURL + "/" +
                $.jgrid.stripPref($self.jqGrid("getGridParam", "idPrefix"), rowid)
        });
    },
    ajaxGridOptions: {
        contentType: "application/json",
        headers: {
            "X-ZUMO-APPLICATION": "myKey"
        }
    },
    serializeGridData: function (postData) {
        if (postData.sidx) {
            return {
                $top: postData.rows,
                $skip: (parseInt(postData.page, 10) - 1) * postData.rows,
                $orderby: postData.sidx + " " + postData.sord,
                $inlinecount: "allpages"
            };
        } else {
            return {
                $top: postData.rows,
                $skip: (parseInt(postData.page, 10) - 1) * postData.rows,
                $inlinecount: "allpages"
            };
        }
    },
    serializeRowData: function (postData) {
        var dataToSend = $.extend(true, {}, postData);
        if (dataToSend.hasOwnProperty("oper")) {
            delete dataToSend.oper;
        }
        if (dataToSend.hasOwnProperty("id")) {
            delete dataToSend.id;
        }
        return JSON.stringify(dataToSend);
    },
    beforeProcessing: function (data, textStatus, jqXHR) {
        var rows = parseInt($(this).jqGrid("getGridParam", "rowNum"), 10);
        data.total = Math.ceil(data.count / rows);
    },
    jsonReader: {
        repeatitems: false,
        root: "results",
        records: "count"
    },
    loadError: function (jqXHR, textStatus, errorThrown) {
        alert('HTTP status code: ' + jqXHR.status + '\n' +
            'textStatus: ' + textStatus + '\n' +
            'errorThrown: ' + errorThrown);
        alert('HTTP message body (jqXHR.responseText): ' + '\n' + jqXHR.responseText);
    },
    pager: '#pager1',
    viewrecords: true,
    caption: "Schedule Data",
    gridview: true,
    autoencode: true
});

Combined code of inline editing and server side paging :

                        var $grid = $("#list4"),
azureHeaders = { "X-ZUMO-APPLICATION": "mykey" },
myTableURL = "https://mohit.azure-mobile.net/tables/Schedules",
inlineNavParams = {
    save: false, // we want to add Save button manually. So we needn't no standard button
    edit: true, add: true, del: true,
    editParams: { mtype: "PATCH" },
    addParams: {
        addRowParams: {
            //mtype: "POST", // default value
            aftersavefunc: function (rowid, response) {
                var rowData = $.parseJSON(response.responseText),
                    newId = rowData.id,
                    $self = $(this),
                    idPrefix = $self.jqGrid("getGridParam", "idPrefix", newId),
                    selrow = $self.jqGrid("getGridParam", "selrow", newId),
                    selArrayRow = $self.jqGrid("getGridParam", "selarrrow", newId),
                    oldId = $.jgrid.stripPref(idPrefix, rowid),
                    dataIndex = $self.jqGrid("getGridParam", "_index", newId),
                    i;
                // update id in the _index
                if (dataIndex != null && dataIndex[oldId] !== undefined) {
                    dataIndex[newId] = dataIndex[oldId];
                    delete dataIndex[oldId];
                }
                // update id attribute in <tr>
                $("#" + $.jgrid.jqID(rowid)).attr("id", idPrefix + newId);
                // update id of selected row
                if (selrow === rowid) {
                    $self.jqGrid("setGridParam", { selrow: idPrefix + newId });
                }
                // update id in selarrrow array
                // in case of usage multiselect:true option
                if ($.isArray(selArrayRow)) {
                    i = $.inArray(rowid, selArrayRow);
                    if (i >= 0) {
                        selArrayRow[i] = idPrefix + newId;
                    }
                }
                // the next line is required if we use ajaxRowOptions: { async: true }
                $self.jqGrid("showAddEditButtons");
            }
        }
    }
};

// set common options which we want to use in inline editing
                  $.extend(true, $.jgrid.inlineEdit, {
keys: true,
afterrestorefunc: function () {
    $(this).jqGrid("showAddEditButtons");
},
aftersavefunc: function () {
    $(this).jqGrid("showAddEditButtons");
},
                });

               $grid.jqGrid({
colNames: ['RouteId', 'Area'],
        colModel: [
                      { name: 'RouteId', index: 'RouteId', width: 70 },
                      { name: 'Area', index: 'Area', width: 150 }
                  ],
        cmTemplate: { editable: true, editrules: { required: true} },
// the parameters below are needed to load the grid data from the server
// we use loadonce: true option below. One can use server side pading instead.
// see http://stackoverflow.com/a/15979809/315935 for the changes
url: myTableURL,
rownumbers: true,
datatype: "json",
rowNum: 10,
rowList: [10, 20, 30],
prmNames: {search: null, nd: null, sort: null, rows: null},
ajaxGridOptions: { contentType: "application/json", headers: azureHeaders },
                 // jsonReader: {
               //     repeatitems: false,
                   //     root: function (obj) { return obj; }
                   // },
                  jsonReader: {
            repeatitems: false,
            root: "results",
            records: "count"
        },
loadError: function (jqXHR, textStatus, errorThrown) {
            alert('HTTP status code: ' + jqXHR.status + '\n' +
                'textStatus: ' + textStatus + '\n' +
                'errorThrown: ' + errorThrown);
            alert('HTTP message body (jqXHR.responseText): ' + '\n' + jqXHR.responseText);
        },
gridview: true,
autoencode: true,
height: "auto",
                   // we implement additionally inline editing on double-click.
                  // it's optional step in case of usage inlineNav
                ondblClickRow: function (rowid) {
    var $self = $(this);

    $self.jqGrid("editRow", rowid, {
        mtype: "PATCH",
        keys: true,
        url: myTableURL + "/" +
            $.jgrid.stripPref($self.jqGrid("getGridParam", "idPrefix"), rowid)
    });
},
                     // next options are important for inline editing
                     ajaxRowOptions: { contentType: "application/json", headers: azureHeaders },
editurl: myTableURL,
serializeRowData: function (postData) {
            var dataToSend = $.extend(true, {}, postData);
            if (dataToSend.hasOwnProperty("oper")) {
                delete dataToSend.oper;
            }
            if (dataToSend.hasOwnProperty("id")) {
                delete dataToSend.id;
            }
            return JSON.stringify(dataToSend);
        },

serializeGridData: function (postData) {
    if (postData.sidx) {
        return {
            $top: postData.rows,
            $skip: (parseInt(postData.page, 10) - 1) * postData.rows,
            $orderby: postData.sidx + " " + postData.sord,
            $inlinecount: "allpages"
        };
    } else {
        return {
            $top: postData.rows,
            $skip: (parseInt(postData.page, 10) - 1) * postData.rows,
            $inlinecount: "allpages"
        };
    }
},

beforeProcessing: function (data, textStatus, jqXHR) {
            var rows = parseInt($(this).jqGrid("getGridParam", "rowNum"), 10);
            data.total = Math.ceil(data.count/rows);
        },

viewrecords: true,
rownumbers: true,
height: "auto",
pager: "#pager1",
caption: "Windows Azure Mobile Services REST API"
           }).jqGrid("navGrid", "#pager1", { edit: false, add: false, del: false, search: false });

             $grid.jqGrid("inlineNav", "#pager1", inlineNavParams);

                $grid.jqGrid("navButtonAdd", "#pager1", {
caption: $.jgrid.nav.savetext || "",
title: $.jgrid.nav.savetitle || "Save row",
buttonicon: "ui-icon-disk",
id: $grid[0].id + "_ilsave",
onClickButton: function () {
    var $self = $(this),
        gridIdSelector = $.jgrid.jqID(this.id),
        savedRow = $self.jqGrid("getGridParam", "savedRow"),
        prmNames = $self.jqGrid("getGridParam", "prmNames"),
        editUrl = $self.jqGrid("getGridParam", "editurl"),
        rowid = savedRow != null ? savedRow[0].id : "",
        id = $.jgrid.stripPref($self.jqGrid("getGridParam", "idPrefix"), rowid),
        tmpParams = {};

    if (rowid != null) {
        if ($("#" + $.jgrid.jqID(rowid), "#" + gridIdSelector).hasClass("jqgrid-new-row")) {
            if (!inlineNavParams.addParams.addRowParams.extraparam) {
                inlineNavParams.addParams.addRowParams.extraparam = {};
            }
            inlineNavParams.addParams.addRowParams.extraparam[prmNames.oper] = prmNames.addoper;
            tmpParams = inlineNavParams.addParams.addRowParams;
        } else {
            if (!inlineNavParams.editParams.extraparam) {
                inlineNavParams.editParams.extraparam = {};
            }
            inlineNavParams.editParams.extraparam[prmNames.oper] = prmNames.editoper;
            inlineNavParams.editParams.url = editUrl + "/" + id;
            tmpParams = inlineNavParams.editParams;
        }
        if ($self.jqGrid("saveRow", rowid, tmpParams)) {
            $self.jqGrid("showAddEditButtons");
        }
    } else {
        $.jgrid.viewModal("#alertmod", {gbox: "#gbox_" + gridIdSelector, jqm: true});
        $("#jqg_alrt").focus();
    }
}
                });
                 $("#" + $grid[0].id + "_ilsave").addClass("ui-state-disabled");

Code update 3 :

                      var $grid = $("#list4");
    var myTableURL = 'https://mohit.azure-mobile.net/tables/Schedules';
    var azureHeaders = { "X-ZUMO-APPLICATION": ", mykey" };

    $grid.jqGrid({
        url: myTableURL,
        editurl: myTableURL,
        datatype: "json",
        height: "auto",
        colNames: ['RowNo', 'RouteId', 'Area', 'BusStop', 'Seater', 'Lat', 'Long', 'Timing', 'FromTo', 'KeyPoint'],
        colModel: [
                      { name: 'id', index: 'id', width: 70, editable: false },
                      { name: 'RouteId', index: 'RouteId', width: 70 }
                                            ],
        cmTemplate: { editable: true, editrules: { required: true} },
        rowList: [10, 20, 30],
        rowNum: 10,
        sortname: "id",
        prmNames: { search: null, nd: null},
        ondblClickRow: function (rowid) {
            var $self = $(this);

            $self.jqGrid("editRow", rowid, {
                mtype: "PATCH",
                keys: true,
                url: myTableURL + "/" + $.jgrid.stripPref($self.jqGrid("getGridParam", "idPrefix"), rowid)
            });
        },

        ajaxGridOptions: { contentType: "application/json", headers: azureHeaders },
        ajaxRowOptions: { contentType: "application/json", headers: azureHeaders },

        serializeGridData: function (postData) {
            if (postData.sidx) {
                return {
                    $top: postData.rows,
                    $skip: (parseInt(postData.page, 10) - 1) * postData.rows,
                    $orderby: postData.sidx + " " + postData.sord,
                    $inlinecount: "allpages"
                };
            }
            else {
                return {
                    $top: postData.rows,
                    $skip: (parseInt(postData.page, 10) - 1) * postData.rows,
                    $inlinecount: "allpages"
                };
            }
        },
        serializeRowData: function (postData) {
            var dataToSend = $.extend(true, {}, postData);
            if (dataToSend.hasOwnProperty("oper")) {
                delete dataToSend.oper;
            }
            if (dataToSend.hasOwnProperty("id")) {
                delete dataToSend.id;
            }
            return JSON.stringify(dataToSend);
        },
        beforeProcessing: function (data, textStatus, jqXHR) {
            var rows = parseInt($(this).jqGrid("getGridParam", "rowNum"), 10);
            data.total = Math.ceil(data.count / rows);
        },
        jsonReader: {
            repeatitems: false,
            root: "results",
            records: "count"
        },
        loadError: function (jqXHR, textStatus, errorThrown) {
            alert('HTTP status code: ' + jqXHR.status + '\n' +
                                                                    'textStatus: ' + textStatus + '\n' +
                                                                    'errorThrown: ' + errorThrown);
            alert('HTTP message body (jqXHR.responseText): ' + '\n' + jqXHR.responseText);
        },
        pager: '#pager1',
        viewrecords: true,
        caption: "Bus Schedule Data",
        gridview: true,
        autoencode: true
    });

inlineNavParams = {
    save: false, // we want to add Save button manually. So we needn't no standard button
    edit: true, add: true, del: true,
    editParams: { mtype: "PATCH" },
    addParams: {
        addRowParams: {
                            aftersavefunc: function (rowid, response) {
                var rowData = $.parseJSON(response.responseText),
                    newId = rowData.id,
                    $self = $(this),
                    idPrefix = $self.jqGrid("getGridParam", "idPrefix", newId),
                    selrow = $self.jqGrid("getGridParam", "selrow", newId),
                    selArrayRow = $self.jqGrid("getGridParam", "selarrrow", newId),
                    oldId = $.jgrid.stripPref(idPrefix, rowid),
                    dataIndex = $self.jqGrid("getGridParam", "_index", newId),
                    i;
                                    if (dataIndex != null && dataIndex[oldId] !== undefined) {
                    dataIndex[newId] = dataIndex[oldId];
                    delete dataIndex[oldId];
                }
                                    $("#" + $.jgrid.jqID(rowid)).attr("id", idPrefix + newId);
                                    if (selrow === rowid) {
                    $self.jqGrid("setGridParam", { selrow: idPrefix + newId });
                }
                                    if ($.isArray(selArrayRow)) {
                    i = $.inArray(rowid, selArrayRow);
                    if (i >= 0) {
                        selArrayRow[i] = idPrefix + newId;
                    }
                }
                                    $self.jqGrid("showAddEditButtons");
            }
        }
    }
};

    $grid.jqGrid("navGrid", "#pager1", { edit: false, add: false, del: false, search: false });
    $grid.jqGrid("inlineNav", "#pager1", inlineNavParams);

    $grid.jqGrid("navButtonAdd", "#pager1", {
        caption: $.jgrid.nav.savetext || "",
        title: $.jgrid.nav.savetitle || "Save row",
        buttonicon: "ui-icon-disk",
        id: $grid[0].id + "_ilsave",
        onClickButton: function () {
            var $self = $(this),
                gridIdSelector = $.jgrid.jqID(this.id),
                savedRow = $self.jqGrid("getGridParam", "savedRow"),
                prmNames = $self.jqGrid("getGridParam", "prmNames"),
                editUrl = $self.jqGrid("getGridParam", "editurl"),
                rowid = savedRow != null ? savedRow[0].id : "",
                id = $.jgrid.stripPref($self.jqGrid("getGridParam", "idPrefix"), rowid),
                tmpParams = {};

        if (rowid != null) {
            if ($("#" + $.jgrid.jqID(rowid), "#" + gridIdSelector).hasClass("jqgrid-new-row")) {
                if (!inlineNavParams.addParams.addRowParams.extraparam) {
                    inlineNavParams.addParams.addRowParams.extraparam = {};
                }
                inlineNavParams.addParams.addRowParams.extraparam[prmNames.oper] = prmNames.addoper;
                tmpParams = inlineNavParams.addParams.addRowParams;
            } else {
                if (!inlineNavParams.editParams.extraparam) {
                    inlineNavParams.editParams.extraparam = {};
                }
                inlineNavParams.editParams.extraparam[prmNames.oper] = prmNames.editoper;
                inlineNavParams.editParams.url = editUrl + "/" + id;
                tmpParams = inlineNavParams.editParams;
            }
            if ($self.jqGrid("saveRow", rowid, tmpParams)) {
                $self.jqGrid("showAddEditButtons");
            }
        } else {
            $.jgrid.viewModal("#alertmod", {gbox: "#gbox_" + gridIdSelector, jqm: true});
            $("#jqg_alrt").focus();
        }
    }
});


    $.extend(true, $.jgrid.inlineEdit, {
        keys: true,
        afterrestorefunc: function () {
            $(this).jqGrid("showAddEditButtons");
        },
        aftersavefunc: function () {
            $(this).jqGrid("showAddEditButtons");
        },
    });

解决方案

Inline editing mode of jqGrid provide three base methods needed for implementing of editing: editRow, restoreRow and saveRow. The method addRow add empty row and then uses internally editRow for start editing. If one use keys: true option of editRow then one don't need to call saveRow explicitly. editRow do it internally if the user press Enter key in the editing field. The user can use Esc key to cancel editing. editRow calls internally restoreRow in the case instead of saveRow.

jqGrid introduced later formatter: "actions", addRow and inlineNav which simplify a little the usage of inline editing if one needs to have some buttons for starting editing and saving the data. The most problems of usage of formatter: "actions" and inlineNav are in the correct usage of parameters and because the methods provide you less control on usage of parameters. Additionally inlineNav had many bugs which are fixed only in version 4.4.5.

Sorry, for so long common text, but I want just explain why I want answer on your question first without usage of inlineNav and then provide solution which use the method.

The most simple way to use inline editing for edit existing rows is the following. One starts just editRow inside of ondblClickRow. The user can press key Enter to save the editing row on the server or press the key Esc to discard the changes. The corresponding code will be about the following:

var azureHeaders = { "X-ZUMO-APPLICATION": "myApplicationKey" },
    myTableURL = "https://oleg.azure-mobile.net/tables/Products";

$("#grid").jqGrid({
    url: myTableURL,
    datatype: "json",
    prmNames: {search: null, nd: null, sort: null, rows: null},
    ajaxGridOptions: { contentType: "application/json", headers: azureHeaders },
    jsonReader: { repeatitems: false, root: function (obj) { return obj; } },
    ondblClickRow: function (rowid) {
        var $self = $(this);

        $self.jqGrid("editRow", rowid, {
            mtype: "PATCH",
            keys: true,
            url: myTableURL + "/" +
                $.jgrid.stripPref($self.jqGrid("getGridParam", "idPrefix"), rowid)
        });
    },
    ajaxRowOptions: { contentType: "application/json", headers: azureHeaders },
    serializeRowData: function (postData) {
        var dataToSend = $.extend(true, {}, postData);
        if (dataToSend.hasOwnProperty("oper")) {
            delete dataToSend.oper;
        }
        if (dataToSend.hasOwnProperty("id")) {
            delete dataToSend.id;
        }
        return JSON.stringify(dataToSend);
    },
    gridview: true,
    loadonce: true,
    autoencode: true,
    ... // other parameters of jqGrid
});

(To make the code easier I removed any error handling during loading of data or saving of editing results)

The above example works. The user can view the data, select rows, make local paging etc. On the other side the user can double-click on the row to edit it. It's important to understand that design inline editing allows editing multiple lines at the same side. The user can make double-click on one row, make some modifications, then make double-click on another row, makes some other modifications. Finally the user can finish editing of every row either by pressing on Enter or Esc key to save or to discard the current changes of the line.

At the beginning of editing of every row we set url option of editRow which will be associated with the row of grid. If the user press Enter key the method editRow calls internally saveRow with the same parameters.

After you understand how inline editing work I can explain how all works in case of usage inlineNav. If you examine the code of inlineNav (see here) then you will see that it uses mostly the method navButtonAdd which add custom button to navigator bar. Inside of onClickButton callback it calls addRow, editRow, saveRow or restoreRow. The version 4.4.5 fixes many bugs in inlineNav (see here, here, here, here and here), but it still don't solves not all existing problems. For example if you permit to edit multiple rows at the same time (if you use currently undocumented option restoreAfterSelect: false of inlineNav) then because of usage $t.p.savedRow[0].id expression to get the rowid the code of jqGrid can use wrong rowid for saving or discarding of row. So you should not use option restoreAfterSelect: false in the current version of jqGrid.

The main problem of inlineNav in my opinion is that one use not the same options for saving or discarding which one has during initializing of editing of rows. I mean that inlineNav calls saveRow or restoreRow *not with the same options which was used for call of editRow. If one changes for example the url property of editRow so that RESTfull url with id of row will be used the call of saveRow will be not made with the same options if the user clicks on "Save" button.

Moreover there are exist no callback which can be used to modify the current options (to modify url mostly) if the user click on saveRow. Nether inlineNav nor saveRow have currently (in jqGrid 4.4.5 or lower) such callbacks.

The only way to solve the problem which I see is:

  1. never use restoreAfterSelect: false options
  2. use save: false option of inlineNav
  3. add custom "Save" button which looks like the corresponding button of inlineNav and modify the url option of manually before one calls saveRow. In other words one should re-implement "Save" button of inlineNav.

An example of the corresponding implementation you can find below. I used loadonce: true option. If one have large table and prefer server side paging then one will need make changes of some parameters correspond with my previous answer on your question. Additionally I removed error handling to simplify the code a little:

var $grid = $("#list"),
    azureHeaders = { "X-ZUMO-APPLICATION": "myApplicationKey" },
    myTableURL = "https://oleg.azure-mobile.net/tables/Products",
    inlineNavParams = {
        save: false, // we want to add Save button manually. So we needn't no standard button
        editParams: { mtype: "PATCH" },
        addParams: {
            addRowParams: {
                //mtype: "POST", // default value
                aftersavefunc: function (rowid, response) {
                    var rowData = $.parseJSON(response.responseText),
                        newId = rowData.id,
                        $self = $(this),
                        p = $self.jqGrid("getGridParam"), // get all parameters as object
                        idPrefix = p.idPrefix,
                        oldId = $.jgrid.stripPref(idPrefix, rowid),
                        selrow = p.selrow,
                        selArrayRow = p.selarrrow,
                        dataIndex = p._index,
                        keyIndex = p.keyIndex,
                        colModel = p.colModel,
                        localRowData = $self.jqGrid("getLocalRow", rowid),
                        i;
                    // update id in the _index
                    if (dataIndex != null && dataIndex[oldId] !== undefined) {
                        dataIndex[newId] = dataIndex[oldId];
                        delete dataIndex[oldId];
                    }
                    // update id value in the data
                    if (localRowData.hasOwnProperty("_id_")) {
                        localRowData._id_ = newId;
                    }
                    if (keyIndex !== false) {
                        for (i = 0; i < colModel.length; i++) {
                            if (colModel[i].key) {
                                if (localRowData.hasOwnProperty(colModel[i].name)) {
                                    // update the value of the column
                                    localRowData[colModel[i].name] = idPrefix + newId;
                                    $self.jqGrid("setCell", rowid, i, newId);
                                }
                                break; // one can have only one column with key:true
                            }
                        }
                    }

                    // update id attribute in <tr>
                    $("#" + $.jgrid.jqID(rowid)).attr("id", idPrefix + newId);
                    // update id of selected row
                    if (selrow === rowid) {
                        $self.jqGrid("setGridParam", { selrow: idPrefix + newId });
                    }

                    // update id in selarrrow array
                    // in case of usage multiselect:true option
                    if ($.isArray(selArrayRow)) {
                        i = $.inArray(rowid, selArrayRow);
                        if (i >= 0) {
                            selArrayRow[i] = idPrefix + newId;
                        }
                    }
                    // the next line is required if we use ajaxRowOptions: { async: true }
                    $self.jqGrid("showAddEditButtons");

                }
            }
        }
    };

// set common options which we want to use in inline editing
$.extend(true, $.jgrid.inlineEdit, {
    keys: true,
    afterrestorefunc: function () {
        $(this).jqGrid("showAddEditButtons");
    },
    aftersavefunc: function () {
        $(this).jqGrid("showAddEditButtons");
    },
});

$grid.jqGrid({
    colModel: [
        { name: "id", key: true, width: 100 }, // optional column
        { name: "Name", width: 450, editable: true }
    ],
    // the parameters below are needed to load the grid data from the server
    // we use loadonce: true option below. One can use server side pading instead.
    // see http://stackoverflow.com/a/15979809/315935 for the changes
    url: myTableURL,
    datatype: "json",
    prmNames: {search: null, nd: null, sort: null, rows: null},
    ajaxGridOptions: { contentType: "application/json", headers: azureHeaders },
    jsonReader: {
        repeatitems: false,
        root: function (obj) { return obj; }
    },
    gridview: true,
    autoencode: true,
    loadonce: true,
    // we implement additionally inline editing on double-click.
    // it's optional step in case of usage inlineNav
    ondblClickRow: function (rowid) {
        var $self = $(this);

        $self.jqGrid("editRow", rowid, {
            mtype: "PATCH",
            keys: true,
            url: myTableURL + "/" +
                $.jgrid.stripPref($self.jqGrid("getGridParam", "idPrefix"), rowid)
        });
    },
    // next options are important for inline editing
    ajaxRowOptions: { contentType: "application/json", headers: azureHeaders },
    editurl: myTableURL,
    serializeRowData: function (postData) {
        var dataToSend = $.extend(true, {}, postData); // make copy of post data
        if (dataToSend.hasOwnProperty("oper")) {
            delete dataToSend.oper;
        }
        if (dataToSend.hasOwnProperty("id")) {
            delete dataToSend.id;
        }
        return JSON.stringify(dataToSend);
    },
    rowNum: 2,
    rowList: [2, 5, 10],
    sortname: "Name",
    sortorder: "desc",
    viewrecords: true,
    rownumbers: true,
    height: "auto",
    pager: "#pager"
    caption: "Windows Azure Mobile Services REST API"
}).jqGrid("navGrid", "#pager", { edit: false, add: false, del: false, search: false });
$grid.jqGrid("inlineNav", "#pager", inlineNavParams);
$grid.jqGrid("navButtonAdd", "#pager", {
    caption: $.jgrid.nav.savetext || "",
    title: $.jgrid.nav.savetitle || "Save row",
    buttonicon: "ui-icon-disk",
    id: $grid[0].id + "_ilsave",
    onClickButton: function () {
        var $self = $(this),
            gridIdSelector = $.jgrid.jqID(this.id),
            savedRow = $self.jqGrid("getGridParam", "savedRow"),
            prmNames = $self.jqGrid("getGridParam", "prmNames"),
            editUrl = $self.jqGrid("getGridParam", "editurl"),
            rowid = savedRow != null ? savedRow[0].id : "",
            id = $.jgrid.stripPref($self.jqGrid("getGridParam", "idPrefix"), rowid),
            tmpParams = {};

        if (rowid != null) {
            if ($("#" + $.jgrid.jqID(rowid), "#" + gridIdSelector).hasClass("jqgrid-new-row")) {
                if (!inlineNavParams.addParams.addRowParams.extraparam) {
                    inlineNavParams.addParams.addRowParams.extraparam = {};
                }
                inlineNavParams.addParams.addRowParams.extraparam[prmNames.oper] = prmNames.addoper;
                tmpParams = inlineNavParams.addParams.addRowParams;
            } else {
                if (!inlineNavParams.editParams.extraparam) {
                    inlineNavParams.editParams.extraparam = {};
                }
                inlineNavParams.editParams.extraparam[prmNames.oper] = prmNames.editoper;
                inlineNavParams.editParams.url = editUrl + "/" + id;
                tmpParams = inlineNavParams.editParams;
            }
            if ($self.jqGrid("saveRow", rowid, tmpParams)) {
                $self.jqGrid("showAddEditButtons");
            }
        } else {
            $.jgrid.viewModal("#alertmod", {gbox: "#gbox_" + gridIdSelector, jqm: true});
            $("#jqg_alrt").focus();
        }
    }
});
$("#" + $grid[0].id + "_ilsave").addClass("ui-state-disabled");

How you can see the most complex is the implementation of aftersavefunc callback of the addRowParams parameter. I plan to post later my suggestion to trirand which extends the code of inline editing, but simplify the code of aftersavefunc callback so that it could be just

aftersavefunc: function (rowid, response) {
    return response.responseText ?
        $.parseJSON(response.responseText).id :
        undefined;
}

All other things should jqGrid do internally if the type of the value returned by aftersavefunc is not "undefined".

这篇关于如何实现的Azure移动服务表的内联编辑(编辑)。如何处理错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆