Sarath
Sarath

Reputation: 2844

jqgrid fixed column header and fixed footers

I was looking to fix the jqgrid column header and fixed footers. When there are other items along with jqgrid with data I was looking at fixing the header so that the user knows at all the time what he is looking at.

Here is the sample for what I am looking for

Note that here I am looking at browsers scroll bar. Does jqgrid support this?

Edit

As JQGrid is html table after all, I tried to use jQuery TH Float Plugin. Now it turns out that JqGrid is made of three tables One for the header, one for the data and the other for the footer. So it seems that I either have to modify thfloat to accommodate this or come up with something else...

Upvotes: 3

Views: 10105

Answers (3)

Carl Smith
Carl Smith

Reputation: 151

Sarath, what a great solution, helped me a lot. I've expanded on your work, so that the header will only "bounce" once, when it first gets scrolled off the page / repositioned. Afterward the position gets switched to fixed, but there all a lot of other elements that need compensation. Enjoy!

$(window).bind('scroll', function () {
    var _grid = $('#jqGrid');  // jqgrid name
    var dataTable = $(_grid[0].grid.bDiv);
    var headerTable = $(_grid[0].grid.hDiv);
    var dataTableTop = dataTable.offset().top;
    var dataTableHeight = dataTableTop + dataTable.outerHeight();
    var windowTop = $(window).scrollTop();
    var headerTablePosition = headerTable[0].style.position;

    //Scroll down         
    if (windowTop > dataTableTop - headerTable.height() && windowTop < (dataTableHeight - headerTable.height()) && headerTablePosition != "fixed")
    {
        var leftOffset = headerTable.offset().left + 'px';  // grab the offset before changing postition
        $(dataTable).css("top", (headerTable.height()+1) + "px");  // +1 to account for the border width of the header
        headerTable[0].style.position = "fixed";
        headerTable[0].style.top = "0px";
        headerTable[0].style.left = leftOffset;
        dataTable[0].style.height = "auto";
        $($(_grid[0].grid.sDiv)).css("top", (headerTable.height() + 1) + "px");  // footer table, +1 to account for the border width of the header
        var gridHeightString = $('#gview_jqGrid').css("height").replace("px", "");
        var newGridHeight = parseInt(gridHeightString) + headerTable.height() + 1;  // +1 to account for the border width of the header
        $("#gview_jqGrid").css("height", newGridHeight + "px"); //outermost grid element
    }
    //Scroll up
    else if (windowTop < (dataTableTop - headerTable.height()) && headerTablePosition == "fixed") 
    {
        headerTable[0].style.left = "0px";
        headerTable[0].style.position = "relative";
        $(dataTable).css("top", "0px");  
        $($(_grid[0].grid.sDiv)).css("top", "0px");  // footer table
        $("#gview_jqGrid").css("height", "100%");  //outermost grid element
    }
});

Upvotes: 0

Mat Newport
Mat Newport

Reputation: 3

I thought I'd mention how to populate the missing vars.

//grid = $("#yourGrid").jqGrid( ...

dataTable = $(grid[0].grid.bDiv);
footerTable = $(grid[0].grid.sDiv);
headerTable = $(grid[0].grid.hDiv);
//my header column was behind the grid
headerTable.css('z-index', '1000');
setInitializeHeadersAndFootersPosition();

Upvotes: 0

Sarath
Sarath

Reputation: 2844

This was a tough nut to crack.

I got it working by First css override the default which is overflow:hidden to

.ui-jqgrid .ui-jqgrid-sdiv{overflow:visible;}
.ui-jqgrid .ui-jqgrid-hdiv{overflow:visible;}

On the javascript JQuery came to my rescue I implemented the following

function screenBottom() {
    return $(window).scrollTop() + $(window).height();
}     
$(window).scroll(function () {
        var dataTableTop = dataTable.offset().top;
        var dataTableHeight = dataTableTop + dataTable.outerHeight();
        var windowTop = $(window).scrollTop();
        var windowBottom = screenBottom();
        //Scroll down         
        if (windowTop > dataTableTop - headerTable.height()
                && windowTop < (dataTableHeight - headerTable.height())) {
            headerTable.offset({ top: windowTop, left: headerTable.offset().left });
        }
        //For footer
        if (windowBottom > dataTable.offset().top + footerTable.outerHeight()
                && windowBottom < dataTableHeight + footerTable.outerHeight()) {
            footerTable.offset({ top: windowBottom - footerTable.outerHeight(), left: footerTable.offset().left });
        }
        //Re adjust of the movement is too fast
        if (windowTop < (dataTableTop - headerTable.height())
            && dataTableTop < (headerTable.offset().top + headerTable.height())) {
            headerTable.offset({ top: dataTable.offset().top - headerTable.height(), left: headerTable.offset().left });
        }
        if (windowBottom > dataTableHeight + footerTable.outerHeight()) {
            footerTable.offset({ top: dataTableHeight, left: footerTable.offset().left });
        }

    });

And then to check the footer and header while resizing the window

        $(window).resize(function () {
            setInitializeHeadersAndFootersPosition();
        });
function setInitializeHeadersAndFootersPosition() {
            var dataTableTop = dataTable.offset().top;
            var dataTableHeight = dataTableTop + dataTable.outerHeight();
            var windowTop = $(window).scrollTop();
            var windowBottom = screenBottom();
            if (windowBottom > dataTableTop && windowBottom < dataTableHeight) {
                footerTable.offset({ top: windowBottom - footerTable.outerHeight(), left: footerTable.offset().left });
            }
            if (footerTable.offset().top < dataTableHeight && windowBottom > dataTableHeight) {
                footerTable.offset({ top: dataTableHeight, left: footerTable.offset().left });
            }
            if (windowTop > dataTableTop && windowTop < dataTableHeight) {
                headerTable.offset({ top: windowTop, left: headerTable.offset().left }); //Header does not need the offset
            }
        }

Upvotes: 1

Related Questions