How to fix GridView's Header row while scrolling?
I googled a lot, find some are using expression wich only work for IE and the performance is bad. Some are using TBody scroll, which also does not work well in all browsers. Also I found a JQuery plugin which is working very well in their demo page, but does not work for my case. Below is my Html Code:
<div style="overflow-x:hidden; overflow-y:auto; height:360px;">
<asp:GridView ID="gvClient" runat="server" AutoGenerateColumns="false" CssClass="gvList"
Width="100%" GridLines="none" OnRowDataBound="gvClient_RowDataBound">
<HeaderStyle CssClass="gvHeader" />
<RowStyle CssClass="gvmRow" />
<SelectedRowStyle CssClass="gvSelRow" />
<AlternatingRowStyle CssClass="gvmAlternateRow"/>
<Columns>
....
</Columns>
</asp:GridView>
</div>
My purpose is to fix the GridView's header while scroll the "div". How to do this? After some search, I decide to use JavaScript to Clone the HeaderRow and put it above of "div" container. My Html code looks like:
<div id="fixClientHeader"></div>
<div style="overflow-x:hidden; overflow-y:auto; height:360px;">
....
</div>
The next step is to write JavaScript function to copy the GridView header row into fixClientHeader div. Below is my JavaScript function:
var isIE = (navigator.appName.indexOf("Microsoft")!=-1)? true:false;
function fixHeader(fhId, tblId, headerRowCount)
{
var divHeader = document.getElementById(fhId);
var tbl = document.getElementById(tblId);
var tempTable = document.createElement("table");
tempTable.cellPadding = tbl.cellPadding;
tempTable.cellSpacing = tbl.cellSpacing;
tempTable.border = tbl.border;
tempTable.bgColor = tbl.bgColor;
tempTable.className = tbl.className;
var tBody = document.createElement("tbody");
var hdrRow, numOfCells, newRow;
var maxRowCount = tbl.rows.length;
for(var i=0;i<headerRowCount;i++)
{
tBody.appendChild(fixHeader_CreateHeaderRow(tbl.rows[i]));
}
tempTable.appendChild(tBody);
divHeader.innerHTML = "";
divHeader.appendChild(tempTable);
if( isIE )
{
var div = document.createElement("div");
divHeader.parentNode.appendChild(div);
divHeader.parentNode.removeChild(div);
}
setTimeout(function(){refreshDataCols(tempTable, tbl);}, 50);
}
function refreshDataCols(header, source)
{
var headerRow = header.rows[0];
var numOfCells = headerRow.cells.length;
if( isIE )
numOfCells--;
for(var row=0;row<source.rows.length;row++)
{
for (var n=0; n<numOfCells; n++)
{
fixHeader_SetCellStyle(source.rows[row].cells[n], headerRow.cells[n], "width");
}
}
}
function fixHeader_CreateHeaderRow(hdrRow)
{
var newRow = document.createElement("tr");
var numOfCells = hdrRow.cells.length
newRow.className = hdrRow.className
for (var n=0; n<numOfCells; n++)
{
var cell = document.createElement("th");
cell.innerHTML = hdrRow.cells[n].innerHTML
cell.align = hdrRow.cells[n].align
cell.className = hdrRow.cells[n].className
cell.scope = hdrRow.cells[n].scope;
if ( isIE )
{
if( n != (numOfCells - 1))
{
cell.style.width = hdrRow.cells[n].clientWidth;
}
else
{
cell.style.width = 1;
cell.innerHTML = "";
cell.className = "";
}
cell.style.height = hdrRow.cells[n].clientHeight;
}
else
{
fixHeader_SetCellStyle(cell, hdrRow.cells[n], "width");
fixHeader_SetCellStyle(cell, hdrRow.cells[n], "height");
}
newRow.appendChild(cell);
}
hdrRow.style.visibility = "hidden";
hdrRow.style.display = "none";
return newRow;
}
function fixHeader_SetCellStyle(target, source, styleName)
{
var v = getStyle(source, styleName);
if( v && v != "undefined")
target.style[styleName] = v;
}
function getStyle(ele,name)
{
var style = ele.currentStyle?ele.currentStyle:document.defaultView.getComputedStyle(ele,null);
return style[name];
}
If you read the JavaScript code carefully, you will find I have put some special handling for IE browsers. For example: getStyle(ele,name) function only works in FireFox, Safari, does not work in IE. So I use the clientWidth instead if the browser is IE.
But the clientWidth property does not work well in IE also, that is why I ignore the last column when I resizing the GridView column with after I hide the GridView's HeaderRow.
How to use this? Just simply call: fixHeader('fixClientHeader', 'gvClient', 1)
I have tested this function in FireFox 3.5.4 and IE7, It works fine.