Introduction
Last year I had posted an article: Expanding / Collapsing GridView Rows. In that article, I had described implementation details of Expanding / Collapsing rows of a GridView
using JavaScript
with smooth dynamic effect. Now through this article, I'm going to demonstrate how to expand and collapse columns of a GridView
using JavaScript
with smooth dynamic effect.
CSS Code
I've used the following CSS classes for this demo. Header
and Footer
CSS classes have been used for GridView
’s header and footer rows respectively and Row
and AlternateRow
CSS classes for GridView
’s normal and alternate rows respectively. Grid
CSS class has been used for GridView
’s background.
.Header
{
background-color:#0053E1;
color:White;
font-weight:bold;
text-align:right;
vertical-align:middle;
height:25px;
}
.Footer
{
background-color:#0053E1;
height:25px;
}
.Row
{
background-color:#C1DAEB;
text-align:right;
vertical-align:middle;
height:25px;
}
.AlternateRow
{
background-color:#7FB4D3;
text-align:right;
vertical-align:middle;
height:25px;
}
.Grid
{
background-color:White;
}
I've put these CSS classes in a separate StyleSheet.css file and attached its reference in the Grid.aspx page as follows:
<link href="CSS/StyleSheet.css" rel="stylesheet" type="text/css" />
HTML Code
Below is the HTML of the GridView
that has been used for this demo. I've applied Header
, Footer
, Row
& AlternateRow
CSS classes in the GridView
through HeaderStyle
, FooterStyle
, RowStyle
and AlternatingRowStyle
respectively. Grid
CSS class is applied through the CssClass
property of the GridView
. I've taken TemplateField
columns inside the GridView
and put an Image
control in HeaderTemplate
of each TemplateField
column.
<asp:GridView ID="gvTab" CssClass="Grid" runat="server" AutoGenerateColumns="False"
ShowFooter="True" GridLines="Vertical">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:Image ID="imgN" onclick="javascript:Toggle(this,0);"
runat="server" ImageUrl="~/Images/minus.gif"
ToolTip="Collapse" ImageAlign="AbsMiddle" />
<asp:Label ID="lblHeaderN" runat="server" Text="n"></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblItemN" runat="server" Text='<%# Eval("n") %>'></asp:Label>
</ItemTemplate>
<HeaderStyle Width="50px" />
<ItemStyle Width="50px" />
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<asp:Image ID="imgSqrt" onclick="javascript:Toggle(this,1);"
runat="server" ImageUrl="~/Images/minus.gif"
ToolTip="Collapse" ImageAlign="AbsMiddle" />
<asp:Label ID="lblHeaderSqrt" runat="server" Text="sqrt(n)"></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblItemSqrt" runat="server" Text='<%# Eval("sqrtn") %>'>
</asp:Label>
</ItemTemplate>
<HeaderStyle Width="150px" />
<ItemStyle Width="150px" />
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<asp:Image ID="imgQbrt" onclick="javascript:Toggle(this,2);"
runat="server" ImageUrl="~/Images/minus.gif"
ToolTip="Collapse" ImageAlign="AbsMiddle" />
<asp:Label ID="lblHeaderQbrt" runat="server" Text="qbrt(n)"></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblItemQbrt" runat="server" Text='<%# Eval("qbrtn") %>'>
</asp:Label>
</ItemTemplate>
<HeaderStyle Width="150px" />
<ItemStyle Width="150px" />
</asp:TemplateField>
</Columns>
<HeaderStyle CssClass="Header" />
<RowStyle CssClass="Row" />
<AlternatingRowStyle CssClass="AlternateRow" />
<FooterStyle CssClass="Footer" />
</asp:GridView>
Attaching click Event
I've attached click event
on header Image
of each GridView
column as:
<asp:Image ID="imgSqrt" onclick="javascript:Toggle(this,1);"
runat="server" ImageUrl="~/Images/minus.gif"
ToolTip="Collapse" ImageAlign="AbsMiddle" />
Page’s window.onload Event
I've used window.onload event
to initialize global variables.
var Grid = null;
var UpperBound = 0;
var LowerBound = 1;
var CollapseImage = 'Images/minus.gif';
var ExpandImage = 'Images/plus.gif';
var Rows = null;
var n = 1;
var TimeSpan = 25;
window.onload = function()
{
Grid = document.getElementById('<%= this.gvTab.ClientID %>');
UpperBound = parseInt('<%= this.gvTab.Rows.Count %>');
Rows = Grid.getElementsByTagName('tr');
}
GridView’s Header Image’s Click Event
This event
gets invoked on successive clicks on any one header Image
. This event
first toggles the header Image and then toggles the requested column of the GridView
by invoking the ToggleImage
and ToggleColumns
methods respectively.
function Toggle(Image, Index)
{
ToggleImage(Image, Index);
ToggleColumns(Image, Index);
}
The first argument
is the reference of the Image to be clicked while the second argument
is the column
index of the GridView
that contains the particular Image.
ToggleImage Method
This method is invoked from the Toggle
method. The basic function of this method is to toggle the source as well as tooltip of the selected header Image.
function ToggleImage(Image, Index)
{
if(Image.IsExpanded == undefined || Image.IsExpanded)
{
Image.src = ExpandImage;
Image.title = 'Expand';
n = UpperBound;
Image.IsExpanded = false;
}
else
{
Image.src = CollapseImage;
Image.title = 'Collapse';
n = LowerBound;
Image.IsExpanded = true;
}
}
ToggleColumns Method
The first time this method is invoked from the Toggle
method, after that it is invoked by itself recursively, using the setTimeout
method. I've invoked it recursively here in order to create a smooth dynamic effect during the expanding/collapsing of the GridView
columns.
In order to make a delay in each recursion
, each call of the ToggleColumns
method has been delayed for 25 milliseconds. You can set it by altering the TimeSpan
value depending on your need.
I've used here JavaScript closure
to invoke ToggleColumns
method recursively with arguments
through setTimeout
method.
function ToggleColumns(Image, Index)
{
if (n < LowerBound || n > UpperBound) return;
var Condition = Rows[n].getElementsByTagName('td')[Index].style.visibility == '';
Condition = Condition || Rows[n].getElementsByTagName('td')
[Index].style.visibility = 'visible';
Rows[n].getElementsByTagName('td')[Index].style.visibility =
Condition ? 'hidden' : 'visible';
if(Image.IsExpanded) n++; else n--;
setTimeout(function(){ToggleColumns(Image, Index);},TimeSpan);
}
Winding Up
I have toggled visibility of all TD
elements of a GridView column
in order to create an illusion of smooth dynamic effect with the help of setTimeout
method through recursion. Different browsers have different effects of Expanding / Collapsing GridView Columns. In Internet Explorer 7/8, Safari, Google Chrome and Opera, it seems that columns are Expanding / Collapsing while in case of Mozilla, Firefox and Netscape Navigator, it seems that column’s text are Expanding / Collapsing.
Supporting Browsers
I have tested this code on the following browsers:
History
- 4th July, 2009 -- Original version posted