Sie sind auf Seite 1von 20

Generated by Jive on 2014-07-22+02:00

1
Development of Custom Top Level Navigation
-- Horizontal Drop-Down Menu
Top Level Navigation - Horizontal Drop-Down Menu
June, 2014


Prerequisites:

Basic knowledge of SAP NetWeaver 7.3
Basic knowledge of SAP NWDS 7.3
Basic knowledge of HTML, Java Script, CSS
Basic knowledge of SAP NetWeaver Portal Adminstration
Basic knowledge of LSAPI's

II Introduction:
This article will tell you how to develop a cutom top level naviagation using Navigation Tag Library and LSAPI's
-- Horizontal Drop Down Menu which behaves like a SAP delivered TLN. It works pefectly in IE 9 (Internet
Explorer only).

Process for creation of TLN:
Create a war file in NWDS studio. Create a two jsp files namely header.jsp and header_style.jsp with the code
as shown below
Include the header_style.jsp file in header.jsp file. The header_style.jsp file contains only the CSS.

Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
2
Download the com.sap.portal.navigation.afp.tln war file and import the war file into the NWDS studio or create
a new war/ear file. Include the header.jsp and header_style.jsp file in jsp folder under dist folder. Also make
changes to the portalapp.xml file as mentioned below.

Using the cascading style sheet the top level navigation is displayed with different colors.
Using the Javascript the drop down menu will be visible for a hovered role if the role has child elements like
roles/iviews.

header.jsp

<%@ taglib uri="NavigationTagLibrary" prefix="nav" %>
<%@ taglib uri="FrameworkTagLibrary" prefix="frm" %>
<%-- an include clause for css file --%>

<%@ include file="header_style.jsp" %>
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
3
<script type="text/javascript">
var clicked = false;
var currEl = 0;
function(navigationDiv) {
if (!document.all) return; // continue only for IE
var liEls = document.getElementById(navigationDiv).getElementsByTagName("LI");
var id21;
var countLevels1 = 0;
var brandingWidth = 0;
for (var i=0; i<liEls.length; i++) {

liEls[i].setAttribute("idValue");
liEls[i].idValue = i;

if(liEls[i].className == "current" || liEls[i].className == "Level1"){
id21 = i; liEls[i].setAttribute("id2Value"); liEls[i].id2Value = id21;
var contentAEl = document.getElementById("navigation").getElementsByTagName("A")[i].innerHTML;

// To set the width of the TLN we need to get the continue only for IE
brandingWidth = brandingWidth + (contentAEl.length)*7 ;
countLevels1++;
}

The below figure is taken from the developer tools of IE 9.

Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
4
/*
In the above figure it has four roles indicated as "Level1" and "current" class. The class name
assigned is Level1 .

When the user clicks on the role for eg. User Administration the class name of that parent
node / parent role is set to current and the current elements parent node / parent role calss
name is set to currenthref. The font color of parent node / parent role is set to the shade of red
("#C51733").

If the roles do not have child elements, the idvalue will be same as of id2Value.

But for User Administration role there are four child elements and so their idvalues will be
different from id2Value. The class name assigned is Level2 for these child elements. These
id2Values are same as of their parent node as shown in below figure. This will help to distinguish
the node of the parent from the child elements to set the color and background color when the
child element is selected.
*/
// as shown in the above fiugre I have mainly added the above code to find out the level one with level
two node.

if(liEls[i].className == "Level2"){
liEls[i].setAttribute"id2Value");
liEls[i].id2Value = id21;
}


liEls[i].onmouseover = function() {
this.className += " hover";
var aEl = document.getElementById(navigationDiv).getElementsByTagName("A");
this.id2Value].style.color="#C51733";
};
liEls[i].onmouseout = function() {
this.className = this.className.replace(new RegExp(" hover\\b"), "");
var lEl = document.getElementById(navigationDiv).getElementsByTagName("LI");
var aEl = document.getElementById(navigationDiv).getElementsByTagName("A");
if(clicked)
{
// The if condition is used for used for work protect mode
if(currEl != this.id2Value)
{
this.id2Value].className = "Level1";
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
5
this.id2Value].className = "";
this.id2Value].style.color="#FFFFFF";
lEl[currEl].className = "current";
aEl[currEl].className = "currenthref";
aEl[currEl].style.color = "#C51733";
}
}
else
{
this.id2Value].style.color="#FFFFFF";

