blo0p3r
blo0p3r

Reputation: 6850

ui:include dependent on viewParam

I have a page where I want to include a part of the page (footer in this instance) dependant on values given from a view parameter.

I have my ViewScoped backing bean initializing on preRenderView

<f:metadata>
    <f:viewParam name="racecode" value="#{displayResults.racecode}" />
    <f:event type="preRenderView" listener="#{displayResults.init}" />  
</f:metadata>

This queries the database to get the name of the footer to be included. This then, is used in this fashion :

<h:panelGroup id="customFooter" display="block">
    <ui:include src="#{displayResults.customFooter}" />
</h:panelGroup>

This always gives me a missing page. But if I enter the page name manually it works. Same if I replace the ui:include with an h:outputText.

I understand that it has something to do with the phases of JSF and that at the time the ui:include is done, the value is not set yet. (reading up and better understanding the phases is something on my TODO list).

The question remains. How can I get something of the sort done. Have a bean use the viewParam, query the database and use that value in a ui:include?

Upvotes: 4

Views: 1010

Answers (2)

BalusC
BalusC

Reputation: 1108632

@wemu has already explained the cause. The <ui:include src> is evaluated before init() method is called. His proposed <f:phaseListener> solution is however clumsy.

Just use @ManagedProperty/@PostConstruct on a @RequestScoped bean.

@ManagedProperty("#{param.racecode}")
private String racecode;

@PostConstruct
public void init() {
    // ...
}

Upvotes: 3

wemu
wemu

Reputation: 8160

PreRenderView listeners are called within the RenderResponsePhase, before components are rendered BUT AFTER the TagHandlers are called. This means that TagHandlers will NOT see data initialized within a PreRenderView event.

If you are using a <ui:include value="#{myBean.myViewId}" /> to dynamically switch an include you can't use a PreRenderView event listener to set the myViewId property of myBean.

If you need to do that use a <f:phaseListener>.

Upvotes: 1

Related Questions