Click here to Skip to main content
Click here to Skip to main content

Grid View with Fixed Header

By , 11 Mar 2010
 

Introduction

GridView control of ASP.NET makes our task much simpler as compared to HTML tables. But one problem which I always faced with GridView control is of scrolling headers. I tried several forums and websites, but didn’t come up with a good solution.

In this article, I am trying to solve the problem of scrolling headers in ASP.NET GridView control.

This article will fulfill the following requirements:

  • GridView will have fixed header.
  • GridView can be scrolled horizontally.
  • GridView can be scrolled vertically.

GridViewWithFixedHeader.png

Overview

GridView doesn’t have the ability to scroll. But if the GridView contains the larger number of rows or columns (say more than 100 rows and 15 columns), we want it to have scrollbars.

Since, the Div control has the ability to scroll horizontally and vertically, therefore, to achieve scrolling in GridView, we have to wrap the GridView in the Div control. It is the Div that actually scrolls, but it looks like the GridView is scrolling.

Wrapping the GridView in a Div (say DataDiv) and making the DataDiv overflow property to auto solves the problem of scrolling in GridView, but one problem is that the header of the GridView also scrolls up while scrolling it vertically (this is because, the DataDiv is actually scrolling but not the GridView).

To get the solution of this problem, put another Div (say HeaderDiv) above DataDiv.

The next step is to create a new HTML table in HeaderDiv which will contain the new header for the GridView. This job will be done by a JavaScript function (say CreateGridHeader()). This JavaScript function also sets the HeaderDiv style as per the DataDiv and new HTML table style as per GridView style and also we will hide the original header of GridView. This function will be called every time after filling the GridView with data as well as on the Page Load.

At this point, we will have header (new HTML table) and GridView as different entities.

Since, header and GridView both are different entities; therefore, one thing which is still left is how to scroll the header while scrolling the GridView horizontally. This job will be done by a JavaScript function (say Onscrollfnction ()) which will be executed at the scroll event of the DataDiv. This function will scroll the HeaderDiv along with the DataDiv while scrolling in the horizontal direction.

Objective

The main objective behind the overall exercise is to create the new table (which contains the new header row) above the GridView with the similar style attributes of the original header and hides the original header of GridView.

Using the Code

  1. The first thing we have to do is to put the GridView inside the Div tag and also define a Header Div which will contain the new Header as follows:
      <%--Div contains the new header of the GridView--%>
      <div id="HeaderDiv">
      </div>
      <%--Wrapper Div which will scroll the GridView--%>
      <div id="DataDiv" style="overflow: auto; border: 1px solid olive; 
    	width: 600px; height: 300px;" onscroll="Onscrollfnction();">
           <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="true" 
                  CellPadding="6" CssClass="GridViewStyle">
                  <HeaderStyle  CssClass="GridViewHeaderStyle" />
            </asp:GridView>
       </div>

    Please note the following points in the above code:

    1. GridView1 is the GridView which contains the data.
    2. DataDiv will make the GridView scrollable (horizontally as well as vertically). To make it scrollable, we have to set its overflow property to auto.
    3. I put a JavaScript function say Onscrollfnction () on DataDiv scrolling. This function will be executed every time when the DataDiv scrolls. The main idea behind this function is to scroll the HeaderDiv along with the DataDiv.
    4. HeaderDiv will contain the new header for GridView.
    5. Except this, other styling is not necessary. I just use all other styling for display purposes.
  2. In the second step, write a JavaScript function Onscrollfnction(), which will be executed when you scroll the DataDiv horizontally.
        function Onscrollfnction() 
        {   
            var div = document.getElementById('DataDiv'); 
            var div2= document.getElementById('HeaderDiv'); 
            //****** Scrolling HeaderDiv along with DataDiv ******
            div2.scrollLeft = div.scrollLeft; 
            return false;
        }

    This function will scroll the HeaderDiv along with the DataDiv while scrolling in horizontal direction.

  3. The third step is to write a Javascript function CreateGridHeader(). This function will create a new header table for the GridView in HeaderDiv and hides the original header. This function also resolves the style issues between HeaderDiv and DataDiv. This function will be called every time after filling the GridView with data as well as on the Page Load.
        function CreateGridHeader(DataDiv, GridView1, HeaderDiv) 
        { 
            var DataDivObj = document.getElementById(DataDiv);
            var DataGridObj = document.getElementById(GridView1);
            var HeaderDivObj = document.getElementById(HeaderDiv);
            //********* Creating new table which contains the header row ***********
            var HeadertableObj = HeaderDivObj.appendChild(document.createElement('table'));
            DataDivObj.style.paddingTop = '0px';
            var DataDivWidth = DataDivObj.clientWidth;
            DataDivObj.style.width = '5000px';
            //********** Setting the style of Header Div as per the Data Div ************
            HeaderDivObj.className = DataDivObj.className;
            HeaderDivObj.style.cssText = DataDivObj.style.cssText;
            //**** Making the Header Div scrollable. *****
            HeaderDivObj.style.overflow = 'auto'; 
            //*** Hiding the horizontal scroll bar of Header Div ****
            //*** this is because we have to scroll the Div along with the DataDiv.  
            HeaderDivObj.style.overflowX = 'hidden';
            //**** Hiding the vertical scroll bar of Header Div **** 
            HeaderDivObj.style.overflowY = 'hidden'; 
            HeaderDivObj.style.height = DataGridObj.rows[0].clientHeight + 'px';
            //**** Removing any border between Header Div and Data Div ****
            HeaderDivObj.style.borderBottomWidth = '0px'; 
            //********** Setting the style of Header Table as per the GridView ************
            HeadertableObj.className = DataGridObj.className;
            //**** Setting the Headertable css text as per the GridView css text 
            HeadertableObj.style.cssText = DataGridObj.style.cssText; 
            HeadertableObj.border = '1px';
            HeadertableObj.rules = 'all';
            HeadertableObj.cellPadding = DataGridObj.cellPadding;
            HeadertableObj.cellSpacing = DataGridObj.cellSpacing;
            //********** Creating the new header row **********
            var Row = HeadertableObj.insertRow(0); 
            Row.className = DataGridObj.rows[0].className;
            Row.style.cssText = DataGridObj.rows[0].style.cssText;
            Row.style.fontWeight = 'bold';
            //******** This loop will create each header cell *********
            for(var iCntr =0; iCntr < DataGridObj.rows[0].cells.length; iCntr++)
            {
                var spanTag = Row.appendChild(document.createElement('td'));
                spanTag.innerHTML = DataGridObj.rows[0].cells[iCntr].innerHTML;
                var width = 0;
                //****** Setting the width of Header Cell **********
                if(spanTag.clientWidth > DataGridObj.rows[1].cells[iCntr].clientWidth)
                {
                    width = spanTag.clientWidth;
                }
                else
                {
                    width = DataGridObj.rows[1].cells[iCntr].clientWidth;
                }
                if(iCntr<=DataGridObj.rows[0].cells.length-2)
                {
                    spanTag.style.width = width + 'px';
                }
                else
                {
                    spanTag.style.width = width + 20 + 'px';
                }
                DataGridObj.rows[1].cells[iCntr].style.width = width + 'px';
            }
            var tableWidth = DataGridObj.clientWidth;
            //********* Hidding the original header of GridView *******
            DataGridObj.rows[0].style.display = 'none';
            //********* Setting the same width of all the components **********
            HeaderDivObj.style.width = DataDivWidth + 'px';
            DataDivObj.style.width = DataDivWidth + 'px';    
            DataGridObj.style.width = tableWidth + 'px';
            HeadertableObj.style.width = tableWidth + 20 + 'px';
            return false;
        }  

    This function will take three parameters DataDiv, GridView, and HeaderDiv. This function needs to be called from the server side every time the Grid is filled with data and also on the Page Load.

  4. The final step is to fill the GridView with Data and call the JavaScript function CreateGridHeader () from server side. This JavaScript function is also called on page load.
    string conString = "Provider=Microsoft.JET.OLEDB.4.0; 
    data source=" + Server.MapPath (string.Empty)  + @"\Database\Northwind.mdb";
    string sqlString = "SELECT * FROM CUSTOMERS";
    OleDbConnection conn = new OleDbConnection(conString);
    DataSet ds = new DataSet();
    OleDbDataAdapter adapter = new OleDbDataAdapter(sqlString, conn);
    adapter.Fill(ds);
    GridView1.DataSource = ds.Tables[0];
    GridView1.DataBind();
    ClientScript.RegisterStartupScript(this.GetType(), "CreateGridHeader", 
    "<script>CreateGridHeader('DataDiv', 'GridView1', 'HeaderDiv');</script>");
  5. The CreateGridHeader () function needs to be called on Page Load also.
     protected void Page_Load(object sender, EventArgs e)
     {
           if (GridView1.Rows.Count > 0)
          {
               ClientScript.RegisterStartupScript(this.GetType(), 
    		"CreateGridHeader", 
                   	"<script>CreateGridHeader('DataDiv', 'GridView1', 
    		'HeaderDiv');</script>");
          }
     } 

