jQuery – jqGrid – onSelectRow事件中不需要的行为

我之前有一个问题,关于在jqGrid的每一行中都有可用的按钮,这些按钮会在选择行时激活。 在@Oleg帮助下,我能够像我认为的那样让它工作。

然而,在进一步的测试中,我已经在onSelectRow事件中发现了不受欢迎的行为。 我发现如果我有一个有3行的网格,然后我点击第2行(激活按钮),然后(不点击第2行按钮)点击第3行(这将停用第2行按钮&激活第3行按钮),然后再次改变主意并单击第1行或第2行(无关紧要),然后点击"Re-Send" (提交)按钮,会发生的是所选行是重新发送3次。

以下是昨天从“1次重新发送”点击中写入的4行的时间戳。

 2013-05-28 16:49:04.817 2013-05-28 16:49:04.653 2013-05-28 16:49:04.560 2013-05-28 16:49:04.467 

我在页面中添加了一些日志记录并确认它分别调用POST 4,每次点击一次网格中的一行。

以下部分包含我目前拥有jqGrid构建的大多数配置/设置。

 colNames: ["Destination", "Message Text", "Send Time","Message Action"], colModel:[ {name:"Destination",index:"Destination",width:col1width,align:"left", xmlmap:"Rowset>Row>Destination",sortable:false}, {name:"MessageText",index:"MessageText",width:col2width,align:"left",xmlmap:"Rowset>Row>MessageText",sortable:false}, {name:"SendTime",index:"SendTime",width:col3width,align:"center",formatter:"date",formatoptions: {"srcformat":"ISO8601Long", "newformat":"Ymd H:i:s"},xmlmap:"Rowset>Row>SendTime",sortable:false}, {name: "msgAct", width: col4width, align: "center", formatter: function() { return "" + "" }} ], viewrecords: true, caption: capMsg, rownum: 0, height: "100%", width: gridwidth, toolbar: [true, "top"], pager: jQuery("#pager1"), sortname: "SendTime", hidegrid: false, // hides the ability to collapse grid defaults: { altrows: true, recordtext: "View {0} - {1} of {2}", emptyrecords: "No records to view", loadonce: true, pgtext: "Page {0} of {1}" }, 

