Forrest-like
Example 2 : Reproduction of Forrest Navigation Bars
In the Java world, everybody knows the typical
Apache Forrest powered
documentation websites (like the present site) with the JavaScript navigation bars
on the left.
It is easy (took me less than 1 hour inclusive icon-drawing)
and instructive to (nearly) reproduce this type of
navigation bars with the NavigationBar component.
This example demonstrates the use of the parameters
itemMode
and
level .
- There are only two types of items, named 'folder' and 'item' but folder structure may be infinitely deep and hierarchical level increases indentation
- Open folders have different icons and CSS-class than closed folders
- Selected items look something different than normal items
- There are no mouse-over effects
Screenshots
This is the preview of the static layout HTML Note
This is static documentation.
There is a client-dynamics version of this example showing the folder open/closing live (without server dynamics) You can see this example in full action if you install the examples web-app |
A Screenshot 'live'
|
How to build it?
- A table with one column is used
- There are 4 rows: open, closed, normal item, selected item
One of them (open) is just for preview. The other 3 are used by the component - Level indentation is accomplished by the getSpaces()-method that simply inserts a number of spaces corresponding to the hierarchical level.
Forrest.html
<link rel="stylesheet" href="../css/navbar/forrest.css" type="text/css"/> <span id="forrestLike"> <table jwcid="@sotacs:NavigationBar" width="180" xmlSource="asset:model" value="ognl:item" level="ognl:level" itemMode = "ognl:mode" selected="ognl:selected" cellspacing="0" cellpadding="0" listener="listener:onClickDirectItem" > <!-- folder closed --> <tr jwcid="@sotacs:NavigationItem" type="folder;OUT|OVER|OUT_OPEN|OVER_OPEN"> <td class="folderClosed" jwcid="folderTd"> <span jwcid="@Insert" value="ognl:spaces" raw="true"> </span> <img src="../../images/navbar/forrest/folder-closed.gif" jwcid="folderImg"/> <span jwcid="@Insert" value="ognl:item.value">Folder Closed</span> </td> </tr> <!-- folder open (just preview)--> <tr> <td class="folderOpen"> <img src="../../images/navbar/forrest/folder-open.gif" /> Folder Opened </td> </tr> <!-- item --> <tr jwcid="@sotacs:NavigationItem" type="item;OUT"> <td class="itemOut"> <span jwcid="@Insert" value="ognl:spaces" raw="true"> </span> <img src="../../images/navbar/forrest/item.gif" jwcid="@Image" image="asset:item" hspace="2"/> <span class="itemOutText"> <span jwcid="@Insert" value="ognl:item.value">Normal Item</span> </span> </td> </tr> <!-- item selected --> <tr jwcid="@sotacs:NavigationItem" type="item;OUT_SEL"> <td class="itemSel"> <span jwcid="@Insert" value="ognl:spaces" raw="true"> </span> <img src="../../images/navbar/forrest/item-sel.gif" jwcid="@Image" image="asset:itemSel"/> <span class="itemSelText"> <span jwcid="@Insert" value="ognl:item.value">Selected Item</span> </span> </td> </tr> </table> <div style="width: 180px; height: 10px; font-size: 6pt"> </div> </span>
forrest-menu.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE navigation PUBLIC "-//sf//sotacs//NavigationBar0.7//EN" "http://sotacs.sourceforge.net/dtds/navigation-bar_0.7.dtd"> <navigation> <item value="Food" type="folder" id="food"> <item value="Pizza" type="item" id="pizza"><directLink/></item> <item value="Hamburger" type="item" id="hamburger"><directLink/></item> <item value="Fish" type="item" id="fish"><directLink/></item> <item value="Fruits" type="folder" id="vegs"> <item value="Apple" type="item" id="apple"><directLink/></item> <item value="Peach" type="item" id="peach"><directLink/></item> <item value="Pineapple" type="item" id="pineapple"><directLink/></item> <item value="Mango" type="item" id="mango"><directLink/></item> <item value="3. Level I" type="folder" id="f3"> <item value="Books" type="item" id="books1"><directLink/></item> <item value="Glass" type="item" id="glass1"><directLink/></item> <item value="Fish" type="item" id="fish1"><directLink/></item> </item> <item value="3. Level II" type="folder" id="f4"> <item value="More items" type="item" id="more"><directLink/></item> <item value="More..." type="item" id="more2"><directLink/></item> <item value="And More...." type="item" id="andmore"><directLink/></item> </item> <item value="3. Level III" type="folder" id="f5"> <item value="This is Great" type="item" id="great"><directLink/></item> <item value="Even Better" type="item" id="better"><directLink/></item> <item value="Best!!" type="item" id="best"><directLink/></item> <item value="Bad" type="item" id="bad"><directLink/></item> <item value="Horrible" type="item" id="horr"><directLink/></item> </item> </item> </item> <item value="Drinks" type="folder" id="drinks"> <item value="Whiskey" type="item" id="whiskey"><directLink/></item> <item value="Wine" type="item" id="wine"><directLink/></item> <item value="Beer" type="item" id="beer"><directLink/></item> <item value="Juices" type="folder" id="juice"> <item value="Orange Juice" type="item" id="aj"><directLink/></item> <item value="Apple Juice" type="item" id="oj"><directLink/></item> </item> <item value="Soft Drinks" type="folder" id="soft"> <item value="Coca Cola" type="item" id="cc"><directLink/></item> <item value="Pepsi" type="item" id="pepsi"><directLink/></item> </item> </item> <item value="Top Level Item 1" type="item" id="tli1"><directLink/></item> <item value="Top Level Item 2" type="item" id="tli2"><directLink/></item> <item value="Kongo" type="item" id="kongo"><directLink/></item> <item value="Russia" type="item" id="russia"><directLink/></item> </navigation>
Forrest.java
public abstract class Forrest extends BasePage{ public abstract INavBarItem getItem(); public abstract int getLevel(); public abstract ItemMode getMode(); public abstract void setSelected(String sel); public String getSpaces(){ StringBuilder sb = new StringBuilder(); for (int i = 0; i < getLevel(); i++) { sb.append(" "); } return sb.append(" ").toString(); } /** * listens to the DirectLinks */ public void onClickDirectItem(IRequestCycle cycle, String id){ System.out.println("item '" + id + "' was invoked (DirectLink)"); setSelected(id); } }
Forrest.page
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE page-specification PUBLIC "-//Apache Software Foundation//Tapestry Specification 4.0//EN" "http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd"> <page-specification > <asset path="classpath:/examples/navbar/forrest-menu.xml" name="model"/> <asset path="context:/images/navbar/forrest/folder-closed.gif" name="folderClosed"/> <asset path="context:/images/navbar/forrest/folder-open.gif" name="folderOpen"/> <asset path="context:/images/navbar/forrest/item.gif" name="item"/> <asset path="context:/images/navbar/forrest/item-sel.gif" name="itemSel"/> <property name="selected" persist="client" initial-value="literal:apple"/> <component id="folderTd" type="Any"> <binding name="class" value="ognl:mode.opened ? 'folderOpen' : 'folderClosed'"/> </component> <component id="folderImg" type="Image"> <binding name="image" value="ognl:mode.opened ? assets.folderOpen : assets.folderClosed"/> </component> </page-specification>
forrest.css
#forrestLike TABLE TR, #forrestLike DIV{ background-color: 666699; } .itemOut{ height: 14px; } .itemOutText{ color: white; font-size: 8pt; text-decoration: underline; } .itemSel{ height: 20px; } .itemSelText{ color: black; font-size: 11pt; font-weight: bold; height: 20px; background-image: url("../../images/navbar/forrest/item-sel-bg.gif"); background-repeat: repeat-x; background-position: 0px 2px; } .folderOpen{ color: white; font-size: 11pt; height: 20px; font-weight: bold; vertical-align: bottom; } .folderClosed{ color: white; font-size: 11pt; height: 20px; font-weight: bold; vertical-align: bottom; text-indent: 3px; }