You are now ready with the GridView with fixed headers.

Points of Interest

This solution is tested well with Internet Explorer, Mozilla Firefox, and Google Chrome.

History

  • Updated on 5-March-2010

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Prakash Varun 2010
Architect Inca Informatics
India India
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Questionproblem: selected index changed event is firing only oncememberGBVSivaRamKumar20 Mar '13 - 0:16 
I have used the above code and it is working fine for fixing header constant. I have written the following code in addition
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
    {
        ScriptManager.RegisterStartupScript(this,this.GetType(),"selectedindex","alert('"+GridView1.SelectedIndex+"');",true);       
        ClientScript.RegisterStartupScript(this.GetType(), "CreateGridHeader", "<script>CreateGridHeader('DataDiv', 'GridView1', 'HeaderDiv');</script>");
    }
    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        switch (e.Row.RowType)
        {
            case DataControlRowType.DataRow:
                e.Row.Attributes["onmouseover"] = "this.style.cursor='pointer';this.style.textDecoration='underline';";
                e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';";
                e.Row.ToolTip = "Click to select row";
                e.Row.Attributes["onclick"] = this.Page.ClientScript.GetPostBackClientHyperlink((GridView)sender, "Select$" + e.Row.RowIndex);
                break;
        }
    }
 
problem is selected index changed event is firing only once.Can u pls rectify the problem.
QuestionHeader not visible on page loadmemberixashish4 Feb '13 - 19:31 
Hello thank you for such good Gridview.
but facing some problems with Fixed header, it is not visible when page loads first, as soon as i refresh page it will visible unable to resolve please help.
 
also i want to fix first 2 columns and fix first row with header.
 
Thank you.
QuestionDemo file is correct ?memberMatin11021 Jan '13 - 6:52 
Hi Prakash.
 
I download and run your DEMO file .
Its very nice but Dont have Header and then fix header .
 
May I dont set any parameter & property correct ?
 
Can you help me solve this problem ?
 
thxalot.
matin
QuestionFreeze 1st 4 columns of Gridview along with Frozen headersmembersarada ganesh9 Nov '12 - 5:12 
I have a Gridview which has around 20 columns and 300+ rows. I need to fix their headers(which I have already done using code from CodeProject) and freeze the 1st 4 columns. I am not able to implement the 2nd part with css as suggested by many sites. Pls help.
QuestionIE9 fixmembergringoman130 Oct '12 - 2:59 
took me some time to figure Smile | :)
HeaderDivObj.style.height = "27px"; //DataGridObj.rows[0].clientHeight + 'px';
AnswerRe: IE9 fixmemberTony Dong13 Feb '13 - 12:29 
It is works for IE9, that is what I am looking for. Thanks
GeneralMy vote of 4memberFlyntMD25 Oct '12 - 7:39 
Working PERFECT in Chrome & FF. But NOT in IE 9.
GeneralMy vote of 5memberwsc091826 Aug '12 - 22:06 
Nice learning fix row/column header. I use superTable to match this function. I go learning
GeneralMy vote of 5memberNitin Jain 100521 Jun '12 - 7:22 
I have test It is working fine as i was expecting.. Seriously this guy is awesome...and example also.
QuestionUsing in MasterpagememberBpwill18 Jun '12 - 7:51 
I'm having an issue with using with Master pages as described here: http://debughere.blogspot.com/2011/11/creating-fixed-headers-in-aspnet.html?showComment=1339776358196
 
However, I cant understand the solution. Can anyone clarify?
GeneralMy vote of 5membertejashri.gandhi10 May '12 - 2:32 
Thanks..its works great for DataGrid as well..
GeneralMy vote of 5memberNilesh Patil Kolhapur16 Apr '12 - 20:27 
very very very nice sir
QuestionHow to get onscroll event for div ?memberpmahanta10 Apr '12 - 20:55 
onscroll= funtion()
SuggestionExcellent but when come to IE 9.0 it's changing designmemberBojjaiah27 Mar '12 - 23:53 
Hi prakash,
 
