I have an xhtml view being rendered via a prettyfaces request. I am running into a problem where the Action mapping from prettyfaces is being executed twice, but only when I have a ui:include tag. The example pretty config is like this:
<url-mapping id="testRedirector">
<pattern value="/project/#{lookupBean.projectId}/#{lookupBean.cardNumber}" />
<view-id value="/lookup.xhtml" />
<action>#{myController.init}</action>
</url-mapping>
The .xhtml is like this:
...
<ui:include src="/header.xhtml">
<ui:param name="this_tab_class" value="current"/>
</ui:include>
<h:panelGrid columns="4">
...
And upon request to the URL, I see a log call on the myController.init() being executed twice. If I comment out the ui:include, the init is properly only called once. I've experimented wiht the other jsf phase listeners on prettyfaces url-mapping element, but all other enum types result in init() never being called.
My question is, how do I accomplish the same goal of including a predefined header.xhtml, or other predefined component, into a page and not invoke RENDER_REDRAW phase twice? Or is this a pretty-faces specific problem?
This sounds like a JSF bug. Does this occur when you do not include PrettyFaces?
Related
I'm using Pretty Faces to do URL rewriting, in order to be able to reuse some xhtml files. I'd like to have URLs like '/honda/index.xhtml' and '/toyota/index.xhtml' both go to the same /make/index.xhtml file, with the make coming in as a parameter. This routing seems to work OK with a config like this:
<url-mapping id="carMake">
<pattern value="/#{make}/index.xhtml"></pattern>
<view-id value="/make/index.xhtml"/>
</url-mapping>
I also have this mapping for a search results type of page:
<url-mapping id="search">
<pattern value="/#{make}/search/index.xhtml" />
<view-id value="/search/index.xhtml" />
</url-mapping>
Both of these work as expected when I manually put the URL in the browser.
I run into a problem when I try to put a form on the first page, that I want to redirect to the second page. I have this jsf xhtml code for a form:
<h:form>
<h:messages />
<h:inputText id="searchTerm"/>
<h:commandButton value="search" action="/honda/search/index.xhtml?faces-redirect=true"/>
</h:form>
(hard coding /honda here to simplify the example)
When I try to submit this search, it bounces back to the same /honda/index.xhtml, with no messages being displayed on the page.
The logs show this:
09-23 11:39:55 DEBUG PrettyNavigationHandler:57 - Navigation requested: fromAction [/honda/search/index.xhtml?faces-redirect=true], outcome [/honda/search/index.xhtml?faces-redirect=true]
09-23 11:39:55 DEBUG PrettyNavigationHandler:60 - Not a PrettyFaces navigation string - passing control to default nav-handler
I've tried without the faces-redirect param, but got the same result.
Why does /honda/search/index.xhtml work when I put it into the browser directly, but not as the result of an action?
If you want to use separate the URL from the View ID, and you don't want to reference the view-id in the app, then you need to use pretty navigation strings:
<h:commandButton value="search"
action="pretty:honda"><f:param name="make" value="honda" /></h:commandLink>
But this really is just making it more complicated than it needs to be. I would recommend doing what #chkal suggested, except his example is a little wrong. It should have been:
<h:commandButton value="search"
action="/search/index.xhtml?faces-redirect=true&make=honda"/>
This should be covered in the docs :) http://ocpsoft.org/docs/prettyfaces/3.3.3/en-US/html/components.html#components.prettylink Check that section (and the ones below it) and see if that helps!
You cannot use a pretty URL as a value for the action attribute this way. You have to use a standard JSF outcome with make being a query parameter.
Try this:
<h:commandButton value="search"
action="/honda/search/index.xhtml?faces-redirect=true&make=honda"/>
I am working on an enhancement project. There is a parent <form> element. I have an XHTML file included inside this parent form. The included XHTML file has an <a4j:commandLink>. This action is not getting called.
Now, this will work if i wrap the <a4j:commandLink> inside an <h:form>. This way, the parent form's action is called as well as the <a4j:commandLink>'s action. But nesting forms is not encouraged.
I can't use the parent form's action because it goes to a servlet and my action is in a
request scoped bean. I cant access the bean in the servlet.
Any help on how to make the action call without the <h:form> is highly appreciated.
Here is how it looks like:
<form id="parentFormId" name="parentFormId" action="aservletaction">
<a4j:outputPanel id="includedRegion">
<ui:include src="setupView.xhtml"></ui:include>
</a4j:outputPanel>
</form>
Contents of setupView.xhtml:
<ui:composition>
<a4j:outputPanel>
<h:form>
<a4j:commandLink action="#{myBean.actionMethod}"
render="adatatableid" limitRender="true"/>
</h:form>
</ui:composition>
RichFaces components have to be inside a form otherwise they won't work (at least the executable ones).
Now, <a4j:commandLink> (and commandButton) executing the whole form is the default behaviour, to change it use the execute attribute:
<a4j:commandLink execute="#this" … >
This will limit the execution only to the link.
It ought not work. Do not nest forms, as its not legal in HTML in general and in HTML code rendered by JSF in particular. So, you've got a following construct in your code:
<form>
...
<h:form>
...
</h:form>
...
</form>
Get rid if it and it'll work as expected, i.e. by creating a plain form-to-form structure.
According to this: http://java.net/jira/browse/JAVASERVERFACES-2136 flash-"scoped" messages should survive a redirect to a page on a different path.. I wanted to use something like this in my application so i downloaded javax.faces-2.1.14-20121003.074348-10 snapshot from here
https://maven.java.net/content/repositories/snapshots/org/glassfish/javax.faces/2.1.14-SNAPSHOT/ to test.
My situation is this: I have a page (call it test.xhtml) in the root directory that in the view-scoped backing bean during the call of the constructor does a check and conditionally sets a message using Omnifaces Message.addFlashGlobalInfo and redirects to index.xthml also in the root directory using Omnifaces Faces.Redirect() (thanks BalusC!). In index.xhtml i have a Primefaces
<p:messages id="msg" showDetail="false" autoUpdate="true" />
I use the same "configuration" described above in other pages as well and it works fine when the redirect is done to the same page called the bean method.
So shouldn't the message survive the different path redirect or did i misunderstood something about this issue?? maybe there is something else wrong here??
Thanks in advance! (i'm looking forward hearing BalusC opinion on this btw :) )
i just used to call an init method that does sets message and redirects but again no message appears!! so i don't think PostConstruct will work either..
Indeed, the <f:event type="preRenderView"> is too late to set a flash message. The flash scope can't be created when JSF is currently sitting in render response phase. You basically need to set the flash message before render response phase. In spite of the name preRenderView, this event is actually fired during (the very beginning of) the render response phase.
The #PostConstruct may be on time, provided that it's not been called during render response. This however won't work very well together with <f:viewParam>.
To fix this, as you're using OmniFaces already, just use <f:event type="postInvokeAction">.
<f:metadata>
<f:viewParam name="some" value="#{bean.some}" />
<f:event type="postInvokeAction" listener="#{bean.init}" />
</f:metadata>
See also:
JSF - Keep Faces Messages after redirect from #PostConstruct
Adding faces message to redirected page using ExternalContext.redirect()
This is related to Changing Browser URL from backing bean
#balusc
How do I do the same thing in JSF 2? I have a search page with 6 different components (mostly PrimeFaces 3.0) for setting the search parameters. How can I get all the parameters to appear in the URL so that the user can share the results page using the URL?
I looked at PrettyFaces, and that seems to be capable of doing this in a better way, but I would rather make it work with just JSF2 if that is a simpler solution...
Thanks!
You should either manually specify all the parameters via nested f:param tags like this:
<h:link outcome="nextPage">
<f:param name="param1" value="val1" />
<f:param name="param2" value="val2" />
</h:link>
or just specify includeViewParams parameter:
<h:link outcome="nextPage" includeViewParams="true">
The same goes for h:button
When I use the following command link:
<h:commandLink action="student" value="students" />
And the following navigation rule in faces-config.xml:
<navigation-rule>
<from-view-id>/home.xhtml</from-view-id>
<navigation-case>
<from-outcome>student</from-outcome>
<to-view-id>/student.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
Then I get the following development stage faces message:
This link is deactivated, because it is not embedded in a JSF form.
How is this caused and how can I solve it?
The <h:commandLink> fires a POST request. You need to embed it in a <h:form>.
<h:form>
<h:commandLink action="student" value="students" />
</h:form>
Since you're already on JSF 2.0, you can also just use <h:link> instead which fires a GET request which doesn't require a form and is thus way much better for bookmarkability and SEO. Also you can get rid of the whole <navigation-rule> since JSF 2.0 utilizes implicit navigation.
<h:link value="students" outcome="student" />
It will implicitly go to student.xhtml.
Ensure that you're reading JSF 2.0 tutorials, not the ones targeted on JSF 1.x. In JSF 2.0 a lot of new tags and features have been added.
See also:
When should I use h:outputLink instead of h:commandLink?
We don't need stinkin' faces-config
You need to have <h:form> wrapping the link.