简体   繁体   中英

f:ajax rendered=false by default

Suppose I've got this small piece of code:

<h:panelGroup id="panel1" rendered="falseByDefault">
    <h:selectBooleanCheckbox value="#{bean.booleanProperty}">
        <f:ajax event="click" render="alwaysrendered">
    </h:selectBooleanCheckbox>
</h:panelGroup>

<h:panelGroup id="alwaysrendered">
    <h:panelGroup id="panel2" rendered="#{!bean.booleanProperty}">
        <p>Some stuff here</p>
    </h:panelGroup>
</h:panelGroup>

panel1 is not rendered until I press another component. booleanProperty is true by default until I press the booleanCheckBox, so the panel2 should appear in that moment because of the ajax request to re-render alwaysrendered.

It doesn't work. I think because the "f:ajax" tag is inside a component that is not rendered when the page loads.

What do you think about this? Do you know any other way to make this work?

Summary: I want to render a component with a tag that is inside a panel not rendered by default.

Thanks!

It doesn't work. I think because the tag is inside a component that is not rendered when the page loads.

That's exactly the problem. JSF ajax update work by replacing the elements in the DOM-Tree of the browser with the new version. But if there is no such element with the ID you just re-rendered, because it wasn't rendered before, then the browser doesn't know where to put that updated element and ignores it.

Try something like this instead:

<h:panelGroup id="panel2" >
    <h:panelGroup rendered="#{!bean.booleanProperty}">
        <p>Some stuff here</p>
    </h:panelGroup>
</h:panelGroup>

You also need to set your bean to at least @ViewScoped . This is because it works like this:

Initially your first panel is not visible because of " rendered="falseByDefault" ". Then you click something else and that condition becomes true making your panel visible, but only for that one request+response. Now you click on the checkbox in that visible panel and want to set #{bean.booleanProperty} to another value in order to show panel2. The request will be sent, but JSF performs some validity checks on that request. It also checks that the checkbox you just clicked, could be clicked (that means it was visible). But because the panel around that checkbox is not visible anymore (it was visible only for one request), JSF decides that this request is not valid and does not process it the way you want it. That's why the boolean value of your checkbox is never changed and your panel2 will not be visible.

As a rule of thumb: never use @RequestScoped together with Ajax requests.

You need to put a wrapping tag with an id around the panelGroup "pane2" and then reference that one in the ajax render attribure. This is needed because javascript tries to update the components by id. But when it is not rendered and therefore not found no update will occur.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM