JQuery - jqGrid - unwanted behavior in onSelectRow event

I had a previous question regarding the presence of buttons in each jqGrid row that would activate when a row was selected. With @Oleg I was able to get it to work, as I thought it should be.

However, upon further testing, I found unwanted behavior in this onSelectRow event. I found 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 buttons on row 2) click on row 3 (which deactivates the buttons of row 2 and activates the buttons 3 -th line), and again change the mind and click line 1 or 2 (it does not matter), and at the THAT point, click the "Re-Send" button, which happens, the selected line is then re-sent 3 times.

Below are the timestamps of the 4 lines that were written with 1 “Resend”. Click.

 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 

I put a few entries on the page and confirmed that it calls POST 4 times in a row, once for each click on a row in the grid.

The following sections contain most of the settings / settings that I currently have when jqGrid is created.

 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":"Ymd 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}" }, 

The following is the onSelectRow event.

 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"); }); }, 

and the rest of the jqGrid 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"); } }); 

This is similar to the onSelectRow event, which accumulates the number of clicks and then calls the click event functions, however, a row was selected many times in a row, but the button was not pressed.

I tested, though, if I click on a line and then click on any of the submit buttons, it is processed as expected (" Re-Send " sends the line 1 time, and " Cancel " clears the selection and does nothing).

I do not know if this is possible, but can you prevent subsequent onSelectRow firing if the row already selected? Can you remove the previous selection (or reset it) to prevent onSelectRow (and the click event for the button) several times?

I would appreciate any thoughts, comments, or suggestions on how to fix this behavior.

EDIT

Including code for beforeSelectRow as indicated in the answer below.

 $("#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; } }); 

Moving the .click event from onSelectRow to loadComplete (for the Cancel button as a test), I tried the above code both inside and outside the grid code. He does the same thing.

The problem is that the Cancel button should reset select $("#myGrid").resetSelection(); and reload the grid. The code executes and does not give an error, but the next time when beforeSelectRow triggered (when the grid reloads), the identifier remains the same as when running beforeSelectRow and onSelectRow , when I pressed a line, which means that I can never select a new line before until the whole page is reloaded. Only on page loading when beforeSelectRow does not fire.

EDIT

Below is the Cancel button code, which is now inside the loadComplete event.

 // 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"); 
0
jquery events jqgrid
source share
1 answer

Incorrect button binding (use .click ) inside onSelectRow .

Instead, you can move the code registering the click event handler inside loadComplete . You can simply move the code from onSelectRow to loadComplete and replace $(tr) with $(this) to search inside all the grid buttons, not just the buttons of the selected row. You can set or remove the disabled attribute inside the onSelectRow .

It would be better to make an individual binding for each button. You can simply use onCellSelect or beforeSelectRow , which will be called from the click handler associated with the entire grid. See the answer and this for code examples.

UPDATED . I'm not sure I understand your problem correctly, but I hope the demo will demonstrate a solution to the problem. I did not use an explicit click handler. The most important change (which may be important when using Internet Explorer) is to add class='cbox' to the formatter to prevent return in jqGrid's line of code. The most important part of the code below

 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; } 

You can replace the warnings inside beforeSelectRow with the desired action.

+2
source share

All Articles