I am using jQuery datatables. I am getting few values in JSON as columns in datatables. In two of those columns , one has only radio buttons and one has only checkboxes. I want to sort on the basis of checkboxes (like if the checkbox is checked it should appear first) and radio buttons. How can I do that?
See Live DOM ordering example.
/* Create an array with the values of all the checkboxes in a column */
$.fn.dataTable.ext.order['dom-checkbox'] = function ( settings, col )
{
return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
return $('input', td).prop('checked') ? '1' : '0';
} );
}
/* Initialise the table with the required column ordering data types */
$(document).ready(function() {
$('#example').DataTable( {
"columns": [
{ "orderDataType": "dom-checkbox" }
]
} );
} );
Related
In jquery datatable, single check box should be selected.
This link is working fine.
But above link is using jquery.dataTables 1.10.16 version. And I am using jquery.dataTables 1.9.4.
Can the same functionality as listed in example given above be possible with jquery.dataTables 1.9.4 instead of jquery.dataTables 1.10.16?
In the same page which you give the link, there are many explanation about to using "single check" oparetion.
At the end of the listed attachment, you can see the referanced .js file is
https://cdn.datatables.net/select/1.2.5/js/dataTables.select.min.js
In your page, you should add this file referance after dataTable.js.
I think, the version of jquery is not important. The important file is "dataTables.select.js"!
Secondly, you must update your dataTable maker codes like the sample below;
$(document).ready(function() {
$('#example').DataTable( {
columnDefs: [ {
orderable: false,
className: 'select-checkbox',
targets: 0
} ],
select: {
style: 'os',
selector: 'td:first-child' // this line is the most importan!
},
order: [[ 1, 'asc' ]]
} );
} );
UPDATES :
Why dont you try to write your own selector function?
for example;
$(document).ready(function() {
$('#example').DataTable( {
/// put your options here...
} );
$('#example').find("tr").click(function(){ CheckTheRow(this); });
} );
function CheckTheRow(tr){
if($(tr).find("td:first").hasClass("selected")) return;
// get the pagination row count
var activePaginationSelected = $("#example_length").find("select").val();
// show all rows
$("#example_length").find("select").val(-1).trigger("change");
// remove the previous selection mark
$("#example").find("tr").each(function(i,a){
$(a).find("td:first").removeClass("selected");
$(a).find("td:first").html("");
});
// mark the picked row
$(tr).find("td:first").addClass("selected");
$(tr).find("td:first").html("<i class='fa fa-check'></i>");
// re turn the pagination to first stuation
$("#example_length").find("select")
.val(activePaginationSelected).trigger("change");
}
Unfortunately, legacy data table does not support or have that select extension.
Workaround:
Create checkbox element inside 'mRender' callback.
Bind action to the checkbox. (This can be done inside the fnRowCallback or outside as in my example in below fiddle
https://jsfiddle.net/Rohith_KP/dwcatt9n/1/
$(document).ready(function() {
var userData = [
["1", "Email", "Full Name", "Member"],
["2", "Email", "Full Name", "Member"]
];
var table = $('#example').DataTable({
'data': userData,
'columnDefs': [{
'targets': 0,
'className': 'dt-body-center',
'mRender': function(data, type, full, meta) {
return '<input type="checkbox" value="' + $('<div/>').text(data).html() + '">';
}
}],
'order': [1, 'asc']
});
$('#example tr').click(function() {
if ($(this).hasClass('row_selected'))
$(this).removeClass('row_selected');
else
$(this).addClass('row_selected');
});
});
Also, I suggest you to upgrade your datatable version. Then you can use that select extension.
Can the same functionality as listed in example given above be possible with jquery.dataTables 1.9.4 instead of jquery.dataTables 1.10.16?
Yes.
But, not using the Select Extension since it requires at least version 1.10.7.
For 1.9.4, a possible solution would be:
$(document).ready(function() {
$('#example').find("td input[type='checkbox']").click(function() {
selectRow(this);
});
var table = $('#example').DataTable();
function selectRow(clickedCheckBox) {
var currentPage = table.fnPagingInfo().iPage;
// Being unchecked
if (!$(clickedCheckBox).is(':checked')) {
$(clickedCheckBox).removeAttr('checked');
getRow(clickedCheckBox).removeClass('selected');
return;
}
var selectEntries = $("#example_length").find("select");
var showEntriesCount = selectEntries.val();
var totalRows = table.fnGetData().length;
// If show entries != totalRows append total rows opiton that can be selected
if (totalRows != showEntriesCount)
selectEntries.append($('<option>', {
value: totalRows,
text: totalRows
}));
// Display all rows
selectEntries.val(totalRows).trigger("change");
// Removes all checked attribute from all the rows
$("#example").find("td input[type='checkbox']").each(function(value, key) {
getRow(key).removeClass('selected');
$(key).removeAttr('checked');
});
// Check the clicked checkBox
$(clickedCheckBox).prop('checked', true);
getRow(clickedCheckBox).addClass('selected');
// Re set the show entries count
selectEntries.val(showEntriesCount).trigger("change");
// If added, Remove the additional option added to Show Entries
if (totalRows != showEntriesCount)
selectEntries.find("[value='" + totalRows + "']").remove();
// Go to the page on which the checkbox was clicked
table.fnPageChange(currentPage);
}
function getRow(element) {
return $(element).parent().parent();
}
});
The above will require fnPagingInfo to take the user back to initial page. I haven't tested the solution on large dataset, tested it on a table with 150 rows, but should work fine on larger datasets too.
JSFiddle
Have you tried below code and I checked and it is working fine, you need to update styles and scripts:
You havr to update the latest styles and scripts to achieve latest functionality.
Single check box selection with jquery datatable
My table contains thre columns; "name", "description" and "status". I have a dropdown field which filters the table on the status column. Essentially:
$('.js-status-dropdown').dropdown({
onChange: function (value) {
$('#dt').DataTable().column('status:name').search(value).draw();
}
});
This works, but the problem is the standard free-text search input field includes the status field in the free-text search.
Setting searchable: false on the status field causes the dropdown to stop working since Datatable ignores it.
{
data: 'status',
name: 'status',
searchable: false // Stops table.column().search(value) from working :-(
}
Ideally, the (standard) free-text search field should ignore the stuatus column, but the dropdown code should still be working.
This works:
Set the column to searchable: false. This makes the table ignore this column in free text searches.
Add a custom search which uses the original row data, settings.aoData, instead of the data array (it doesn't contain the column because of 1.)
Redraw the table when the filter dropdown changes.
Code:
$('#dt').DataTable(defaults)
.on('init.dt', statusHandling);
function statusHandling(e, settings, processing) {
// Redraw table on dropdown status change
$('.js-status-dropdown').dropdown({
onChange: function (value) {
$(options.table).DataTable().draw();
}
});
// Our custom search function which adds an AND 'status = foo' condition
$.fn.dataTable.ext.search.push(
function (settings, data, dataIndex) {
var input = $('input[name=status]').val().toLowerCase();
// Use original data instead of 'data' because status is not searchable
var status = settings.aoData[dataIndex]['_aData']['status'];
return status.toLowerCase().indexOf(input) === 0;
}
);
}
I have a datatable from ajax source. I want to display a checkbox in one column based on its value.
If the value is active, checkbox should be checked, otherwise it remains unchecked.
I am using Switchery JS to stylize the checkbox. It works fine in normal HTML body, but not inside a datatable column.
Here is the fiddle:
https://jsfiddle.net/sohal/gfuuazxL/4/
The problem is that you are doing the Switchery' before the dataTable is populated with data. And even if you did it after, you would still end up not having Switcherys on hidden rows, i.e on page #2, #3 and so on.
So you must initialise Switchery after the dataTable is initialised and do the Switchery on all rows. You can do this in the initComplete() callback, and iterate over all rows by using the API every() method :
$(document).ready(function() {
var table = $('#datatable-buttons').DataTable({
initComplete : function() {
this.api().rows().every( function ( rowIdx, tableLoop, rowLoop ) {
this.nodes().to$().find('.js-switch').each(function(i, e) {
var switchery = new Switchery(e, {
color: '#26B99A'
})
})
})
},
...//rest of the options
})
})
forked fiddle -> https://jsfiddle.net/jpkysyp1/
I do have a php generated page, with a table that exists after the page loaded.
<table id="#previewTable">
<thead>
<th class="colA">column a - Firstname</th>
<th>column b - Lastname</th>
</thead>
<tbody>
<tr>
<td class="colA">Alexander
</td>
<td class="colB">Zandvoort
</td>
</tr>
<tr>
<td class="colA">Alexander
</td>
<td class="colB">Brno
</td>
</tr>
<tr>
<td class="colA">Bastian
</td>
<td class="colB">Zolder
</td>
</tr>
</tbody>
</table>
During doc.ready I apply the tablesorter widget like so:
var the_table = $('#previewTable');
//the_wrapper ==> any jquery selector (not object!) like '.mywrapper' or '#mywrapper'
//the_table ==> any jquery selector (not object!) like '.mytable' or '#mytable'
//the_childs_class ==> class name of the chilkd rows, like 'child-row' - NO dot!
var idx = $(the_table+'.ts-date').index(); //all headers with german dates
var options = {
showProcessing: true,
sortReset : true,
saveSortReset : false,
resort:true,
widgets: [ 'saveSort','zebra','stickyHeaders' ],
cssInfoBlock : "row-sorter-false",
//those rows will NOT be included in a sorting! useful to implement blockwise sorting
widgetOptions: {
// number or jquery selector targeting the position:fixed element
stickyHeaders_offset : 0,
// added to table ID, if it exists
stickyHeaders_cloneId : '-sticky',
// trigger "resize" event on headers
stickyHeaders_addResizeEvent : true,
// if false and a caption exist, it won't be included in the sticky header
stickyHeaders_includeCaption : true,
// scroll table top into view after filtering
stickyHeaders_filteredToTop: true,
/* make the table scroll within its wrapper */
stickyHeaders_attachTo : the_wrapper
},
cssChildRow: the_childs_class,
dateFormat : "ddmmyyyy", // set the default date format
idx: { sorter: "shortDate", dateFormat: "ddmmyyyy" }
};
$(the_table).tablesorter(options);
After that has been done everything is fine.
Now the users will sort any two of the let's say ten columns A and B in whatever direction.
The saveSort widget remembers everything pretty fine.
We do have a checkbox for each column "hide that column".
Un/checking that checkbox for let's say B should hide/show the according column B, remove the sorting of the rows that has been done through column B and reapply any existing remaining sorting - in this case A.
I tried doing that like so:
$(document).on('click','.chk_must',function(){ //all checkboxes in MUST
theSortList = $( '#previewTable' ).get(0).config.sortList;
var new_sort_list = [];
if($('.chk_must_'+$(this).attr('data-nr')).is(':visible')){
$('.chk_must_'+$(this).attr('data-nr')).hide();//show or hide M1 and so on rows
theColumnNumber = $('.chk_must_'+$(this).attr('data-nr')).attr('data-column');
$(theSortList).each(function(key,element){ //get the header text for each selected
//var element[0] // var element[1]; //[0]=field number starting at 0, [1]=sort order, whereas 0=ASC and 1=DESC
if(element[0]!=theColumnNumber){
new_sort_list.push(element);
}
});
if (new_sort_list.length==0){
//nothing
}else{
$( '#previewTable' ).get(0).config.sortList = [new_sort_list];
$('#previewTable').trigger( 'sorton',[new_sort_list] );
}
$("#previewTable").trigger("updateCache").trigger("updateAll");
$('#previewTable').trigger('refreshWidgets', true,false);
}else{
$('.chk_must_'+$(this).attr('data-nr')).show();//show or hide M1 and so on rows
}
});
What ever I do....the sort is not going to be reseted and redone according to [new_sort_list]but stay the same. Hiding/Showing of the column itselfs works as well.
It seems like I'm not applying the correct type /format of new_sort_list and that may be the internal cache is not going to be reseted - even not with refreshWidgets and updateCache and all that.
Any ideas what could be done to get this to work?
TIA
Alex
First off, remove the triggers for updateCache & updateAll. They aren't needed when only sorting is involved.
The values in sortList consist of a column index, and sort direction grouped together. For example:
// [ [ columnA, direction ], [ columnB, direction ] ]
table.config.sortList = [ [0,0], [1,0] ];
So, the code above has this function:
$(theSortList).each(function(key,element){ //get the header text for each selected
//var element[0] // var element[1]; //[0]=field number starting at 0, [1]=sort order, whereas 0=ASC and 1=DESC
if(element[0]!=theColumnNumber){
new_sort_list.push(element);
}
});
This function should be using jQuery.each() and not the each function above which is used for DOM elements.
Maybe instead, if there are only a few columns, you can pick primary columns and sort that one when the others are hidden.
Here is some untested code as an example:
var direction = 'asc', // use 'desc' for descending sort
// sort column priority from left-to-right
priorities = [ 0, 1, 2, 3 ],
config = $( '#previewTable' ).get(0).config,
sortColumn = -1,
theColumnNumber = $('.chk_must_'+$(this).attr('data-nr')).attr('data-column');
$.each( priorities, function(indx, val) {
// config.$headerIndexed sets one header cell for each column
// in a basic array (not a jQuery object set); it is
// needed for tables with multiple thead rows & colspans
if ( !config.$headerIndexed[ val ].is(':hidden') ) {
sortColumn = val;
break;
}
});
if ( sortColumn > -1 ) {
$( '#previewTable' ).trigger('sorton', [ [[ sortColumn, direction ]] ]);
}
Or, you could use the columnSelector widget to do the work of hiding & showing columns. And add this very basic code (only written for 2 columns) which updates the sort when the columns change visibility (demo):
$(function () {
/*** custom css only button popup ***/
$('table').tablesorter({
theme: 'blue',
widgets: ['zebra', 'columnSelector', 'stickyHeaders'],
widgetOptions: {
columnSelector_container: $('#columnSelector'),
columnSelector_mediaquery: false
}
}).on('columnUpdate', function(){
var sortCol = 0,
s = this.config.selector;
// if column a is hidden & column b is showing
// sort column b
if ( !s.states[0] && s.states[1] ) {
sortCol = 1;
}
$(this).trigger('sorton', [ [[sortCol, 0]] ]);
});
});
My goal is to highlight a row if two columns contain the same string within a row using datatables
I am not sure how would I compare two columns. I want to do something like this.
This is part of my code
"columnDefs":[
{
"targets":[3,4],
"render": function ( data, type, full, meta ) {
if value of 3 = 4 {
//highlight the row
}
}
} ],
Thanks in advance.
SOLUTION
Use rowCallback option to define a callback function that will be called when row would be drawn.
$('#example').dataTable({
"rowCallback": function(row, data, index){
if (data[3] === data[4]) {
$(row).addClass('selected');
}
}
});
DEMO
See this jsFiddle for code and demonstration.