title: jQuery - jqGrid - undesired behavior in onSelectRow event
body: <p>I had a previous <a href="https://stackoverflow.com/questions/16717459/jquery-jqgrid-submit-buttons-in-each-row">question</a> regarding having buttons available in each row of a jqGrid, that would activate when the row was selected.  With help from <code>@Oleg</code> I was able to get it to work like I thought it should.</p>
  
  <p>In further testing however, I have identified undesired behavior in that <code>onSelectRow</code> event.  What I found was that if I have a grid with 3 rows in it, and I click on row 2 (which activates the buttons), then (without clicking on the row 2 buttons) click on row 3 (which deactivates row 2 buttons &amp; activates row 3 buttons), and change my mind again &amp; click row 1 or 2 (doesn't matter), and at <strong>THAT</strong> point then click the <code>"Re-Send"</code> (submit) button, what happens is that the selected row is then re-sent 3 separate times.  </p>
  
  <p>Following are the timestamps from 4 rows that were written from 1 "Re-Send" click yesterday.</p>
  
  <pre><code>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
  </code></pre>
  
  <p>I put some logging in the page &amp; confirmed that it does call the POST 4 separate times, once for each click on a row in the grid.  </p>
  
  <p>The following sections contain most of the configuration/settings I currently have where the jqGrid gets built.</p>
  
  <pre><code>colNames: ["Destination", "Message Text", "Send Time","Message Action"],
  colModel:[
      {name:"Destination",index:"Destination",width:col1width,align:"left", xmlmap:"Rowset&gt;Row&gt;Destination",sortable:false},
      {name:"MessageText",index:"MessageText",width:col2width,align:"left",xmlmap:"Rowset&gt;Row&gt;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&gt;Row&gt;SendTime",sortable:false},
      {name: "msgAct",
      width: col4width,
      align: "center",
      formatter: function() {
          return "&lt;input name='resendMsg' style='height:25px;width:65px;' type='submit' value='Re-Send' disabled='disabled' /&gt;" +
                 "&lt;input name='cancelMsg' style='height:25px;width:55px;' type='submit' value='Cancel' disabled='disabled' /&gt;" 
              }}
      ],
  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}"
      },
  </code></pre>
  
  <p>Following is the <code>onSelectRow</code> event.</p>
  
  <pre><code>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 &amp; 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 &amp; sendMsg submit button
      // catch the Cancel button click
      $(tr).find("input[name=cancelMsg]").click(function() {
          // disable all resendMsg &amp; cancelMsg buttons in the grid
          $(this).find("input[name=resendMsg]").attr("disabled","disabled");
          $(this).find("input[name=cancelMsg]").attr("disabled", "disabled");
          // enable the dropdowns &amp; 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 &amp; 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");
          });
      },
  </code></pre>
  
  <p>and the remainder of the jqGrid code:</p>
  
  <pre><code>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");
      }
  });
  </code></pre>
  
  <p>It's like the onSelectRow event is accumulating the number of clicks &amp; then calling the click event's functions however many times a row was selected but a button wasn't clicked.  </p>
  
  <p>I have tested though, that if I click on a row, and then click on either of the submit buttons, that it processes as expected (a "<code>Re-Send</code>" submits the row 1 time, and a "<code>Cancel</code>" clears the selection &amp; does nothing else).  </p>
  
  <p>I don't know if it is possible, but can you prevent a subsequent <code>onSelectRow</code> from firing if a row's already selected?  Can you clear the previous selection (or reset it) to prevent the <code>onSelectRow</code> (and the click event for the button) from firing multiple times?  </p>
  
  <p>I'd appreciate any thoughts, comments or suggestions as to how to fix this behavior.  </p>
  
  <p><strong>EDIT</strong>  </p>
  
  <p>Including the code for <code>beforeSelectRow</code> as noted in a response below.</p>
  
  <pre><code>$("#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 &amp;&amp; id !== lastSel) {
          console.log("id &amp;&amp; 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 + "   &lt;&gt;  id = "  +id + "    gsr = " + gsr);
              return false;
              }
          }
      else {
          console.log(" ****  beforeSelectRow - otherwise they matched -  lastSel  = " + lastSel + "     id = " + id + "  gsr = " + gsr);
          return true;
          }
      });
  </code></pre>
  
  <p>After moving the <code>.click</code> event from the <code>onSelectRow</code> into the <code>loadComplete</code> (for the Cancel button as a test), I tried the above code both inside &amp; outside the code for the grid.  It performs the same either way.</p>
  
  <p>The issue is that the <code>Cancel</code> button is supposed to reset the selection <code>$("#myGrid").resetSelection();</code> and reload the grid.  The code executes &amp; doesn't give an error, but the very next time <code>beforeSelectRow</code> fires (when the grid is reloaded), the id is still the same as it was when <code>beforeSelectRow</code> and <code>onSelectRow</code> fired when I clicked on the row, which means that I can never select a new row until the entire page is reloaded.  Only on page load is when <code>beforeSelectRow</code> doesn't fire.  </p>
  
  <p><strong>EDIT</strong></p>
  
  <p>Following is the code for the Cancel button, which is now located inside the <code>loadComplete</code> event.  </p>
  
  <pre><code>// catch the Cancel button click
  $(this).find("input[name=cancelMsg]").click(function() {
      // disable all resendMsg &amp; cancelMsg buttons in the grid
      $(this).find("input[name=resendMsg]").attr("disabled","disabled");
      $(this).find("input[name=cancelMsg]").attr("disabled", "disabled");
      // enable the dropdowns &amp; clear the selection, reload grid
      console.log("ReloadGrid (inside Cancel function) ");
      lastSel = -1;
      $("#myGrid").trigger("reloadGrid");
  </code></pre>