This is a follow-up article to jQuery DataTables – How to add a checkbox column describing a simple solution to add checkboxes to a table. However proposed solution worked for a table using client-side processing mode only. This article offers universal solution that would work both in client-side and server-side processing modes.
It is loosely based on DataTables example – Row selection but adds extra functionality such as ability to use checkboxes for row selection and other minor improvements.
Example
Example below shows a data table using client-side processing mode where data is received from the server using Ajax. However the same code could be used if data table is switched into server-side processing mode with 'serverSide': true
initialization option.
//
// Updates "Select all" control in a data table
//
function updateDataTableSelectAllCtrl(table){
var $table = table.table().node();
var $chkbox_all = $('tbody input[type="checkbox"]', $table);
var $chkbox_checked = $('tbody input[type="checkbox"]:checked', $table);
var chkbox_select_all = $('thead input[name="select_all"]', $table).get(0);
// If none of the checkboxes are checked
if($chkbox_checked.length === 0){
chkbox_select_all.checked = false;
if('indeterminate' in chkbox_select_all){
chkbox_select_all.indeterminate = false;
}
// If all of the checkboxes are checked
} else if ($chkbox_checked.length === $chkbox_all.length){
chkbox_select_all.checked = true;
if('indeterminate' in chkbox_select_all){
chkbox_select_all.indeterminate = false;
}
// If some of the checkboxes are checked
} else {
chkbox_select_all.checked = true;
if('indeterminate' in chkbox_select_all){
chkbox_select_all.indeterminate = true;
}
}
}
$(document).ready(function (){
// Array holding selected row IDs
var rows_selected = [];
var table = $('#example').DataTable({
'ajax': {
'url': '/lab/articles/jquery-datatables-checkboxes/ids-arrays.txt'
},
'columnDefs': [{
'targets': 0,
'searchable': false,
'orderable': false,
'width': '1%',
'className': 'dt-body-center',
'render': function (data, type, full, meta){
return '<input type="checkbox">';
}
}],
'order': [[1, 'asc']],
'rowCallback': function(row, data, dataIndex){
// Get row ID
var rowId = data[0];
// If row ID is in the list of selected row IDs
if($.inArray(rowId, rows_selected) !== -1){
$(row).find('input[type="checkbox"]').prop('checked', true);
$(row).addClass('selected');
}
}
});
// Handle click on checkbox
$('#example tbody').on('click', 'input[type="checkbox"]', function(e){
var $row = $(this).closest('tr');
// Get row data
var data = table.row($row).data();
// Get row ID
var rowId = data[0];
// Determine whether row ID is in the list of selected row IDs
var index = $.inArray(rowId, rows_selected);
// If checkbox is checked and row ID is not in list of selected row IDs
if(this.checked && index === -1){
rows_selected.push(rowId);
// Otherwise, if checkbox is not checked and row ID is in list of selected row IDs
} else if (!this.checked && index !== -1){
rows_selected.splice(index, 1);
}
if(this.checked){
$row.addClass('selected');
} else {
$row.removeClass('selected');
}
// Update state of "Select all" control
updateDataTableSelectAllCtrl(table);
// Prevent click event from propagating to parent
e.stopPropagation();
});
// Handle click on table cells with checkboxes
$('#example').on('click', 'tbody td, thead th:first-child', function(e){
$(this).parent().find('input[type="checkbox"]').trigger('click');
});
// Handle click on "Select all" control
$('thead input[name="select_all"]', table.table().container()).on('click', function(e){
if(this.checked){
$('#example tbody input[type="checkbox"]:not(:checked)').trigger('click');
} else {
$('#example tbody input[type="checkbox"]:checked').trigger('click');
}
// Prevent click event from propagating to parent
e.stopPropagation();
});
// Handle table draw event
table.on('draw', function(){
// Update state of "Select all" control
updateDataTableSelectAllCtrl(table);
});
// Handle form submission event
$('#frm-example').on('submit', function(e){
var form = this;
// Iterate over all selected checkboxes
$.each(rows_selected, function(index, rowId){
// Create a hidden element
$(form).append(
$('<input>')
.attr('type', 'hidden')
.attr('name', 'id[]')
.val(rowId)
);
});
});
});
In addition to the above code, the following Javascript library files are loaded for use in this example:
//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js//cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js
table.dataTable.select tbody tr,
table.dataTable thead th:first-child {
cursor: pointer;
}
The following CSS library files are loaded for use in this example to provide the styling of the table:
//cdn.datatables.net/1.10.7/css/jquery.dataTables.min.cssOther examples
Problem
The problem with handling checkboxes varies based on DataTables initialization settings. In server-side processing mode ('serverSide':true
) elements <input type="checkbox">
would exist for current page only. Once page is changed, the checked state of the checkboxes would not be preserved. In client-side processing mode, the checked state of checkbox is preserved, but only current page is accessible in DOM, all other pages has to be accessible through DataTables API.
Solution
The solution is to create a global variable (rows_selected
in our example) to store a list of selected row IDs and use it to display checkbox state and highlight selected rows.
Highlights
Javascript
-
Storing selected row IDs
// Array holding selected row IDs var rows_selected = [];
Define array holding selected row IDs.
-
Columns definition
'columnDefs': [{ 'targets': 0, 'searchable': false, 'orderable': false, 'width': '1%', 'className': 'dt-body-center', 'render': function (data, type, full, meta){ return '<input type="checkbox">'; } }],
Option columnsDef is used to define appearance and behavior of the first column (
'targets': 0
).Searching and ordering of the column is not needed so this functionality is disabled with searchable and orderable options.
To center checkbox in the cell, internal DataTables CSS class
dt-body-center
is used.Option render is used to prepare the checkbox control for being displayed in each cell of the first column.
-
Initial sorting order
'order': [[1, 'asc']],
By default, DataTables sorts table by first column in ascending order. By using order option we select another column to perform initial sort.
-
Row draw callback
'rowCallback': function(row, data, dataIndex){ // Get row ID var rowId = data[0]; // If row ID is in the list of selected row IDs if($.inArray(rowId, rows_selected) !== -1){ $(row).find('input[type="checkbox"]').prop('checked', true); $(row).addClass('selected'); }
Callback function rowCallback will be called before each row draw and is useful to indicate the state of the checkbox and row selection. We use internal DataTables CSS class
selected
.Important
Please note that in the example above row ID is stored as first element of the row data array and is being retrieved by using the following code.
// Get row ID var rowId = data[0];
If you’re using data structure other than described in the article, adjust this and other similar lines accordingly.
-
Form submission
// Handle form submission event $('#frm-example').on('submit', function(e){ var form = this; // Iterate over all selected checkboxes $.each(rows_selected, function(index, rowId){ // Create a hidden element $(form).append( $('<input>') .attr('type', 'hidden') .attr('name', 'id[]') .val(rowId) ); }); });
When table is enhanced by jQuery DataTables plug-in, only visible elements exist in DOM. That is why by default form submits checkboxes from current page only.
To submit selected checkboxes from all pages we need to iterate over
rows_selected
array and add a hidden<input>
element to the form with some name (id[]
in our example) and row ID as a value. This will allow all the data to be submitted.For more information on submitting the form elements in a table powered by jQuery DataTables, please see jQuery DataTables: How to submit all pages form data.
HTML
<table id="example" class="display select" cellspacing="0" width="100%">
Additional CSS class select
is used to change cursor when hovering over table rows for specific tables only.
CSS
table.dataTable.select tbody tr,
table.dataTable thead th:first-child {
cursor: pointer;
}
Display cursor in the form of a hand for table rows and first cell in the table heading where “Select all” control is located.
Thanks for your great job.
I’m using these two files:
https://gyrocode.github.io/jquery-datatables-checkboxes/1.2.7/js/dataTables.checkboxes.js
https://gyrocode.github.io/jquery-datatables-checkboxes/1.2.7/css/dataTables.checkboxes.css
How can I get “selected rows ids” ?
Use column().checkboxes.selected() API method.
Hey,
I have an issue I can’t resolve:
When I check a box and I change page using pagination, all the checkboxes on the next page are checked.
I especially created a directory and added your code into a new file that I called index.html with needed links of js and css, still the bug remain.
The only thing I change is the Ajax part, instead of using this :
I am using this (I have a var called dataSet with an initialized list, it is working correctly):
Nevermind, I just resolved the issue, in my dataSet, there was not any ID defined.
Now it is working great !
Glad that you’ve resolved it, I just posted an answer before seeing your second comment. Take a look at jQuery DataTables Checkboxes plug-in, it may be easier to use.
HI,
Even I have given ID blow error is throwing.
DataTables warning: table id=example – Requested unknown parameter ‘1’ for row 0. For more information about this error, please see http://datatables.net/tn/4
{
“ID”:61,
“UserName”:”LAF-000098″,
“FullName”:”sandstruck test”,
“Email”:”123@qwer.vbn”
},
var table = $(‘#example’).DataTable({
‘ajax’: {
‘url’: ‘/WLC/AdminInterfaces/ClientResources/css/ids-arrays.txt’
},
“columns”: [
{ data: “ID” },
{ data: “UserName” },
{ data: “FullName” },
{ data: “Email” }
],
‘columnDefs’: [{
‘targets’: 0,
‘searchable’: false,
‘orderable’: false,
‘width’: ‘1%’,
‘className’: ‘dt-body-center’,
‘render’: function (data, type, full, meta) {
return ”;
},
}],
‘order’: [[1, ‘asc’]],
‘rowCallback’: function (row, data, dataIndex) {
// Get row ID
var rowId = data[0];
// If row ID is in the list of selected row IDs
if ($.inArray(rowId, rows_selected) !== -1) {
$(row).find(‘input[type=”checkbox”]’).prop(‘checked’, true);
$(row).addClass(‘selected’);
}
}
});
This may occur if your dataset doesn’t have unique values for the column containing checkboxes. Notice that Ajax response in my examples contains 1, 2, 3 as the values for the first column containing checkboxes.
Overall I recommend to use jQuery DataTables Checkboxes plugin instead as it simple to use and supports various jQuery DataTables extensions as well.
Thank you !
Hi,
In this specific example for select rows using checkbox, you have handled the click event of checkbox for select the data table row. In that event, you have handled the code by adding/removing “selected” class of data table row. Is actually displayed that row is selected but it is not actually consider as selected row by data table functions.
Proper way to select or deselect row is use the jquery Datatable function as below link.
https://datatables.net/reference/api/row().select()
https://datatables.net/reference/api/rows().deselect()
So I just replaced the code for selecting/deselecting rows on the click event of checkboxes as below,
Hello how can i get the id of the checkboxes , currenly using MS server databse in jquery datatable and when i hit the submit button the id comes out empty
Possibly you’re not providing data initially for the column containing checkboxes. Or not retrieving the data from appropriate request parameter. It is hard to say without seeing the actual code.
How can i pass the id of the checkbox to a ASP.net MVC Controller , having a tough time with that
Dear,
I am also waiting for the answer. I am facing so much difficulty with this in MVC ASP.Net.
Hope someone will post complete answer. Pray to the god.
What if the ajax response is array with key name? What should i change this part data[0] with? I’ve tried by change to data[‘id’], but it doesn’t work.
Yes, it should be something like
data['id']
if “id” is the property holding unique value for the checkbox.I have another problem when i try to set initial value of checkbox. It’s checked, but when i submit the form, it’s return null
Can you share the code to set the initial value of checkbox? I am trying to do the same without any lucks.
What i was trying to accomplished was providing the user the ability to edit their data so when they load the table the second time I wanted to check the checkboxes based on their saved data.
Fill the array
rows_selected
with appropriate IDs.For example:
See this example for demonstration.
Generally I recommend using jQuery DataTables Checkboxes plugin for adding support for checkboxes in a table powered by jQuery DataTables. See this example demonstrating how to select checkboxes on page load with jQuery DataTables Checkboxes plugin.
Kindly, is there any sample project I can download and see full? Preferably in ASP.NET MVC Project sample? Please help me.
After form posted event, returned all columns checked.
This line is causing problems during post processing.
I found the solution to interpret it:
Most likely you’re using the code not as intended in the original article. I recommend using jQuery DataTables Checkboxes plugin for adding support for checkboxes in a table powered by jQuery DataTables.
Heelo Mr. Michael.. I have a case in selected data for a row…for example , I can’t bring column of office or salary..how to escape it (bring into data submitted)?
Please Help Me ….
Is any options to select all checkboxes only when click the checkbox select_all , not td element?
Please help me
Just remove event handler for
td
elements. See updated example for demonstration.Can you share the codes to set the initial value of checkbox(s)?
What i was trying to accomplished was providing the user the ability to edit their data so when they load the table the second time I wanted to check the checkboxes based on their saved data.
Show/Hide rows on custom button click
We need to create a click button to hide and show selected and unselected row only.
For example:
1. If click to “Check Selection” button, then show only selected rows and Unselected rows hide.
2. If click to “Uncheck Selection” button, then show only unselected rows and selected rows hide.
See this example demonstrating how to filter rows based on the state of checkboxes in a table powered by jQuery DataTables. I also added example demonstrating how to do the same with Checkboxes plug-in.
Hi Michael
I’m using your jQuery DataTables Checkboxes plugin. Great work by the way. I manage to get the selected elements (unique ids in my case) like so:
I send those by Jquery Ajax call to an API which deletes the data in the database. On Success I want to delete the selected rows.
I know how to delete all the rows like so:
Now I would like to only delete the selected rows. But everything I try doesn’t work as expected. Any help is appreciated.
Stephan, thanks! Please see https://github.com/gyrocode/jquery-datatables-checkboxes/issues/26 and this example for a possible workaround.
Basically, use
table.rows({ selected: true }).deselect().remove().draw();
to remove selected rows.Thank you! I checked your fiddle. I tried your proposed solution. It didn’t work. I get this error:
Uncaught TypeError: $(…).DataTable(…).rows(…).deselect is not a function
Just to be sure I implemented this as well:
I get, not to my surprise, the same error. Do you have an idea what I might make wrong? The checkbox and datatable plugin works fine.
It looks like you’re missing Select extension. If you don’t want to select rows or use that extension, I would need to work on alternative solution to that problem.
I have a problem. I can’t loop to get row values from datatable row when I click on submit button. For example:
And I want to get value from row. But I only get: “x ros selected”. I can’t get the value from each row.
Great job, Michael. It saved me lots of work.
Hi sir, i am a beginner can you please tell me how to change checkboxes into radio button for selecting one row
how do count the number of checkboxes that are checked ?
i would like to do a if checkbox.checked count < 1 then button is disable
Questions I have a jQuery datable with IDs hidden in checkboxes in this order
(0)3
(1)1
(2)2
Once I hit the select all checkbox and send them to my Mvc action result they arrive like this
(0)1
(1)2
(2)3
Why does the select all check box change my array order
Very good. Thanks.
I change .DataTable for my process.
Thanks for Post. It is very helpful..