How to include pages in a JSPX and Trinidad project in run-time without breaking the JSF lifecycle? - jsf

I am struggling to figure out a way to include dynamically determined pages in run-time in a JSPX and Trinidad project. You will have an idea when you see what I have, which is:
<tr:panelAccordion>
<tr:showDetailItem
text="Test tab">
<jsp:include page=".test.jspx" /> <!-- This part is working fine -->
</tr:showDetailItem>
<jsp:scriptlet>
BackingTest backing = (BackingTest) session.getAttribute("backingTest");
for (CaseTabConfigurationDTO tab : backing.getTabs()) {
java.io.File f = new java.io.File(request.getRealPath(tab.getPagePath()));
if (f.exists()) {
pageContext.include(tab.getPagePath(), true);
}
}
</jsp:scriptlet>
</tr:panelAccordion>
jsp:include part is working fine, nothing is breaking the JSF lifecycle.
jsp:scriplet part is successful for including the correct pages. However, it is breaking the later actions in JSF lifecycle including still persisting backing beans of dialogs opened using useWindow="true".
In order to be make it complaint with Facelet, thus not breaking JSF lifecycle. I tried using tr:forEach, c:forEach, ui:include, ui:repeat approaches without any luck of actually including pages.
Can you share a proper solution for it? Thanks in advance!

You probably want to reconfigure your project so you can use Facelets with Trinidad. After reconfiguring your project can use Facelets for templating. You will end up using xhtml instead of jspx though.
See also:
When to use <ui:include>, tag files, composite components and/or custom components?
How to include another XHTML in XHTML using JSF 2.0 Facelets?

Related

Embed JSF code in a xhtml

I need to complete a xhtml page with some JSF code (with p:panel and p:datatables, etc.) from a managed bean, but I'm not sure that is possible.
My attemps:
1º
<h:outputText escape="true" value="#{controller.jsfString}"/>
It's not be able to understand "p:" components, only simple html.
2º
<ui:include src="#{controller.jsfString}">
It expects a xhtml path, not a String.
I don't know what else try... Is it even possible?
It's not be able to understand "p:" components, only simple html.
Of course it is not!
The h:outputText value is evaluated at view render time, so if you render JSF tags, they won't be evaluated again since rendering is done.
In principle, it could have been possible to add JSF tags this way using the JSTL <c:out>, but it is not available in JSF facelets.
Anyway, just tell yourself that it prevents you from making bad design.
We'll need more information regarding what the controller is supposed to output in order to help you.
Here p means prime-faces u need to include prime-faces dependency in pom and enable tag lib for prime-faces in XHTML then u can use the all the prime-faces components.

Where can i find the Servlet generated by the JSF file?

When i try to run my jsf file i get this warning:
12:27:49,357 WARNING [javax.enterprise.resource.webcontainer.jsf.renderkit] (http-localhost- 127.0.0.1-8080-7) JSF1090: Navigation case not resolved for component j_idt24.
In order to fix this problem I need to find out which one is the j_idt24 component, And I'm not sure how to do it, so I figured that I would probably find it in the generated servlet file(Am i right?) , So where can i find the generated Servlet file, or what would be a better way?
-Java
You're confusing JSF with JSP. JSF is a MVC framework which can for the "V" part use either JSP, or Facelets or something entirely different.
What you're stating is true for JSP, but not necessarily for JSF. In JSF2, JSP is succeeded by Facelets which is compiled to a XML document, not a Servlet class. You're also confusing "JSF source code" with "JSF component tree". Those autogenerated IDs are not visible in the compiled XML document of Facelets nor Servlet class of JSP. They are only created during generating the HTML output based on the JSF component tree in server's memory during view render time (that JSF component tree is in turn created based on that XML document or Servlet class during view build time).
Coming back to your concrete problem, this warning will occur when you specify an invalid outcome in <h:link> or <h:button> component. Easiest way to naildown the culprit is to give every single <h:link> and <h:button> a fixed ID so that JSF doesn't need to autogenerate them so that you can just do rightclick, View Source in browser and do a Ctrl+F.
<h:link id="fooLink" value="Foo" outcome="foo" />
An alternative is to add <ui:debug> and explore the JSF component tree which is presented "plain text" in the debug popup and then trackback the found component to its declaration in the JSF (XHTML) source code.
See also:
WARNING JSF1090: Navigation case not resolved for component j_idt51
how to debug JSF/EL

Migrating JSF 1.1 with Ajax4jsf 1.x to JSF 2

We are migrating JSF 1.1 (MyFaces) project to JSF 2. The idea is to migrate periodically by keeping both JSP and XHTML together for some time. We use many ajax4jsf-1.1.1 tags in JSP pages. We don't use RichFaces. After configuring the system to JSF 2 (with all config changes mentioned in tutorial by Balusc) When tried to access the JSP page with ajax4jsf.jar in classpath, we get an exception:
Caused by: java.lang.IllegalStateException: setViewHandler may not be executed after a lifecycle request has been completed
at org.apache.myfaces.application.ApplicationImpl.setViewHandler(ApplicationImpl.java:853)
at org.ajax4jsf.framework.ajax.InitPhaseListener.beforePhase(InitPhaseListener.java:92)
at org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersBefore(PhaseListenerManager.java:76)
at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:131)
It looks ajax4jsf.jar is not compatible with JSF 2. Looks some issue with LifeCycle configuration.
Is there any way we can make a4j work with JSF 2 JSPs? I know when we use XHTML we don't need all this.
Get rid of Ajax4jsf 1.x altogether. It's indeed not compatible with JSF2. Instead, JSF2 offers a new main ajax tag <f:ajax> which covers all the core functionality as previously offered by Ajax4jsf 1.x.
If upgrading to RichFaces 4 is not an option (because, as you said yourself, you aren't using RichFaces components anywhere), then just remove Ajax4jsf 1.x and replace all <a4j:xxx> tags by standard JSF2 equivalents.
<a4j:ajaxListener>: use <f:ajax listener>.
<a4j:keepAlive>: just put managed bean in the view scope by #ViewScoped.
<a4j:log>: use jsf.ajax.addOnEvent() or jsf.ajax.addOnError() in JS context.
<a4j:commandLink>: just nest <f:ajax> inside <h:commandLink>.
<a4j:outputPanel>: use <h:panelGroup> and remember to include its ID in <f:ajax render> or PrimeFaces <p:outputPanel>.
<a4j:repeat>: just use standard <ui:repeat>.
<a4j:form>: just use <h:form>, it will autorecognize <f:ajax>.
<a4j:htmlCommandLink>: just nest <f:ajax> inside <h:commandLink>.
<a4j:jsFunction>: just use standard <h:commandScript>. It was however introduced late in JSF 2.3. If you can't upgrade to JSF 2.3 then consider OmniFaces <o:commandScript> or PrimeFaces <p:remoteCommand>.
<a4j:region>: just use <f:ajax execute>, you can even wrap <f:ajax> around a group of components.
<a4j:loadBundle>: just use standard <f:loadBundle>.
<a4j:status>: use jsf.ajax.addOnEvent() or jsf.ajax.addOnError() in JS context.
<a4j:actionparam>: just use standard <f:param>.
<a4j:loadScript>: just use standard <h:outputScript>.
<a4j:mediaOutput>: no replacement. Consider PrimeFaces <p:media>.
<a4j:poll>: no replacement. Consider OmniFaces <o:commandScript> or PrimeFaces <p:poll>.
<a4j:commandButton>: just nest <f:ajax> inside <h:commandButton>.
<a4j:include>: just use standard <ui:include>.
<a4j:loadStyle>: just use standard <h:outputStylesheet>.
<a4j:support>: just use standard <f:ajax>.
You also need to rename/rewrite JSP files to Facelets files. In simple cases, this is usually just a matter of changing root declarations and file extensions. Facelets makes it easier to replace all duplicated code by a single template. The following answer applies:
Migrating from JSF 1.2 to JSF 2.0

Migrating from JSF1.2 to JSF2.0: What to do with JSTL?

we are going to migrate our JSF 1.2 project to JSF 2. We are already using facelets (not JSPs) as our presentation technology.
We are using lot of JSTL -> "xmlns:c="http://java.sun.com/jstl/core"
We are using lot of <c:if> statements. I know that JSF2 brings rendered attribute, which should also evaluate boolean expressions.
Should I bother rewriting stuff to new rendered attribute or is it ok to continue using JSTL in JSF2?
JSTL works the same way in JSF2 as it worked in JSF1. The rendered attribute is not JSF2 specific, it has been in JSF all the lifetime long. If those JSTL tags have always worked as intended in your JSF 1.2 application, then you don't necessarily need to migrate them for JSF2. You only need to change the taglib uri to include the /jsp (!!) path.
xmlns:c="http://java.sun.com/jsp/jstl/core"
However, whenever possible, using the rendered attribute definitely is more recommended than relying on JSTL tags. For sure if you plan to bind JSTL tag attributes to a #ViewScoped bean. See also Communication in JSF 2.0 - #ViewScoped fails in taghandlers.

how to generate dynamic rich:panelMenu?

i have a problem to generate dynamic menu, i'm using JSF1.2. I tried the c:forEach with an arrayList to generate dynamic rich:panelMenu as BalusC advised in a related forum, but get Accessor never triggered in c:forEach. it ruined me a day. can anyone provide me a solution ?
<c:forEach items="#{serviceListBean.services}" var="child">
<rich:panelMenuItem mode="none">
<h:outputText value="#{child.serviceId}"></h:outputText>
</rich:panelMenuItem>
</c:forEach>
what's wrong in this code? can anyone enlighten me?. For info, serviceListBean is request scoped bean.
Two possible causes:
JSTL is not declared as taglib in JSP or Facelets. To confirm this, rightclick page in browser and choose View Source. Do you see <c:forEach> tag unparsed among the generated HTML? If you're using JSP, declare it as follows:
<%#taglib prefic="c" uri="http://java.sun.com/jsp/jstl/core" %>
Or if you're using Facelets, declare it as follows in root element:
xmlns:c="http://java.sun.com/jsp/jstl/core"
On some servers like Tomcat, which doesn't ship with JSTL out the box, you would also need to install JSTL first, see also this info page.
This piece of code is in turn been placed inside a JSF repeating component, like <h:dataTable> with a var="serviceListBean". This is also not going to work. You would need to replace the JSF repeating component by <c:forEach> as well.

Resources