jQuery - jqGrid - submit buttons in each row

2020-08-01 02:14发布

问题:

Using jqGrid 4.5.2 & jQuery 1.9.1. I have a jqGrid in a web page that displays rows of data returned from a query. Each row in the grid will have 2 submit buttons that by default are disabled, but become enabled within the onSelectRow event of the jqGrid.

I am adding the buttons in the code below:

var ids = $("#myGrid").jqGrid("getDataIDs");
for (var i=0;i < ids.length;i++) {
    var cl = ids[i];
    sm = "<input id='resendMsg' style='height:25px;width:65px;' type='submit' value='Re-Send' disabled='true'  />";
    ca = "<input id='cancelMsg' style='height:25px;width:55px;' type='submit' value='Cancel' disabled='true' />";
    $("#myGrid").jqGrid("setRowData",ids[i], {msgAct:sm+ca});
    }

Please note that the submit buttons come up disabled by default.

When a row in the grid is selected, I want the two buttons for that row only to be enabled. Also taking place in the onSelectRow event are where I set variables for use later on.

var gridRow = $(this).jqGrid("getRowData",id);
var srow = $(this).jqGrid("getGridParam","selrow");

Other behavior I want in onSelectRow -

Do not want to be able to click off the row - one of the 2 submit buttons must be clicked to go to another row in the grid. One submit takes one set of action & then resets the grid (nothing is selected & all buttons on all rows are disabled).
The other submit button (a Cancel button) does not take the action in the previous step, but does reset the grid (nothing is selected & all buttons on all rows are disabled).

I've tried various things to enable the buttons on the selected row, but it either enables the first row only, all rows, or no rows. I've looked at the value in srow above & can confirm it has the correct id for the row.

How do you target the submit buttons in the selected row to enable them (and to keep all other buttons in the grid disabled)?

Thanks!

EDIT:

Thanks to @Oleg & his suggestions & follow-up, I was able to resolve my question. @Oleg's responses put me onto the right track.

In the colModel I put the msgAct to get the buttons on each row & associated with that row.

{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' />" 
    }}

In the OnSelectRow, I also used his suggestion to switch off all the buttons in the jqGrid & then switch on the ones in the row I had selected.

// 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");

I also had other code in there to disable any other drop downs on the page, so that only one of three things could happen:

  1. the user can click the Re-Send button
  2. the user can click the Cancel button
  3. the user can click another row on the jqGrid

Since #3 above would trigger another OnSelectRow event, I wanted the user to have to do something with the selected row.

Using @Oleg's suggestion to turn off all & then turn on only the selected row's buttons, I also put the click event code for each of them in the onSelectRow event.

$(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");
    ....do other stuff .....
    ReloadGrid();
    });
$(tr).find("input[name=resendMsg]").click(function() {
    ReSend(gridRow.Col1, gridRow.Col2);
    // disable all resendMsg & cancelMsg buttons in the grid
    $(this).find("input[name=resendMsg]").attr("disabled","disabled");
    $(this).find("input[name=cancelMsg]").attr("disabled", "disabled");
    .... do other stuff ....
    });
},

The grid now does what I want it to do. For example -

  • When the grid loads, all rows in the grid have a msgAct column, and that column has in it a Re-Send and a Cancel button, both of which are present, but greyed out.
  • If Row #3 is selected, Row #3's msgAct Re-Send & Cancel buttons are now activated and can be clicked. All other rows in the grid each have the buttons in those rows still greyed out.
  • If the user clicks either Re-Send or Cancel, the appropriate action for that row in the grid takes place. Re-send adds another row to the grid, while Cancel resets the selection & the grid appears as it did when it was loaded.
  • The only options available to the user are to click Re-Send, Cancel or to select a different row. Selection of a different row then enables the buttons on that row (disabling the ones on the previous selection), and clicking on either of them initiates the appropriate action for that row.

The question now might be - is there a better way to do this?

Thank you @Oleg for your valuable help!

回答1:

The main problem is creating wrong HTML data.

You add buttons with the same ids (id='resendMsg' and id='cancelMsg') in all rows of the grid, but id attribute must be unique over the whole HTML page. If you would try enable the button by indexing it by id you will find probably only the first button having the id. It will by typically buttons from the first row. You can use name attribute instead of id attribute

Another problem is the usage of wrong value for disabled attribute. You should use disabled='disabled' instead of disabled='true' if you want that the code works correctly in all web browsers.

The best way to create such buttons is to use custom formatter. You can add formatter property in the msgAct which would create the buttons directly. The code could be about the following

colModel: [
    ...
    { name: "msgAct", width: 150,
        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'/>"
        }}
],
onSelectRow: function (rowid) {
    var tr = $(this).jqGrid("getInd", rowid, true);

    // first disable all "resendMsg" buttons in the grid
    $(this).find("input[name=resendMsg]").attr("disabled", "disabled");

    // then enable the button from the current row only
    $(tr).find("input[name=resendMsg]").removeAttr("disabled");
},
gridview: true

The answer described advantages of usage gridview: true and custom formatters.