How can I show/hide component with JSF?
You can actually accomplish this without JavaScript, using only JSF's rendered
attribute, by enclosing the elements to be shown/hidden in a component that can itself be re-rendered, such as a panelGroup, at least in JSF2. For example, the following JSF code shows or hides one or both of two dropdown lists depending on the value of a third. An AJAX event is used to update the display:
<h:selectOneMenu value="#{workflowProcEditBean.performedBy}"> <f:selectItem itemValue="O" itemLabel="Originator" /> <f:selectItem itemValue="R" itemLabel="Role" /> <f:selectItem itemValue="E" itemLabel="Employee" /> <f:ajax event="change" execute="@this" render="perfbyselection" /></h:selectOneMenu><h:panelGroup id="perfbyselection"> <h:selectOneMenu id="performedbyroleid" value="#{workflowProcEditBean.performedByRoleID}" rendered="#{workflowProcEditBean.performedBy eq 'R'}"> <f:selectItem itemLabel="- Choose One -" itemValue="" /> <f:selectItems value="#{workflowProcEditBean.roles}" /> </h:selectOneMenu> <h:selectOneMenu id="performedbyempid" value="#{workflowProcEditBean.performedByEmpID}" rendered="#{workflowProcEditBean.performedBy eq 'E'}"> <f:selectItem itemLabel="- Choose One -" itemValue="" /> <f:selectItems value="#{workflowProcEditBean.employees}" /> </h:selectOneMenu></h:panelGroup>
Generally, you need to get a handle to the control via its clientId. This example uses a JSF2 Facelets view with a request-scope binding to get a handle to the other control:
<?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"> <h:head><title>Show/Hide</title></h:head> <h:body> <h:form> <h:button value="toggle" onclick="toggle('#{requestScope.foo.clientId}'); return false;" /> <h:inputText binding="#{requestScope.foo}" id="x" style="display: block" /> </h:form> <script type="text/javascript"> function toggle(id) { var element = document.getElementById(id); if(element.style.display == 'block') { element.style.display = 'none'; } else { element.style.display = 'block' } } </script> </h:body></html>
Exactly how you do this will depend on the version of JSF you're working on. See this blog post for older JSF versions: JSF: working with component identifiers.
You should use <h:panelGroup ...>
tag with attribute rendered
. If you set true
to rendered, the content of <h:panelGroup ...>
won't be shown. Your XHTML file should have something like this:
<h:panelGroup rendered="#{userBean.showPassword}"> <h:outputText id="password" value="#{userBean.password}"/></h:panelGroup>
UserBean.java:
import javax.faces.bean.ManagedBean;import javax.faces.bean.SessionScoped;@ManagedBean@SessionScopedpublic class UserBean implements Serializable{ private boolean showPassword = false; private String password = ""; public boolean isShowPassword(){ return showPassword; } public void setPassword(password){ this.password = password; } public String getPassword(){ return this.password; }}