Datatables - fixedHeader with scrollX

I am trying to use datatables with fixedheader (v3) and also enable horizontal scrolling. Attached Violin http://jsfiddle.net/xF8hZ/344/

$(document).ready(function() {
    var table = $('#example').DataTable({        
       searching: false,
        paging: false,
        ordering: false,
        info: false,
        fixedHeader: true,
        scrollX: true
    });

} );

.

When scrolling, a fixed header width does not match the rest of the table. Can you help me solve this please?

thanks

+6
source share
5 answers

I found a solution in my project by doing the following:

$('#example').scroll(function() {
    if ( $(".fixedHeader-floating").is(":visible") ) {
        $(".fixedHeader-floating").scrollLeft( $(this).scrollLeft() );
    }
});

DataTables creates a new table as fixedHeader when scrolling down, what I do here is to detect when the user scrolls horizontally in the table $('#example'), and then I use scrollLeft()the fixedHeader to match the scroll position.

.css, fixedHeader:

.fixedHeader-floating {
    overflow: hidden;
}
0

.

let tableParams = {
    autoWidth: false,
    // etc...
    scrollX: true,
    fixedHeader: true,
    initComplete: function(settings, json) {
        // To fix the issue of when scrolling on the X axis, the header needs also to scroll as well.
        this.find('.dataTables_scrollBody').on('scroll', function() {
            this.find('.dataTables_scrollHeadInner').scrollLeft($(this).scrollLeft());
        });
    },
};   

, .

me.containerElement.find('.dataTables_scrollBody').css({'overflow-y': 'hidden'});   

containerElement - .

0

  $('.dataTables_scrollBody').on('scroll', function () {
       $('.dataTables_scrollHead', $(this).parent()).scrollLeft($(this).scrollLeft());
  });
0

(: FixedHeader ==> . 1 , )

:

  1. FixedHeader (.dataTables_scrollHeadInner) - (.dataTables_scrollBody)
  2. scrolltop FixedHeader.
  3. when scrolling horizontally, it will scroll through FixedHeader with body ( $('.dataTables_scrollHeadInner').scrollLeft($(this).scrollLeft()))

Js

// sorry - had to use global variable
// global variable for scroll-body y position
var yPositionOfScrollBody;

function adjustDatatableInnerBodyPadding(){
    let $dtScrollHeadInner = $('.dataTables_scrollHeadInner');
    let outerHeightOfInnerHeader = $dtScrollHeadInner.outerHeight(true);
    //console.log('outerHeightOfInnerHeader => ' + outerHeightOfInnerHeader);
    $('.dataTables_scrollBody').css('padding-top', outerHeightOfInnerHeader); 
}

function setFixedHeaderTop(header_pos){
    //console.log("header_pos : " + header_pos);
    $('.dataTables_scrollHeadInner').css({"top": header_pos});
}

function fixDatatableHeaderTopPosition(){
    //console.log("fixHeaderTop...");

    yPositionOfScrollBody = window.scrollY + document.querySelector('.dataTables_scrollBody').getBoundingClientRect().top;
    //console.log("yPositionOfScrollBody: " + yPositionOfScrollBody);

    setFixedHeaderTop(yPositionOfScrollBody);
}

function onDataTableInitComplete(settings, json) {

    // for vertical scolling
    yPositionOfScrollBody =  window.scrollY + document.querySelector('.dataTables_scrollBody').getBoundingClientRect().top;

    // datatable padding adjustment
    adjustDatatableInnerBodyPadding();

    // data table fixed header F5 (refresh/reload) fix
    let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
    //console.log("scrollTop => " + scrollTop);
    if(scrollTop > 1){
        let header_pos;
        if (scrollTop < yPositionOfScrollBody){
           header_pos = yPositionOfScrollBody - scrollTop;
        } else {
           header_pos = 0;
        }
        setFixedHeaderTop(header_pos);
    }

    let $dtScrollHeadInner = $('.dataTables_scrollHeadInner');
    // horizontal scrolling
    $('.dataTables_scrollBody').on('scroll', function () {

        let $dtScrollBody = $(this);

        // synchronize
        let amountOfLeftScroll = $dtScrollBody.scrollLeft();
        $dtScrollHeadInner.scrollLeft(amountOfLeftScroll);

        let scrollDiff =  $dtScrollHeadInner.scrollLeft() - amountOfLeftScroll;

        //console.log("scrollDiff: " + scrollDiff);

        if(scrollDiff < 0){
            $dtScrollHeadInner.css('left', scrollDiff);
        }else{
            //console.log("scroll back to left side");
            $dtScrollHeadInner.css('left', '');
        }

    });

    //console.log("adjusment mergin: " + yPositionScrollHeadInner);
    $(document).on('scroll', function () {
        let scroll_pos = $(this).scrollTop();
        if(scroll_pos <= 0){
            fixDatatableHeaderTopPosition();
        }else{
            let margin = yPositionOfScrollBody; // Adjust it to your needs
            let cur_pos = $('.dataTables_scrollHeadInner').position();
            let header_pos = cur_pos.top;
            if (scroll_pos < margin){
               header_pos = margin - scroll_pos;
            } else {
               header_pos = 0;
            }
            setFixedHeaderTop(header_pos);
        }
    });
}


$(function(){

    $("#tableId").DataTable({
        scrollX: true,
        fixedHeader: true,
        initComplete: onDataTableInitComplete,
        // ... : ...
    });
});

CSS

/* data table - scroll and fixed header */
table.dataTable.fixedHeader-floating {
    display: none !important;  /*Hide the fixedHeader since we dont need it*/
}

.dataTables_scrollHeadInner{
    margin-left: 0px;
    width: 100% !important;
    position: fixed;
    display: block;
    overflow: hidden;
    /*margin-right: 30px;*/
    background: white;
    z-index: 1;
}

.dataTables_scrollBody{
    padding-top: 2.5em;
}

div.dataTables_scrollHead table.dataTable {
    padding-right: 0;
}

Update 1 - Fix Sort Issue

use fixedHeader: false

$(function(){

    $("#tableId").DataTable({
        scrollX: true,
        fixedHeader: false,
        initComplete: onDataTableInitComplete,
        // ... : ...
    });
});
0
source

You can change the "left", but first save the initial value:

var initLeft = 0;

$(".dataTables_scrollBody").scroll(function () {
    if ($(".fixedHeader-floating").is(":visible")) {
        if (initLeft == 0)
            initLeft = $(".fixedHeader-floating").position().left;

        $(".fixedHeader-floating").css("left", $(this).scrollLeft() * (-1) + initLeft);
    }
});
0
source

All Articles