you did excellent but when running application in IE 9.0 changing design So,
if you possible update this article as per Supporting all versions browser.
 
but set compitable view it's working very good.
 
any way my vote a 5.
Smile | :)
GeneralThank youmemberDarshanKumar25 Mar '12 - 23:49 
Thank you for such nice work.
QuestionNice but column width and header width not equalmemberabtinC# 20093 Feb '12 - 21:47 
I'm trying your code.it work very nice but my grid header and column width's no equal.
please help
GeneralMy vote of 1memberPratik_Vish30 Jan '12 - 0:17 
there's more better and simple solution to this
GeneralRe: My vote of 1memberPrakash Varun 201017 Apr '12 - 7:45 
plz share the same.....
QuestionNot working with UpdatepanelmemberMember 810652128 Dec '11 - 18:35 
Hi,
 
I use this solution its work fine. but when I use it under UpdatePanel then scrollable Header not worked. Means scrollable
Header disappear & gridview original header show.
GeneralMy vote of 5memberAytha Raki14 Dec '11 - 19:22 
Good article..but when i run this code in IE..header is invisible
QuestionAnyone know why the example code stopped working in IE9?memberjnewquis28 Sep '11 - 9:30 
Tried all day to figure this one out. The original header gets hidden but the replacement header is never shown/added.
 
Thanks ahead of time.
Generalsignificance of '5000px'membernirmalsat5 May '11 - 7:37 
What is the significance of setting the width of the datadivobj to '5000px'
GeneralPaging Not workingmemberJayakumar23 Mar '11 - 5:07 
Paging Not working
GeneralErrormemberJayakumar22 Mar '11 - 20:36 
I am getting error. Error
 
The name 'GridView1' does not exist in the current context
F:\Sample Projects\GridViewFixedHeader\GridViewFixedHeader\Default.aspx.cs
 
protected void Page_Load(object sender, EventArgs e)
{
if (GridView1.Rows.Count > 0) {
ClientScript.RegisterStartupScript(this.GetType(), "CreateGridHeader", "<script>CreateGridHeader('DataDiv', 'GridView1', 'HeaderDiv');</script>");
}
}
 
The bold line is producing error
GeneralRe: ErrormemberMember 826116926 Sep '11 - 20:22 
you have to specify the ID of the grid view in GRIDVIEW1.
QuestionNot working for table with too many columns?memberMember 76507804 Feb '11 - 3:10 
I tried this solution it is working fine if table no of columns are less but if there are too many columns(70) data and column header are in mismatch.
 
I tried the same code for table1 with 5 columns and table2 with 70 columns
 
The code works fine for table 1 but not for table 2. I think something should be changed in this code.Please le me know the soultion..I really need this to be done.
 
//****** Setting the width of Header Cell **********
if (spanTag.clientWidth > DataGridObj.rows[1].cells[iCntr].clientWidth) {
width = spanTag.clientWidth;
}
else {
width = DataGridObj.rows[1].cells[iCntr].clientWidth;
}
if (iCntr <= DataGridObj.rows[0].cells.length - 2) {
spanTag.style.width = width + 'px';
}
else {
spanTag.style.width = width +20+ 'px';
}
DataGridObj.rows[1].cells[iCntr].style.width = width + 'px';
 
Do you think I need to change add value 'spanTag.style.width = width +20+ 'px';' to 30 ect to fit my table?
GeneralMy vote of 5memberahsan sarfraz24 Jan '11 - 1:07 
i was in search of this. and your solution worked for me thanks
GeneralAwsome! Help me a lot! Thank you!memberdesheng li8 Dec '10 - 9:59 
Awsome! Help me a lot! Thank you!
GeneralSorting featurememberMargarita186 Oct '10 - 12:02 
Great article, but it would be completely awesome if the code allow column sorting
GeneralRe: Sorting featurememberMargarita186 Oct '10 - 12:08 
I take my words back. It Does sort. All you have to do is to make Sortable = True in the Grid Smile | :) Thanks a lot for a great code!
GeneralRe: Sorting featurememberPrakash Varun 20106 Oct '10 - 18:57 
Good to hear that Smile | :)
GeneralMy vote of 4memberSebastien Termote5 Aug '10 - 2:14 
Good article, thanks
GeneralPager and Footer Stylememberonur_odemis22 Jun '10 - 6:08 
Hi this is excelent article but I have a question about pager style.
I would like to show pager style in the footer container
Sign In·View Thread·Permalink
Generalwith master page y ajaxmemberwiviropu2 Jun '10 - 13:34 
hello Prakash,
it would be like the example with Ajax and masterpage
Thank
GeneralProblem when used with master pagememberRam6192 Jun '10 - 2:28 
Hi Prakash,
 
