After having explained in Part 1 what I mean by "good" HTML, I now want to show you some real life examples.
Here once again the topics of this 4-part weblog:
Recursive Vertical Tree-Navigation</li>
<li>Inplace Sitemap (in Part 3)</li>
<li>Suckerfish DropDowns (in Part 3)</li>
<li>Hover Trays Arranged in <code style="margin:0"><div></code>-Columns (in Part 4)</li>
<li>Trays with Different Colors (in Part 4)</li>
</ul>
<h2 id="breadcrumb">Simple Hierarchical Breadcrumb</h2>
<p>This is the goal: We want a simple hierarchical breadcrumb that shows the path from the entrypoint level to the current page in a single line with links separated by ">".</p>
<p>And here's how we're going to do it:</p>
<ul>
<li>The iteration is implemented with <code style="margin:0"><nav:iterateNavNodesInSelectedPath></code></li>
<li>The separator (“>”) is done with <code style="margin:0"><nav:ifHasMoreIterations>></nav:ifHasMoreIterations></code></li>
</ul>
<p>The resulting JSP code is as follows:</p>
<pre><%@ taglib uri="NavigationTagLibrary" prefix="nav"%>
<div id="breadcrumb">
<nav:iterateNavNodesInSelectedPath>
<nav:navNodeAnchor navigationMethod="byURL"/>
<nav:ifHasMoreIterations>></nav:ifHasMoreIterations>
</nav:iterateNavNodesInSelectedPath>
</div>
</pre>
<p>See the outcome here (look at the center of the image):</p>
<p>!https://weblogs.sdn.sap.com/weblogs/images/112/screenshot_breadcrumb.png|height=167|alt=Breadcrumb|w...!</p>
<p>This was really pretty easy, wasn't it? Well, it'll get a bit more complex in the next example.</p>
<h2 id="treenav">Recursive Vertical Tree-Navigation</h2>
<p>In this example we want a vertical tree-navigation that recursively shows the links of the selected path and their siblings. The navigation should start at the second level and have highlighting and hover effects.</p>
<p>The solution will be made up like this:</p>
<ul>
<li>From the taglib we basically use <code style="margin:0"><nav:iterateSelectedNavNodesLevel level="2"></code> in combination with <code style="margin:0"><nav:recurseNavNodeChildren currentDepth="depth"></code></li>
<li>The navigation is rendered as a hierarchical navigation list with <code style="margin:0"><ul></code> and <code style="margin:0"><li></code> tags.</li>
<li>Since <code style="margin:0"><nav:recurseNavNodeChildren/></code> internally traverses the navigation tree with an iteration and a stack, some tags need to be closed manually (<code style="margin:0"></ul></li></code>). This is done by a method <code style="margin:0">writeClosingTags(times)</code> that we need to define.</li>
<li>The “recursion” is done only for nodes in the selected path:<br>
<pre><nav:ifNotNavNodeInSelectedPath>
<nav:doNotRecurseNavNodeChildren />
</nav:ifNotNavNodeInSelectedPath></pre></li>
<li>The styling will be done exclusively with CSS.</li>
</ul>
<p>Here's the code:</p>
<pre><%@ taglib uri="NavigationTagLibrary" prefix="nav"%>
<%!
public String writeClosingTags(int times) {
if(times <= 0) return "";
StringBuffer buf = new StringBuffer(32);
for(int l = 0; l < times; l++) buf.append("</ul></li>");
return buf.toString();
}
String START_LEVEL = "2";
int start = Integer.parseInt(START_LEVEL);
int last = -1;
int current = -1;
StringBuffer cssClass = new StringBuffer(32);
%>
<ul class="treenav">
<nav:iterateSelectedNavNodesLevel level="<%=START_LEVEL%>">
<nav:recurseNavNodeChildren currentDepth="depth">
<%
current = start + depth.intValue() - 1;
%><%=writeClosingTags(last - current)%><%
last = current;
cssClass.setLength(0);
%>
<nav:ifNavNodeEqualsLaunchedNavNode>
<%cssClass.append("current");%>
</nav:ifNavNodeEqualsLaunchedNavNode>
<nav:ifNotNavNodeEqualsLaunchedNavNode>
<nav:ifNavNodeInSelectedPath>
<%cssClass.append("path");%>
</nav:ifNavNodeInSelectedPath>
<nav:ifNotNavNodeInSelectedPath>
<nav:ifNavNodeHasChildren>
<%cssClass.append("folder");%>
</nav:ifNavNodeHasChildren>
</nav:ifNotNavNodeInSelectedPath>
</nav:ifNotNavNodeEqualsLaunchedNavNode>
<%if(cssClass.length()>0)
cssClass.insert(0," class="").append(""");
%>
<li><nav:navNodeAnchor
navigationMethod="byURL"
anchorAttributes="<%=cssClass.toString()%>" />
<nav:ifNotNavNodeInSelectedPath>
</li><nav:doNotRecurseNavNodeChildren />
</nav:ifNotNavNodeInSelectedPath>
<nav:ifNavNodeInSelectedPath>
<nav:ifNextRecursionDepthWillNotChange>
</li>
</nav:ifNextRecursionDepthWillNotChange>
<nav:ifNextRecursionDepthWillIncrease>
<ul>
</nav:ifNextRecursionDepthWillIncrease>
</nav:ifNavNodeInSelectedPath>
</nav:recurseNavNodeChildren>
<%=writeClosingTags(last - start)%><%
last = start;
%>
</nav:iterateSelectedNavNodesLevel>
</ul>
</pre>
<p>The result of this will be a nice hierarchical navigation list, e.g. like this:</p>
<pre><ul class="treenav">
<li>[Home | #]</li>
<li>[Finanzen | #]
<ul>
<li>
ABO-Abwicklung0.1.
0.2. Finanzen, Bilanzen
0.1.
0.2. Dritte Ebene, Thema 1
0.3.
0.4. Zweites Thema
0.5.
0.6. Thema Drei
0.7.
0.8. Viertes Thema
0.9.
0.1.
0.2. Informationsverarbeitung
0.3.
0.4. Investionsabwicklung,
Anlage-Buchhaltung (#)
0.5.
0.1.
0.2.
A-Ressort0.1.
0.2. Entwicklung, Einkauf
0.3.
0.4.
Personal-/Sozialwesen0.1.
0.2. Produktion
0.3.
Or, when viewing it in the browser, like this:
With the addition of CSS, e.g. ...
ul.treenav {
list-style: none;
margin: 20px 0 0 0;
padding: 0;
}
ul.treenav a
ul.treenav a:hover {
background-color: #FFF;
color: #000;
}
ul.treenav ul {
list-style: none;
margin-left: 14px;
}
ul.treenav li
ul.treenav a.path {
font-weight: bold;
}
ul.treenav a.current
ul.treenav a.folder {
background-image: url(group_pf_re.gif);
background-position: 0px 3px;
background-repeat: no-repeat;
}
ul.treenav a.folder.path {
background-image: url(group_pf_dn.gif);
background-position: 0px 3px;
background-repeat: no-repeat;
}
... the final result can be as stunning as this:
!https://weblogs.sdn.sap.com/weblogs/images/112/screenshot_leftnav.png|height=307|alt=Recursive Vertical Tree-Navigation|width=175|src=https://weblogs.sdn.sap.com/weblogs/images/112/screenshot_leftnav.png|border=0!</body>