27

I've posted this in the datatables.net forums, but after a week, still no response. Hopefully I can find help here...

I'm using datatables version 1.8.1 and am having nightmares over column header alignment with vertical scrolling enabled.

With the code posted below, the headers line up correctly in Firefox and IE8 and IE9, but Chrome and IE7 are off. I'm using a lot of datatables on this project, and this is a problem with every one. I'm desperate for help!

EDIT: I have figured out that this has something to do with setting the width of the table. The datatable takes the width of its container. If I set no width, everything lines up fine (but the table is too big for where I need it on the page). If I give the table's div (or a parent div somewhere higher up) a width at all, the headers don't line up properly.

Thanks!!

Screenshots:

www.dennissheppard.net/firefox_alignment.png

www.dennissheppard.net/chrome_alignment.png

www.dennissheppard.net/ie7_alignment.png

otable = $('#order_review_grid').dataTable({                
    'fnRowCallback': function (nRow, strings, displayIndex, dataIndex) {
        return formatRow(nRow, dataIndex);
    },
    'fnDrawCallback':function()
    {
        checkIfOrderSubmitted(this);                    
    },
    'aoColumnDefs':
    [
        { 'bVisible': false, 'aTargets': [COL_PRODUCT] },
        { 'bSortable': false, 'aTargets': [COL_IMAGE, COL_DELETE] },
        { 'sClass': 'right_align', 'aTargets': [COL_PRICE] },
        { 'sClass': 'center_align', 'aTargets': [COL_BRAND,COL_PACK] },
        { 'sClass': 'left_align', 'aTargets': [COL_DESCRIPTION] }
    ],
    'sDom': 't',
    'sScrollY':'405px',
    'bScrollCollapse':true,
    'aaSorting':[]
});

<table id="order_review_grid" class="grid_table" cellpadding="0px" cellspacing="0px">                 
    <thead class="grid_column_header_row" id="order_review_grid_column_header_row">
        <tr>
            <td class="" id='sequenceNumber'>SEQ #</td>
            <td class="grid_sc_header" id='statusCode'>Sc</td>
            <td class="grid_sc_header" id='onOrderGuide'>O.G.</td>
            <td class="grid_image_header" id='image'>Image</td>                         
            <td class="grid_description_header" id='description'>Description</td>                           
            <td class="grid_brand_header" id='label'>Brand</td>
            <td class="grid_pack_header" id='packSize'>Pack</td>
            <td class="grid_price_header" id='price'>Price</td>
            <td class="grid_qtrfull_header" id='caseQuantity'>Full</td>
            <td class="grid_qtrypart_header" id='eachQuantity'>Partial</td>
            <td class="grid_refnum_header" id='referenceNumber'>Ref #</td>
            <td class="grid_refnum_header">&nbsp;</td>
        </tr>
    </thead>
    <tbody class="">
        <!-- loaded data will go here -->
    </tbody>
</table>
dennis.sheppard
  • 2,565
  • 3
  • 19
  • 16
  • Did you ever find a soltuion for this? – DDiVita May 16 '12 at 20:56
  • Not really. tmanthey's answer below is partially true. If I turn off all my css, the issue goes away. But adding in every style one by one to see what causes the problem wasn't practical. I ended up looping through each data column and putting their widths in an array, then looping through the header columns and assigning each one the corresponding width from that array. This works well, to a point. If you have images in your DT, it's best if you run that piece of code after all images are loaded, else, the widths are adjusted once the images load, and everything is thrown off again. – dennis.sheppard May 18 '12 at 04:19
  • Note that this is a duplicate of http://stackoverflow.com/questions/13178039/datatables-header-alignment-issue – Ruslans Uralovs Aug 08 '13 at 08:10
  • 2
    I would venture to say since my question was posted a year before that one, that the other one is the duplicate. – dennis.sheppard Aug 08 '13 at 13:48

21 Answers21

26

I'm having the same problem here. It works fine (pixel-perfect column aligned) in Mozilla Firefox, Opera but not in Chrome 21.

Solution:

Like mentioned in this post http://datatables.net/forums/discussion/3835/width-columns-problem-in-chrome-safari/p1

