65.9K
CodeProject is changing. Read more.
Home

Toggle Panel Control

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (3 votes)

Apr 2, 2006

LGPL3

3 min read

viewsIcon

51354

downloadIcon

234

This control is designed to show content that can be collapsed.

Sample Image - togglepanel.gif

Introduction

This is a free control, TogglePanel, designed to show content that can be collapsed. The control has two templates: one for the content shown in the expanded state, and one for the content (or title) shown in the collapsed state.

Use the ExpandedTemplate for the normal content and the CollapsedTemplate for the collapsed content.

This control is designed for ASP.NET 2.0.

License

The control is free and Open Source under the LGPL license.

Installation

Installing the controls

You can install the controls in the standard way:

  • create a "bin" folder inside the application root of your website (if it's not already there)
  • copy the assembly file togglepanel.dll into the bin folder

You may want to add the control to the toolbox of your editor (Visual Studio or C# Builder). This will allow you to set its properties in the Property Pane. Follow the editor's procedure to add a control to the toolbox.

Using the controls

Adding the controls to your page

There are two ways to add controls to your page:

  1. Drag the control from the toolbox onto the page (if it was installed on the toolbox).
  2. Add the code manually. Add this line to the top of your page:
  3. <%@ Register TagPrefix="rw" Namespace="rw" Assembly="TogglePanel" %>

    Then, add a tag like this where you want the schedule to be displayed:

    <rw:TogglePanel id="TogglePanel1" runat="server" >
         <ExpandedTemplate>
         </ExpandedTemplate>
         <CollapsedTemplate>
         </CollapsedTemplate>
    </rw:ScheduleGeneral>

Setting the control's properties

You should set both values for the ImageUrl: ImageUrlCollapsed for the collapsed state (usually, a plus sign image), and ImageUrlExpanded for the expanded state (usually, a minus sign). Optionally, you may set the Collapsed property to True if you want the control to be collapsed initially.

Providing template content

The next step is to add the contents of the templates.

There are two templates. You should provide content for both. Use the smart tag menu to edit both templates separately. You can add any text or control to the templates.

Demo page

The control comes with a demo page. The page contains two instances of the control:

How it works

The control is derived from CompositeControl. The main code is in the CreateChildControls method.

In this method, an HtmlTable control is constructed with one row and two cells. The first cell will contain the image, and in the second, two panels will be added. At a given time, only one of these panels will be visible. A hidden field is added to keep track of the state of the control on the client side as well as on the server side.

In order for the panels to be switched without a postback request, they are toggled on and off through JavaScript.

Here's the CreateChildControls method:

Protected Overrides Sub CreateChildControls()
    Controls.Clear()
    ' Create a table for the child controls
    Table1 = New Table
    Controls.Add(Table1)
    ' Copy style attributes (BorderStyle, GridLines, etc.) to child table
    Table1.CopyBaseAttributes(Me)
    If ControlStyleCreated Then Table1.ApplyStyle(ControlStyle)

    Table1.Rows.Add(New TableRow)

    ' Add a cell for the clickable image
    Table1.Rows(0).Cells.Add(New TableCell)
    Table1.Rows(0).Cells(0).VerticalAlign = VerticalAlign.Top
    Table1.Rows(0).Cells.Add(New TableCell)

    Image1 = New Image()
    Table1.Rows(0).Cells(0).Controls.Add(Image1)
    ' Image should not keep state, because it can be changed on the client
    Image1.EnableViewState = False

    ' Create the first panel for the collapsed state
    PanelCollapsed = New Panel()
    Table1.Rows(0).Cells(1).Controls.Add(PanelCollapsed)
    ' panel should not keep state, because it can be changed on the client
    PanelCollapsed.EnableViewState = False
    Dim item1 As New TogglePanelItem()
    ' Instantiate item using the template 
    If (Not CollapsedTemplate Is Nothing) Then
        CollapsedTemplate.InstantiateIn(item1)   ' initialize item from template
    Else
        Throw New HttpException("The CollapsedTemplate is missing")
    End If
    PanelCollapsed.Controls.Add(item1)

    ' Create the second panel for the expanded state
    PanelExpanded = New Panel()
    Table1.Rows(0).Cells(1).Controls.Add(PanelExpanded)
    PanelExpanded.EnableViewState = False
    Dim item2 As New TogglePanelItem()
    ' Instantiate item using the template 
    If (Not ExpandedTemplate Is Nothing) Then
        ExpandedTemplate.InstantiateIn(item2)   ' initialize item from template
    Else
        Throw New HttpException("The ExpandedTemplate is missing")
    End If
    PanelExpanded.Controls.Add(item2)

    ' A hidden field is used to keep track of the state, 
    ' even if it changes on the client side
    Hidden1 = New HtmlInputHidden()
    Controls.Add(Hidden1)
    ' We store the "Collapsed" value in a hidden control (and not in ViewState), 
    ' so that it can be changed on the client side and still be posted back
    ' the value is 'col' for collapsed and empty for expanded
    Hidden1.Value = IIf(Collapsed, "col", "").ToString()

    'Create the client script for switching between panels
    Dim clientScript As String = _
    "var hidden1=document.getElementById('" & Hidden1.ClientID & "');" & _
    "var pe=document.getElementById('" & PanelExpanded.ClientID & "');" & _
    "var pc=document.getElementById('" & PanelCollapsed.ClientID & "');" & _
    "if(hidden1.value!='col') {" & _
    " pe.style.display='none';" & _
    " pc.style.display='block';" & _
    " this.src='" & ResolveUrl(ImageUrlCollapsed) & "';" & _
    " hidden1.value='col';}" & _
    "else{" & _
    " pe.style.display='block';" & _
    " pc.style.display='none';" & _
    " this.src='" & ResolveUrl(ImageUrlExpanded) & "';" & _
    " hidden1.value='';}"
    Image1.Attributes("onclick") = clientScript

    If (Not DesignMode And Page.IsPostBack) Then
        ' find the postback name for the hidden field
        ' TODO: is there no predefined function for this hack?
        Dim HiddenClientName As String = Hidden1.ClientID.Replace("_", "$")
        ' retrieve the state of the control from the request
        Collapsed = Not (Page.Request.Params.Get(HiddenClientName) <> "col")
    End If
    UpdateLayout()
End Sub

Future

Here are some ideas for improvement:

  • Allow different locations for the toggle image (currently only on the left side).

If anyone decides to extend this control, or has any comments, bug reports, or questions, then it would be great to hear from you.

Points of interest

  • Templated control in ASP.NET 2.0.