/* * Created on Mar 30, 2004 */ package com.idega.presentation; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import com.idega.presentation.text.AnchorLink; import com.idega.presentation.text.Link; import com.idega.presentation.text.Text; /** * A Javascript style multi level dropdown menu but implemented in pure CSS and HTML! <br> * Based on the great work of <a href="http://www.alistapart.com/articles/taminglists/">ALA</a> and <br> * <a href="http://www.aplus.co.yu/">Aplus</a> (ADxMenu). To customize the look of this component you simply <br> * need to copy the default style sheet it uses and change it. The menus can contain any PresentationObject. * * Example usage:<br> * <code> CSSMultiLevelMenu menuBar = new CSSMultiLevelMenu(); //create a menu CSSMenu level0101 = menuBar.createCSSMenu("First top menu"); //add as a top menu menuBar.add(level0101); //insert items level0101.add("Item one"); level0101.add("Item two"); level0101.add("Item three"); //insert item that is a submenu CSSMenu level010103 = menuBar.createCSSMenu("Item three submenu"); level0101.add(level010103); level010103.add("Item one in submenu"); level010103.add(new Link("Item two in submenu","#")); //one last item level0101.add(new Text("Item four")); //create and add an empty top menu CSSMenu level0102 = menuBar.createCSSMenu("Second top menu"); menuBar.add(level0102); add(menuBar); </code> * * @author <a href="mailto:eiki@idega.is">Eirikur Hrafnsson</a> */ public class CSSMultiLevelMenu extends PresentationObjectContainer { Map topMenuMap; private static String prefix = "<div id=\"menu\">\n<ul id=\"menuList\">\n"; private static String suffix = "\t</ul>\n</div>"; private static String CSS_FILE_PATH = "cssmenu/CSSMultiLevelMenu.css"; private static String WCH_JAVASCRIPT_FILE_PATH = "cssmenu/WCH.js";//for layering over dropdowns etc. private static String ADxMENU_JAVASCRIPT_FILE_PATH = "cssmenu/ADxMenu.js";//for fixing explorer on windows private boolean addTestData = false; /** * */ public CSSMultiLevelMenu() { super(); } /* * Constructs and returns a CSSMenu with your presentationobject as the label */ public CSSMenu createCSSMenu(String menuName, PresentationObject menuLabel) { if(this.topMenuMap==null) { this.topMenuMap = new LinkedHashMap(); } CSSMenu menu = (CSSMenu)this.topMenuMap.get(menuName); if(menu==null) { menu = new CSSMenu(menuName,menuLabel); this.topMenuMap.put(menuName,menu); } return menu; } /* * Constructs and returns a CSSMenu with a Link(menuName,"#") as the label */ public CSSMenu createCSSMenu(String menuName) { AnchorLink menuNameNowherelink = new AnchorLink(new Text(menuName),""); return createCSSMenu(menuName, menuNameNowherelink); } /* * Add a CSSMenu. You could add other things but the results might be strange. */ public void add(PresentationObject menu) { super.add(menu); } /* * Add a CSSMenu. */ public void addCSSMenu(CSSMenu menu) { add(menu); } /* (non-Javadoc) * @see com.idega.presentation.PresentationObject#main(com.idega.presentation.IWContext) */ public void main(IWContext iwc) throws Exception { Page parentPage = this.getParentPage(); //not needed any more, implementing with ADxMenu 2b /*if(iwc.isIE()) { String pathToExplorerFixCSS = this.getBundle(iwc).getVirtualPathWithFileNameString(CSS_EXPLORER_FIX_FILE_PATH); parentPage.setStyleDefinition("body","behavior:url(\""+pathToExplorerFixCSS+"\");"); }*/ String pathToMenuCSS = this.getBundle(iwc).getVirtualPathWithFileNameString(CSS_FILE_PATH); String pathToWCH = this.getBundle(iwc).getVirtualPathWithFileNameString(WCH_JAVASCRIPT_FILE_PATH); String pathToMainScript= this.getBundle(iwc).getVirtualPathWithFileNameString(ADxMENU_JAVASCRIPT_FILE_PATH); parentPage.addStyleSheetURL(pathToMenuCSS); parentPage.addJavascriptURL(pathToWCH); parentPage.addJavascriptURL(pathToMainScript); if(this.addTestData) { //A little test code, //create a menu CSSMenu level0101 = createCSSMenu("First top menu"); //add as a top menu this.add(level0101); //insert items level0101.add(new Link("Item one","#")); level0101.add(new Link("Item two","#")); //insert item that is a submenu CSSMenu level010103 = createCSSMenu("Item three submenu"); level0101.add(level010103); level010103.add(new Link("Item one in submenu","#")); level010103.add(new Link("Item two in submenu","#")); //one last item level0101.add(new Link("Item four","#")); //create and add an empty top menu CSSMenu level0102 = createCSSMenu("Second empty top menu"); this.add(level0102); } } /* (non-Javadoc) * @see com.idega.presentation.PresentationObject#print(com.idega.presentation.IWContext) */ public void print(IWContext iwc) throws Exception { if(getMarkupLanguage().equals("HTML")) { if(this.topMenuMap!=null && !this.topMenuMap.isEmpty()) { println("<script type=\"text/javascript\">\n ADXM.Add( \"menuList\", \"H\" ); \n </script>"); print(prefix); super.print(iwc); print(suffix); } } } public void setToAddTestData(boolean addTestData) { this.addTestData = addTestData; } /** * An helper object to support multiple levels of menus. CSSMenu stores presentationobjects and other CSSMenus as its menu items. * It cannot be used alone so it must be added to a CSSMultiLevelMenu to work. * @author <a href="mailto:eiki@idega.is">Eirikur S. Hrafnsson</a> * **/ public class CSSMenu extends PresentationObjectContainer{ private static final String UL_END_TAG = "</ul>"; private static final String UL_START_TAG = "\n<ul>"; private static final String LI_END_TAG = "</li>"; private static final String LI_START_TAG = "<li>"; private List menuItems; private String menuName; private PresentationObject topMenuItem; /** * Constructs a CSSMenu with the given presentationobject as the top item. */ public CSSMenu(String menuName, PresentationObject topMenuItem) { this.menuName = menuName; this.topMenuItem = topMenuItem; } /* * Add a PresentationObject (another CSSMenu for example) as a menu item. */ public void addMenuItem(PresentationObject menuItem) { add(menuItem); } /* * Add a PresentationObject (another CSSMenu for example) as a menu item. */ public void add(PresentationObject menuItem) { super.add(menuItem); } /* * Constructs and adds an Link("#") object to the menu using the supplied text. */ public void add(String menuItem) { addMenuItem(menuItem); } /* * Constructs and adds an Link("#") object to the menu using the supplied text. */ public void addMenuItem(String textMenuItem) { AnchorLink menuItemNowhereLink = new AnchorLink(new Text(textMenuItem),""); addMenuItem(menuItemNowhereLink); } /* (non-Javadoc) * @see com.idega.presentation.PresentationObject#print(com.idega.presentation.IWContext) */ public void print(IWContext iwc) throws Exception { List children = getChildren(); if(children!=null && !children.isEmpty()) { this.topMenuItem.setStyleClass("submenu"); print(LI_START_TAG); this.topMenuItem._print(iwc); println(UL_START_TAG); //iterate through the children and print them to Iterator iter = children.iterator(); while (iter.hasNext()) { PresentationObject obj = (PresentationObject) iter.next(); if(!(obj instanceof CSSMenu)){ print(LI_START_TAG); obj._print(iwc); println(LI_END_TAG); } else { obj._print(iwc); } } println(UL_END_TAG); println(LI_END_TAG); } else { //topMenuItem.setStyleClass("menuitem"); print(LI_START_TAG); this.topMenuItem._print(iwc); print(LI_END_TAG); } } public String getMenuName() { return this.menuName; } public void setMenuName(String menuName) { this.menuName = menuName; } } /* (non-Javadoc) * @see com.idega.presentation.PresentationObject#isContainer() */ public boolean isContainer() { //not allowed to add to this module in the Builder yet! return false; } }