jsfjstlcommandbuttonconditional-renderingajax-update

Conditional rendering of two different h:commandButton actions


Technology Used :

JSF 2

Primefaces

Problem statement :

We have one drop down list as below -

<h:selectOneMenu value ="#{bean.value}"> 
   <f:ajax event="change" listener="#{bean.processValue}" 
    render="{one,two or panel}" />   //render correct id based on approach

   <f:selectItem itemValue = "1" itemLabel = "Item 1" /> 
   <f:selectItem itemValue = "2" itemLabel = "Item 2" />
   <f:selectItem itemValue = "3" itemLabel = "Item 3" /> 
   <f:selectItem itemValue = "4" itemLabel = "Item 4" /> 
</h:selectOneMenu>          

If user selects item 2 , a button is displayed which when clicked opens up a pop up menu. If user selects item 1 or 3 or 4 , another button is displayed which triggers a business action when clicked.

We are able to get AJAX invocation for h:selectOneMenu using f:ajax. We are using render attribute of f:ajax

This is working fine.

The question is how to design two buttons on AJAX response.

Approach one without using JSTL :

<h:commandButton id="one" value="Submit" onClick="openPopup" rendered="#{bean.render}">
<h:commandButton id="two" value="Submit" action="#{bean.businessAction}" rendered="#{bean.render}">

where #{bean.render} will check for value of item clicked and return true/false.

Approach two with using JSTL :

Wrap two buttons within same panelGrid and render only panelGrid. Use JSTL inside panelGrid to control rendering.

<h:panelGrid id="panel">
  <c:choose>     
     <c:when test = "${itemVlaue == 2}"> // use appropriate EL expression 
       <!-- render command button 1 to open pop up --> 
     </c:when>

     <c:when test = "${itemVlaue == 1 or 3 or 5  }"> // use appropriate EL expression 
       <!-- render command button 2 to invoke action --> 
     </c:when>
  </c:choose>
</h:panelGrid>

I have searched over internet and it seems approach one is more correct since it is not advisable to use JSTL inside JSF to control rendering.

But the question is then :

We end up creating two command buttons when only one is being used.

Also what if two command buttons need to have only one id . That is only one should be present at any point on time .

Please advice


Solution

  • Your Y-problem is answered in:

    Your X-problem is answered as below:

    <h:selectOneMenu value="#{bean.value}">
       ...
       <f:ajax listener="#{bean.processValue}" render="oneAndOnly" />
    </h:selectOneMenu>
    ...
    <h:commandButton id="oneAndOnly" value="Submit"
        onclick="#{bean.render ? 'openPopup();return false;' : ''}"
        action="#{bean.businessAction}">
    </h:commandButton>
    

    In other words, just let it conditionally render the onclick attribute itself which returns false.