Reputation: 2409
I am using datatables and I populate the table with data using javascript. It works fine but I would like to prevent datables from resizing the table's column width after filtering. I have tried several solutions found on the web but it does not seem to solve the issue.
My HTML is:
<table class="table table-striped table-bordered table-hover" id="id-table" width="100%"></table>
I instantiate the table like:
var table = $('#id-table').DataTable(
{
paging: false,
ordering: false,
info: false,
"bAutoWidth": false, // Disable the auto width calculation : false,
columns: columns,
data : assignments,
sScrollX: "100%",
// aoColumns : aoColumns
// aoColumns : [
// { "sWidth": "150px" },
// { "sWidth": "150px" },
// { "sWidth": "150px" },
// { "sWidth": "150px" },
// { "sWidth": "150px" },
// { "sWidth": "150px" },
// { "sWidth": "150px" },
// { "sWidth": "150px" },
// { "sWidth": "150px" },
// { "sWidth": "150px" },
// { "sWidth": "150px" },
// { "sWidth": "150px" }
// ]
// aoColumns: aoColumns
// columnDefs : cdefs
}
);
where data is an array with the data and columns is an array of objects such as:
bSearchable false
sTitle "Column Title"
sWidth "100px"
title "Column Title"
mRender function(data, type, full, meta)
render function(data, type, full, meta)
I have tried setting the width in both "columns" directly and using the "aoColumns" options (commented out in the code above). In both cases, columns widths still get resized after filtering. Any idea on how I can disable this auto-resizing?
Upvotes: 7
Views: 11868
Reputation: 470
I got frustrated, so I wrote a hacky workaround for this. It is probably not a good idea. If it breaks you get to keep both pieces.
function saveColumnWidths(): string[][] {
const heads = Array.from(document.querySelectorAll('.dataTable > thead'));
const cells = heads.map((x) => Array.from(x.querySelectorAll('th')));
const widths = cells.map((x) => x.map((x) => x.style.width));
return widths;
}
function restoreColumnWidths(widths: string[][]) {
const heads = Array.from(document.querySelectorAll('.dataTable > thead'));
const cells = heads.map((x) => Array.from(x.querySelectorAll('th')));
if (widths.length !== cells.length) {
console.error("Cannot restoreColumnWidths:", cells, widths);
return;
}
cells.forEach((element, index) => {
if (element.length !== widths[index].length) {
console.error("Cannot restoreColumnWidths:", cells, widths);
return;
}
});
cells.forEach((element, i) => {
element.forEach((th, j) => {
th.style.width = widths[i][j];
});
});
}
It does an extra iteration (over 'thead' elements) to deal with the fact that the 'scroller' plugin (which I am using) causes each table to have two of them. This will also cause it to save all datatables on the page, if there are multiple, which may or may not be what you want.
It also does a bunch of checks, to make sure that the number of columns on the page is exactly the same when restoring as it was when saving. This means columns won't be restored if the number of columns changes, but will be restored if the set of columns changes but the number stays the same. This is not an issue in my application, but it's definitely hacky.
Call x = saveColumnWidths
before any operation that causes DataTables to wipe them out, and then restoreColumnWidths(x)
afterwards. Because of asynchronous operations, this may not be where you expect. I'm using serverSide: true
with an ajax
function; I call saveColumnWidths
in my ajax function, after I receive the server's response but before I call DataTables' callback. Then I call restoreColumnWidths
after DataTables' callback returns. Works like a charm!
Upvotes: 0
Reputation: 32073
I had this problem with the current version of DataTables (v1.10.16) and it was because I set autoWidth
to false
without understanding what it does.
In the default configuration (CSS table-layout: auto
+ DataTables' autoWidth: true
) the columns are appropriately sized based on the data and do not jump when filtering.
Upvotes: 0
Reputation: 2582
In your html table tag set style table-layout
to 'fixed'
and pass bAutoWidth = false
to datatable function
Upvotes: 13