if(lEl[this.id2Value].className == "current")
this.id2Value].style.color="#C51733";
}
clicked = false;
};
liEls[i].onclick = function() {

//
// one can uncomment the below code and can try also. This was mainly used for work protect mode

/* var lEl = document.getElementById(navigationDiv).getElementsByTagName("LI");
var aEl = document.getElementById(navigationDiv).getElementsByTagName("A");

for(var j=0; j<lEl.length; j++)
{
if(lEl[j].className == "current") {
lEl[j].className = "Level1"; aEl[j].className = "";
aEl[j].style.color="#FFFFFF";
break;
}

}
lEl[this.id2Value].className = "current";//05/06/2014
aEl[this.id2Value].className = "currenthref"; //05/06/2014
aEl[this.id2Value].style.color="#C51733";
//document.getElementById("level2").style.visibility="hidden";

clicked = true;
*/
};
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
6

}

/* The below code help to set the branding width of the TLN. The top level width is set depending upon the
number of roles. The style set for the top level navigation are font family is Verdana with size of 12. Each the
role text length is taken and multipled by 7(on an average) and then added to the brandingwidth. The gap
between the roles also need to be conisdered. The gap between the roles is taken as 22 pixels and this gap is
multipled by the number of roles and then added to the branding width. */
brandingWidth = brandingWidth + countLevels1*22;
document.geElementById("navigation").style.width = brandingWidth;
</script>
<%-- this is the main navigation section --%>
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td nowrap="nowrap">

<div id="branding">
<div id="navigation">
<%-- start the unordered list --%>
<ul>
<%-- go through all the level 1 navigation nodes --%>
<nav:iterateInitialNavNodes>
<li class='Level1' style="font-size: 12px;"><nav:navNodeAnchor navigationMethod="byEPCM" />
<%-- check to see if there are level 2 nodes, if so start another <ul> and assign a CSS class --%>
<nav:ifNavNodeHasChildren>
<ul>
<%-- again go through all the nodes in level 2 --%>
<nav:iterateNavNodeChildren>
<%-- id l1 is written for second level hover and to set its css properties --%>
<li class='Level2' id='l1'><nav:navNodeAnchor navigationMethod="byEPCM" /></li>
</nav:iterateNavNodeChildren>
</ul>
</nav:ifNavNodeHasChildren>
</li>
</nav:iterateInitialNavNodes>
</ul>
</div>
</div>
</td>
</tr>
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
7
</table>

<script>

TLNHover("navigation");

var nodeNameFromNaviagation;

/*


Whenever the navigation changes, the raiseEvent is fired with the current selected/clicked Node name. We can
get the path of the current selected/clicked Node by using the LSAPI's. The first element in the pathArray will
be have the node name of the "Level one/Parent Node" of the "Top Level Navigation".


This event is subscribed using the function as mentioned below in the header.jsp in top level navigation war file

*/

EPCM.subscribeEvent("urn:com.node.test", "currentNode", onCurrentNode );

function onCurrentNode( eventObj ) {
var aEls = document.getElementById("navigation").getElementsByTagName("A");
var lEls = document.getElementById("navigation").getElementsByTagName("LI");


nodeNameFromNaviagation = eventObj.sourceId;
aEls[currEl].style.color="#FFFFFF";
for(var n1=0;n1<aEls.length;n1++)
{
if(lEls[n1].className == "current") {
lEls[n1].className = "Level1"; aEls[n1].className = "";
//aEls[n1].style.color="#FFFFFF";
}
}
for(var n=0;n<aEls.length;n++)
{
if(aEls[n].innerHTML == eventObj.sourceId){
aEls[n].className = "currenthref";
lEls[n].className = "current";
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
8
aEls[n].style.color = "#C51733";
currEl = n;
clicked =true;
break;
}
}
}
</script>
header_style.jsp

<style>

