DataTables 1.10.12 - scrollX bug when grid is rendered inside a hidden div.
DataTables 1.10.12 - scrollX bug when grid is rendered inside a hidden div.
Hi,
This is not a question so much as a comment, that will hopefully help other developers who spent hours troubleshooting similar problems.
The scrollX functionality creates a bunch of separate divs, and for whatever reason he draw callback does not always correctly calculate the footer width. I believe this has something to do with the fact that the draw callback sets the width to 0px, and therefore causes the footer to not resize the same as the header because the footer doesn't have the sorting icon affordances. So, even though the footer cells have identical content to the header, they will always render with less width because they do not have the inserted sorting affordances.
The stupid workaround I have found that works is re-draw the table, then call sort twice. I have no idea why this works, but it does. If I had to guess, there is some peculiarity behind whether the table is "culled" by the graphics rendering engine. For example, if you have a tabbed UI and the grid is rendered on a hidden tab, then the calculations used by DataTables.Net will be off. This would explain why it gets assigned 0px - at the moment it is rendered, it has no layout.
Another solution would be to redraw the grid whenver the tab becomes visible.
Here is some TypeScript code which helps give people some clues:
var $myTableId = $("#myTableId");
var $dt = $myTableId.DataTable(<any>{
"lengthMenu": [10, 20, 50, 100],
"scrollX": true
});
$.ajax({
url: route_url,
method: "GET",
dataType: "json"
}).done(function (data: any) {
data.forEach(function (val: any) {
$dt.row.add([
val.id,
val.name,
val.a,
val.b,
val.c,
val.d,
val.e,
val.f,
val.g,
val.h,
val.i,
val.j,
val.k,
val.l,
val.m,
val.n,
val.o,
val.p,
val.q,
val.r,
val.s,
val.t,
val.u,
val.v,
val.w,
val.x,
val.y,
val.z,
]);
}
$dt.draw(true);
$(".dataTables_scrollHead table.dataTable tr th:first-child", "#myTableId").click();
$(".dataTables_scrollHead table.dataTable tr th:first-child", "#myTableId").click();
}
HTML5 w/ Bootstrap4 alpha2:
<div class="table-responsive">
<table id="myTableId" class="table table-striped table-bordered">
<thead class="thead-inverse">
<tr>
<th>ID</th>
<th>Name</th>
<th>A is for Apple</th>
<th>B is for Boy</th>
<th>C is for Carrot</th>
<th>D is for Doppelganger</th>
<th>E is for Ebony</th>
<th>F is for Faucet</th>
<th>G is for Giraffe</th>
<th>H is for Helium</th>
<th>I is for Igloo</th>
<th>J is for Joker</th>
<th>K is for Key</th>
<th>L is for Laughable</th>
<th>M is for Money</th>
<th>N is for Nancy</th>
<th>O is for Oscar</th>
<th>P is for Popular</th>
<th>Q is for Query</th>
<th>R is for Roger</th>
<th>S is for Stanley</th>
<th>T is for Titanium</th>
<th>U is for Uranium</th>
<th>W is for Watchmen</th>
<th>X is for Xena Warrior Princess</th>
<th>Y is for Yellow</th>
<th>Z is for Zebra</th>
</tr>
</thead>
<tfoot class="tfoot-inverse">
<tr>
<th>ID</th>
<th>Name</th>
<th>A is for Apple</th>
<th>B is for Boy</th>
<th>C is for Carrot</th>
<th>D is for Doppelganger</th>
<th>E is for Ebony</th>
<th>F is for Faucet</th>
<th>G is for Giraffe</th>
<th>H is for Helium</th>
<th>I is for Igloo</th>
<th>J is for Joker</th>
<th>K is for Key</th>
<th>L is for Laughable</th>
<th>M is for Money</th>
<th>N is for Nancy</th>
<th>O is for Oscar</th>
<th>P is for Popular</th>
<th>Q is for Query</th>
<th>R is for Roger</th>
<th>S is for Stanley</th>
<th>T is for Titanium</th>
<th>U is for Uranium</th>
<th>W is for Watchmen</th>
<th>X is for Xena Warrior Princess</th>
<th>Y is for Yellow</th>
<th>Z is for Zebra</th>
</tr>
</tfoot>
<tbody>
</tbody>
</table>
</div>
CSS3:
table.dataTable,
table.dataTable th,
table.dataTable td,
.datatTables_scrollFootInner {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
See also, similar to the problems mentioned in this thread: https://datatables.net/forums/discussion/14342/column-header-not-aligned-with-column-data-with-horizontal-scrolling/p2
This question has an accepted answers - jump to answer
Answers
Hi,
If the DataTable is initialised in a hidden element, you must call
columns.adjust()
when it is made visible.The reason for that is that hidden elements have no height or width, so DataTables can't correctly align the columns while it is hidden.
Allan
Thanks, that seems much simpler and works just as well as my hack. I read the code and it has this comment:
My question is: Why "probably"?
Because you might want to do something else with the table before calling
draw
. For example you might want to filter the table.I think that comment is actually a little out of date now to be honest. It isn't really required to do a draw after
columns.adjust()
now. It used to be that it would help the alignment with a scrolling table, but that he handled automatically now, so I think that comment is a bit redundant these days.Allan