BlueLemonCode.Com

Yet Another Tech Blog

Freezing gridview header and columns while scrolling rest of the content

Introduction

In asp.net forums I frequently find question about way to freeze gridview header and/or columns while allowing rest of content to scroll. For long gridview data it is also desirable from user perspective. Some of jQuery plugins are available to do this task. In this short article, I am going to demonstrate using "jQuery.FixedTable" plugin for asp.net gridview.

Update: There was a issue with the alignment of frozen and normal columns. The same has been fixed and sample application is attached with this article. To know more read the update section towards the end of article.

Article Body

To create this sample, I have used "jQuery.FixedTable" plugin. You can download it here
Also, I have used NorthWind database table to populate gridview in this sample.

To start with, Follow below steps.

  • Create new asp.net website
  • Download and add jQuery.FixedTable.js file in your script folder of web site project
  • Add reference to jQuery file jquery-1.4.1.min.js in aspx file
  • Add reference to jQuery file jquery.fixedtable.js in aspx file

Adding GridView control in aspx page

The jQuery plugin which we are going to use, works on simple table tag. The GridView control is rendered as normal table in the browser at the end. However, to use the plugin, we have to wrap GridView inside separate div control. The both Div and GridView controls should be given a unique class name which would then be used to bind it with the jQuery plugin.

The required aspx side code is

<div id="divGrid" class="tableDiv">

        <asp:GridView ID="grdData" runat="server" AutoGenerateColumns="true" 
            CellPadding="4" GridLines="None" class="FixedTables" Width="600">            
            
        </asp:GridView>
</div> 

I have used AutoGenerateColumn as true above. You could set it to false and create bound fields inside grid without any issue. Apart from aspx design, add below style in the page head (or in separate style sheet file)

<style type="text/css">
        body
        {
            width: 900px;
        }
        p
        {
            float:left;
            width: 100%;
            margin: 20px 0px;
        }
        .fixedColumn .fixedTable td
        {
            color: #FFFFFF;
            background-color: #5097d1;
            font-size: 14px;
            font-weight: normal;
        }
        
        .fixedHead td, .fixedFoot td
        {
            color: #FFFFFF;
            background-color: #5097d1;
            font-size: 14px;
            font-weight: normal;
            padding: 5px;
            border: 1px solid #187BAF;
        }
        .fixedTable td
        {
            font-size: 10pt;
            background-color: #FFFFFF;
            padding: 5px;
            text-align: left;
            border: 1px solid #CEE7FF;
        }
    </style>

Next, in the code behind file, bind the GridView to the dataset

        DataSet ds = cl.GetData("select * from dbo.Customers");
        grdData.DataSource = ds;
        grdData.DataBind();
        grdData.HeaderRow.TableSection = TableRowSection.TableHeader;

Using HeaderRow.TableSection property

Our jQuery plugiin also requires that header row of the HTML table should be enclosed inside <thead> tag. However, when rendered by default, GridView does not emit <thead> tag and hence, jQuery plugin fails to freeze the header row. 

To make GridView control emit the <thead> tag, we can use HeaderRow.Tablesection property of gridview. It should be used only after DataBind has been called for GridView.

Using jQuery Plugin

After following all above steps, we would get simple GridView populated with data. Now, this is the time to associate it with the jQuery plugin and see freezing of gridview header and columns.

Add below javascript code in head of your page

<script type="text/javascript">
         $(document).ready(function () {
               
                $(".tableDiv").each(function () {
                    var Id = $(this).get(0).id;
                    var maintbheight = 355;
                    var maintbwidth = 860;

                    $("#" + Id + " .FixedTables").fixedTable({
                        width: maintbwidth,
                        height: maintbheight,
                        fixedColumns: 1,
                        // header style
                        classHeader: "fixedHead",
                        // footer style        
                        classFooter: "fixedFoot",
                        // fixed column on the left        
                        classColumn: "fixedColumn",
                        // the width of fixed column on the left      
                        fixedColumnWidth: 100,
                        // table's parent div's id           
                        outerId: Id,
                        // tds' in content area default background color                     
                        Contentbackcolor: "#FFFFFF",
                        // tds' in content area background color while hover.     
                        Contenthovercolor: "#99CCFF",
                        // tds' in fixed column default background color   
                        fixedColumnbackcolor: "#5097d1",
                        // tds' in fixed column background color while hover. 
                        fixedColumnhovercolor: "#99CCFF"
                    });
                });
            });
           $(".fixedTable table").attr('rules', 'All');
    </script>

Note that, we have to specify height and width of the complete GridView in maintbheight and maintbwidth Javascript variables. After running the page, the gridview is displayed with headers and left first column in freeze mode. The scroll positions in below snapshot indicate the same.

In FixedTable function in jQuery code above, you can change value of parameter named fixedColumns; so as to increase number of columns in freeze mode or remove column freezing (freeze headers only). the fixedColumnWidth parameter indicates total width of all columns in freeze mode. Hence, if you increase number of columns in freeze mode then, increase this width or if you remove column freezing (by setting fixedColumns parameter to 0) then set the width parameter to zero.

If you find any issue with this code or plugin, please let me know. I will try to fix the same.

I hope somebody out there find this short article useful. Thanks for visiting my site! :)

Update:

While following this article, many readers faced issue regarding alignment of frozen column with rest of columns and many of them reported in the comment and some even dropped me a e-mail requesting to fix the same. Although, there would not be any issue in case you are using IE. But, with FireFox the issue was quite visible.

It took me quite some time to spend some time on it. But, here is the fix.

simply add this line at the end of JavaScript code (The JavaScript code section above has been update with the same).

$(".fixedTable table").attr('rules', 'All');

I have tested this fix in multiple browsers. However if you still face the issue, Please drop a line the comment section. Additionally, I have also attached the sample demo application below.

GridFreeze.zip (134.22 kb)