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
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 want to produce a link looking like this:
http://domain.com/page.jsf?test=12#top
I tried using <h:outputLink> :
<h:outputLink value="/page.jsf#top">
<f:param name="test" value="12" />
My link
</h:outputLink>
But it failed and produced the link http://domain.com/page.jsf#top?test=12, which is wrong.
Is there a way to do this using JSF, or do I have to create this kind of links "manually"?
Since JSF 2.0 there is an <h:link> component that takes a JSF navigation case outcome through its outcome attribute, thus making it a perfect candidate for navigation within a JSF-based application. The component you used, <h:outputLink> is best used for navigation to the external world. You can of course use it to handle JSF navigation but it will feel plain clumsy.
If you decide to switch to <h:link> you can make use of its fragment attribute to attach your anchor (always look at the documentation - linked above):
The identifier of the page fragment which should be brought into focus when the target page is rendered. The value of this attribute is appended to the end of target URL following a hash (#) mark. This notation is part of the standard URL syntax.
All in all, your link should come as:
<h:link value="My link" outcome="/page" fragment="top">
<f:param name="test" value="12" />
</h:link>
It will produce the HTML that you desire.
Further point of reference:
When should I use h:outputLink instead of h:commandLink?
This example is from a book on JSF. The excercise is to refactor the following Facelets code while eliminating <c:if> and fn:toUpperCase(). Usage of <c:forEach> is allowed.
#{myBean.numbers} returns String["one","two","three"]
As the book is on JSF and not on Java, I suppose the existing Java-code is not to be touched. But I can't think of another way to do this solely in Facelets.
<c:forEach var="item" items="#{myBean.numbers}">
<c:if test="#{not fn:endsWith(item,'o')}">
#{item}
</c:if>
<c:if test="#{fn:endsWith(item,'o')}">
#{fn:toUpperCase(item)}
</c:if>
</c:forEach>
Only thing I can think of is using a converter that conditionally uses String#toUpperCase() and then I still do not understand why use of <c:forEach> should still be allowed:
<ui:repeat var="item" value="#{myBean.numbers}">
<h:outputText value="#{item}" converter="conditionalConverter"/>
</ui:repeat>
Is there a more "Facelets way" to do this (and still a need to use <c:forEach>)?
UPDATE:
Instead of <c:if> one could still use e.g. <h:outputPanel> and it's rendered-attribute, but there is still no Java-less replacement for fn:toUpperCase().
I am asking for learning purposes only. I suppose the <ui:repeat>-solution with a converter is the cleanest and represents most how JSF is supposed to be used. Do you think so, too?
As to <c:if>, the JSF alternative to JSTL <c:if> is the rendered attribute on any component. For example, <h:panelGroup> or <h:outputText>. Those components doesn't generate additional markup if there are no attribtues specified which should end up in HTML, like id or styleClass, otherwise they generate a <span>.
Here's an example of both:
<h:panelGroup rendered="#{not fn:endsWith(item,'o')}">
#{item}
</h:panelGroup>
<h:outputText value="#{fn:toUpperCase(item)}" rendered="#{fn:endsWith(item,'o')}" />
As to fn:toUpperCase(), JSF has no alternative. I'm not sure why you would need a JSF alternative as it's essentially not a tag, but a simple EL function which is perfectly usable in both JSTL and JSF tags. In any case, you could if necessary throw in CSS text-transform: uppercase. As this takes place entirely client side, your only problem may be the browser support.
<h:outputText value="#{item}" style="text-transform: uppercase" />
(note: this is just an example, the normal practice is to put styles in its own .css file which you load by <h:outputStylesheet>)
<h:outputText value="#{item}" styleClass="uppercased" />
I suppose the -solution with a converter is the cleanest and represents most how JSF is supposed to be used. Do you think so, too?
I'm a big fan of "Use the right tool for the job". Use JSTL tags to conditionally build the JSF component tree. Use JSF components to generate HTML. That's it. See also JSTL in JSF2 Facelets... makes sense?
I have one application running on tomcat sever.I removed the path in in server.xml so i am able to access the application like
http://localhost:8080/login.xhtml
I am using Pretty faces as well for URL rewrite.
Now i want to know how to send a request to server like
http://localhost:8080
so that it should display my login page.
My pretty-config.xml is
<url-mapping id="login">
<pattern value="/" />
<view-id value="/login.xhtml" />
</url-mapping>
it is not working.please let me know the solution.
Your pretty-config part (which is valid) tells that a path / should be mapped to /login.xhtml and may be referred to as pretty:login in outcomes of JSF components (as well as in action methods).
From here there are two possible options for inconsistencies:
Prettyfaces must be pointed to a valid URL, meaning that FacesServlet mapping in web.xml should be *.xhtml in your case, not faces/*, not *.jsf, etc.
Prettyfaces should be used appropriately in your JSF components. For instance, <h:link outcome="pretty:login" value="Home" /> will render an HTML a element with the value / (which will internally show login.xhtml when you click on it).
Also, it would be helpful to read the excellent PrettyFaces documentation.
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.