navigation, #navigation ul {
background-color: #414141;
font: 11px verdana;
padding-top: 4px;
padding-bottom: 4px;
margin: 0;
list-style: none;
height: 22px;
}
#navigation a {
padding-left: 10px;
padding-right: 10px;
padding-top: 4px;
padding-bottom: 4px;
text-decoration: none;
background-color: #414141;
color: #FFFFFF;
display: block;
width: auto;
}
#navigation a.currenthref {
padding-left: 10px;
padding-right: 10px;
padding-top: 4px;
padding-bottom: 4px;
text-decoration: none;
background-color: #FFFFFF;
color: #C51733;
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
9
display: block;
width: auto;
}
#navigation a:hover {
background-color: #F4F4F4;
color: #C51733;
display: block;
border-color: #FFFFFF;
font-weight: normal;
}
#navigation li {
bacground-color: #616F9E;
float: left;
}
#navigation li ul {
position: absolute;
width: 17em;
white-space: nowrap;
padding-top: 0px;
padding-bottom: 0px;
color: #ffff00;
left: -999em;
}
#navigation li:hover ul {
left: auto;
width: auto;
display: block;
position: relative;
}
#navigation li:hover ul,
#navigation li.hover ul{
left: auto;
display: block;
border: 1px solid #CBDBEA;
}
#navigation li.hover ul a:hover{
left: auto;
display: block;
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
10
border: 0px solid #CBDBEA;
background-color: #F4F4F4;
color: #414141;
}
.current {
font: 0.4em verdana;
font-size: 11 px;
border: 0px solid #000000;
font-weight: light;
background-color: #FFFFFF;
color: #C51733;
}
.Level1 {
font: 0.4em verdana;
font-size: 11 px;
border: 0px solid #000000;
font-weight: light;
background-color: #FFFFFF;
color: #C51733;
}
.Level2 {
font: 11px verdana;
border: 0px solid #000000;
font-size: 11px;
display: block;
width: 17em;
white-space: nowrap;
background-color: #F4F4F4;
color: #414141;
}
.clicklink{
background-color: #FFFF00;
color: #0000FF;
}
#navigation ul li.hover a{
left: auto;
display: block;
border: 0px solid #CBDBEA;
background-color: #F4F4F4;
font-weight: normal;
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
11
color: #414141;
}
#navigation ul li.hover .Level2{
left: auto;
display: block;
border: 0px solid #CBDBEA;
background-color: #F4F4F4;
font-weight: normal;
color: #414141;
}
#navigation ul li.hover a:hover{
left: auto;
display: block;
border: 0px solid #CBDBEA;
background-color: #F4F4F4;
color: #C51733;
}
.Level2 a{
left: auto;
display: block;
border: 0px solid #CBDBEA;
background-color: #F4F4F4;
color: #FFFF00;
}
#l1 a {
width: auto;
border: 0px solid #000000;
background-color: #F4F4F4;
color: #414141;
}
#l1 a:hover {
width: auto;
border: 0px solid #000000;
background-color: #F4F4F4;
color: #414141;
}
</style>
portalapp.xml
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
12

<?xml version="1.0" encoding="utf-8" standalone="no"?>

<application name ="com.sap.portal.navigation.afp.tln">
<application-config>
<property name="PrivateSharingReference"
value="com.sap.portal.useragent,com.sap.portal.navigation.navigationtaglibrary,
com.sap.portal.themes.lafservice,com.sap.portal.runtime.system.connection,com.sap.portal.pagebuilder,
SAPJ2EE::library:com.sap.portal.common,SAPJ2EE::library:tc~cmi,com.sap.portal.common.commonservices,
SAPJ2EE::library:com.sapportals.htmlb,com.sap.portal.navigation.api_service,com.sap.portal.navigation.helperservice,
com.sap.portal.navigation.service,com.sap.portal.productivity.resolverservice,com.sap.portal.navigation.afp.helperservice,
com.sap.portal.runtime.system.favorites,SAPJ2EE::service:engine.security.facade,
SAPJ2EE::library:com.sap.base.technology.facade,S
APJ2EE::library:engine.j2ee14.facade,com.sap.portal.search.provider_api,com.sap.portal.search.service,com.sap.portal.contenttaggingservice,S
APJ2EE::library:tc~epbc~pcd~gl~api,com.sap.portal.themes.lafservice,com.sap.portal.runtime.system.connection,com.sap.portal.pagebuilder"/
>
<property name="SharingReference"
value="com.sap.portal.themes.lafservice,com.sap.portal.navigation.navigationtaglibrary,com.sap.portal.runtime.application.jcoclient,
com.sap.portal.ivs.connectorservice,com.sap.portal.htmlb"/>
<!-- <property name="PrivateSharingReference"
value="com.sap.portal.useragent,com.sap.portal.navigation.afp.helperservice,com.sap.portal.navigation.helperservice,
SAPJ2EE::library:tc~epbc~pcd~gl~api"/> -->
<property name="Vendor" value="sap.com"/>
<property name="SecurityArea" value="NetWeaver.Portal"/>
<property name="fail-over-enable" value="disable"/>
<property name="ClassLoadingPolicy" value="transitive"/>
</application-config>

