Skip to Content

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|width=379|src=https://weblogs.sdn.sap.com/weblogs/images/112/screenshot_breadcrumb.png|border=0!</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-Abwicklung

0.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-Ressort

0.1.

0.2. Entwicklung, Einkauf

0.3.

0.4.

Personal-/Sozialwesen

0.1.

0.2. Produktion

0.3.

Or, when viewing it in the browser, like this:

Navigation List

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>

To report this post you need to login first.

8 Comments

You must be Logged on to comment or reply to a post.

  1. Anonymous
    Hi Sven,

    long time – no see!
    ( I love german English 🙂

    Even if you haven’t published the last two parts of you rblog series, I am sure that this will help me some day…

    As I am too lazy to search for – where are all those new JSP tags documented??

    Greetz,
    Michael

    (0) 
    1. Sven Kannengiesser Post author
      Hi Michael,
      nice to hear from you! Guess where I am sitting right now…
      You can find the documentation in the SAP Help:
      http://help.sap.com/saphelp_nw04s/helpdata/en/42/f35146a7203255e10000000a1553f7/frameset.htm (for the Navigation Taglib), http://help.sap.com/saphelp_nw04s/helpdata/en/42/ef0bd053491a71e10000000a422035/frameset.htm (for the Framework Taglib), and http://help.sap.com/saphelp_nw04s/helpdata/en/42/ea3a29b28e1bcae10000000a11466f/frameset.htm (for the Layout Taglib).
      Best regards
      Sven
      (0) 
  2. Sebastian Wilde
    Hi Sven,

    At first thanks a lot for your short explanations that helped me a lot.

    But i’ve still got one question left. I didn’t manage to create a breadcrumb with a certain entry level. Is there any way to solve this?!

    Kind regards!
    Sebastian

    (0) 
    1. Sven Kannengiesser Post author

      Hi Sebastian,<br/>good point. It would be nice to have some extra attribute like <nav:iterateNavNodesInSelectedPath startLevel=”3″> or so. I will mention it to Product Management. Practically the only two ways I see is either a) using mixed scriptlet/taglib approach with a counter and an if-statement to keep track of the levels, or b) using the Navigation API directly (within a scriptlet) to render breadcrumb with the required start level.<br/>Best regards,<br/>Sven

      (0) 
      1. Sebastian Wilde

        Hi Sven,<br/><br/>thanks for your answer!<br/><br/>I solved my problem via stylesheet definitions and a <nav:iterateSelectedNavNodesLevel>.<br/><br/>Worked for me :-)<br/><br/>Greets

        (0) 
  3. swathi mallepeddi
    Hi sven,
    This is a very very excellent blog for beginners like me .
    I have a question regarding this.
    I implemented your code and everything looks fine.
    But when i try to close the folder after opening it doesnt seem to close .It only switches back when i click on another node outside of it.
    How can i modify this behavior.
    Also i want to set the folders to be open by default when a user first logs in.
    How can i acheive that.

    Thank you very much for the great blog.

    Regards
    swathi

    (0) 
    1. Sven Kannengiesser Post author
      Hello Swathi!

      The way that the featured code works is that it opens and hightlights the currently selected path, showing the siblings on each level, but hiding/closing all other folders.

      If you rather want the behavior like in the Windows Explorer (where you can click the +/- icon to collapse/expand) then you’d have to dig deeper and develop a solution that for instance uses JavaScript (AJAX request for retrieving the children of an expanded folder). Or like the Detail Navigation in the shipped Light Framework Page does it (by memorizing which folders are clicked open, on the server side).

      The latter question I don’t quite understand. Do you want _all_ folders to be open by default? That would have an impact on performance! Or do you want to open only some (which?) folders by default?

      Regards,
      Sven

      (0) 
  4. Anonymous
    Hello Sven,

    Great blog, this really helped in developing custom detail level navigation. After following your blog, The detail level navigation is generated, however when i integrate with the freamework page and click on top level navigation , it opens the content area of top level link in new window. The top level navigation is standard top level navigation and It works fine with standard detail level navigation.

    (0) 

Leave a Reply