Fixed GridView's Header while scrolling using JavaScript

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.

Subscribe
Rss Feed Email Follow Us on Twitter
Search