I use a commandLink to navigate to another page:
<t:commandLink action="go_orderForm" immediate="true">
<h:outputText value="#{order.number}" />
<t:updateActionListener property="#{orderForm.orderId}"
value="#{order.id}" />
</t:commandLink>
This is working and setting the value of order.id to the backing bean orderForm.orderId.
In another place, I use a commandButton to call an action in the backing bean of the current page and navigate after to the new page:
<h:commandButton value="Create Batch" action="#{orderList.createBatchOrder}" />
The action in the backing bean looks like:
public String createBatchOrder() {
// do something
return "go_orderForm";
}
The faces-config.xml contains
<navigation-rule>
<navigation-case>
<from-outcome>go_orderForm</from-outcome>
<to-view-id>/orderForm.jsp</to-view-id>
</navigation-case>
</navigation-rule>
How can I pass the parameter for orderForm.orderId when I navigate using the action in the backing bean?
Before redirect put your parameter to flash:
FacesContext.getCurrentInstance().getExternalContext().getFlash().put(key, value);
After redirect you may get it by:
FacesContext.getCurrentInstance().getExternalContext().getFlash().get(key);
Related
I want when user in not logged-in, after clicking the Add To Card button, the Login dialog should appears.
Here is Book.xhtml:
<h:form>
<p:commandButton value="Add To Card"
actionListener="#{booksBean.orderBook()}"
class="QtyBtn">
<f:ajax execute="#form" rendered="#form"/>
</p:commandButton>
</h:form>
This is bean:
#Component
#Scope("session")
public class BooksBean implements Serializable {
...
public void orderBook() {
...
if (currentUser == null) { // show the login dialog
RequestContext.getCurrentInstance().openDialog("Login");
}
But Login.xhtml not opened.
First, what you want to do is to use PrimeFaces Dialog Framework(DF).
DF let's you open XHTML view in a dialog
Add this to your faces-config.xml
<application>
<action-listener>
org.primefaces.application.DialogActionListener
</action-listener>
<navigation-handler>
org.primefaces.application.DialogNavigationHandler
</navigation-handler>
<view-handler>
org.primefaces.application.DialogViewHandler
</view-handler>
</application>
Create your login.xhtml page as
any XHTML page.
Add the corresponding outcome to your faces-config.xml. For example,
<navigation-case>
<from-outcome>Login</from-outcome>
<to-view-id>/pages/login.xhtml</to-view-id>
<redirect />
</navigation-case>
Open the dialog with RequestContext.getCurrentInstance().openDialog("Login");
Note that the DF opens the new dialog inside a frame.
Good morning in my timezone,
I am adding some features in a JSF application,
i add the following code
<h:link outcome="nameOut1.innerName" >
<f:param name="idX" value="#{xbean.idElement}"/>
<f:param name="idY" value="#{xBean.param1.param2.id}"/>
</h:link>
And i change it by this one
<h:commandLink action="#{xBean.validateBeforeClose}" >
<f:param name="idX" value="#{xbean.idElement}"/>
<f:param name="idY" value="#{xBean.param1.param2.id}"/>
</h:commandLink>
And in the bean
public String validateBeforeClose(){
if (isValidToRemove()) {
setValidationToRemove(true);
return "";
}else{
return "nameOut1.innerName";
}
}
if the first condition is true then it come back to the same View, and displays a popupWindow, if this condition is not met , then return the same outcome that the old link tag was setting.
The problem is : True the link the h:link tag the parameters are sent, i see that in the URL, but through the action the parameters are not sent.
in the faces-config i have the following configuration
<navigation-case>
<from-outcome>nameOut1.innerName</from-outcome>
<to-view-id>/folder1/folder2/view2.xhtml</to-view-id>
<redirect include-view-params="true">
</redirect>
</navigation-case>
Why is this happening ?
Thanks in advance
Best regards
I am looking for a another way of JSF navigation other than mentioning navigation-cases in faces-config.xml.
At present i am using faces-config.xml to navigate. I want to clean it up.
Please suggest all other ways so that i can use whatever suits my need.
For simple page-to-page navigation (without submitting anything) you should be using <h:outputLink> instead of <h:commandLink>.
So, instead of
<h:form>
<h:commandLink value="Page 1" action="page1" />
<h:commandLink value="Page 2" action="page2" />
<h:commandLink value="Page 3" action="page3" />
</h:form>
and those navigation cases
<navigation-rule>
<navigation-case>
<from-outcome>page1</from-outcome>
<to-view-id>page1.jsf</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>page2</from-outcome>
<to-view-id>page2.jsf</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>page3</from-outcome>
<to-view-id>page3.jsf</to-view-id>
</navigation-case>
</navigation-rule>
you should use
<h:outputLink value="page1.jsf">Page 1</h:outputLink>
<h:outputLink value="page2.jsf">Page 2</h:outputLink>
<h:outputLink value="page3.jsf">Page 3</h:outputLink>
For real form submits you should rewrite the action methods to return void or null instead of an outcome. So, instead of
<h:form>
<h:inputText value="#{bean.query}" />
<h:commandButton value="Search" action="#{bean.search}" />
</h:form>
with
public String search() {
results = searchService.find(query);
return "results";
}
on one page and
<h:dataTable value="#{bean.results}" var="result">
...
</h:dataTable>
on other page and this navigation case
<navigation-rule>
<from-view-id>search.jsf</from-view-id>
<navigation-case>
<from-outcome>results</from-outcome>
<to-view-id>results.jsf</to-view-id>
</navigation-case>
</navigation-rule>
you should use
<h:form rendered="#{empty bean.results}">
<h:inputText value="#{bean.query}" />
<h:commandButton value="Search" action="#{bean.search}" />
</h:form>
<h:dataTable value="#{bean.results}" var="result" rendered="#{not empty bean.results}">
...
</h:dataTable>
with
public void search() {
results = searchService.find(query);
}
You can if necessary include page fragments by <jsp:include>.
See also:
When should I use h:outputLink instead of h:commandLink?
//JSF
<h:outputLink value="login.xhtml" >
Login page
</h:outputLink>
//HTML output
<a href="login.xhtml">
Login page
</a>
Refer this URL for more info:-
commandLink and outputLink example
You can set the return value of a navigation action to the name of the page you want to go to (e.g. return "page2"; to switch to page2.jsf). But as far as I know, this feature has been implemented first in JSF 2.0.
From an action in my bean, I'm trying to redirect to another page expecting a view parameter. What is the recommended way to do this in JSF2?
E.g., say my source page is:
http://localhost/page1.xhtml
it has a commandButton that calls an action:
<h:commandButton value="submit" action="#{myBean.submit}" />
where my bean looks like:
#ManagedBean
#RequestScoped
public class MyBean {
private int id;
public String submit() {
//Does stuff
id = setID();
return "success";
}
And now, I want the 'submit' action's return to navigate to
http://localhost/page2.xhtml?id=2
I've tried to do this with a view-param in my navigation case, but with odd results. The faces-config snippet looks like the following:
<navigation-rule>
<from-view-id>/page1.xhtml</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/page2.xhtml</to-view-id>
<redirect>
<view-param>
<name>id</name>
<value>#{myBean.id}</value>
</view-param>
</redirect>
</navigation-case>
</navigation-rule>
The weird behaviour being, even though myBean is set to request scoped, it only calls myBean.getId() the first time I load my application, and reuses that same value for all subsequent calls, producing incorrect view parameters for page2.
So I'm looking for either a better way to do this, or a reason/solution for why the view-param is not being requested from my bean each time.
The unintuitive thing about passing parameters in JSF is that you do not decide what to send (in the action), but rather what you wish to receive (in the target page).
When you do an action that ends with a redirect, the target page metadata is loaded and all required parameters are read and appended to the url as params.
Note that this is exactly the same mechanism as with any other JSF binding: you cannot read inputText's value from one place and have it write somewhere else. The value expression defined in viewParam is used both for reading (before the redirect) and for writing (after the redirect).
With your bean you just do:
#ManagedBean
#RequestScoped
public class MyBean {
private int id;
public String submit() {
//Does stuff
id = setID();
return "success?faces-redirect=true&includeViewParams=true";
}
// setter and getter for id
If the receiving side has:
<f:metadata>
<f:viewParam name="id" value="#{myBean.id}" />
</f:metadata>
It will do exactly what you want.
Without a nicer solution, what I found to work is simply building my query string in the bean return:
public String submit() {
// Do something
return "/page2.xhtml?faces-redirect=true&id=" + id;
}
Not the most flexible of solutions, but seems to work how I want it to.
Also using this approach to clean up the process of building the query string:
http://www.warski.org/blog/?p=185
Check out these:
http://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/#get
http://mkblog.exadel.com/2010/07/learning-jsf2-page-params-and-page-actions/
You're gonna need something like:
<h:link outcome="success">
<f:param name="foo" value="bar"/>
</h:link>
...and...
<f:metadata>
<f:viewParam name="foo" value="#{bean.foo}"/>
</f:metadata>
Judging from this page, something like this might be easier:
<managed-bean>
<managed-bean-name>blog</managed-bean-name>
<managed-bean-class>com.acme.Blog</managed-bean-class>
<managed-property>
<property-name>entryId</property-name>
<value>#{param['id']}</value>
</managed-property>
</managed-bean>
You can do it using Primefaces like this :
<p:button
outcome="/page2.xhtml?faces-redirect=true&id=#{myBean.id}">
</p:button>
Just add the seen attribute to redirect tag as below:
<redirect include-view-params="true">
<view-param>
<name>id</name>
<value>#{myBean.id}</value>
</view-param>
</redirect>
A solution without reference to a Bean:
<h:button value="login"
outcome="content/configuration.xhtml?i=1" />
In my project I needed this approach:
<h:commandButton value="login"
action="content/configuration.xhtml?faces-redirect=true&i=1" />
I created a simple master/detail using myfaces and richfaces. By clicking a h:commandLink in the rich:dataTable the user is able to open the detail view and edit the entity.
Now I want to create a URL that allows the user to open the detail view directly. Normally I would to this by creating an URL like /detail.jsp?id=12 - how can I achieve that with JSF?
You can construct the URL using parameters on a link control:
<h:outputLink value="reqscope.faces">
<f:param name="id" value="#{row.id}" />
<h:outputText value="link" />
</h:outputLink>
On the target page, you can read the id from the parameter map, either directly using the expression language or via a managed bean.
View:
<f:view>
id= <h:outputText value="#{param['id']}" />
<br />
id= <h:outputText value="#{lookupBean.id}" />
</f:view>
Bean:
public class LookupBean implements Serializable {
public String getId() {
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext extContext = context.getExternalContext();
Map<String, String> params = extContext.getRequestParameterMap();
return params.get("id");
}
}
faces-config.xml declaration:
<managed-bean>
<managed-bean-name>lookupBean</managed-bean-name>
<managed-bean-class>reqscope.LookupBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
I use an a4j:commandlink to first pass the id of the entity I want to show details for to the detail view bean. And then I simply use document.location to navigate to the view.
<a4j:commandLink action="#{detailviewBean.setDetailID(entity.someid)}" value="#{entity.someid}" oncomplete="document.location='/app/detailview.seam'"/>
If you are using JSF 1.2, you can use f:setPropertyActionListener:
<h:commandLink action="#{reqscope.faces}">
<h:outputText value="link"/>
<f:setPropertyActionListener
value="#{id}"
target="#{lookupBean.id}"/>
</h:commandLink>
Executing Methods From LinkButton Parameters