0

I have a big form that I need to reuse in multiple pages. So, I decided to create a
<ui:composition> that contains the form and include it in some pages (page1.xhtml and page2.xhtml).

form.xhtml:

<ui:composition ...>
    <!-- The form goes here -->
</ui:composition>

This form has a controller called FormController.

In page1.xhtml and page2.xhtml I just include the form using a <ui:include> tag:

<ui:include src="/WEB-INF/.../form.xhtml"/>

I need to initialize a property in the FormController bean, so, in page1.xhtml I decided to set an attribute with the Id that I need (for example 5):

<c:set var="id" scope="request" value ="5"/>

And in the controller I just get the value of this attribute:

@PostConstruct
public init() {
    Long id = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getAttribute("id");
    //Do some queries to the database
}

Until know, everything works fine. But in page2.xhtml the "initialization" of the bean property has to be done after an ajax request, so I used the following code:

<h:selectOneMenu ...>
    <f:selectItems ...>
    <f:ajax listener="#{otherBean.doSomething}" render="panel"/>
</h:selectOneMenu>

<h:panelGroup id="panel">
    <c:set var="id" scope="request" value ="#{otherBean.id}"/>
    <ui:include src="/WEB-INF/.../form.xhtml"/>
</h:panelGroup>

What is weird is that this works just the first time I select an element in the <h:selectOneMenu>. The second time, the doSomething() method is called but the panel is not rendered (I don't know why, you know why?), so I decided to explore the following alternative that works well in both pages, but I feel that it isn't a good solution:

#{bean.init(otherBean.id)}
<ui:include src="/WEB-INF/modules/company/company.xhtml"/>

As you see, I am just calling an init method (before the <ui:include>) with the argument I need. In the controller I just set the property and do the corresponding queries:

public init(Long id) {
    this.id = id;
    //Do some queries
}

What do you thing about this solution?

Jucaalpa
  • 310
  • 1
  • 4
  • 15
  • You can use `` and `another_init_function('MYID2')` for the 2nd form – Holger Jun 20 '19 at 07:05
  • Btw., JSTL `` tags are all taghandlers and they are executed during view build time, while JSF `` tags are all UI components and they are executed during view render time. https://stackoverflow.com/questions/3342984/jstl-in-jsf2-facelets-makes-sense/ – Holger Jun 20 '19 at 07:24
  • But how you call the another_init_function for the first page (in this case there isn't any Ajax request to initialiaze the id in the FormController bean) – Jucaalpa Jun 20 '19 at 15:51

1 Answers1

0

If the form has to be initialized at start, you can use

<f:metadata>
    <f:viewAction action="#{otherBean.initSomething('MYID2')}"/>
</f:metadata>

If the form has to be initialized by an action

<h:commandButton action='#{otherBean.doSomething('MYID1')}'...>

or

<f:ajax listener="#{otherBean.doSomething('MYID')}" .../>
Holger
  • 899
  • 2
  • 7
  • 12
  • Thank you Holger. I will try with as you suggested. Is there anything wrong calling #{bean.init(otherBean.id)} directly in the xhtml? – Jucaalpa Jun 24 '19 at 01:31