dennis.sheppard
dennis.sheppard

Reputation: 2595

jQuery Datatables Header Misaligned With Vertical Scrolling

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>

Upvotes: 27

Views: 77062

Answers (21)

Albert Alberto
Albert Alberto

Reputation: 952

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;
  }

Upvotes: 0

Sudhir
Sudhir

Reputation: 113

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

Upvotes: 0

user934948
user934948

Reputation: 19

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!

Upvotes: 0

NinjaOnSafari
NinjaOnSafari

Reputation: 1016

if you are using bootstrap:

.table {
    width: 100%;
    max-width: none; // >= this is very important
}

Upvotes: 1

user6832758
user6832758

Reputation: 1

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>

Upvotes: 0

jonathan
jonathan

Reputation: 43

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

Upvotes: 0

afnpires
afnpires

Reputation: 609

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.

Upvotes: 0

Gkrish
Gkrish

Reputation: 1881

var table = $("#myTable").DataTable({
            "sScrollY": "150px",
            //"bAutoWidth": false // Disable the auto width calculation 
        });

    $(window).resize( function () {
        table.columns.adjust();
    } );

Upvotes: 6

Daniel
Daniel

Reputation: 37051

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)

Upvotes: 2

Anupam Sharma
Anupam Sharma

Reputation: 1569

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 ! :)

Upvotes: 0

user4190052
user4190052

Reputation: 51

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

Worked perfect for me!

Upvotes: 5

sonstone
sonstone

Reputation: 717

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.

Upvotes: 0

Colbiocin
Colbiocin

Reputation: 1

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>

Upvotes: 0

pat capozzi
pat capozzi

Reputation: 1459

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.

Upvotes: 1

Sharjeel Ahmed
Sharjeel Ahmed

Reputation: 2061

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.

Upvotes: 10

Eli
Eli

Reputation: 444

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.

Upvotes: 0

Holger
Holger

Reputation: 1

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.

Upvotes: 0

broadband
broadband

Reputation: 3488

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 );

});

Upvotes: 26

Beniston
Beniston

Reputation: 542

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>

Upvotes: 1

Kunmi
Kunmi

Reputation: 31

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.. :)

Upvotes: 3

tmanthey
tmanthey

Reputation: 4615

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.

Upvotes: 8

Related Questions