Do I have to pass ui:param in template if I am using ui:composite and ui:insert, ui:include? - jsf

I have one page main.xhtml, which contains ui:composition. This composition uses template1.xhtml file. template1.xhtml file contains ui:insert, ui:include tag which are pointing to template2.xhtml file. Now, I want to use parameters that are passed from ui:composition inside template2.xhtml.
main.xhtml
<ui:composition template="template1.xhtml">
<ui:param name="a1" value="val1"/>
</ui:composition>
template1.xhtml
<ui:insert name="header">
<ui:include src="template2.xhtml">
</ui:insert>
template2.xhtml
<h:panelGroup rendered="#{not empty a1}" layout="block">
<h4>#{a1}</h4>
</h:panelGroup>
My question is can I directly access parameter named a1 or I had to again pass ui:param in ui:include?

Depends on Facelets version and JSF impl/version.
In original Facelets 1.x, any <ui:param> in parent composition is inherited into all <ui:include> children.
<ui:include src="template2.xhtml" />
In Facelets 2.x as integrated in JSF 2.x, any <ui:param> of a parent composition which ought to be reused in an <ui:include> (or <ui:decorate>) must be explicitly passed through.
<ui:include src="template2.xhtml">
<ui:param name="a1" value="#{a1}" />
</ui:include>
At least, that's the case when you're using Mojarra 2.x. In MyFaces 2.0 / 2.1, however, it was not necessary as the original Facelets 1.x behavior unintentionally slipped into MyFaces 2.0 / 2.1.
<ui:include src="template2.xhtml" />
They have fixed it in MyFaces 2.2, so you need to explicitly pass them through.
<ui:include src="template2.xhtml">
<ui:param name="a1" value="#{a1}" />
</ui:include>
In case you're using MyFaces 2.2 or newer, and want to retain the original Facelets 1.x behavior, then you can add the following context param to web.xml:
<context-param>
<param-name>org.apache.myfaces.STRICT_JSF_2_FACELETS_COMPATIBILITY</param-name>
<param-value>true</param-value>
</context-param>
<ui:include src="template2.xhtml" />
No such context param exist for Mojarra, so this should not be relied upon in case you want to have your code to work the same across all JSF implementations.

Related

Reuse some .xhtml pages on a JSF primefaces application

I developing a simple application using JSF and PrimeFaces and here's a problem that I'm facing:
These are managed beans that have a Person property:
ClientBean
EmployeeBean
I have the person.xhtml that shows the data from a person. I include the person.xhtml on a client.xhtml and employee.xhtml. I need to create two person.xhtml because I'm using different beans. What I want to do is something like that:
<c:set var="person" value="clientBean.person" />
<ui:include src="person.xhtml"/>
<c:set var="person" value="employeeBean.person" />
<ui:include src="person.xhtml"/>
And in my person.xhtml I can use #{person.name} , #{person.dateOfBirth}.
I searched and use <c:set/> in JSF is wrong.
Anyone can help?
Pass it as <ui:param>.
<ui:include src="person.xhtml">
<ui:param name="person" value="#{clientBean.person}" />
</ui:include>
<ui:include src="person.xhtml">
<ui:param name="person" value="#{employeeBean.person}" />
</ui:include>
Register person.xhtml if necessary as a tag file to make it look better, see also When to use <ui:include>, tag files, composite components and/or custom components?
<my:personForm value="#{clientBean.person}" />
<my:personForm value="#{employeeBean.person}" />
Beware of duplicate component ID errors. See also Avoiding duplicate ids when reusing facelets compositions in the same naming container.

h:outputText to conditionally render groups of JSF elements no longer working in JSF 2?