My aspx page has a master page. I implemented ur script function when i drag the horizontal scroll, masterpage content is moving and header is not visible.
 
Regards
Sivaram.
GeneralRe: Problem when used with master pagememberShuraF28 Sep '10 - 6:14 
you need to adjust onscroll function:
 
function Onscrollfunction(dataDivID, headerDivID) {
var div = document.getElementById(dataDivID);
var div2 = document.getElementById(headerDivID);
//****** Scrolling HeaderDiv along with DataDiv ******
div2.scrollLeft = div.scrollLeft;
return false;
}
and pass in corresponding element's ClientID
GeneralRe: Problem when used with master pagememberMember 984637119 Feb '13 - 1:34 
/*
you need to adjust onscroll function:

function Onscrollfunction(dataDivID, headerDivID) {
var div = document.getElementById(dataDivID);
var div2 = document.getElementById(headerDivID);
//****** Scrolling HeaderDiv along with DataDiv ******
div2.scrollLeft = div.scrollLeft;
return false;
}
and pass in corresponding element's ClientID
*/
 

Could you please add the sample code for this step?
 
How to pass the ClientIDs of two different div's to a js function?
GeneralGridview in Ajaxmembercornfed19 Apr '10 - 5:09 
Great code m8! I'm using the code in an Updatepanel tho. Tried using the animationextender to call your code every time it gets updated. Having the problem that my width changes when I update the panel after refreshing the data in the grid. U might have a clue where I can find a solution for that? thnx
GeneralRe: Gridview in AjaxmemberPrakash Varun 201019 Apr '10 - 19:00 
Can you send me the sample code, or solution, so that I can check that....
GeneralRe: Gridview in Ajaxmemberjcabiling21 Dec '10 - 12:54 
Does not work inside an Update Panel. DO you have a sample code?
GeneralNice workmemberGaurav Dudeja India11 Apr '10 - 18:55 
Nice article, my vote is 4
Gaurav Dudeja
http://www.gdinfotechindia.com

Dont be afraid of changing your life to better !

GeneralIn this code does not work in FireFoxmemberdipaksalusalpha8 Apr '10 - 0:18 
Please help me
GeneralRe: In this code does not work in FireFoxmemberPrakash Varun 20108 Apr '10 - 2:49 
I had already tested this code in Firefox. It works fine. Just download the sample code and try to run it.
GeneralIE 8 IssuememberSatishChandraKV24 Mar '10 - 3:41 
Hi Prakash, I am getting an issue of the column widhts not matching for the data ans header. Any thoughts ?
GeneralRe: IE 8 IssuememberPrakash Varun 201024 Mar '10 - 4:46 
Hi Satish,
 
I had already tested my code in IE 8 and it is working fine. One thing you can do is... change the "compatibility view settings" in IE8.
 
Go to Tools.... "Compatibility View Settings" and check "Display all websites in Compatibility View".
 
I think this will resolve the issue.
GeneralRe: IE 8 IssuememberAnurag Gandhi23 Apr '10 - 19:07 
changing "Compatibility View Settings" is not the solution.
Just understand what is compatibility view.
Anurag Gandhi.
http://www.gandhisoft.com
Life is a computer program and every one is the programmer of his own life.

GeneralMy vote of 2memberMember 386855019 Mar '10 - 1:24 
good
GeneralGood jobmemberArlen Navasartian18 Mar '10 - 5:50 
But It doesn't work well in IE8
Does It need any changes ?
The header and rows are not in the same position.
Thank you.
-------
Arlen.N

GeneralRe: Good jobmemberPrakash Varun 201019 Mar '10 - 21:03 
Hi Arlen
 
I had already tested this code in IE 8. It works well. Just download the sample code and try to run it.
GeneralCoolmemberthatraja12 Mar '10 - 20:54 
It's working in Firefox too 3 browsers(i mean Gridview Fixed Header). 5 from me. Smile | :)

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 11 Mar 2010
Article Copyright 2010 by Prakash Varun 2010
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid