I have a static menu in the sidebar which I include in every JSF page. The menu looks like so:
<li class="nav-header">Item 1</li>
<li class="active"><a href="index.xhtml">Item 2</a></li>
<li><a href="new_workload.xhtml">Item 3</a></li>
<li><a href="import_workload.xhtml">Item 4</a></li>
Adding a class="active"
to the <li>
highlights the menu. How do I go about making sure selected item is highlighted dynamically in JSF2?
I know PrimeFaces and RichFaces have ready made components for this, but I want to try a pure JSF 2 solution first. A pure client side JavaScript solution is also acceptable.
You can get the current view ID in EL as follows
#{view.viewId}
So, this should do
class="#{view.viewId eq '/index.xhtml' ? 'active' : ''}"
It'd be easier to hold all those links in some List<Page>
so that you can just do something like
<li class="nav-header">#{menu.header}</li>
<ui:repeat value="#{menu.pages}" var="page">
<li class="#{view.viewId eq page.viewId ? 'active' : ''}">
<h:link value="#{page.title}" outcome="#{page.viewId}" />
</li>
</ui:repeat>
instead of copypasting the same piece of code over and over.
I've used @BalusC idea plus his other tip at 12473461 but with some modification:
<ul>
<li class="#{view.viewId eq '/admin/index.xhtml' ? 'active' : ''}"><h:link value="Main" outcome="main"/></li>
<li class="#{fn:startsWith(view.viewId, '/admin/sess1/') ? 'active' : ''}"><h:link value="Session 1" outcome="sess1"/></li>
<li class="#{fn:startsWith(view.viewId, '/admin/sess2/') ? 'active' : ''}"><h:link value="Session 2" outcome="sess2"/></li>
<li class="#{fn:startsWith(view.viewId, '/admin/sess3/') ? 'active' : ''}"><h:link value="Session 3" outcome="sess3"/></li>
</ul>
My solution is based on custom component:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:composite="http://java.sun.com/jsf/composite" xmlns:c="http://java.sun.com/jsp/jstl/core" >
<composite:interface>
<composite:attribute name="outcome" />
<composite:attribute name="label" />
</composite:interface>
<composite:implementation>
<li class="menuItem #{view.viewId == cc.attrs.outcome ? 'active' : ''}">
<h:outputText value="#{cc.attrs.label}" rendered="#{view.viewId eq cc.attrs.outcome}"/>
<h:link outcome="#{cc.attrs.outcome}" value="#{cc.attrs.label}" rendered="#{view.viewId ne cc.attrs.outcome}" />
</li>
</composite:implementation>
</html>
Used in code:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:my="http://java.sun.com/jsf/composite/my">
...
<ul class="nav">
<my:menuItem outcome="/home.xhtml" label="Home" />
</ul>