jumpstart0321
asked on
ASP.net Expandable panel.
Ok, it sounds easy enough; but for some reason I can't find anything. What I'm looking for is some sort of panel type thing that appears like the following:
+Click here for options
[when + is clicked, I want it to expand]
[Buttons, textboxes, etc in expanded menu]
I'm using vs 2008. Anybody have any idea of which control to use?
+Click here for options
[when + is clicked, I want it to expand]
[Buttons, textboxes, etc in expanded menu]
I'm using vs 2008. Anybody have any idea of which control to use?
Hi There,
There are all sort of ways to do this. I would use a javascript framework. Have a look here (http://jqueryui.com/demos/), it's easy to implement and you don't have all the cumbersome code in your page like you do when you use the Microsoft ajax controls.
Sean
There are all sort of ways to do this. I would use a javascript framework. Have a look here (http://jqueryui.com/demos/), it's easy to implement and you don't have all the cumbersome code in your page like you do when you use the Microsoft ajax controls.
Sean
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Here is another collapsible panel that doesn't need ajax. Personally, I prefer this one as it is more cutomizable. You just have to add the class in a class library project, build the project and then reference the dll in you web application project. You can change everything if you want. I attached a snippet.
P.S.: In the Panel project, you have to manually include the references : System.Drawing and System.Web
If you prefer to use it as is, just change the extension of the file I attach from .txt to .dll and then include it in your project.
Hope it helps.
P.S.: In the Panel project, you have to manually include the references : System.Drawing and System.Web
If you prefer to use it as is, just change the extension of the file I attach from .txt to .dll and then include it in your project.
Hope it helps.
***********The panel class ********************
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Text;
using System.Collections.Specialized;
using System;
using System.Web;
namespace CollapsiblePanel
{
#region Panel Control (Expandable)
[ToolboxData("<{0}:Panel runat=server Expandable='true' Width='200px'></{0}:Panel>")]
public class Panel :System.Web.UI.WebControls.Panel,IPostBackDataHandler
{
public Panel()
: base()
{
Expandable = true;
RenderInBox = false;
Title = "Panel";
Font.Name = "verdana";
Font.Size = FontUnit.Point(10);
Margin = 2;
Closed = false;
ToggleButton = null;
CaptionDithered = false;
RightToLeft = false;
ForeColor = Color.Black;
BorderColor = Color.AliceBlue;
ClickButtonColor = ForeColor;
}
// Automatically updates the Closed property based on the content
// of hidden field named as this control
public virtual bool LoadPostData(string postDataKey,NameValueCollection postCollection)
{
bool currentValueOfClosed = Closed;
bool postedValueOfClosed = Convert.ToBoolean(postCollection[postDataKey]);
// In case where the field would be empty?
if (!currentValueOfClosed.Equals(postedValueOfClosed))
{
Closed = postedValueOfClosed;
return true;
}
return false;
}
public virtual void RaisePostDataChangedEvent()
{
}
// Fires when the panel gets loaded
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// Check the browser capabilities and disable collapse/expand if needed
bool uplevel = false;
HttpBrowserCapabilities caps = Page.Request.Browser;
if (caps.Browser.ToUpper().IndexOf("IE") > -1)
{
// This is IE. But is it at least v5?
if (caps.MajorVersion > 4)
uplevel = true;
}
// If the browser is not IE5 or higher, drop collapse/expand
if (!uplevel)
{
Expandable = false;
RenderInBox = true;
}
}
// Gets the name of the hidden field used to carry client info
private string HiddenFieldName
{
get
{
return ID;
}
}
// Makes the control expandable on demand
public bool Expandable
{
get
{
return Convert.ToBoolean(ViewState["Expandable"]);
}
set
{
ViewState["Expandable"] = value;
}
}
// Render the contents of the in a box
// (used only if Expandable is false)
public bool RenderInBox
{
get
{
return Convert.ToBoolean(ViewState["RenderInBox"]);
}
set
{
ViewState["RenderInBox"] = value;
}
}
// Whether the contents of the expandable panel must be visible
public bool Closed
{
get
{
return Convert.ToBoolean(ViewState["Closed"]);
}
set
{
ViewState["Closed"] = value;
}
}
// The text displayed as the caption of the expandable panel
public string Title
{
get
{
return Convert.ToString(ViewState["Title"]);
}
set
{
ViewState["Title"] = value;
}
}
// The margin to use if the panel is expandable
public int Margin
{
get
{
return Convert.ToInt32(ViewState["Margin"]);
}
set
{
ViewState["Margin"] = value;
}
}
// The background of the caption is hor. dithered
public bool CaptionDithered
{
get
{
return Convert.ToBoolean(ViewState["CaptionDithered"]);
}
set
{
ViewState["CaptionDithered"] = value;
}
}
// Indicates the direction of the dithering
public bool RightToLeft
{
get
{
return Convert.ToBoolean(ViewState["RightToLeft"]);
}
set
{
ViewState["RightToLeft"] = value;
}
}
// Indicates the color of the click button to expand/collapse
public Color ClickButtonColor
{
get
{
return (Color)ViewState["ClickButtonColor"];
}
set
{
ViewState["ClickButtonColor"] = value;
}
}
// Render the control
protected override void Render(HtmlTextWriter output)
{
if (!Expandable)
{
if (!RenderInBox)
base.Render(output);
else
RenderContentsInBox(output);
return;
}
// Add margin information if the panel is expandable
Style["margin"] = Margin.ToString();
Style["display"] = (Closed ? "none" : "");
string originalID = this.UniqueID;
ID = this.UniqueID + "_theDiv";
// The internal panel must cover 100% of the parent area
// irrespective of the physical width.
Unit oldWidth = Width;
Width = Unit.Percentage(100);
// Register the hidden field to communicate
Page.ClientScript.RegisterHiddenField(originalID,Closed.ToString());
// Capture the default output of the Panel
StringWriter writer = new StringWriter();
HtmlTextWriter buffer = new HtmlTextWriter(writer);
base.Render(buffer);
string panelOutput = writer.ToString();
// Restore the wanted width
Width = oldWidth;
BuildControlTree(output,originalID,panelOutput);
return;
}
// Handle the PreRender event
protected LiteralControl ToggleButton;
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (Expandable)
ToggleButton = CreateClientButton();
}
// Build the markup for this custom Panel control
private void BuildControlTree(HtmlTextWriter output,string id,string panelOutput)
{
Table t = new Table();
t.ID = id + "_thePanel";
t.CellPadding = 0;
t.CellSpacing = 0;
t.BorderColor = BorderColor;
t.BorderStyle = BorderStyle.Outset;
t.BorderWidth = Unit.Pixel(1);
t.ForeColor = ForeColor;
t.Font.Name = Font.Name;
t.Font.Size = Font.Size;
t.Width = Width;
if (CaptionDithered)
{
string filterString = "progid:DXImageTransform.Microsoft.Gradient(gradienttype=1,startColorstr='{0}',endColorstr='{1}'";
if (RightToLeft)
t.Style["filter"] = String.Format(filterString,
Color.Snow.Name,
BorderColor.Name);
else
t.Style["filter"] = String.Format(filterString,
BorderColor.Name,
Color.Snow.Name);
}
// Prepare the topmost row
TableRow rowTop = new TableRow();
if (!CaptionDithered)
rowTop.BackColor = t.BorderColor;
// Leftmost cell: title
TableCell cellTop = new TableCell();
cellTop.Text = String.Format("<b> {0}</b>",Title);
cellTop.HorizontalAlign = HorizontalAlign.Left;
rowTop.Cells.Add(cellTop);
// Rightmost cell: expand/collapse button
TableCell cellTopRight = new TableCell();
cellTopRight.HorizontalAlign = HorizontalAlign.Right;
LiteralControl imgRight = ToggleButton;
if (imgRight != null)
cellTopRight.Controls.Add(imgRight);
rowTop.Cells.Add(cellTopRight);
// Add the top row to the table
t.Rows.Add(rowTop);
// Insert the Panel's markup in the table cell
TableRow rowBody = new TableRow();
TableCell cellBody = new TableCell();
cellBody.BackColor = Color.White;
cellBody.ColumnSpan = 2;
cellBody.Text = panelOutput;
rowBody.Cells.Add(cellBody);
t.Rows.Add(rowBody);
// Output
t.RenderControl(output);
}
// Add a client-side DHTML button
private LiteralControl CreateClientButton()
{
string scriptFuncName = "Toggle" + this.UniqueID;
string scriptName = "__TogglePanel" + this.UniqueID;
string html = "<a href='javascript:{0}()'><span style='color:{1};font-family:webdings;text-decoration=none;font-weight=700;'>2</span></a> ";
html = String.Format(html,
scriptFuncName,
ClickButtonColor.Name);
LiteralControl lit = new LiteralControl(html);
string stateVar = "closed_" + this.UniqueID;
string ctlVar = this.UniqueID + "_theDiv";
// Get the name of the Form
string formName = "Form1";
foreach (Control ctl in Page.Controls)
{
if (ctl is HtmlForm)
formName = ctl.ID;
}
StringBuilder sb = new StringBuilder("<script language=Javascript>\n");
sb.Append("function ");
sb.Append(scriptFuncName);
sb.Append("() {\n");
string hiddenFieldExpr = "document.forms[\"" + formName + "\"][\"" + UniqueID + "\"].value";
sb.Append("var " + stateVar + " = " + hiddenFieldExpr + ";");
sb.Append("if (" + stateVar + ".toLowerCase()==\"true\") {\n");
sb.Append(ctlVar);
sb.Append(".style[\"display\"] = \"\";");
sb.Append(hiddenFieldExpr + "=false;}");
sb.Append("\nelse {\n");
sb.Append(ctlVar);
sb.Append(".style[\"display\"] = \"none\"; " + hiddenFieldExpr + "=true;}");
sb.Append("\n}\n<");
sb.Append("/");
sb.Append("script>");
if (!Page.ClientScript.IsClientScriptBlockRegistered(scriptName))
Page.ClientScript.RegisterClientScriptBlock(typeof(String),scriptName,sb.ToString());
return lit;
}
// Render the panel in a box
private void RenderContentsInBox(HtmlTextWriter output)
{
Style["border-left"] = String.Format("{0} solid {1}",BorderWidth,BackColor.Name);
Style["border-right"] = String.Format("{0} solid {1}",BorderWidth,BackColor.Name);
Style["border-top"] = String.Format("3px solid {0}",BorderColor.Name);
Style["border-bottom"] = String.Format("3px solid {0}",BorderColor.Name);
Style["padding"] = Margin.ToString();
base.Render(output);
}
}
#endregion
}
*********** The aspx file *****************
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="ColPanel.aspx.vb" Inherits="ColPanel" %>
<%@ Register Namespace="CollapsiblePanel" Assembly="CollapsiblePanel" TagPrefix="col" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<col:Panel ID="ClosedPanel" runat="server" Closed="true" Width="80%">
<asp:Label ID="lblName" runat="server" Text="Enter your first name here:" ForeColor="blue"/>
<asp:TextBox ID="txtName" runat="server" />
</col:Panel>
<col:Panel ID="OpenPanel" runat="server" Closed="false" Width="90%">
<asp:Label ID="Label1" runat="server" Text="Enter your last name here:" ForeColor="blue"/>
<asp:TextBox ID="TextBox1" runat="server" />
</col:Panel>
</div>
</form>
</body>
</html>
CollapsiblePanel.txt
Follow aibusinesssolutions's solution. Ive used this many times, and it works well enough for me!
I am actually currently using it in one of my applications now
I am actually currently using it in one of my applications now
http://www.asp.net/AJAX/AjaxControlToolkit/Samples/CollapsiblePanel/CollapsiblePanel.aspx
You could also just create a div layer that shows or hides with CSS and javascript for a simple approach.