jqGrid - customizing the multi-select option (restrict single selection and adding custom events)
- by Renso
Goal:
Using the jgGrid to enable a selection of a checkbox for row selection - which is easy to set in the jqGrid - but also only allowing a single row to be selectable at a time while adding events based on whether the row was selected or de-selected.
Environment:
jQuery 1.4.4
jqGrid 3.4.4a
Issue:
The jqGrid does not support the option to restrict the multi-select to only allow for a single selection. You may ask, why bother with the multi-select checkbox function if you only want to allow for the selection of a single row? Good question, as an example, you want to reserve the selection of a row to trigger another kind of event and use the checkbox multi-select to handle a different kind of event; in other words, when I select the row I want something entirely different to happen than when I select to check off the checkbox for that row.
Also the setSelection method of the jqGrid is a toggle and has no support for determining whether the checkbox has already been selected or not, So it will simply act as a switch - which it is designed to do - but with no way out of the box to only check off the box (as in not to de-select) rather than act like a switch.
Furthermore, the getGridParam('selrow') does not indicate if the row was selected or de-selected, which seems a bit strange and is the main reason for this blog post.
Solution:
How this will act:
When you check off a multi-select checkbox in the gird, and then commence to select another row by checking off that row's multi-select checkbox - I'm not talking there about clicking on the row but using the grid's multi-select checkbox - it will de-select the previous selection so that you are always left with only a single selection.
Furthermore, once you select or de-select a multi-select checkbox, fire off an event that will be determined by whether or not the row was selected or de-selected, not just merely clicked on. So if I de-select the row do one thing but when selecting it do another.
Implementation (this of course is only a partial code snippet):
multiselect: true,
multiboxonly: true,
onSelectRow: function (rowId) {
var gridSelRow = $(item).getGridParam('selrow');
var s;
s = $(item).getGridParam('selarrrow');
if (!s || !s[0]) {
$(item).resetSelection();
$('#productLineDetails').fadeOut();
lastsel = null;
return;
}
var selected = $.inArray(rowId, s) != -1;
if (selected) {
$('#productLineDetails').show();
}
else {
$('#productLineDetails').fadeOut();
}
if (rowId && rowId !== lastsel && selected) {
$(item).GridToForm(gridSelRow, '#productLineDetails');
if (lastsel) $(item).setSelection(lastsel, false);
}
lastsel = rowId;
},
In the example code above:
The "item" property is the id of the jqGrid.
The following to settings ensure that the jqGrid will add the new column to select rows with a checkbox and also the not allow for the selection by clicking on the row but to force the user to have to click on the multi-select checkbox to select the row:
multiselect: true,
multiboxonly: true,
Unfortunately the var gridSelRow = $(item).getGridParam('selrow') function will only return the row the user clicked on or rather that the row's checkbox was clicked on and NOT whether or not it was selected nor de-selected, but it retrieves the row id, which is what we will need.
The following piece get's all rows that have been selected so far, as in have a checked off multi-select checkbox:
var s;
s = $(item).getGridParam('selarrrow');
Now determine if the checkbox the user just clicked on was selected or de-selected:
var selected = $.inArray(rowId, s) != -1;
If it was selected then show a container "#productLineDetails", if not hide that container away.
The following instruction populates a form with the grid data using the built-in GridToForm method (just mentioned here as an example) ONLY if the row has been selected and NOT de-selected but more importantly to de-select any other multi-select checkbox that may have been selected:
if (rowId && rowId !== lastsel && selected) {
$(item).GridToForm(gridSelRow, '#productLineDetails');
if (lastsel) $(item).setSelection(lastsel, false);
}