Reputation: 2844
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
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
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
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