Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataTables fixed headers misaligned with columns in wide tables

Problem

When using the sScrollX, sScrollXInner and/or sScrollY to achieve a fixed header table with its inner content scrolling, the headers of the table go out of alignment with the rest of the body in Chrome and IE. Firefox, on the other hand, displays them perfectly.

Using the version 1.9.4, as far as I can tell, this issue only occurs when there is a lot of data with fluctuating widths, and with words that are very long/unwrappable combined in the same columns as small ones. Also, the table in question needs to be fairly wide.

All these factors are demonstrated in this fiddle:

Output

Chrome:
Chrome Screenshot

IE:
IE9 Screenshot

Firefox
Firefox Screenshot

Suggested Solutions

These solutions have been suggested before but have had no effect on my implementation. Owing to some of these suggestions, I setup a clean plain vanilla demo as I wanted to ensure that no other code was contributing to this effect.

  • turn-off/remove all my css
  • setTimeout( function () { oTable.fnAdjustColumnSizing(); }, 10 );
  • calling oTable.fnFilter( "x",0 ) and oTable.fnFilter( "",0 ) in that order
  • "sScrollXInner": "100%"
  • get rid of all widths

The only solution that I found to the misaligned headers was taking out sScrollX and sScrollY, but this can't be counted as a solution as you lose the fixed header/inner content scrolling functionality. So sadly it's a temporary hack, not a fix!

Note

To edit/play with the latest fiddle.

I have tried various combinations which can be observed in the revision history of the fiddle by using the link http://jsfiddle.net/pratik136/etL73/#REV# where 1 <= #REV# <= 12

History

StackO
This question has been asked before: jQuery Datatables Header Misaligned With Vertical Scrolling
but the vital difference is that the OP of that question mentioned that they were able to fix the issue if all CSS was removed, which is untrue in my case, and I have tried a few permutations, thus thought the question worthy of a repost.

External
This issue has also been flagged on the DataTables forum:

  • http://datatables.net/forums/discussion/7395/sscrolly-and-sscrollx-broken/p1
  • http://datatables.net/forums/discussion/7778/vertical-scrolling-messes-up-column-header-alignment#Item_1
  • http://datatables.net/forums/discussion/3835/width-columns-problem-in-chrome-safari/p1
  • My bug report: http://datatables.net/forums/discussion/12491/datatables-header-alignment-issue-refresh#Item_1

This issue has driven me nuts! Please contribute your thoughts!

like image 646
bPratik Avatar asked Nov 01 '12 13:11

bPratik


People also ask

How do you fix a column in a DataTable?

FixedColumns allows columns to be fixed from both the left and the right hand sides of the table. Fixing right hand-side columns is done by using the fixedColumns. right initialisation parameter, which works just the same as fixedColumns. left does for the left side of the table.

What is fixed header in DataTable?

FixedHeader is an extension for DataTables that provides the ability to show a header and / or footer that is sticky - i.e. the element will affix itself to the top or bottom of the window as the end user scrolls through the table.

What is aaData DataTable?

By default DataTables will use the "aaData" property of the returned data which is an array of arrays with one entry for each column in the table.

What is FixedColumns in DataTables?

FixedColumns provides the option to freeze one or more columns to the left or right of a horizontally scrolling DataTable. This allows information in the fixed columns to remain visible even when scrolling through the data set. This can be particularly useful if you wish to show a large number of columns.


2 Answers

EDIT: See the latest Fiddle with "fixed header":


The Fiddle.

One of the solutions is to implement scrolling yourself instead of letting DataTables plugin do it for you.

I've taken your example and commented out sScrollX option. When this option is not present DataTables plugin will simply put your table as is into a container div. This table will stretch out of the screen, therefore, to fix that we can put it into a div with required width and an overflow property set - this is exactly what the last jQuery statement does - it wraps existing table into a 300px wide div. You probably will not need to set the width on the wrapping div at all (300px in this example), I have it here so that clipping effect is easily visible. And be nice, don't forget to replace that inline style with a class.

$(document).ready(function() { var stdTable1 = $(".standard-grid1").dataTable({     "iDisplayLength": -1,     "bPaginate": true,     "iCookieDuration": 60,     "bStateSave": false,     "bAutoWidth": false,     //true     "bScrollAutoCss": true,     "bProcessing": true,     "bRetrieve": true,     "bJQueryUI": true,     //"sDom": 't',     "sDom": '<"H"CTrf>t<"F"lip>',     "aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]],     //"sScrollY": "500px",     //"sScrollX": "100%",     "sScrollXInner": "110%",     "fnInitComplete": function() {         this.css("visibility", "visible");     } });  var tableId = 'PeopleIndexTable'; $('<div style="width: 300px; overflow: auto"></div>').append($('#' + tableId)).insertAfter($('#' + tableId + '_wrapper div').first())}); 
like image 169
Ruslans Uralovs Avatar answered Sep 19 '22 16:09

Ruslans Uralovs


The following is a way to achieve a fixed header table, I don't know if it will be enough for your purpose. Changes are:

  1. use "bScrollCollapse" instead of "sScrollXInner"
  2. don't use fieldset to wrap table
  3. add a "div.box" css class

It seems fully working on my local machine, but it's not fully working using Fiddle. It seems that Fiddle adds a css file (normalize.css) that in some way broke the plugin css (quite sure I can make fully working also in Fiddle adding some css clear rules, but not have time to investigate further now)

My working code snippet is below. Hope this can help.

<!DOCTYPE html> <html> <head>   <meta http-equiv="content-type" content="text/html; charset=UTF-8">    <script type='text/javascript' src='http://code.jquery.com/jquery-1.8.2.js'></script>   <script type='text/javascript' src="http://datatables.net/release-datatables/media/js/jquery.dataTables.min.js"></script>   <style type='text/css'>        div.box {        height: 100px;        padding: 10px;        overflow: auto;        border: 1px solid #8080FF;        background-color: #E5E5FF;    }    .standard-grid1, .standard-grid1 td, .standard-grid1 th {     border: solid black thin;    } </style>  <script type='text/javascript'>  $(window).load(function(){ $(document).ready(function() {     var stdTable1 = $(".standard-grid1").dataTable({         "iDisplayLength": -1,         "bPaginate": true,         "iCookieDuration": 60,         "bStateSave": false,         "bAutoWidth": false,         //true         "bScrollAutoCss": true,         "bProcessing": true,         "bRetrieve": true,         "bJQueryUI": true,         "sDom": '<"H"CTrf>t<"F"lip>',         "aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]],         "sScrollX": "100%",         //"sScrollXInner": "110%",         "bScrollCollapse": true,         "fnInitComplete": function() {             this.css("visibility", "visible");         }     }); }); });  </script>   </head> <body> <div>     <table class="standard-grid1 full-width content-scrollable" id="PeopleIndexTable">         <thead>           <!-- put your table header HTML here -->        </thead>        <tbody>           <!-- put your table body HTML here -->         </tbody>     </table> </div> </body> </html> 
like image 33
Draykos Avatar answered Sep 20 '22 16:09

Draykos