Basically what is happening, is that DataTables is trying to read the width of the table, that the browser has drawn, so it can make the header match. The problem is that when DataTables does this calculation on your page, the browser hasn't shown the scrollbar - and hence the calculation is slightly wrong! The reason I suggest that it's a Webkit bug, is that, even after DataTables has run through all of it's logic, the scrollbar still hasn't been displayed. If you add the following code you can see the effect of this:

console.log( $(oTable.fnSettings().nTable).outerWidth() ); setTimeout( function () { console.log( $(oTable.fnSettings().nTable).outerWidth() ); }, 1 );

The interesting part is that after I added setTimeout and after it executed there was still one column not aligned. After adding "sScrollX": "100%", "sScrollXInner": "100%" all columns were aligned (pixel-perfect).

Solution for Chrome/Chromium, works ofcource in FF, Opera, IE9:

$(document).ready(function()
{
  var oTable = $('#mytable').dataTable(
  {
    "sScrollY":  ( 0.6 * $(window).height() ),
    "bPaginate": false,
    "bJQueryUI": true,
    "bScrollCollapse": true,
    "bAutoWidth": true,
    "sScrollX": "100%",
    "sScrollXInner": "100%"
  });


  setTimeout(function ()
  {
    oTable.fnAdjustColumnSizing();
  }, 10 );

});
broadband
  • 3,266
  • 6
  • 43
  • 73
10

I solved this problem by wrapping the "dataTable" Table with a div with overflow:auto

.dataTables_scroll
{
    overflow:auto;
}

and add this JS after your dataTable initialization

jQuery('.dataTable').wrap('<div class="dataTables_scroll" />');

Dont use sScrollX or sScrollY, remove then and add a div wrapper yourself which does the same thing.

Sharjeel Ahmed
  • 2,051
  • 2
  • 17
  • 25
  • I like your approach to this problem, however I am having a problem: while the scroll-x is acting fine just for the dataTable, the scroll-y is working for the whole web page instead of just for the dataTable -- am I missing something else? – Fausto R. Nov 16 '13 at 21:06
  • This is only good for a table without pagination or search bar. Since they all will be scrollable within that wrapper – Qiang Apr 21 '16 at 17:45
  • @FaustoR., that is because of tab-index attribute set on some parent of datatable,, try removing tab-index property and your datatable should scroll vertically as well – Akshay Vijay Jain Apr 03 '17 at 10:05
  • checkout scrolling effect of tab-index https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex – Akshay Vijay Jain Apr 03 '17 at 10:21
  • Apply this CSS to make it work fully: .dataTables_scroll { position: relative; overflow: auto; max-height: 200px; width: 100%; } – Albert Alberto Apr 02 '21 at 19:00
9

I had the problem and it turned out to be a side effect with my CSS. Try to disable all external css and see if the problem persists.

tmanthey
  • 4,547
  • 6
  • 35
  • 42
6
var table = $("#myTable").DataTable({
            "sScrollY": "150px",
            //"bAutoWidth": false // Disable the auto width calculation 
        });

    $(window).resize( function () {
        table.columns.adjust();
    } );
Gkrish
  • 1,811
  • 1
  • 14
  • 18
5
if ( $.browser.webkit ) {
    setTimeout( function () {
        oTable.fnAdjustColumnSizing();
    }, 10 );
}

Worked perfect for me!

setec
  • 15,506
  • 3
  • 36
  • 51
user4190052
  • 51
  • 1
  • 2
3

I had a similar issue, but mine resizes to fit after searching or sorting or interacting with the table in a way to cause a redraw, tried the redraw...function but no luck had to improvise in the end. The funny fix I that worked for me was calling oTable.fnFilter( "x",0 ) and oTable.fnFilter( "",0 ) in this same order (search and clear search)... this works...lol.. :)

Druid
  • 6,423
  • 4
  • 41
  • 56
Kunmi
  • 31
  • 3
2

this might help you (not sure but i guess that its worth trying)

add this code to the page

if ( $.browser.webkit ) {
   setTimeout( function () {
       oTable.fnAdjustColumnSizing();
   }, 10 );
}

