alampada
alampada

Reputation: 2409

Datatables: disable column resizing after filtering

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

Answers (3)

Glenn Willen
Glenn Willen

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

Nickolay
Nickolay

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

Amar Kamthe
Amar Kamthe

Reputation: 2582

In your html table tag set style table-layout to 'fixed' and pass bAutoWidth = false to datatable function

Upvotes: 13

Related Questions