jqGrid - saving checkbox selected state
The first part of the answer contain the answer on your question. A little improved version of the demo you can find here.
If you don't need to sort by "multiselect" column the demo do what you need. Some small remarks about the demo: The checkbox over the "multiselect" column select/unselect all rows only on the current page. If you want another behavior, the code will be even more simple. I included in the demo selection of 3 items directly by loading the grid. Two items will be selected on the first page and one item on the second page. In some situation the behavior can be interesting. If you don't need this you should just comment the line idsOfSelectedRows = ["8", "9", "10"];
Below you will find the most important parts of the code of the demo
var $grid = $("#list"), idsOfSelectedRows = [],
updateIdsOfSelectedRows = function (id, isSelected) {
var index = $.inArray(id, idsOfSelectedRows);
if (!isSelected && index >= 0) {
idsOfSelectedRows.splice(index, 1); // remove id from the list
} else if (index < 0) {
idsOfSelectedRows.push(id);
}
};
// initialize selection
idsOfSelectedRows = ["8", "9", "10"];
$grid.jqGrid({
datatype: 'local',
// ... other parameters
multiselect: true,
onSelectRow: updateIdsOfSelectedRows,
onSelectAll: function (aRowids, isSelected) {
var i, count, id;
for (i = 0, count = aRowids.length; i < count; i++) {
id = aRowids[i];
updateIdsOfSelectedRows(id, isSelected);
}
},
loadComplete: function () {
var $this = $(this), i, count;
for (i = 0, count = idsOfSelectedRows.length; i < count; i++) {
$this.jqGrid('setSelection', idsOfSelectedRows[i], false);
}
}
});
If you want you can consider to hold idsOfSelectedRows
as an additional parameter of jqGrid. Currently there are no validation of jqGrid parameters and you can extend there. The advantage will be persistence of idsOfSelectedRows
together with the corresponding jqGrid.
UPDATED: Free jqGrid fork of jqGrid supports multiPageSelection: true
option which can be combined with multiselect: true
option. It allows to hold the parameter selarrrow
(the list of ids of selected rows) over many pages. By default jqGrid reset the array selarrrow
during paging, but in case of usage multiPageSelection: true, multiselect: true
it doesn't so resetting. Moreover it preselects all rows from selarrrow
array during the building the page. Thus if one fills selarrrow
array with all rowids of the items (all rows over all pages) then the rows will be displayed selected. The user still can deselect some rows and jqGrid will not change the changes made by the user.
The demo, created for the answer, shows the usage of multiPageSelection: true
in free jqGrid. Another answer describes shortly other new options of free jqGrid: multiselectPosition: "right"
, which allows to move the column of multiselect checkboxes to the right, multiselectPosition: "none"
, which allows use multiselect functionality without any multiselect column and hasMultiselectCheckBox
callback, which can be used to create multiselect checkboxes not in all rows of jqGrid.
jqGrid - checkbox editing not able to edit selected row
I think there is a misunderstanding in the usage of formatter: "checkbox", formatoptions: { disabled: false }
. If you creates non-disabled checkboxs in the column of the grid in the way then the user just see the checkbox, which can be clicked and which state can be changed. On the other side nothing happens if the user changes the state of the checkbox. On the contrary the initial state of the checkbox corresponds to input data of the grid, but the changed checkbox makes illusion that the state is changed, but nothing will be done automatically. Even if you use datatype: "local"
nothing is happens and even local data will be changed on click. If you do need to save the changes based on the changing the state of the checkbox then you have to implement additional code. The answer demonstrates a possible implementation. You can change the state of some checkboxes on the corresponding demo, then change the page and go back to the first page. You will see that the state of the checkbox corresponds the lates changes.
Now let us we try to start inline editing (start editRow
) on select the row of the grid. First of all inline editing get the values from the rows (editable columns) using unformatter, saves the old values in internal savedRow
parameter and then it creates new editing controls inside of editable cells on the place of old content. Everything is relatively easy in case of using standard disabled checkbox of formatter: "checkbox"
. jqGrid just creates enabled checkboxs on the place of disabled checkboxs. The user can change the state of the checkboxs or the content of any other editable columns and saves the changes by usage of Enter for example. After that the selected row will be saved and will be not more editable. You can monitor the changes of the state of the checkbox additionally (by usage editoptions.dataEvents
with "change"
event for example) and call saveRow
on changing the state. It's important that the row will be not editable after the saving. If you do need to hold the row editable you will have to call editRow
once more after successful saving of the row. You can call editRow
inside of aftersavefunc
callback of saveRow
, but I recommend you to wrap the call of editRow
inside of setTimeout
to be sure that processing of previous saving is finished. It's the way which I would recommend you.
On the other side if you try to combine enabled checkboxs of formatter: "checkbox"
with inline editing then you will have much more complex processing. It's important that enabled checkbox can be changed first of all before processing of onclick
and onchange
event handlers. The order of 3 events (changing the state of the checkbox, processing of onclick
and processing of onchange
) can be different in different web browsers. If the method editRow
be executing it uses unformatter of checkbox-formatter to get the current state of the checkbox. Based of the value of the state editRow
replace the content of the cell to another content with another enabled checkbox. It can be that the state of the checkbox is already changed, but editRow
interprets the changes state
like the initial state
of the checkbox. In the same way one can call saveRow
only after editRow
. So you can't just use saveRow
inside of change
handler of formatter: "checkbox", formatoptions: { disabled: false }
, because the line is not yet in editing mode.
UPDATED: The corresponding implementation (in case of usage formatter: "checkbox", formatoptions: { disabled: false }
) could be the following:
editurl: "SomeUrl",
beforeSelectRow: function (rowid, e) {
var $self = $(this),
$td = $(e.target).closest("tr.jqgrow>td"),
p = $self.jqGrid("getGridParam"),
savedRow = p.savedRow,
cm = $td.length > 0 ? p.colModel[$td[0].cellIndex] : null,
cmName = cm != null && cm.editable ? cm.name : "Quantity",
isChecked;
if (savedRow.length > 0 && savedRow[0].id !== rowid) {
$self.jqGrid("restoreRow", savedRow[0].id);
}
if (cm != null && cm.name === "W3LabelSelected" && $(e.target).is(":checkbox")) {
if (savedRow.length > 0) {
// some row is editing now
isChecked = $(e.target).is(":checked");
if (savedRow[0].id === rowid) {
$self.jqGrid("saveRow", rowid, {
extraparam: {
W3LabelSelected: isChecked ? "1" : "0",
},
aftersavefunc: function (response) {
$self.jqGrid("editRow", rowid, {
keys: true,
focusField: cmName
});
}
});
}
} else {
$.ajax({
type: "POST",
url: "SomeUrl", // probably just p.editurl
data: $self.jqGrid("getRowData", rowid)
});
}
}
if (rowid) {
$self.jqGrid("editRow", rowid, {
keys: true,
focusField: cmName
});
}
return true; // allow selection
}
See jsfiddle demo http://jsfiddle.net/OlegKi/HJema/190/
jqgrid: multiselect checkbox values
The answer on your question depends on the fork of jqGrid, which you use. I develop free jqGrid fork and implemented multiPageSelection: true
option. One need just fill selarrrow
array (which you can do, for example, inside of beforeProcessing
based on the data returned from the server). Look at the demo created for the answer. It shows that the selarrrow
array contains the ids more as on the current page. On paging or during initial filling free jqGrid set the state of chechboxes based on the selarrrow
array. In the way it works effective like custom formatters, rowattr
or cellattr
.
If you can't upgrade to free jqGrid then you can call setSelection
inside of loadComplete
(see the old answer). It will work slower as in case of usage multiPageSelection: true
, but it will work.
jqgrid: multiselect and disable check (conditional)
I would suggest you to disable some checkboxed from the be selectable with respect of "disabled" attribute. To make full implementation you will need
- set "disabled" inside of
loadComplete
event handle - additionally prevent selection of disabled rows inside
beforeSelectRow
event handle - to have support of "select all" checkbox in the header of the multiselect column implement
onSelectAll
event handle which fix selection of disabled rows.
The corresponding demo can you see here. The most important part of the code is here:
var grid = $("#list10"), i;
grid.jqGrid({
//...
loadComplete: function() {
// we make all even rows "protected", so that will be not selectable
var cbs = $("tr.jqgrow > td > input.cbox:even", grid[0]);
cbs.attr("disabled", "disabled");
},
beforeSelectRow: function(rowid, e) {
var cbsdis = $("tr#"+rowid+".jqgrow > td > input.cbox:disabled", grid[0]);
if (cbsdis.length === 0) {
return true; // allow select the row
} else {
return false; // not allow select the row
}
},
onSelectAll: function(aRowids,status) {
if (status) {
// uncheck "protected" rows
var cbs = $("tr.jqgrow > td > input.cbox:disabled", grid[0]);
cbs.removeAttr("checked");
//modify the selarrrow parameter
grid[0].p.selarrrow = grid.find("tr.jqgrow:has(td > input.cbox:checked)")
.map(function() { return this.id; }) // convert to set of ids
.get(); // convert to instance of Array
}
}
);
UPDATED: Free jqGrid supports hasMultiselectCheckBox
callback, which can be used to create multiselect checkboxes not for all rows of jqGrid. One can use rowattr
to disable some rows additionally. As the result one will get the described above functionality in more simple way. It's recommended to use multiPageSelection: true
option additionally for free jqGrid with local data (datatype: "local"
or loadonce: true
). The option multiPageSelection: true
will hold the array selarrrow
on paging. It allows "pre-select" some rows by filling the corresponding ids inselarrrow
. See UPDATED part of the answer and the answer with the demo for additional information.
Related Topics
How to Search JSON Tree with Jquery
Differencebetween Typeof and Instanceof and When Should One Be Used VS. the Other
Replacing Spaces with Underscores in JavaScript
Need to Cancel Click/Mouseup Events When Double-Click Event Detected
What Does Arrow Function '() => {}' Mean in JavaScript
Facebook How to Check If User Has Liked Page and Show Content
How to Use Nodejs to Open Default Browser and Navigate to a Specific Url
Convert Object Array to Hash Map, Indexed by an Attribute Value of the Object
JavaScript Get Textarea Input via .Value or .Innerhtml
Amazon S3 Direct File Upload from Client Browser - Private Key Disclosure
Split String Only on First Instance of Specified Character
How to Remove a Key from a JavaScript Object
Google Maps API V3 - Multiple Markers on Exact Same Spot
How to Get a JavaScript Object Property Name That Starts with a Number