taken from here width columns problem in Chrome & Safari

Also, i guess it worth trying to define the columns in the constructor only instead of defining them in the (leave tag empty)

NullPoiиteя
  • 56,591
  • 22
  • 125
  • 143
Daniel
  • 36,833
  • 10
  • 119
  • 200
  • fnAdjustColumnSizing doesn't do much. I've tried calling it in the JS console after the table loads. The columns only move slightly. Not nearly enough to make them line up. – dennis.sheppard Dec 23 '11 at 20:31
  • you used the setTimeout ? or called it only once? – Daniel Dec 23 '11 at 20:39
  • I don't mean I've done it in code. I've done it via the developer tools and firebug consoles after the page is loaded. If it doesn't do anything then, would it make a difference if I were to do it in code with a timeout? And if it would make a difference to put it in code somewhere (which I don't see how it would), where should it go? – dennis.sheppard Dec 24 '11 at 00:03
  • just put it (the entire code block) beneath the creating of your table otable = $('#order_review_grid').dataTable({ ... }); put the entire code that I posted (kust like in the link i posted in my answer...) worth case scenario it will do nothing... – Daniel Dec 24 '11 at 17:57
  • 1
    Worked for me. var oTable = $('#tblList').dataTable({ //"bInfo": false, //"bLengthChange": false "sScrollY": "320px", "bScrollCollapse": true, }); setTimeout(function(){ oTable.fnAdjustColumnSizing(); },10); – Vishnoo Rath Jun 24 '13 at 11:27
  • @VishnooRath Are you sure it worked ? didnt work for me – Santhosh Nov 28 '14 at 05:32
1

I also had this problem. After many different tries I tried the below and succeeded.

I tried adding label tag with the float property in the style attribute. Then it worked find.

For example:

<td class="" id='sequenceNumber'><label style="float:left;">SEQ #</label></td>
Beniston
  • 542
  • 1
  • 8
  • 17
1

I had a problem where the data in the columns was too large to fit and there was no place in the data for a line break. My solution was to add a div with an overflow and a title attribute like this:

<td style="width: 110px;max-width:200px;"><div style="overflow:hidden;" title="@item.NewValue" >@item.NewValue</div></td>

This caused the table to settle down almost completely.

pat capozzi
  • 1,412
  • 1
  • 20
  • 16
1

if you are using bootstrap:

.table {
    width: 100%;
    max-width: none; // >= this is very important
}
NinjaOnSafari
  • 998
  • 1
  • 8
  • 32
0

This is how I have got rid of this problem:

I use this generally to execute functions after a Ajax call has been completed

    WaAjaxHelper = {
    arr_execute_after_ajax: null,
    add_function_to_execute_after_ajax: function (fun) {

        if (typeof fun == 'function') {
            if (!this.arr_execute_after_ajax) {
                this.arr_execute_after_ajax = [];
            }
            this.arr_execute_after_ajax.push(fun)
            return true;
        } else {
            alert('ERROR: WaAjaxHelper.add_function_to_execute_after_ajax only functions possible');
            return false;
        }
    },
    execute_after_ajax: function () {
        if (this.arr_execute_after_ajax) {
            $.each(this.arr_execute_after_ajax, function (index, value) {
                try {
                    value();

                } catch (e) {
                    console.log(e);
                }
            })
        }
        this.arr_execute_after_ajax = null;
    }
}


$(document).ready(function () {
    $.ajaxSetup({
        async: true,
        beforeSend: function (xhr) {
            xhr.setRequestHeader("Accept", "text/javascript");
            $('.blockUI').css('cursor', 'progress');
        },
        complete: function (jqXHR, textStatus) {
            $('body').removeClass('waiting');
        },
        error: function (jqXHR, textStatus, errThrown) {
            alert("Ajax request failed with error: " + errThrown);
            ajax_stop();
        }
    });
    $(document).ajaxStart(ajax_start).ajaxStop(ajax_stop);
});


ajax_start = function () {
    // do something here
}
ajax_stop = function () {
   WaAjaxHelper.execute_after_ajax();
}

in the view:

  var tbl;
  WaAjaxHelper.add_function_to_execute_after_ajax(function (){tbl.fnDraw()})

where tbl stores the datatable object.

Holger
  • 1
0

Having the same problem in firefox, I changed a little the script jquery like this (in jquery.dataTables.js version 1.9.4) :

line 3466 (v1.9.4) : nScrollHeadInner.style.paddingRight = "0px"; //instead of bScrolling ? o.oScroll.iBarWidth + "px" : "0px";

line 3472 (v1.9.4) : nScrollFootInner.style.paddingRight = "0px"; //instead of bScrolling ? o.oScroll.iBarWidth + "px" : "0px";

It works even after sorting and filtering.

Eli
  • 414
  • 5
  • 10
0

I use bootstrap and I managed with this

<table id="datatable_patients" class="table table-striped table-bordered table-hover table-responsive" width="100%">
     <thead></thead>
     <tbody></tbody>
</table>
0

I had this problem with bootstrap 3 and the problem was related to left and right padding on my th and td elements that I added after the bootstrap styling was applied. Removing my left and right padding fixed the problem in my case.

sonstone
  • 697
  • 6
  • 9
0

We can handle this using css and minor changes in sDom.

Add following class in your css file

.scrollDiv {
    max-width:860px; //set width as per your requirement
    overflow-x:scroll;  
}

replace your 't' in sDom attribute of table with <"scrollDiv"t> and remove scrollX attribute of table

Save and Enjoy ! :)

Anupam Sharma
  • 1,529
  • 1
  • 14
  • 33
0

I found that the width would misalign in the first window scroll, so the solution is to, on the first scroll only request a new table draw.

const $table = $('#table').DataTable({ ... });

$(window).on('scroll', () => {
  $(window).off('scroll');
  $table.tables().draw();
});

Edit: Also works with a setTimeout function. This depends when the misaligning happens.

$table.tables().draw() is the key here.

afnpires
  • 601
  • 1
  • 8
  • 24
0

I too faced the same issue. I solved it by removing 'sScrollY':'405px' from the datatable property and used fixed header.

jonathan
  • 33
  • 5
0

JS

$('#<%=gridname.ClientID%>').dataTable( {                   

           "paging":         false
            });        

        });

Then above your gridview add a div element as below.

  <div style ="height:600px; overflow:auto;"> 
  <asp:GridView ID="id" runat="server" DataKeyNames="key" ClientIDMode="Static" HeaderStyle-BackColor="#99ccff"
        BorderStyle="Inset" BorderWidth="1px" CellPadding="4" HorizontalAlign="Center" AutoGenerateColumns="false" Width="98%"  >
etc..
</div>
Patrick Q
  • 6,373
  • 2
  • 25
  • 34
0

Not sure if I had the exact same problem. I was dealing with a very large table, 40+ columns, and was using horizontal and vertical scrolling. However, if the browser window was set so big that you could see the whole table, the column headings were left aligned and the table content was in the center.

I noticed in firebug that the table had gotten a width of 1352px through DataTables. Setting that to 100% made everything line up!

user934948
  • 19
  • 2
  • 7
0

I know this is quite old thread, but I landed here when searching for the header alignment issue. Turned out I needed a different solution, so posting here so that someone will find it useful.

I just added following in my style block and it solved the issue:

.table {table-layout:auto !important;}

Seems that Datatables adds fixed layout, so adding this line made my headers align correctly with data when scrolling

Sudhir
  • 113
  • 8
0

After a long struggle I managed to tweak it:

  1. add this after initializing the data table. Avoid adding "scrollY/scrollX", and also avoid enabling "scrollCollapse"
 $('#table_id').wrap('<div class="dataTables_scroll" />');
  1. Add these to your CSS Styles.
.dataTables_scroll
    {
        position: relative;
        overflow: auto;
        max-height: 200px;/*the maximum height you want to achieve*/
        width: 100%;
    }
  .dataTables_scroll thead{
    position: -webkit-sticky;
    position: sticky;
    top: 0;
    background-color: #fff;
    z-index: 2;
  }
Albert Alberto
  • 801
  • 8
  • 15