AJAX render attribute doesn't work with rendered="false" component

Piotr Nowicki picture Piotr Nowicki · Dec 8, 2012 · Viewed 8.7k times · Source

I have a component that I want to show/hide after user hits a commandButton.

It's like this:

<h:commandButton id="showButton" value="#{bean.wasPressed ? 'Hide' : 'Show'}">
    <f:ajax listener="#{bean.toggle()}" render="explanation showButton" />
</h:commandButton>

and

<h:panelGroup id="explanation" rendered="#{bean.wasPressed}">
    <h:outputText value="something" />
</h:panelGroup>

The bean.toggle() simply sets the wasPressed property to true or false appropriately. I am using <h:form prependId="false">.

The problem is the value of the render attribute of my button. It explicitly enlists both: explanation and showButton.

As long as the showButton is always present (it only changes its label), the explanation is present only if the wasPressed property is true. Otherwise it says:

malformedXML: During update: explanaition not found

How can I solve this problem?

I would like not to revert to hiding the element in the source code, so I would like not to use any jQuery toggle(-) or any way of hiding the element using style="display: none" or any of this stuff.

Is it even achievable in JSF 2.1?

Answer

Daniel picture Daniel · Dec 8, 2012

You cannot update elements which are not rendered , rendered=false "is a JSF way to" to remove elements from the DOM Tree ,

its not like css display:none or visibility:hidden <- this two will keep the elements in the DOM tree but hidden , while the JSF rendered=false wont even render (keep) the element in the DOM tree (you wont even see it in the "view source" of the page)

So in you case you need to wrap the panelGroup with another `panelGroup' and update the id of the wrapper

<h:commandButton id="showButton" value="#{bean.wasPressed ? 'Hide' : 'Show'}">
    <f:ajax listener="#{bean.toggle()}" render="explanationWrapper showButton" />
</h:commandButton>


<h:panelGroup id="explanationWrapper">
    <h:panelGroup id="explanation" rendered="#{bean.wasPressed}">
        <h:outputText value="something" />
    </h:panelGroup>
</h:panelGroup>

also look at similar question

Can you update an h:outputLabel from a p:ajax listener?