以下是onSelectRow事件。

 onSelectRow: function(id) { var tr = $(this).jqGrid("getInd",id,true); var gridRow = $(this).jqGrid("getRowData",id); var srow = $(this).jqGrid("getGridParam","selrow"); // disable all resendMsg & cancelMsg buttons in the grid $(this).find("input[name=resendMsg]").attr("disabled","disabled"); $(this).find("input[name=cancelMsg]").attr("disabled", "disabled"); // now enable the buttons for the current row only $(tr).find("input[name=resendMsg]").removeAttr("disabled"); $(tr).find("input[name=cancelMsg]").removeAttr("disabled"); // disable dropdowns & sendMsg submit button // catch the Cancel button click $(tr).find("input[name=cancelMsg]").click(function() { // disable all resendMsg & cancelMsg buttons in the grid $(this).find("input[name=resendMsg]").attr("disabled","disabled"); $(this).find("input[name=cancelMsg]").attr("disabled", "disabled"); // enable the dropdowns & clear the selection, reload grid ReloadGrid(); }); // catch the Re-Send button click $(tr).find("input[name=resendMsg]").click(function() { ReSendMessage(gridRow.Destination, gridRow.MessageText); // disable all resendMsg & cancelMsg buttons in the grid $(this).find("input[name=resendMsg]").attr("disabled","disabled"); $(this).find("input[name=cancelMsg]").attr("disabled", "disabled"); // enable the dropdowns, clear the selection and exit $("#myGrid").jqGrid("resetSelection"); }); }, 

和jqGrid代码的其余部分:

 gridview: true, xmlReader: { root: "Rowsets", row: "Row", repeatitems: false, id: "SendTime" }, loadComplete: function() { // increase row height $("td",".jqgrow").height(40); // data grid rows // alternate background of every other row $("tr.jqgrow:odd").css({"background-color": "#DDDDDC", "background-image": "none"}); $("th.ui-th-column").css("font-weight","bold"); } }); 

这就像onSelectRow事件正在累积点击次数然后调用click事件的函数,但是多次选择了一行但没有点击按钮。

我已经测试过,如果我单击一行,然后单击任一提交按钮,它将按预期处理(“ Re-Send ”提交行1次,“ Cancel ”清除选择&别无其他)。

我不知道是否可能,但是如果已经选择了一行,你可以阻止后续的onSelectRow触发吗? 你能清除之前的选择(或重置它)以防止onSelectRow (以及按钮的click事件)多次触发吗?

我很感激有关如何解决此问题的任何想法,意见或建议。

编辑

包括beforeSelectRow的代码,如下面的响应中所述。

 $("#myGrid").bind("jqGridBeforeSelectRow", function(e, id, eventOriginal) { var gsr = $("#myGrid").jqGrid("getGridParam","selrow"); console.log(" **** beforeSelectRow - (before if) lastSel = " + lastSel + " id = " + id + " gsr = " + gsr); if (id && id !== lastSel) { console.log("id && id !== lastSel"); console.log(" id = " + id + " lastSel = " + lastSel); }; if (id !== lastSel) { if (lastSel == -1) { // first time thru lastSel = id; console.log(" **** beforeSelectRow - first time thru - new val = " + lastSel + " gsr = " + gsr); return true; } else { console.log(" **** beforeSelectRow - lastSel - " + lastSel + "  id = " +id + " gsr = " + gsr); return false; } } else { console.log(" **** beforeSelectRow - otherwise they matched - lastSel = " + lastSel + " id = " + id + " gsr = " + gsr); return true; } }); 

.click事件从onSelectRow移动到loadComplete (作为测试的Cancel按钮)后,我在网格代码的内部和外部尝试了上述代码。 它的执行方式相同。

问题是Cancel按钮应该重置选择$("#myGrid").resetSelection(); 并重新加载网格。 代码执行并且没有给出错误,但是在下一次onSelectRow触发时(重新加载网格时),id仍然与beforeSelectRowonSelectRow在我单击行时触发时相同,这意味着在重新加载整个页面之前,我永远无法选择新行。 仅在页面加载时才会触发beforeSelectRow

编辑

以下是“取消”按钮的代码,该按钮现在位于loadComplete事件内。

 // catch the Cancel button click $(this).find("input[name=cancelMsg]").click(function() { // disable all resendMsg & cancelMsg buttons in the grid $(this).find("input[name=resendMsg]").attr("disabled","disabled"); $(this).find("input[name=cancelMsg]").attr("disabled", "disabled"); // enable the dropdowns & clear the selection, reload grid console.log("ReloadGrid (inside Cancel function) "); lastSel = -1; $("#myGrid").trigger("reloadGrid"); 

onSelectRow回调中绑定按钮(使用.click )是错误的。

而不是你可以通过在loadComplete注册click事件处理程序来移动代码。 您可以将代码从onSelectRow移动到loadComplete并将$(tr)替换$(tr) $(this)以搜索网格的所有按钮内部,而不仅仅是所选行的按钮。 您仍然可以在onSelectRow回调中设置或删除disabled属性。

更好的方法是不对每个按钮进行单独绑定 。 可以使用onCellSelectonCellSelect ,它将从整个网格上绑定的click处理程序调用。 请参阅答案和代码示例。

更新 :我不确定我是否正确理解你的问题,但我希望该演示能够certificate问题的解决方案。 我没有使用任何明确的click处理程序。 最重要的更改(如果您使用Internet Explorer可能很重要)是将class='cbox'添加到格式化程序以防止在jqGrid代码行中返回。 代码中最重要的部分如下

 colModel: [ { name: "text", width: 500 }, { name: "msgAct", width: 150, formatter: function () { return "" + "" }} ], onSelectRow: function (rowid) { var tr = $(this).jqGrid("getInd", rowid, true); $(this).find("input[name=resendMsg],input[name=cancelMsg]").attr("disabled", "disabled"); $(tr).find("input[name=resendMsg],input[name=cancelMsg]").removeAttr("disabled"); }, beforeSelectRow: function (rowid, e) { var $self = $(this), $td = $(e.target).closest("td"), iCol = $.jgrid.getCellIndex($td[0]), name = $(e.target).attr("name"); if (this.p.colModel[iCol].name === "msgAct") { if (name === "resendMsg") { alert("'Re-Send' button clicked in the row with id=" + rowid + "\ntext in the row =\"" + $self.jqGrid("getCell", rowid, "text") + "\""); } else if (name === "cancelMsg") { alert("'Cancel' button clicked in the row with id=" + rowid); setTimeout(function () { $self.trigger("reloadGrid"); }, 50); } } return true; } 

您可以将beforeSelectRow中的警报替换为您需要的操作。