Mottie/tablesorter

Graphic error for long tables opened in modal

Closed this issue · 8 comments

Not much to say here, but this error occurs ONLY if the table exceeds the length of the page.
http://awesomescreenshot.com/0fc4htlr54

Hi @clod986!

It appears that you are referring to the stickyHeader widget not aligning with the table?

I can't actually tell what type of modal window is being used in that screenshot, but if you are using the Magnific Popup, then please refer to the stickyHeader widget demo, or cssStickyHeaders demo.

See this demo on how to make the stickyHeader widget work within a jQuery UI dialog window.

Essentially, it all in how the stickyHeaders_attachTo option is set:

  • Magnific wrapper: cssStickyHeaders_attachTo: '.mfp-wrap'
  • jQuery UI Dialog wrapper: stickyHeaders_attachTo: '#popup' (same ID used to init)
$(function () {

    $('.open-popup-link').click(function () {
        dialog.dialog("open");
    });

    var dialog = $("#popup").dialog({
        autoOpen: false,
        height: $(window).height() - 20,
        width: 650,
        modal: true,
        open: function (event, ui) {
            // Will fire when this popup is opened
            // jQuery UI Dialog widget
            $('#table0').tablesorter({
                theme: 'blue',
                headerTemplate: '{content} {icon}', // Add icon for various themes
                widgets: ['zebra', 'filter', 'stickyHeaders'],
                widgetOptions: {
                    // jQuery selector or object to attach sticky header to
                    stickyHeaders_attachTo: '#popup',
                    stickyHeaders_offset: 0,
                    stickyHeaders_addCaption: true
                }
            });
        }
    });

});

Hi @Mottie , thank you for the quick reply.
YES, the widget is exactly that one, but NO, the modal is a bootstrap modal. Is the code you wrote useful for that scenario also?

It looks like it's not just broken when placed inside a modal...
Until last month this was working as intended

I got it working, but the top is offset incorrectly due to the modal header

http://jsfiddle.net/856bzzeL/42/

if you remove the header & title, and add a negative margin to the wrapper, it works better:

http://jsfiddle.net/856bzzeL/44/

I noticed that the stickyHeaders_offset is not working within an attachTo element. I'll work on a fix.

It still won't work if you open the modal for the second time...

It appears that the "shown.bs.modal" event isn't firing after the animation completes, so remove the "modal" class from the wrapper (demo):

<div class="modal" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">

So the problem is with the modal opening animation. If you trigger a scroll event on the modal window within the "shown" event, it hides the sticky header properly the second time the modal is opened (demo):

$(function () {

    $('#myModal').on('shown.bs.modal', function () {
        $('#table0').tablesorter({
            theme: 'blue',
            headerTemplate: '{content} {icon}', // Add icon for various themes
            widgets: ['zebra', 'filter', 'stickyHeaders'],
            widgetOptions: {
                // jQuery selector or object to attach sticky header to
                stickyHeaders_attachTo: '#myModal',
                stickyHeaders_offset : 0,
                stickyHeaders_addCaption: true
            }
        });
        // make sure the stickyHeader isn't showing the second
        // time a modal is opened
        $('#myModal').scroll();
    });

});

I don't think I'm going to modify the stickyHeaders widget to accommodate for the differences with Bootstrap. If I did, I'd have to add another option to offset the top positioning - right now the offset option changes the point where the stickyHeader appears along with it's location. For Bootstrap, the two points are actually different. I just don't have the time to add another option, and test it in all scenarios. So, for now if you want to use a Bootstrap modal, you'll need to include some css to change the stickyheader wrapper top margin to position it correctly:

/* Bootstrap tweaks 
 adjust margin-top to accomodate for the Modal title block
 adjust margin-left to tweak positioning
*/
 .tablesorter-sticky-wrapper {
    margin-top: -87px;
    margin-left: -2px;
}
.modal-body {
    overflow-x: auto;
}

Hi @Mottie!

Today I had to find a solution to this and developed these few lines. Maybe you'll find them helpful, but we both know they are fine just with Bootstrap modals

if($table.closest('.modal').length > 0){
    $sticky_container = $($table.closest('.modal'));
    var $modal_body = $('.modal-body', $sticky_container);
    var $margin_height = parseInt($('.modal-dialog', $sticky_container).css('margin-top'));
    $margin_height += parseInt($('.modal-header', $sticky_container).outerHeight(true));
    $margin_height += parseInt($modal_body.css('padding-top'));
    if($table.parentsUntil($modal_body).length > 0){
        $.each($($table.parentsUntil($modal_body), $modal_body).prevAll(), function(){
            $margin_height += $(this).outerHeight(true);
        });
    }
    $('<style>#'+$sticky_container.prop('id')+'.modal .tablesorter-sticky-wrapper{margin-top: -'+Math.floor($margin_height)+'px; margin-left: '+parseInt($modal_body.css("padding-left"))+'px;}</style>').appendTo($sticky_container);
}