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

时间:2013-05-29 13:35:19

标签: jquery events jqgrid

我之前有一个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仍然与我beforeSelectRowbeforeSelectRow解雇时的ID相同单击该行,这意味着在重新加载整个页面之前,我永远不能选择新行。仅在页面加载时onSelectRow不会触发。

修改

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

loadComplete

1 个答案:

答案 0 :(得分:2)

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

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

更好的方法是为每个按钮设置无个人绑定。可以使用onCellSelectbeforeSelectRow,它将从整个网格上绑定的click处理程序调用。有关代码示例,请参阅the answerthis 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内的提醒替换为您需要的操作。