简体   繁体   中英

Jquery fixed header and a fixed column for a table, width of cell may be varying

This question has been asked quite a lot of time and I have tried with quite a few solutions from stack-overflow, including few mentioned below question-1 , question-2 but none of them seem to work when the table width is dynamic and so are the element rows.

My table structure uses another jquery plugin jqueryTreeTable Plugin. and structure is a little complex. It looks something like this , what I need to here is have it's header fixed on scrolling horizontal and have a column fixed for horizontal scrolling for the content may have horizontal scrollbar.

Useful jQuery Plugins for Working with Tables ( include re-sizable columns and fixed header )

I found this solution on the internet but I cannot find the reference where I found, I had to make quite a few changes. Please refer the comments in the code below for the changes I added. This worked for floating header part.

           $("table.tableWith-FloatingHeader").each(function() {
                $(this).wrap("<div class=\"divTableWithFloatingHeader\" style=\"position:relative\"></div>");

                var originalHeaderRow = $("thead", this);
                originalHeaderRow.before(originalHeaderRow.clone());
                var clonedHeaderRow = $("thead", this);

                clonedHeaderRow.addClass("tableFloatingHeader");

                originalHeaderRow.addClass("tableFloatingHeaderOriginal");
                if(originalHeaderRow.hasClass("tableFloatingHeader")){
                    originalHeaderRow.removeClass("tableFloatingHeader");
                }

                clonedHeaderRow = $('.tableFloatingHeader');
                clonedHeaderRow.css("position", "absolute");
                clonedHeaderRow.css("top", "0px");
                clonedHeaderRow.css("left", $(this).css("margin-left"));
                // originally visibility hidden only was used but it didn't work for me so I had to use display:none
                clonedHeaderRow.css("visibility", "hidden");
                clonedHeaderRow.css("display", "none");

                var tableBody = $('tbody', this);
                tableBody.css('display', 'table');


            });


            UpdateTableHeaders();
            $(window).scroll(UpdateTableHeaders);
            $(window).resize(UpdateTableHeaders);


            // since my table's width could be changing on click to the td (expand/collapse of td leads to change in width so to fix the width for the head and body UpdateTableHeader function is called.
            $("table.tableWith-FloatingHeader").undelegate("td", "click");
            $("table.tableWith-FloatingHeader").delegate("td", "click", function() {
                UpdateTableHeaders();
            });


// functions **



// function to fix the table head's width and it's visibility
    function UpdateTableHeaders() {
        $("div.divTableWithFloatingHeader").each(function() {
            var originalHeaderRow = $(".tableFloatingHeaderOriginal", this);
            var floatingHeaderRow = $(".tableFloatingHeader", this);
            var offset = $(this).offset();
            var scrollTop = $(window).scrollTop();
            if ((scrollTop > offset.top) && (scrollTop < offset.top + $(this).height())) {
                floatingHeaderRow.css("visibility", "visible");
                floatingHeaderRow.css("display", "block");
                floatingHeaderRow.css("top", Math.min(scrollTop - offset.top, $(this).height() - floatingHeaderRow.height()) + "px");
                if(!floatingHeaderRow.hasClass('visible'))
                    floatingHeaderRow.addClass('visible');
                originalHeaderRow.css("visibility", "hidden");
                originalHeaderRow.css("display", "none");

                // Copy cell widths from original header
                $("th", floatingHeaderRow).each(function(index) {
                    var cellWidth = $("th", originalHeaderRow).eq(index).css('width');
                    $(this).css('width', cellWidth);
                });

                // Copy row width from whole table
                floatingHeaderRow.css("width", $(this).css("width"));
            }
            else {
                originalHeaderRow.css("visibility", "visible");
                originalHeaderRow.css("display", "block");
                floatingHeaderRow.css("visibility", "hidden");
                floatingHeaderRow.css("display", "none");
                floatingHeaderRow.removeClass('visible');
                floatingHeaderRow.css("top", "0px");
            }
// since my problem was when I cloned the original head and hide it, it  wasn't able to sync with the change in width of the table body. I had to sync the width of the each of the tbodys tds with theads tds. 
            updateHeaderWidth();
        });
    }

// function to sync width for the table head with table body. 
    function updateHeaderWidth() {


        $("div.divTableWithFloatingHeader").each(function() {

            var table = $(this);
            var widths = [];
            var i = 0;

           // iterate through each of the tbodys first trs tds to get their width
            table.find('tbody .first-row td div.width-set').each(function(){

                widths[i] = $(this).width();
                i ++;
            });

           // iterate through theads ths add an element with the same width to both first tds and ths
           // note: step to add element to both the element is required else it would go a little out of sync
            table.find('thead.tableFloatingHeaderOriginal th.width-get, thead.tableFloatingHeader th.width-get').each(function(){

                i = $(this).attr('data-col-number');
                var width = widths[i];
                var widthKeeperTag = '<div style="width: ' + width + 'px; height: 1px;"></div>';
                if($(this).find('div').length){
                    $(this).find('div').replaceWith($(widthKeeperTag));
                }else{
                    $(this).html($(this).html() + widthKeeperTag);
                }
            });
        });
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM