2013-05-29 38 views
0

我有一个前面的question关于在jqGrid的每一行中有可用的按钮,当选中该行时会激活这些按钮。在@Oleg的帮助下,我能够像我认为的那样工作。jQuery - jqGrid - onSelectRow事件中不需要的行为

但是,在进一步测试中,我发现在该事件中存在不良行为。我发现的是,如果我有一个3行的网格,然后点击第2行(激活按钮),然后(无需点击第2行按钮)单击第3行(取消激活第2行按钮&激活第3行按钮),然后再次改变主意&单击第1行或第2行(无所谓),然后在那个点点然后点击"Re-Send"(提交)按钮,会发生什么情况,发送3次不同的时间。

以下是来自4个行的时间戳,这些行是从1“重新发送”昨天点击写入的。

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次,并且“Cancel”清除选择&没有别的)。

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

我很感激任何想法,意见或建议如何解决此行为。

EDIT

包括对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; 
     } 
    }); 

onSelectRow.click事件移动到loadComplete(Cancel按钮作为测试)后,我试图内外&上面的代码为网格代码之外。它执行相同的任何方式。

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

回答

2

是错误的绑定按钮(使用.clickonSelectRow回调的内部。

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

更好的办法是让没有单独绑定每个按钮。人们可以使用onCellSelectbeforeSelectRow这将从click处理程序绑定整个网格。有关代码示例,请参阅the answerthis one

已更新:我不确定我是否正确理解您的问题,但我希望the demo能证明问题的解决方案。我没有使用任何明确的click处理程序。最重要的变化(如果您使用Internet Explorer,这一点可能很重要)将class='cbox'添加到格式化程序中,以防止return中的the line 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内警报您需要的动作。

+0

将'.click'移动到'loadComplete'帮助它只被调用一次。但是,我注意到'rowID'仍然是它的值,并且不会重置,即使我在'.click'中调用'$(“#myGrid”)。ResetSelection();''事件处理程序移动到'loadComplete'中。这意味着如果我有3行显示和选择第3行,然后点击该行上的取消按钮,'beforeSelectRow'仍然有第3行的ID和除非我重新加载页面,我永远不能选择任何其他行,直到页面重新加载。我已经包含了上面的'beforeSelectRow'代码。 –

+0

@steve_o:你在'beforeSelectRow'里写了关于“重新加载网格”的问题,但是你提出的代码不包含任何触发器reloadGrid。你能否包含显示*你怎么做的代码?你在'setTimeout'里面调用了reloadGrid吗?重新加载之前,你是否重新设置像'lastSel'这样的变量?我不明白你发布的代码的某些部分。为什么你在'jqGridBeforeSelectRow'里面访问'selrow'而不是使用'id'参数? – Oleg

+0

添加了上面的代码。要回答你的问题:我不会在'setTimeout'里面调用reloadGrid。取消点击事件中变量'lastSel'设置为-1。 'jqGridBeforeSelectRow'内的'selrow'用于'console.log'语句中使用的信息。我在'beforeSelectRow'中显示'id',可以看到它没有被重置 - 正在显示'selrow'向我显示所选行已被重置。我不知道'id'如何被重置。 –