I have some code that uses <h:outputText> to conditionally render groups of JSF elements. Examples:
<h:outputText rendered="#{authorization.admin}">
<h:outputText value="#{msgs.someinfo}" />
<h:inputSecret value="#{usermanager.password}" />
</h:outputText>
<h:outputText rendered="#{contactmanager.editAction}">
<li>
<label for="name"><h:outputText value="#{msgs.nameinfo}" /></label>
<h:inputText id="name" value="#{contactmanager.name}" />
<h:messages for="name" />
</li>
</h:outputText>
The code is on glassfish 2.1.1 which has the MANIFEST.MF in jsf-impl.jar looking like this (I'm not sure whether it actually uses this jar or some other one for JSF):
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: 1.5.0_19-b02 (Sun Microsystems Inc.)
Specification-Title: JavaServer Faces
Specification-Version: 1.2MR2
Implementation-Title: Mojarra
Implementation-Version: 1.2_13-b01-FCS
Implementation-Vendor: Sun Microsystems, Inc.
Implementation-Vendor-Id: com.sun
Extension-Name: com.sun.faces
I'm trying to move to glassfish 4 which has some version of JSF 2 or higher.
All the hundreds of instances of this construct worked on the old glassfish, but they no longer work on the new one - they are replaced with nothing, regardless of what the rendered attribute evaluates to. Why?
Indeed, since JSF 2.0, children of UIInput and UIOutput are by default not anymore rendered. This is the consequence of fixes for issue 1154. In Mojarra 2.x, you can still turn it back on via a web.xml context parameter:
<context-param>
<param-name>com.sun.faces.allowTextChildren</param-name>
<param-name>true</param-name>
</context-param>
See also the Mojarra 2.0.0 release notes.
It's however more recommended to instead use <h:panelGroup> or <ui:fragment> for conditional rendering of blocks as the <h:outputText> is just the Wrong Toolâ„¢ for the job.

Primefaces multiple dynamic content panels to be displayed

I'm trying to do a kind of simple customizable news view page into my web application, like Google's one but much simpler, with frames. Each frame object simply has his title and an url to be added as its content.
I'm using JSF and primefaces, both on their newest versions. So my backing bean, which is #ViewScoped, has access to the logged user, which is stored in a #SessionScoped bean, and that user has his corresponding frames loaded.
Problem comes when I try to iterate it over the #ViewScoped bean, because the only way I find to do it is with a c:forEach tag. That's the way I do:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<h:form>
<p:panel header="Noticias">
<h:panelGrid columns="#{fn:length(navegableHomeManager._UserFrames)}"
width="100%">
<c:forEach var="frame" items="#{navegableHomeManager._UserFrames}">
<p:column>
<p:panel header="#{frame._Name}" closable="true"
style="width:95%;height:500px;" id="#{frame._Name}">
<p:ajax event="close"
listener="#{navegableHomeManager.actionFrameClosed}" />
<ui:include src="#{frame._Path}" />
</p:panel>
</p:column>
</c:forEach>
</h:panelGrid>
</p:panel>
</h:form>
That iteration obviusly does not work with navegableHomeManager bean because it is #ViewScoped. So the bean will be rebuilt in each of the iterations. The solution I've reached uses another #SessionScoped bean between the navegableHomeManager and the loggedBean, so that way the frames are stored there and I can have access to them properly into the iteration. That's working with the code above.
However I don't think it should be compulsory to use a #SessionScoped bean (creating an specific bean for every single case) every time I want to iterate in that way. That's why I have tried using components to avoid the iteration.
<p:dataGrid columns="#{fn:length(navegableHomeManager._UserFrames)}"
value="#{navegableHomeManager._UserFrames}" var="frame">
<p:column>
<p:panel header="#{frame._Name}" closable="true"
style="width:95%;height:500px;">
<p:ajax event="close"
listener="#{navegableHomeManager.actionFrameClosed}" />
<ui:include src="#{frame._Path}" />
</p:panel>
</p:column>
</p:dataGrid>
It doesn't work neither when the bean is #ViewScoped or #SessionScoped, because even the frames properties are set, the ui:include tag has already been built with no destination path, so I can't render the destination path dinamically. I think that, as ui:include is being applied at the same time as c:forEach, using a c:forEach tag is really the only way to go through this.
Pool your ideas.
UPDATE
Here I post more xhtml code to help in the understanding of the context. The new's page is integrated into a template. That's the page which is targeted (/system/home/index.xhtml):
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
template="/templates/general_template.xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<ui:define name="metadata">
<f:event type="preRenderView"
listener="#{navegableHomeManager.initialize}" />
</ui:define>
<ui:define name="general_content">
<ui:include src="/system/home/home_view.xhtml" />
</ui:define>
And that's the way I also tried to do it, but not making the c:forEach tag to work:
<context-param>
<param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
<param-value>/system/home/index.xhtml</param-value>
</context-param>
And that's the backing bean header:
#ManagedBean
#ViewScoped
#URLMapping(id = "home", pattern = "/home", viewId = "/system/home/index.xhtml")
public class NavegableHomeManager extends SystemNavegable {
/**
*
*/
private static final long serialVersionUID = 6239319842919211716L;
#ManagedProperty(value = "#{loggedBean}")
private LoggedBean _LoggedBean;
//More stuff
Stick to <c:forEach>. It does the job you're looking for. The <ui:include> runs during view build time, so the iteration tag should also run during view build time.
As to the #ViewScoped bean problem, you've 2 options:
Turn off partial state saving for the particular view:
<context-param>
<param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
<param-value>/news.xhtml</param-value>
</context-param>
Change it to a #RequestScoped bean and use <f:param> and #ManagedProperty to maintain state across postbacks by request parameters.
There would be a third option if JSF 2.2 is available: just upgrade to JSF 2.2. They've fixed the chicken-egg problem in view scoped beans and partial state saving.

How do I dynamically include the backing bean value in jsf 1.2

Hi i have the following code
creatPage1.jsp
<h:inputText id="inputId1" value="#{createPage.item.name}"/>
i have updatePage1.jsp
<h:inputText id="inputId1" value="#{updatePage.item.name}"/>
I want to be able to do include (via ui:include or jsp:include) and be able to pass in the value dynamically (the base backing bean to be createPage or updatePage).
So the result should be
<ui:include src="Page1.jsp" basebean="#{createPage}"/>
Page1.jsp
<h:inputText id="inputId1" value="#{baseBean.item.name}"/>
Whats the best way to do this in jsf?
You can use ui:param :
<ui:include src="Page1.jsp">
<ui:param name="basebean" value="#{createPage}"/>
</ui:include>
You will probably need to create your own custom tag. Check this out: http://www.ibm.com/developerworks/java/library/j-facelets/

How to use ui:include with parameters?

Have JSF 1.2 two pages(one.xhtml and other.xhtml), that are included to the current page by following rule:
...
<c:if test="#{flowScope.Bean.param1}">
<ui:include src="one.xhtml"/>
</c:if>
<c:if test="#{!flowScope.Bean.param1}">
<ui:include src="other.xhtml"/>
</c:if>
...
As far one.xhtml differs from other.xhtml only by action parameters:
one.xhtml:<h:commandLink action="actionOne">
other.xhtml:<h:commandLink action="actionTwo">
Is it possible to use some general xhtml? Instead of one.xhtml and other.xhtml,something like this:
...
<c:if test="#{flowScope.Bean.param1}">
<ui:include src="general.xhtml" param="actionOne"/>
</c:if>
<c:if test="#{!flowScope.Bean.param1}">
<ui:include src="general.xhtml" param="actionTwo"/>
</c:if>
...
thank you for help.
You need to nest <ui:param> inside <ui:include> to pass parameters to the included file.
<ui:include src="general.xhtml">
<ui:param name="action" value="actionOne" />
</ui:include>
and in the include:
<h:commandButton action="#{action}" />
Note that this only supports strings, not action methods. For the latter you would need to upgrade to JSF 2.0 and use composite components.
In addition to BalusC's answer:
Note that this only supports strings,
not action methods. For the latter you
would need to upgrade to JSF 2.0 and
use composite components.
There is a way to do this with JSF 1.2, though it's somewhat ugly:
<ui:include src="general.xhtml">
<ui:param name="actionBean" value="#{myBackingBean}" />
<ui:param name="actionMethod" value="edit" />
</ui:include>
and
<h:commandButton action="#{actionBean[actionMethod]}" />

Resources