<components>
<component name="TopLevel">
<component-config>
<property name="ClassName" value="com.sap.portal.navigation.afp.Tln"/>
<property name="ResourceBundleName" value="TopLevel_nls"/>
<property name="SafetyLevel" value="no_safety"/>
</component-config>
<component-profile>
<property name="resourceBundleToClient" value="true"/>
<property name="com.sap.portal.navigation.afp.numberOfLevels" value="2">
<property name="validvalues" value="1/11/2"/>
<property name="plainDescription" value="Number of Display Levels"/>
<property name="longDescription" value="Specifies the number of levels displayed in the top-level navigation.
Levels following this number are continued in the detailed navigation area"/>
<property name="category" value="Navigation"/>
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
13
</property>
<property name="com.sap.portal.navigation.afp.removableTabs" value="false">
<property name="plainDescription" value="Enable Removable Tabs"/>
<property name="longDescription" value="Enable portal users to remove tabs from top-level navigation"/>
<property name="category" value="Navigation"/>
<property name="administration" value="NON-DIALOG"/>
</property>
<property name="com.sap.portal.navigation.afp.dragableTabs" value="true">
<property name="validvalues" value="4/true5/false"/>
<property name="plainDescription" value="Enable Dragging of Tabs"/>
<property name="longDescription" value="Enables portal users to rearrange the order of top-level navigation
tabs"/>
<property name="category" value="Personalization"/>
<property name="configattribute" value="baseLevel"/>
</property>
<property name="com.sap.portal.navigation.afp.numberOfFixedTabs" value="0">
<property name="validvalues" value="1/01/1"/>
<property name="plainDescription" value="Number of Fixed Entries"/>
<property name="longDescription" value="Defines the number of entries that will be fixed in top-level
navigation. All other entries can be scrolled."/>
<property name="category" value="Personalization"/>
<property name="configattribute" value="baseLevel"/>
<property name="mandatory" value="true"/>
</property>
<property name="com.sap.portal.navigation.afp.displayMode" value="Default">
<property name="validvalues" value="7/Default9/No Images"/>
<property name="plainDescription" value="Display Mode"/>
<property name="longDescription" value="Specify the display mode for top-level navigation. Choose 'No
Images' to display top-level navigation with smaller tabs and without tab images."/>
<property name="category" value="Top-Level Navigation"/>
<property name="configattribute" value="fullLevel"/>
<property name="mandatory" value="true"/>
</property>
<property name="com.sap.portal.navigation.afp.notifyOnFinishedLoading" value="true"/>
<property name="AuthScheme" value="anonymous"/>
<property name="com.sap.portal.prt.xhtml.compliant" value="true"/>
</component-profile>
</component>
<!-- Header -->
<component name="HoverTLN">

<component-config>
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
14
<property name="JSP" value="jsp/header.jsp"/>
<property name="ComponentType" value="jspnative"/>
<property name="AuthScheme" value="anonymous"/>
</component-config>

<component-profile>
<property name="NavigationTagLibrary" value="/SERVICE/com.sap.portal.navigation.navigationtaglibrary/
taglib/TagLibrary.tld"/>
<property name="FrameworkTagLibrary" value="/SERVICE/com.sap.portal.pagebuilder/taglib/framework.tld"/>
<property name="EPCFLevel" value="0"/> <property name="com.sap.portal.iview.ShowTray" value="false"/>
<property name="com.sap.portal.reserved.iview.IsolationMode" value="EMBEDDED"/>
</component-profile>
</component>
</components>
<services/>
</application>

Create another war/ear file where we use the LSAPI. Create a JSPDyn page
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
15

nav.jsp

