Header does not resize when using scrollX

Header does not resize when using scrollX

rich_bradyrich_brady Posts: 5Questions: 0Answers: 0

My webpage has a left menu that can be hidden. The datatable is within a div which resizes to fill the screen as the menu hides.

If the datatable uses scrollX the columns resize correctly but the header does not. This leaves a large gap to the right of the header.

This JSFiddle shows the problem - click on the separator bar to hide the menu
https://jsfiddle.net/qofmcth3/6/

I have a workaround which uses ResizeObserver to fire a columns.adjust() whenever the datatable element resizes but this seems like a bug to me.

Has anyone else experienced this and know of a better fix?

Replies

  • colincolin Posts: 15,240Questions: 1Answers: 2,599
    edited July 2021

    It's because the scrolling creates an overlay on the table, so yep, you would need to use columns.adjust(). Unfortunately with the sliding animation that makes it messy, you need to delay the adjustment,

    Colin

  • rich_bradyrich_brady Posts: 5Questions: 0Answers: 0

    Hi Colin. Thanks for confirming the issue.

    Inspecting I can see that while the dataTables_scrollBody div and it's table (the main data table) have their widths set to 100% the dataTables_scrollHeadInner div and the header datatable have widths explicitly set to a number of pixels.

    Changing dataTables_scrollHeadInner and the header table to width=100% allows them to resize with the menu hiding but as soon as the main window is resized the datatables code sets them explicitly again.

    Hard to say exactly where in the minimised code (function Fa(a) :smile: ) but it's these two lines set the header width to the outerWidth of the main datatable in pixels.

    If I override those calls with the console and set both widths back to "100%" then the menu resizing works OK after a window resize.

  • allanallan Posts: 63,535Questions: 1Answers: 10,475 Site admin

    Yes, the inner one needs to have pixel sizing, otherwise the browser will attempt to collapse it down when it does overflow, causing the header and body to go out of sync.

    It sounds like you might be initialising the table while it is hidden, and then displaying it. Perhaps in a tab for example? You need to use the columns.adjust() method that Colin mentioned, when the table is made visible.

    Here is an example of that for Bootstrap tabs.

    Allan

  • rich_bradyrich_brady Posts: 5Questions: 0Answers: 0

    Hi Allen, thanks for your help.

    It doesn't open hidden.. unless something very odd is happening that I'm missing.

    This JSFiddle shows the issue.
    https://jsfiddle.net/h9qa1pwL/

    (That's a slightly cleaner example than my first post)

  • allanallan Posts: 63,535Questions: 1Answers: 10,475 Site admin

    Thanks - I missed that before, sorry. What do I need to do to trigger the error? It appears okay to me in both Firefox and Chrome:

    Allan

  • rich_bradyrich_brady Posts: 5Questions: 0Answers: 0

    If you click on the grey separator bar between the menu and table it will hide the menu and you'll see the issue on the far right of the header. The scrollbar doesn't have to be visible. Thanks.

  • allanallan Posts: 63,535Questions: 1Answers: 10,475 Site admin

    Oh I see - thanks. You need to tell DataTables that it needs to adjust it's column widths due to something else on the page having changed. That is done with the columns.adjust() method. For example you could use:

            setTimeout( function () {
                table.columns.adjust();
            }, 500);
    

    in your click handler to trigger it at the end of the animation.

    It is the scrolling that causes this to be needed. DataTables needs to use pixel defined width columns to sync the columns in the header and body when using scrolling. That isn't the case if you don't use scrollX or scrollY. If your UI allows for it, I would suggest not using those options on a UI which has animations such as this. Use Responsive instead to collapse the table down to fit.

    Allan

  • rich_bradyrich_brady Posts: 5Questions: 0Answers: 0

    Thanks very much Allen, that was my 'workaround', good to confirm that it's the correct way to handle this.

    The table was responsive and worked beautifully... but users insisted on a scrollable table :/

    For the benefit of others, as my menu code is used app wide but only some tables use scrollX so I have ResizeObserver code to trigger the adjust() and add each datatable to the list of 'observed' elements as required..

        // ResizeObserver to ensure header column widths are adjusted when the containing div resizes.
        // Not supported on IE
        var observer = window.ResizeObserver ? new ResizeObserver(function (entries) {
            entries.forEach(function (entry) {
                $(entry.target).DataTable().columns.adjust();
            });
        }) : null;
    
        // Function to add a datatable to the ResizeObserver entries array
        resizeHandler = function ($table) {
            if (observer)
                observer.observe($table[0]);
        };
    
        // Initiate additional resize handling on datatable
        resizeHandler($('#datatable_id'));
    

    JSFiddle example:
    https://jsfiddle.net/jqxer08t/

Sign In or Register to comment.