I use DataTables.js to generate tables. It\'s great, works fine. I wanted to add Tabs to my \"pages\" but it seems that when DataTables is used on other than primary tab it
The issue is with datatables, it is failing to render correctly when the table is within
a hidden container. You can verify it just by removing display: none
style
from .tab-pane
, all tabs shows up and all tables render correctly. But you have to hide
then tabs right?
Until datatables developers fixes this issue you have only one way to go. Keep all the tab panes visible when page loads, let datatables render all the tables, then hide the tab panes. So you have to tweak your tabs.
It seems datatables can render the tables even if container's visibility is set to hidden if display is set to block. You can use this trick to hide the flash of all the tab panes while the page is still loading. Just to give you an idea, add the following at the bottom of your page withing the body tag.
<style id="datatables_crazyfix">
.tab-content .tab-pane {
visibility: hidden;
display: block;
}
</style>
<script>
jQuery(function($){
$("#datatables_crazyfix").remove();
});
</script>
Do a responsive.recalc() on tabButton click. This will probably require the least amount of work.
tabButtons.map(function (button) {
button.addEventListener("click", function () {
document
.querySelector("li a.active.button")
.classList.remove("active");
button.classList.add("active");
document
.querySelector(".tab-pane.active")
.classList.remove("active");
document
.querySelector(button.getAttribute("href"))
.classList.add("active");
/**** ADDED RESPONSIVE.RECALC ****/
$(button.getAttribute("href"))
.find("table.display.compact")
.DataTable().responsive.recalc();
})
})
Initialize DataTable on tabButton click. In addition to the code shown below you will have to remove your other pieces of code that initializes the DataTable for the initially inactive tabs (Test1 and Test2).
I've found that this produces more consistent layout than Option 1.
tabButtons.map(function (button) {
button.addEventListener("click", function () {
document
.querySelector("li a.active.button")
.classList.remove("active");
button.classList.add("active");
document
.querySelector(".tab-pane.active")
.classList.remove("active");
document
.querySelector(button.getAttribute("href"))
.classList.add("active");
/** ADDED DATATABLE INITIALIZATION HERE **/
var tabPaneToActivate = document
.querySelector(button.getAttribute("href"))
tabPaneToActivate.classList.add("active");
tabPaneToActivate.querySelectorAll("table.display.compact").forEach(function (el) {
if (!$.fn.dataTable.isDataTable(el)) {
/** ^^^ Only initialize once ^^^ **/
$(el).DataTable({
dom: "Bfrtip",
buttons: [
"copyHtml5",
"excelHtml5",
"csvHtml5",
"pdfHtml5"
],
colReorder: true,
paging: true,
pagingType: ["full_numbers"],
lengthMenu: [
[15, 25, 50, 100],
-1,
[15, 25, 50, 100],
"All"
],
ordering: true,
info: true,
procesing: true,
responsive: {
details: true
},
select: true,
searching: true,
stateSave: true
});
}
})
})
})
try:
change html code in tab:
<div>
<ul class="tab-nav">
<li><a class="button tabbtn active" href="#Test">Test </a></li>
<li><a class="button tabbtn" href="#Test1">Test1 </a></li>
<li><a class="button tabbtn" href="#Test2">Test2 </a></li>
</ul>
</div>
and
<script>
$( ".tabbtn" ).on( "click", function() {
setTimeout(function(){
$("#DT-iuyx2s7b").DataTable({
dom: "Bfrtip",
destroy: true,
buttons: [
"copyHtml5",
"excelHtml5",
"csvHtml5",
"pdfHtml5"
],
colReorder: true,
paging: true,
pagingType: ["full_numbers"],
lengthMenu: [
[15, 25, 50, 100],
-1,
[15, 25, 50, 100],
"All"
],
ordering: true,
info: true,
procesing: true,
responsive: {
details: true
},
select: true,
searching: true,
stateSave: true
});
},200)
});
</script>
or
<script>
var table=null;
$(document).ready(function() {
table= $("#DT-iuyx2s7b").DataTable({
dom: "Bfrtip",
buttons: [
"copyHtml5",
"excelHtml5",
"csvHtml5",
"pdfHtml5"
],
colReorder: true,
paging: true,
pagingType: ["full_numbers"],
lengthMenu: [
[15, 25, 50, 100],
-1,
[15, 25, 50, 100],
"All"
],
ordering: true,
info: true,
procesing: true,
responsive: {
details: true
},
select: true,
searching: true,
stateSave: true
});
});
$( ".tabbtn" ).on( "click", function() {
setTimeout(function(){
table.ajax.reload();
},300);
});
</script>
One way of doing this is to initialize Datatables when the tab becomes active, and not at the page load.
$(document).ready(function() {
$('a').on('click', function() {
if ($(this).attr('href')) == "#Test1" && !$.fn.dataTable.isDataTable("#DT-iuyx2s7b") && !$.fn.dataTable.isDataTable("#DT-2u8iw0gr")) {
$("#DT-iuyx2s7b").DataTable(...);
$("#DT-2u8iw0gr").DataTable(...);
} else if ($(this).attr('href')) == "#Test2" && !$.fn.dataTable.isDataTable("#DT-vdk1ir62")) {
$("#DT-vdk1ir62").DataTable(...);
}
});
});
I don't take into consideration the first tab because it's the only visible one on page load.
JSfiddle : https://jsfiddle.net/dqec4xyw/