<%@ page import = "com.sapportals.portal.prt.component.IPortalComponentRequest" %>
<%@ page import = "com.sapportals.portal.prt.component.IPortalComponentContext" %>
<script type="text/javascript">
function updateNavigationMenu(currentNode){
EPCM.getSAPTop().LSAPI.AFPPlugin.model.getNavigationSubTree(null,drawTree,null);
}
function drawTree(nodes, container)
{
var pathArray = EPCM.getSAPTop().LSAPI.AFPPlugin.model.getCurrentSelectedPath();

//alert(pathArray[0].getTitle());
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
16
EPCM.raiseEvent( "urn:com.node.test", "currentNode", "Current Node", pathArray[0].getTitle());
}
</script>
Whenever the navigation changes the raiseEvent is fired which with the current selected/clicked Node name.
We can get the path of the current selected/clicked Node by using the LSAPI's. The first element in the
pathArray will be have the node name of the "Level one" of the "top level naviagation".

portalapp.xml

<?xml version="1.0" encoding="utf-8"?>
<application>
<application-config>
<property name="SecurityArea" value="NetWeaver.Portal"/>
<property name="fail-over-enable" value="disable"/>
<property name="ClassLoadingPolicy" value="transitive"/>
<property name="PrivateSharingReference"
value="com.sap.portal.navigation.navigationtaglibrary,com.sap.portal.themes.lafservice,com.sap.portal.runtime.system.connection,com.sap.portal.pagebuilder,SAPJ2EE::library:com.sap.portal.common,SAPJ2EE::library:tc~cmi,com.sap.portal.common.commonservices,SAPJ2EE::library:com.sapportals.htmlb,com.sap.portal.navigation.api_service,com.sap.portal.navigation.helperservice,com.sap.portal.navigation.service,com.sap.portal.productivity.resolverservice,com.sap.portal.navigation.afp.helperservice,com.sap.portal.runtime.system.favorites,SAPJ2EE::service:engine.security.facade,SAPJ2EE::library:com.sap.base.technology.facade,SAPJ2EE::library:engine.j2ee14.facade,com.sap.portal.search.provider_api,com.sap.portal.search.service,com.sap.portal.contenttaggingservice,SAPJ2EE::library:tc~epbc~pcd~gl~api,com.sap.portal.themes.lafservice,com.sap.portal.runtime.system.connection,com.sap.portal.pagebuilder"/
>
<property name="SharingReference"
value="com.sap.portal.themes.lafservice,com.sap.portal.navigation.navigationtaglibrary,com.sap.portal.runtime.application.jcoclient,com.sap.portal.ivs.connectorservice,com.sap.portal.htmlb"/
>
</application-config>
<components>
<component name="TlnNode">
<component-config>
<property name="ClassName" value="com.test.TlnNode"/>
</component-config>
<component-profile/>
</component>
</components>
<services/>
</application>

Deploy this war/ear file in the server and create a iview for this component with isloation property as
"Embedded". Set the height property as 0.
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
17

Create an page and copy the iview mentioned above as delta link into the page with isloation property as
"URL". Set the height property of the page as 0 fo the page.
Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
18
Add the above created page to your framework page as delta link and check the checkbox of visible for this
page.

Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
19
In the framework page i have selected the container for HoverTLN and TlnNodePage in Page Tool Bar
Container because when I add it in the Top Level Navigation Container I am not able to see the drop down
menu.
As shown in the above figure the TLN works fine. When the user moves the mouse over other nodes the
second level of navigatin will come as drop down menu as shown in above figure with the background color in
the shade of light yellow. The current selected node will is identified with background color white and font color
as red shade.

Development of Custom Top Level Navigation -- Horizontal Drop-Down Menu
Generated by Jive on 2014-07-22+02:00
20
By using Java Script I have hidden the blue arrow which appears on the left side of the browser to display the
detailed navigation.


Till here the code work fine.


For the above code I am trying to restrict the width to 900 px and trying to put the horizontal scroll using buttons
but could not proceed further. So If anyone has the solution please add your comments which is the only thing
I am missing for this code.

For the above shown figure I tried it using html file and it worked fine for the horizontal scroll using the buton
but the horizontal scroll did work but the dorp down menu in not visisble outside when I included in the
framework page. This is because it is div tags are inside the table cells. I tired with "<div id="branding"
style="border:1px; solid #414141; width:300px; overflow-x:hidden;" >". If I remove the style overlfow-x:hidden,
the drop down menu is visible on hover but the scroll does not work as the full width of the navigation will be
visible.

Any suggestions welcome.