Fix HTML Table Header While Scrolling Page Using jQuery
I have heard this question various times:
“Is there a cross-browser CSS/JavaScript technique to display a long HTML table such that the column headers stay fixed on-screen and do not scroll with the table body like the "freeze panes" effect in Microsoft Excel.”
This blog post display how can we use a little bit of jQuery
tweaking to fix position for the header of asp:Repeater (or any table header). It will keep the header
to float and be always on top.
Lets have a quick example for How to Fix HTML Table Header while scrolling page.
ASPX:
<table id="tblEmployee" border="0" cellpadding="5" cellspacing="1" class="tblborder"
width="100%">
<thead>
<tr class="header"
style="font-weight: bold;">
<td
align="center" colspan="7” >
Employee List
</td>
</tr>
<tr class="header"
style="font-weight: bold;">
<td
align="center"
width="3%">
S.No.
</td>
<td
align="center">
Employee Code
</td>
<td
align="center">
Employee Name
</td>
<td
align="center">
Department
</td>
<td
align="center">
Designation
</td>
<td
align="center">
Manager
</td>
<td
align="center">
Action
</td>
</tr>
</thead>
<tbody>
<asp:Repeater ID="rptEmployee"
runat="server">
<ItemTemplate>
<tr
class="bgGray
repeaterRow">
<td align="center" valign="top" width="3%">
<%# Container.ItemIndex + 1 %>
</td>
<td align="center" valign="top" nowrap="nowrap">
<asp:HiddenField ID="hdEmployee_ID"
runat="server"
Value='<%#Eval("Employee_ID")%>' />
<%#Eval("Employee_Code")%>
</td>
<td align="center" valign="top" nowrap="nowrap">
<%#Eval("Employee_Name")%>
</td>
<td align="center" width="10%" nowrap="nowrap">
<%#Eval("Department_Name")%>
</td>
<td align="center" valign="top" width="10%" nowrap="nowrap">
<%#Eval("Designation_Name")%>
</td>
<td align="center" valign="top" width="20%" nowrap="nowrap">
<%#Eval("Manager_Name")%>
</td>
<td align="center" valign="top">
<a id="aEdit"
runat="server"
href='<%#
Eval("Employee_ID","EditEmployee.aspx?Employee_ID={0}" ) %>'>
Edit</a>
</td>
</tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr
class="bgAlt
repeaterRow">
<td align="center" valign="top" width="3%">
<%# Container.ItemIndex + 1 %>
</td>
<td align="center" valign="top" nowrap="nowrap">
<asp:HiddenField ID="hdEmployee_ID"
runat="server"
Value='<%#Eval("Employee_ID")%>' />
<%#Eval("Employee_Code")%>
</td>
<td align="center" valign="top" nowrap="nowrap">
<%#Eval("Employee_Name")%>
</td>
<td align="center" width="10%" nowrap="nowrap">
<%#Eval("Department_Name")%>
</td>
<td align="center" valign="top" width="10%" nowrap="nowrap">
<%#Eval("Designation_Name")%>
</td>
<td align="center" valign="top" width="20%" nowrap="nowrap">
<%#Eval("Manager_Name")%>
</td>
<td align="center" valign="top">
<a id="aEdit"
runat="server"
href='<%#
Eval("Employee_ID","EditEmployee.aspx?Employee_ID={0}" ) %>'>
Edit</a>
</td>
</tr>
</AlternatingItemTemplate>
</asp:Repeater>
</tbody>
</table>
CSS:
.tblborder
{
background-color: #7c7a90;
font-family: Calibri;
font-size: 12px;
font-weight: bold;
text-align: center;
}
.header
{
border: 1px solid #aed0ea;
color: Gray;
font-weight: bold;
font-size: 14px;
font-family: Tahoma;
background: #d7ebf9 url(../../../Styles/images/ui-bg_glass_80_d7ebf9_1x400.png)
50% 50% repeat-x;
text-align:left;
}
.bgGray
{
font-weight: normal;
background: #f2f5f7 url(../../../Styles/images/ui-bg_diamond_100_f2f5f7_10x8.png)
50% 50% repeat;
color: #362b36;
padding:3px;
}
.bgAlt
{
background: #eff6fc;
font-weight: normal;
color: #362b36;
padding:3px;
}
.highlightRow
{
background: rgb(228,245,252);
color: Black;
}
.repeaterRow
{
text-decoration: none;
}
jQuery/Javascript:
<script type="text/javascript">
jQuery.fn.fixedtableheader = function (options) {
var settings = jQuery.extend({
headerrowsize: 1,
highlightrow: false,
highlightclass: "highlight"
},
options);
this.each(function
(i) {
var $tbl = $(this);
var $tblhfixed = $tbl.find("tr:lt("
+ settings.headerrowsize + ")");
var headerelement = "thead";
if ($tblhfixed.find(headerelement).length == 0)
headerelement = "td";
if ($tblhfixed.find(headerelement).length > 0) {
$tblhfixed.find(headerelement).each(function () {
$(this).css("width",
$(this).width());
});
var $clonedTable = $tbl.clone().empty();
var tblwidth = GetTblWidth($tbl);
$clonedTable.attr("id", "fixedtableheader" + i).css({
"position": "fixed",
"top": "0",
"left": $tbl.offset().left
}).append($tblhfixed.clone()).width(tblwidth).hide().appendTo($("body"));
if (settings.highlightrow) $("tr:gt("
+ (settings.headerrowsize - 1) + ")",
$tbl).hover(function () {
$(this).addClass(settings.highlightclass);
}, function () {
$(this).removeClass(settings.highlightclass);
});
$(window).scroll(function () {
if (jQuery.browser.msie &&
jQuery.browser.version == "6.0")
$clonedTable.css({
"position": "absolute",
"top":
$(window).scrollTop(),
"left": $tbl.offset().left
});
else $clonedTable.css({
"position": "fixed",
"top": "0",
"left": $tbl.offset().left -
$(window).scrollLeft()
});
var sctop = $(window).scrollTop();
var elmtop = $tblhfixed.offset().top;
if (sctop > elmtop && sctop
<= (elmtop + $tbl.height() - $tblhfixed.height())) $clonedTable.show();
else $clonedTable.hide();
});
$(window).resize(function () {
if ($clonedTable.outerWidth() !=
$tbl.outerWidth()) {
$tblhfixed.find(headerelement).each(function
(index) {
var w = $(this).width();
$(this).css("width",
w);
$clonedTable.find(headerelement).eq(index).css("width",
w);
});
$clonedTable.width($tbl.outerWidth());
}
$clonedTable.css("left", $tbl.offset().left);
});
}
});
function GetTblWidth($tbl) {
var tblwidth = $tbl.outerWidth();
return tblwidth;
}
};
</script>
<script type="text/javascript">
$(function () {
$("#tblEmployee").fixedtableheader({
headerrowsize: 2
});
/* to highlight row on mouseover*/
$('.repeaterRow').hover(function () {
$(this).children().addClass('highlightRow');
}, function () {
$(this).children().removeClass('highlightRow');
});
});
</script>
And that’s it. Just
place this fixedtableheader
function in a general javascript file reuse and call this function wherever you
want. Only thing to remember is to follow the table structure as mentioned. Let
me know if anything is not clear