1

我以前有一个问题,即在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 事件正在累积点击次数然后调用点击事件的函数,但是多次选择一行但未点击按钮。

不过,我已经测试过,如果我单击一行,然后单击任一提交按钮,它会按预期进行处理(“ Re-Send”提交该行 1 次,“ 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事件从移动onSelectRowloadComplete(对于取消按钮作为测试)后,我在网格代码的内部和外部尝试了上述代码。无论哪种方式,它都执行相同的操作。

问题是该Cancel按钮应该重置选择$("#myGrid").resetSelection();并重新加载网格。代码执行 & 没有给出错误,但是下一次beforeSelectRow触发(重新加载网格时),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");
4

1 回答 1

2

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

您可以使用clickloadComplete. 您可以将代码从onSelectRowtoloadComplete和 replace $(tr)to移动到网格的所有$(this)按钮内部,而不仅仅是选定行的按钮。您仍然可以在回调中设置或删除属性。disabledonSelectRow

更好的是不为每个按钮单独绑定。可以只使用onCellSelect或从绑定在整个网格上beforeSelectRow的处理程序调用。有关代码示例,请参见答案这个click

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

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为您需要的操作。

于 2013-06-03T05:29:20.833 回答