26

How can I show/hide component with JSF? I am currently trying so do the same with the help of javascript but not successfull. I cannot use any third party libraries.

Thanks| Abhi

Abhishek Dhote
  • 1,638
  • 10
  • 41
  • 62
  • Do you want to show/hide it during page generation, or in reaction to some action on already generated page? The first one can be achieved by "rendered" attribute of JSF tags, the latter by JavaScript. – amorfis Sep 12 '10 at 10:16
  • The component should be invisible when the page is rendered and it should be shown when user clicks on a image. If you can tell me the JS approach that will be great! – Abhishek Dhote Sep 12 '10 at 10:19
  • 1
    If you can use JSF 2.0 the `` tag will allow you to easily update a part of the page instead of triggering a complete page refresh. – Thorbjørn Ravn Andersen Sep 12 '10 at 11:58

6 Answers6

66

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>
Aritz
  • 30,971
  • 16
  • 136
  • 217
Kevin Rahe
  • 1,609
  • 3
  • 19
  • 27
  • 3
    It should be noted this uses ajax and will create extra server requests. Although this may be preferable sometimes I would opt for a javascript based solution – Mark W Nov 06 '15 at 11:43
  • 3
    It should be noted, that if you also want to submit the form, only the input fields (or here the SelectOneMenus) with rendered = true gets submitted. – Fl0R1D3R Mar 22 '16 at 15:12
  • For this to work for me, I had to add `onchange="submit()"` to the outer `` element as shown here: https://stackoverflow.com/a/18787995/2577705. The `valueChangeListener` is not necessary, unless the change itself needs to be tracked. – craned Dec 14 '21 at 18:52
17

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.

Aritz
  • 30,971
  • 16
  • 136
  • 217
McDowell
  • 107,573
  • 31
  • 204
  • 267
  • 1
    Completely agree with @jake-long: you're mixing JS with JSF. Although it is possible you are creating a mess, which is not compliant with best practices in modular development. – Hugo Tavares May 18 '18 at 10:01
7

Use the "rendered" attribute available on most if not all tags in the h-namespace.

<h:outputText value="Hi George" rendered="#{Person.name == 'George'}" />
Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
7

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
@SessionScoped
public 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;
    }
}
Eugenijus S.
  • 354
  • 1
  • 3
  • 10
  • 5
    Pretty much the right idea, but the rendered attribute should be used on the components INSIDE the panelGroup, rather than on the panelGroup itself, if you want to be able to show/hide the components dynamically, as with an AJAX event. If you use rendered on the panelGroup and its condition is initially false, you'll get an error the first time you try to update it because it won't exist on the page. – Kevin Rahe Dec 15 '11 at 20:44
3

One obvious solution would be to use javascript (which is not JSF). To implement this by JSF you should use AJAX. In this example, I use a radio button group to show and hide two set of components. In the back bean, I define a boolean switch.

private boolean switchComponents;

public boolean isSwitchComponents() {
    return switchComponents;
}

public void setSwitchComponents(boolean switchComponents) {
    this.switchComponents = switchComponents;
}

When the switch is true, one set of components will be shown and when it is false the other set will be shown.

 <h:selectOneRadio value="#{backbean.switchValue}">
   <f:selectItem itemLabel="showComponentSetOne" itemValue='true'/>
   <f:selectItem itemLabel="showComponentSetTwo" itemValue='false'/>
   <f:ajax event="change" execute="@this" render="componentsRoot"/>
 </h:selectOneRadio>


<H:panelGroup id="componentsRoot">
     <h:panelGroup rendered="#{backbean.switchValue}">
       <!--switchValue to be shown on switch value == true-->
     </h:panelGroup>

   <h:panelGroup rendered="#{!backbean.switchValue}">
      <!--switchValue to be shown on switch value == false-->
   </h:panelGroup>
</H:panelGroup>

Note: on the ajax event we render components root. because components which are not rendered in the first place can't be re-rendered on the ajax event.

Also, note that if the "componentsRoot" and radio buttons are under different component hierarchy. you should reference it from the root (form root).

Mr.Q
  • 4,316
  • 3
  • 43
  • 40
1

check this below code. this is for dropdown menu. In this if we select others then the text box will show otherwise text box will hide.

function show_txt(arg,arg1)
{
if(document.getElementById(arg).value=='other')
{
document.getElementById(arg1).style.display="block";
document.getElementById(arg).style.display="none";
}
else
{
document.getElementById(arg).style.display="block";
document.getElementById(arg1).style.display="none";
}
}
The HTML code here :

<select id="arg" onChange="show_txt('arg','arg1');">
<option>yes</option>
<option>No</option>
<option>Other</option>
</select>
<input type="text" id="arg1" style="display:none;">

or you can check this link click here

Community
  • 1
  • 1
Gitesh Dang
  • 182
  • 1
  • 14