Ajax render not working on SelectBooleanCheckbox

2019-01-29 01:28发布

问题:

I have a JSF form and on which I have a selectBooleanCheckbox. If the value of the checkbox is true I want to display the combo box next to it. But somehow it is not working.

Here is my code:

      <h:outputText value="Condition"/>
      <h:selectBooleanCheckbox id="provisioningTargetCollector" 
                           value="#{targetSource.provisioningTargetCollector}"
                           disabled="#{!sp:hasRight(facesContext, 'ManageApplication')}"
                           readonly="#{!sp:hasRight(facesContext, 'ManageApplication')}">
                           <f:ajax  render="targetCollectorsGroup" />
                           </h:selectBooleanCheckbox>

      <h:outputText value="Provisioning Target Collector"/>
      <h:panelGroup id="targetCollectorsGroup">
        <a4j:outputPanel id="targetCollectors">
          <h:selectOneMenu id="collector"
                           value="#{targetSource.selectedTargetCollector}"
                           rendered="#{empty targetSource.object.id}"
                           disabled="#{!sp:hasRight(facesContext, 'ManageApplication')}"
                           readonly="#{!sp:hasRight(facesContext, 'ManageApplication')}">
            <f:selectItem itemValue="" itemLabel="#{msgs.select_provisioning_target_collector}"/>
            <f:selectItems value="#{targetSource.targetCollectors}"/>
          </h:selectOneMenu>
          <h:selectOneMenu id="fixedTargetCollector" value="#{empty targetSource.selectedTargetCollector ? 'None' : targetSource.selectedTargetCollector}"
                           rendered="#{not empty targetSource.object.id}"
                           disabled="true"
                           readonly="true">
            <f:selectItem itemValue="#{empty targetSource.selectedTargetCollector ? 'None' : targetSource.selectedTargetCollector}"
                          itemLabel="#{empty targetSource.selectedTargetCollector ? msgs.none : targetSource.selectedTargetCollector}"/>
          </h:selectOneMenu>
        </a4j:outputPanel>
      </h:panelGroup>

Bean Class Methods:

private boolean _provisioningTargetCollector;

public boolean isProvisioningTargetCollector() {

    return _provisioningTargetCollector;
 }

 public void setProvisioningTargetCollector(boolean provisioningTargetCollector) {

     _provisioningTargetCollector = provisioningTargetCollector;
 }

Note: Copied from FireBug

This is the POST Request:

AJAX:EVENTS_COUNT   1
editForm    editForm
editForm:collector  
editForm:collectorType  
editForm:dsCorrelationRul...    
editForm:dsCreationRule 
editForm:dsDescription  
editForm:dsName 
editForm:id 2c90950048166abc0148177755040025
editForm:selectedTargetsF...    
editForm:type   Active Directory - Direct
javax.faces.ViewState   1920301575480395177:8510885827764100150
javax.faces.behavior.even...    click
javax.faces.partial.ajax    true
javax.faces.partial.event   click
javax.faces.partial.execu...    editForm:provisioningTargetCollector editForm:provisioningTargetCollector
javax.faces.partial.rende...    editForm:targetCollectorsGroup
javax.faces.source  editForm:provisioningTargetCollector
rfExt   null

Response:

<?xml version='1.0' encoding='UTF-8'?>
<partial-response><changes><update id="editForm:targetCollectorsGroup"><![CDATA[<span id="editForm:targetCollectorsGroup"><span id="editForm:targetCollectors"><select id="editForm:collector" name="editForm:collector" size="1">  <option value="">Select a Provisioning Target Collector ...</option>
    <option value="AD Test">AD Test</option>
    <option value="ADWindow">ADWindow</option>
    <option value="ADTestSth">ADTestSth</option>
</select></span></span>]]></update><update id="javax.faces.ViewState"><![CDATA[1920301575480395177:8510885827764100150]]></update><extension id="org.richfaces.extension"><render>editForm:targetCollectorsGroup</render></extension></changes></partial-response>

回答1:

The straightforward way to achieve the functionality you desire is, literally, to rerender the combobox basing on the selection of the checkbox. That is done in a following way:

<h:selectBooleanCheckbox binding="#{checkbox}">
    <f:ajax render="group" />
</h:selectBooleanCheckbox>
<h:panelGroup id="group">
    <h:selectOneMenu ... rendered="#{checkbox.value}" />
</h:panelGroup>

Note that the code doesn't need any special fields in the bean and the UIComponent is bound to the view.

Of course, you can do it via a bean property as well, if you need it in your model:

<h:selectBooleanCheckbox value="#{bean.value}">
    <f:ajax render="group" />
</h:selectBooleanCheckbox>
<h:panelGroup id="group">
    <h:selectOneMenu ... rendered="#{bean.value}" />
</h:panelGroup>

Also worth noting is that this functionality can be achieved by plain JavaScript as well, by toggling the display attribute of an element between none and block. But be aware that you must keep the status of JSF components consistent across postbacks to secure against possible malicious attack threats.