我之前有一个question关于在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":"Y-m-d H:i:s"},xmlmap:"Rowset>Row>SendTime",sortable:false},
{name: "msgAct",
width: col4width,
align: "center",
formatter: function() {
return "<input name='resendMsg' style='height:25px;width:65px;' type='submit' value='Re-Send' disabled='disabled' />" +
"<input name='cancelMsg' style='height:25px;width:55px;' type='submit' value='Cancel' disabled='disabled' />"
}}
],
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次,并且“{ {1}}“清除选择&amp;什么都不做”。
我不知道是否可能,但是如果已经选择了某行,是否可以防止后续的Cancel
被解雇?您是否可以清除之前的选择(或重置它)以防止onSelectRow
(以及按钮的单击事件)多次触发?
我很感激有关如何解决此问题的任何想法,意见或建议。
编辑
包括onSelectRow
的代码,如下面的回复中所述。
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
并重新加载网格。代码执行&amp;不会给出错误,但是下次$("#myGrid").resetSelection();
触发时(重新加载网格时),id仍然与我beforeSelectRow
和beforeSelectRow
解雇时的ID相同单击该行,这意味着在重新加载整个页面之前,我永远不能选择新行。仅在页面加载时onSelectRow
不会触发。
修改
以下是“取消”按钮的代码,该按钮现在位于beforeSelectRow
事件内。
loadComplete
答案 0 :(得分:2)
在.click
回调中绑定按钮(使用onSelectRow
)是错误的。
而不是你可以通过在click
内注册loadComplete
事件处理程序来移动代码。您只需将代码从onSelectRow
移至loadComplete
并将$(tr)
替换为$(this)
即可在网格的所有按钮内搜索,而不仅仅是所选行的按钮。您仍然可以在disabled
回调中设置或删除onSelectRow
属性。
更好的方法是为每个按钮设置无个人绑定。可以使用onCellSelect
或beforeSelectRow
,它将从整个网格上绑定的click
处理程序调用。有关代码示例,请参阅the answer和this one。
更新:我不确定我是否正确理解了您的问题,但我希望the demo能够证明问题的解决方案。我没有使用任何明确的click
处理程序。最重要的更改(如果您使用Internet Explorer可能很重要)是将class='cbox'
添加到格式化程序以防止the line jqGrid代码中的return
。代码中最重要的部分是
colModel: [
{ name: "text", width: 500 },
{ name: "msgAct", width: 150,
formatter: function () {
return "<input name='resendMsg' class='cbox' style='height:25px;width:65px;' type='submit' value='Re-Send' disabled='disabled'/>" +
"<input name='cancelMsg' class='cbox' style='height:25px;width:55px;' type='submit' value='Cancel' disabled='disabled'/>"
}}
],
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
内的提醒替换为您需要的操作。