Introduction
Windows XP users are already familiar with a Panel Bar that appears on the left side in Windows Explorer. This article introduces another way to mimic this user interface in web applications. This article is inspired by another great article Windows XP Style Menu already available on CodeProject. However the idea presented in this article makes use of tables a lot to format the panel bar contents and also provides a way to alter stylesheets at run-time.
Panelbar Layout
The following figure shows the HTML layout of a single item in the panel bar. The exact same layout is followed by every other item in the panel bar.
- The entire panel bar is wrapped in a
div
tag.
- The actual panel bar is formed using two
div
tags. Mainly Header
and Links
.
- The header is rendered as a single row
table
.
- The item links are again rendered as
table
rows.
The entire panelbar HTML is generated at runtime using client side JavaScript. So you don't need to include any HTML as required by most of the other panel bars I have seen.
Driving script
The panel bar requires two JavaScript files. The Panelbar.js file houses the actual code for menu generation and ua.js houses the script used for browser detection. The page in which you want to show the panelbar needs to emit the following JavaScript code:
<script language="javascript">
var objTmp;
objTmp = createMenu("Community", "");
createSubMenu(objTmp, "Site Map", "PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "Add To Favorites",
"PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "CodeProject Stuff",
"PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "Who's Who", "PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "Tell a friend", "PanelBar.htm#",
"", "", "", "WKSpace");
createSubMenu(objTmp, "Industry Contacts",
"PanelBar.htm#", "", "", "", "WKSpace");
objTmp = createMenu(".NET", "");
createSubMenu(objTmp, "ASP.NET", "PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "Managed C++", "PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "SOAP & XML", "PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "VB.NET", "PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "C++ Web Services",
"PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "Compact Framework",
"PanelBar.htm#", "", "", "", "WKSpace");
createSubMenu(objTmp, "Cross Platform", "PanelBar.htm#", "", "", "", "WKSpace");
setTheme("XPClassic.css", null, null)
initialize(150);
</script>
The createMenu
function takes two parameters. The first one is the header text and the second is the tooltip text. Currently this parameter is ignored. In future, this can be used with the title
attribute of the span
tag and enclosing the header text within it.
The createSubMenu
function takes the following six parameters:
- The reference to the header object under which the link items are to be rendered.
- The link text to be displayed.
- The link URL.
- The extra data to be passed to the link URL through the query string.
- The tooltip text to be displayed for the link.
- The name of the image file to be rendered before the link text.
- Finally, the target
window
or frame
name in which the link should be opened.
The setTheme
basically allows menu customization. It takes the following three parameters:
- The name of the custom CSS file.
- The relative path and name of the folder containing the custom theme file. The default value is
CSS
.
- The relative path and name of the folder containing the images used in the custom theme. The default value is
IMAGES
.
Finally, the initialize
function which takes a single parameter and uses it to decide the width of the panelbar. This function is also responsible for generating the necessary HTML.
JavaScript structures
The panel bar is composed using the following JavaScript structures. The MenuBand
structure contains information required to render the header portion. It also contains an array of sub items. The drawMenu
member is responsible for rendering the header as well as the sub items.
function MenuBand(pstrDesc, pstrTip)
{
this.id = "";
this.label = pstrDesc;
this.microHelp = pstrTip;
this.isHeader = true;
this.open = false;
this.submenu = new Array;
this.smcount = 0;
this.addSubMenu = addSubMenu;
this.render = drawMenu;
}
The SubMenu
structure contains information required to render the individual sub item. Again it also has a drawMenu
member which is responsible for rendering this sub item. This member is called from the drawMenu
member of MenuBand
.
function SubMenu(pstrDesc, pstrLink, pstrLinkData, pstrTip, pstrImage, pstrTarget)
{
this.parentId = "";
this.label = pstrDesc;
this.hlink = pstrLink;
this.linkTarget = pstrTarget;
this.linkData = pstrLinkData;
this.microHelp = pstrTip;
this.isHeader = false;
this.isSelected = false;
this.iconSrc = pstrImage;
this.render = drawSubMenu;
}
Drawing functions
The two most important functions in the panel bar construction are drawMenu
and drawSubMenu
. As the name suggests, the drawMenu
renders the header part and calls drawSubMenu
on each sub item to render individual sub items.
function drawMenu()
{
var iCntr = 0;
var objMenu;
var strId, strLbl;
document.write("<div class=\"menuHeaderCollapsed\" id=\"" + this.id + "\"" +
" onmouseover=\"mousehover(this)\"" +
" onmouseout=\"mouseout(this)\"" +
"onclick=\"toggle(this)\">");
document.write("<table border=\"0\" cellspacing=\"0\"" +
" cellpadding=\"4\" width=\"100%\">");
document.write("<tr><td style=\"vertical-align: center;\">" +
this.label + "</td></tr>");
document.write("</table></div>");
document.write("<div style=\"display: none; visibility: hidden;\"" +
" class=\"menuItems\" id=\"" + this.id + "_child" + "\">");
document.write("<table border=\"0\" cellspacing=\"0\"" +
" cellpadding=\"4\" width=\"100%\">");
for (iCntr = 0; iCntr < this.smcount; iCntr++)
{
this.submenu[iCntr].render();
}
document.write("</table></div>");
}
function drawSubMenu()
{
var strImg = "";
document.write("<tr><td>");
if (this.iconSrc)
strImg = "<img src=\"" + _strCtxt + _imageFolder + "/" +
this.iconSrc + " border=\"0\"\"> ";
document.write("<a href=" +
getLink(this.linkTarget, (_strCtxt + this.hlink), this.linkData) +
"\">");
document.write(strImg);
document.write(this.label);
document.write("</a>");
document.write("</td></tr>");
}
Stylesheet
There is really nothing special about the stylesheet(s) used. The attached source contains four different stylesheets. The following stylesheet renders the Code Project panelbar:
body
{
font-family: Verdana, Tahoma, Arial;
font-size: 8pt;
font-weight: normal;
background-color: #FC9A04;
}
#panelBar
{
background-color: #FC9A04;
height: 100%;
width: 100%;
vertical-align: top;
}
.menuHeaderExpanded
{
font-family: Verdana, Tahoma, Arial;
font-size: 8pt;
font-weight: bold;
background-image: url('../Images/CPExpand.gif');
background-position: right center;
background-repeat: no-repeat;
color: #FC9A04;
height: 23px;
cursor: hand;
border-left: 1px solid #000000;
}
.menuHeaderExpandedOver
{
font-family: Verdana, Tahoma, Arial;
font-size: 8pt;
font-weight: bold;
background-image: url('../Images/CPExpand.gif');
background-position: right center;
background-repeat: no-repeat;
color: #FC9A04;
height: 23px;
cursor: hand;
border-left: 1px solid #000000;
}
.menuHeaderExpanded td
{
color: #FC9A04;
font-size: 8pt;
font-weight: normal;
}
.menuHeaderExpandedOver td
{
color: #FC9A04;
font-size: 8pt;
font-weight: bold;
}
.menuHeaderCollapsed
{
font-family: Verdana, Tahoma, Arial;
font-size: 8pt;
font-weight: bold;
background-image: url('../Images/CPCollapse.gif');
background-position: right center;
background-repeat: no-repeat;
color: #FC9A04;
height: 23px;
cursor: hand;
border-left: 1px solid #000000;
}
.menuHeaderCollapsedOver
{
font-family: Verdana, Tahoma, Arial;
font-size: 8pt;
font-weight: bold;
background-image: url('../Images/CPCollapse.gif');
background-position: right center;
background-repeat: no-repeat;
color: #FC9A04;
height: 23px;
cursor: hand;
border-left: 1px solid #000000;
}
.menuHeaderCollapsed td
{
color: #FC9A04;
font-size: 8pt;
font-weight: normal;
}
.menuHeaderCollapsedOver td
{
color: #FC9A04;
font-size: 8pt;
font-weight: bold;;
}
.menuItems
{
font-family: Verdana, Tahoma, Arial;
font-size: 8pt;
background-color: #FFCC99;
color: #000000;
position: relative;
}
.menuItems table
{
font-family: Tahoma, Verdana, Arial;
font-size: 8pt;
background-color: #FFCC99;
color: #000000;
border-top: 1px solid #000000;
border-left: 1px solid #000000;
border-right: 1px solid #000000;
border-bottom: 1px solid #000000;
}
.menuItems a
{
color: #000000;
text-decoration: none;
}
.menuItems a:hover
{
color: #000000;
font-weight: bold;
text-decoration: none;
}
Possible Enhancements
- Support for browsers other than Internet Explorer 6.0 and FireFox 1.0.
- Support for header tooltips.
- Drawing box around sub item upon mouse hover.
Revision History