I have a Datatable which if 1 page is returned i want to hide the 'Items per pages' dropdown list and also the pagination. This also needs to work when filtering the table.
I am using the:
.DataTable().page.info()
Below is the code i have
"fnDrawCallback": function () {
var accountSearchDataTableInfo = $('#accountSearchDataTable').DataTable().page.info();
if (accountSearchDataTableInfo.pages == '1') {
console.log(accountSearchDataTableInfo.pages == '1')
$('#accountSearchDataTable_length').hide();
$('#accountSearchDataTable_paginate').hide();
}
if (accountSearchDataTableInfo.pages == 1) {
console.log(accountSearchDataTableInfo.pages == 1)
$('#accountSearchDataTable_length').hide();
$('#accountSearchDataTable_paginate').hide();
}
}
And this gives...
Initial table load table info
Filtered table info
As you can see from my IF i have tried a number and string but when i do console.log on these it comes back true but the items are still displayed.
I have tried .hide() and also .css('display', 'none') but nothing seems to be working and i'm at a loss what else to try.
When i look at the element in Dev tools the style attribute is added but nothing after it:
Initial table load
Filtered table
Found the solution. I was looking for the parent DIV but it appear that if i used each individual identifier i can hide them. so my IF now look like
if (accountSearchDataTableInfo.pages == '1') {
$('.mb-2').hide(); // Items per page DD
$('#accountSearchDataTable_previous').hide(); // Pagintator 'Previous' button
$('#accountSearchDataTable_next').hide(); // Pagintator 'Next' button
$('.paginate_button').hide(); // Pagintator page '1' button
}
You can use below api to determine pages number
table.api().page.info().pages
As stated in documentation:
https://datatables.net/reference/api/page.info()
And use drawCallback() after table is draw As documented here:
https://datatables.net/reference/option/drawCallback
Example how to hide pagination when page is 1 or less:
$('#example').dataTable( {
"drawCallback": function( settings ) {
var api = this.api();
var pagination = $(this).closest('.dataTables_wrapper').find('.dataTables_paginate');
pagination.toggle(api.page.info().pages > 1);
}
} );
I have 2 tables that are using DataTable jQuery Plug-in.
I wondering if there is a way to hide my pagination on the bottom right of my table.
Note:
Only show the pagination when I need one.
Hide the pagination when the query results is less than 10.
Use drawCallback option to handle DT draw event and show/hide pagination control based on available pages:
$('#table_id').dataTable({
drawCallback: function(settings) {
var pagination = $(this).closest('.dataTables_wrapper').find('.dataTables_paginate');
pagination.toggle(this.api().page.info().pages > 1);
}
})
$('#dataTable_ListeUser').DataTable( {
//usual pager parameters//
"drawCallback": function ( settings ) {
/*show pager if only necessary
console.log(this.fnSettings());*/
if (Math.ceil((this.fnSettings().fnRecordsDisplay()) / this.fnSettings()._iDisplayLength) > 1) {
$('#dataTable_ListeUser_paginate').css("display", "block");
} else {
$('#dataTable_ListeUser_paginate').css("display", "none");
}
}
});
Use 'drawCallback' to solve this problem.
1.On the webpage, use developer tool to inspect the 'previous' button, then you will find a div element that wraps both the 'previous' and 'next' buttons. DataTables automatically assigned an id to this div based on your html table element's id.
For example, I have a table with id 'Atable'. In this table, DataTables automatically created a div element with id called 'Atable_paginate' to wrap the previous and next buttons.
2.For drawCallback, we write a function which checks if there is less than 1 page, if so, we hide element by utilising id.
For example, you have set there are 20 records on one page by
pageLength: 20,
which means if there are less then 20 records, we don't need to display 'previous' and 'next' buttons. So we write like below,
drawCallback: function(settings){
if($(this).find('tbody tr').length <= 20){
$('#Atable_paginate').hide();
}
}
3.The initialization of Atable should be like below
var table = $('#Atable').DataTable({
pageLength: 20,
lengthChange: false,
drawCallback: function(settings){
if($(this).find('tbody tr').length <= 20){
$('#Atable_paginate').hide();
}
}
});
4.If there are more than one table on the webpage, apply this method on each table.
You can use fnDrawCallback() method to hide the pagination in dataTable.
var oTable = $('#datatable_sample').dataTable({
"iDisplayLength": 10,
"fnDrawCallback": function(oSettings) {
if ($('#datatable_sample tr').length < 10) {
$('.dataTables_paginate').hide();
}
}
});
The length which you can define as per the row you want to display in the listing.
$(this) did not work for me, probably because I am using TypeScript. So I used a different approach to get the JQuery element for the table wrapper and the DataTables API. This has been inspired by the answer of BitOfUniverse and tested with DataTables 1.10.
TypeScript:
'drawCallback': (settings: any) => {
// hide pager and info if the table has NO results
const api = new $.fn.dataTable.Api(settings);
const pageCount = api.page.info().pages;
const wrapper = $('#' + settings.sTableId).closest('.dataTables_wrapper');
const pagination = wrapper.find('.dataTables_paginate');
const info = wrapper.find('.dataTables_info');
pagination.toggle(pageCount > 0);
info.toggle(pageCount > 0);
}
You can give options when you create your datables on Javascript
$('.examples').DataTable({
"paging": false
});
All options are listed here:
http://www.datatables.net/reference/option/
I'm using Bootstrap and have a striped table that can be filtered by selecting some options on a form. Javascript interprets the form inputs, and hides rows from the table that don't match the selected criteria.
However, this breaks the table striping on the table depending on which rows are hidden (gray rows next to gray rows, white rows next white rows).
I'd like to reapply the striping based on what rows are visible after filtering the results. How can I do this?
Using .remove() on the table rows is not an option, because I may need to show them again if the filter criteria changes and I'm trying to avoid using AJAX to update the table dynamically based on the filter inputs (I'd like to stick to hiding DOM elements).
Any help is appreciated! I can clarify the question if needed :)
Seems like Bootstrap 4 have a different implementation. Following #Anthony's answer, this is how it would work:
$("tr:visible").each(function (index) {
$(this).css("background-color", !!(index & 1)? "rgba(0,0,0,.05)" : "rgba(0,0,0,0)");
});
Tables are now striped by pure CSS and not by adding the "stripe" class name.
Yes, this is definitely one of the annoying parts of table striping. The better part of valor here is probably just to reapply the striping with jQuery after each update:
$("tr:not(.hidden)").each(function (index) {
$(this).toggleClass("stripe", !!(index & 1));
});
Anthony's answer did not work for me. First, it does not hide the Bootstrap table class table-striped, and second, there is not (or at least does not appear to be) a built-in class stripe for table rows.
Here's my approach, where I've filtered rows in a table with an id of "reports".
Here's a version to use if you define the class "stripe" for <tr> elements:
// un-stripe table, since bootstrap striping doesn't work for filtered rows
$("table#reports").removeClass("table-striped");
// now add stripes to alternating rows
$rows.each(function (index) {
// but first remove class that may have been added by previous changes
$(this).removeClass("stripe");
if ( index % 2 == 0) {
$(this).addClass("stripe");
}
});
If you're too lazy to define the CSS class "stripe" then here's a quick & dirty version:
// un-stripe table, since bootstrap striping doesn't work for filtered rows
$("table#reports").removeClass("table-striped");
// now add stripes to alternating rows
$rows.each(function (index) {
// but first remove color that may have been added by previous changes:
$(this).css("background-color", "inherit");
if ( index % 2 == 0) {
$(this).css("background-color", "#f9f9f9");
}
});
This is the same answer as #Jacobski's answer but will keep the hover effect of a bootstrap table-hover.
$("tr:visible").each(function (index) {
$(this).css("background-color", !!(index & 1) ? "rgba(0,0,0,.05)": "rgba(0,0,0,0)");
if (!(index & 1)) {
$(this).hover(
function () { //On hover over
$(this).css("background-color", "rgba(0,0,0,.07)");
},
function () { //On hover out
$(this).css("background-color", "rgba(0,0,0,0)");
}
)
}
});
My answer build upon what #Jacob and #yehuda suggested.
This works with bootstrap4, for a table that needs both the behavior of ".table-striped" and ".table-hover".
The hover part is handled by CSS, which makes it more efficient (I noticed a small delay due to javascript handler, when testing #yehuda's snippet).
// CSS
<style>
.table-striped tbody tr.visible-odd {
background-color: rgba(0, 0, 0, 0.05);
}
.table-striped tbody tr.visible-even {
background-color: rgba(0, 0, 0, 0.00);
}
.table-hover tbody tr.visible-even:hover {
background-color: rgba(0, 0, 0, 0.075);
}
</style>
// JS
$("tr:visible").each( function(index, obj) {
if (index % 2) {
$(this).addClass('visible-odd').removeClass('visible-even');
} else {
$(this).addClass('visible-even').removeClass('visible-odd');
}
});
For me this works fine with hidden rows and reapplies the striping as expected:
$("table#ProductTable").removeClass("table-striped");
$("table#ProductTable").addClass("table-striped");
#Jacobski's answer was great, but I had some pages with multiple tables and the header row's background would get changed on separate tables. Also my table rows that were always visible had the class "accordion-toggle" not sure if that's a bootstrap 5 thing, but that is how I targeted it! (also I don't know JavaScript so there's probably cleaner syntax to do what I did)
$("tr:visible").each(function (index) {
if ($(this).hasClass("tb-header")) {
rowIndex = 0; // need to reset the rowIndex since we are now on a new table!
} else {
if ($(this).hasClass("accordion-toggle")) {
$(this).css("background-color", !!(rowIndex & 1)? "rgba(0,0,0,0)" : "rgba(0,0,0,.05)");
rowIndex++;
}
}
});
I'm new to JS. How can i highlight selected row when user clicked on it at editable datatable?
Thank you.
If you are using the jquery datatable plugin, there is an example here :
http://datatables.net/release-datatables/examples/api/select_row.html
$(document).ready(function() {
/* Add/remove class to a row when clicked on */
$('#example tr').click( function() {
$(this).toggleClass('row_selected');
} );
/* Init the table */
var oTable = $('#example').dataTable( );
} );
/*
* I don't actually use this here, but it is provided as it might be useful and demonstrates
* getting the TR nodes from DataTables
*/
function fnGetSelected( oTableLocal )
{
return oTableLocal.$('tr.row_selected');
}
I'm using dataTables with Jquery Mobile. My dataTable is initiated on pageBeforeShow. Inside my init callback function I construct a JQM select menu. This menu does not get properly enhanced = the button is there, but the custom-select is not created.
That's my problem!
Here's the shortened code:
$('div:jqmData(role="page")').live('pagebeforeshow', function(e, data) {
/** init datatables **/
$('.tbl_orders').dataTable( {
/* callback */
"fnInitComplete": function(oSettings, json) {
var thead = $(oSettings.nTHead),
bodyRows = $(oSettings.nTBody).find("tr, TR"),
hdrCols = thead.find( /* all header columns */ );
/* create select */
tableSelectMenu = $('<select name="toggleCols" id="toggleCols" multiple="multiple" data-icon="setup" data-iconpos="notext"></select>')
/* loop through header cols add options */
hdrCols.each(function(i){
var toggle = $('<option value="'+id+'">'+th.text()+'</option>');
tableSelectMenu.append(toggle);
}); // end hdrCols loop
$('.stickSelectHere').append(tableSelectMenu)
}
});
If I do it like this, the select button is there but does not do anything, because the custom-select-menu is missing.
I tried to create the select earlier on pagebeforecreate, because that's where I'm checking for touch devices and assigning data-native-menu="true/false". But putting the select there, also doesn't do any good, maybe because I just create it and don't drop it in the DOM until my tableInit... mh.
Question:
Can someone tell me how to create a select with custom-menu at pagebeforeshow?
Thanks for help!
You likely just need to add the following after your append, i.e.
$('.stickSelectHere').append(tableSelectMenu)
$('#toggleCols').selectmenu('refresh');