jsf richfaces a4j:jsFunction forward outcome - jsf

Is it possible to create a4j:jsFunction that will call a method inside my managed bean and from there to perform forward to another jsf page ?
Thank's In Advance.

No, it's not possible because the <a4j:jsFunction> will create a javascript method available in the HTML that communicates with the server via Ajax. Instead, you could do something ugly like this:
<h:form id="myForm">
<a4j:jsFunction name="myJSFunction" action="#{myBean.jsLogic}"
oncomplete="document.getElementById('myForm:btnForward').click();" />
<a4j:commandButton id="btnForward" style="display: none;"
action="#{myBean.doForward}" />
</h:form>
In this case at the end of your js function, you will call the method of a <a4j:commandButton> (also <a4j:commandLink> or any other h component) that could do the navigation.

Well, it is not really a forward but you can do a redirect:
Just be sure that your corresponding navigation-case in faces-config file has the corresponding tag:
<redirect />
Then after the ajax call the browser will be redirected to the specified page.
This has the disadvantage in respect to Luiggi's response that makes two server calls, the ajax one and then the redirection.
As advantage, it makes cleaner code.

Related

How to forward using h:commandButton

I have a view where I have a form with p:commandButton and everything works fine beacuse I'm using forward and that's what I need:
<h:form id="formularioAltas">
// More code
<p:commandButton value="Guardar" action="#{altasBean.agregarRefaccion()}" update="cboAlmacen cboEstado cboCategoria" />
</h:form>
The method agregarRefaccion() is void so does not changes the page, I think a forward takes place after that action because it always has the same url. That is Ok beacuse that is what I need.
In the same view a have another form where I have a problem with h:commandButton.
<h:form id="myForm" enctype="multipart/form-data" prependId="false">
// More code
<h:commandButton id="button" style="background-color: black; color: aliceblue" value="Guardar imagen para #{altasBean.refaccion.idRefaccion}" action="#{altasBean.subirImagen()}" />
</h:form>
The subirImagen() method is void too so I thought a forward would take place after that action... but it doesn't. The page updates and the url changes so that means a redirect did that.
I will always need a forward. No matter if it is a p:commandButton or a h:commandButton.
I think has something to be with PrimeFaces and the differences of p:commandButton with JSF h:commandButton.
So I need a forward in that h:commandButton.
Edit
I always have an url like this blabla/AlmacenGM/
but when h:commandButton goes the url is: blabla/AlmacenGM/faces/altas.xhtml
The url changes. I have tried to return the string "altas" int the method subirImagen() so a forward should take place but it still changing the url.
Any ideas?
There's no forward with p:commandButton. It's actually an ajax request what you're peforming, because it's its default behaviour.
However, the standard JSF h:commandButton performs a forward request, as long as you return a String with the navigation case in your action method. If you see a redirection taking place there, you must be forcing it in your bean side.
See also:
Ajax update and submission using h:commandButton

Choosing how to pass parameters to a target bean/page using JSF

I have been using JSF for a few years now, but I still have doubts when it comes to deciding how to pass parameters to a target page/bean.
I do think this question is a bit complex, and that some may tell me to break it down into smaller questions. But, I also think that the answer to all of the questions bellow are related, and that it addresses the lack of intuitiveness when all you want JSF to do is: "Go to that page and pass this as a parameter".
First, how to decide between Forward and Redirect?
After that, how to choose between h:commandLink/h:commandButton, h:link or h:outputLink?
Then, combined with the option I choose above, should I use f:param or f:setPropertyActionListener? Will both properly pass parameters to the target bean, independently of its scope?
Finally, on the target bean/page, when should I use f:viewParam, or recover parameters from the request programmatically?
I'm going to answer your questions based on my own experience. Some of them are so open that more than one answer could fit.
A page forward is the way to go unless you explicitly require the browser url to be changed. A page forward is basically faster than a redirection as it requires less steps. A page redirect is required if you want to make your views bookmarkable.
Use <h:commandLink />/<h:commandButton /> only when you need to POST the server. Later on, you'll be able to perform a page forward or a redirection depending on what the method returns. As an example:
<h:commandLink action="#{bean.processForm}" value="Submit" />
public String processForm(){
try{
save();
return "list";
}
catch(Excepcion e){
addFacesMessage("Error saving");
//Error saving the object, keep in the same view
return null;
}
}
Use <h:link outcome="list" value="Go to list" /> for pure page to page navigation within the JSF application. You can use either page forward and redirect. Use <f:param /> to pass view parameters.
<h:outputLink value="www.stackoverflow.com" /> could be used for external links to other sites (not into your application). Use <f:param /> to pass view parameters. I however prefer to use plain HTML with <a href="www.stackoverflow.com" /> myself for this case.
As for passing parameters to action methods in POST requests, you've got several options. f:setPropertyActionListener was so popular in JSF 1.x, but if you're already at 2.x I would recommend you going with EL 2.2, which allows method parameter declaration. Being able to use it depends on the application server you're using, but even if not available you could import yourself. Then, you'll be able to do things like that:
<h:commandButton action="#{bean.saveCar(currentCar)}" value="Save Car" />
Use it wherever you can, it'll make things just easier.
For the view parameters, use <f:viewParam /> too. It's the standard JSF way of parsing the parameters from the GET request, so just let the framework do the retrieving work for you!
See also:
JSF 2 link, commandLink and outputLink example
Using EL 2.2 with Tomcat 6.0.24
What is the difference between redirect and navigation/forward and when to use what?

View parameter when navigating to another page

I am using JSF2, and I need to be able to pass a parameter from one JSF page to another via a commandLink.
I am on page funding.xhtml (ViewScoped) and have the following link defined:
<p:commandLink styleClass="toolbar"
action="/application/customerApplicationManagement.jsf">
<p:graphicImage url="/resources/gfx/search.png" />
<h:outputText value="#{msg.menu_searchApplications}" styleClass="toolbarLink" />
</p:commandLink>
I need to pass a string value to the customerApplicationManagement page indicating which page I came from so that after selecting an application, I can return to that page. I have tried several suggestions about how to pass this value including f:param, f:viewParam. I have even tried just adding it directly to the url (?fromPage=funding) etc, but they all seem to work only when the value is passed back to the current page, not a new page I am navigating to.
Can someone show me how this can best be accomplished.
Use <f:param> and <f:viewParam>:
Source page:
<p:commandLink styleClass="toolbar"
action="/application/customerApplicationManagement.jsf">
<p:graphicImage url="/resources/gfx/search.png" />
<h:outputText value="#{msg.menu_searchApplications}" styleClass="toolbarLink" />
<f:param name="fromPage" value="funding.xhtml" />
</p:commandLink>
Destination page (bound):
<f:metadata>
<f:viewParam name="fromPage" value="#{destinationBacking.fromPage}" />
</f:metadata />
<h:link value="Go back!" outcome="#{destinationBacking.fromPage}" />
Destination page (unbound):
<f:metadata>
<f:viewParam name="fromPage" />
</f:metadata />
<h:link value="Go back!" outcome="fromPage" />
Backing bean (only if you want to bind the param):
#ManagedBean
#ViewScoped
public class DestinationBacking{
String fromPage;
public String getFromPage(){
return fromPage;
}
public void setFromPage(String frompage){
fromPage = frompage;
}
}
Your view path will be binded to fromPage property from the destination backing bean and after you can use it to return to the original page.
Also I want to say that this way is a bit 'hackeable' by the end user, I mean, you're passing the original path through pure url. See also other ways to achieve that, as flash scope, which is very useful specially if you're working with #ViewScoped beans.
I don't know the specifics of the methods you tried to achieve your goal and hence we cant tell what was wrong with them, but if we consider your code 'as is' you don't have anything that will pass the string you want.
Not to repeat ourselves, there are plenty of answers here dedicated to using this or that method, so I will give you the best references, in my opinion, of course.
How can I pass a parameter to a commandlink inside a datatable;
ViewParam vs #ManagedProperty;
What can <f:metadata> and <f:viewParam> be used for.
Regarding the usage of back buttons in JSF you could also take a look at my own answer on How to get back to the same page in JSF.
By the way, using POST for page-to-page navigation is considered to be a bad practice. If all you need is to navigate to another page you'd better use plain <h:link> or <h:button> instead.

How to update a h:inputHidden with p:commandButton?

I writed an ajax request for any data. But the data don't work with h:inputHidden.
I think it's a bug of Primefaces.
But I don't know how to get the data now.
code:
<h:inputHidden id="buttonData" value="#{buttonDataBean.buttonData}" />
...
<p:commandButton id="getData" action="#{buttonAction.getButtonData}" update="buttonData" />
When I click the commandButton, the value of don't work.
But if I use the h:outputText, it worked.
My requirement:
Before click the commandButton, I have create any html buttons dynamically. I want to click the commandButton and update the name and position of html buttons. So that I must get any data and update the html buttons with Javascript.
how could I do about it?
If I want to use the JavaScript to get the ajax data, how to do it. I see the document and find two method: jsf.ajax.request() and Primefaces.ajax.AjaxRequest(). But I don't know how to use the two method. for example: Primefaces.ajax.AjaxRequest("test.xhtml",,). The "test.xhtml" how to request the method testMethod of TestAction?
use firebug to inspect html code. you can see new value
<h:form id="form">
<h:inputHidden id="buttonData" value="#{buttonDataBean.buttonData}" />
<p:commandButton id="getData" value="button"
action="#{buttonDataBean.buttonAction}" update="buttonData" />
</h:form>
If your problem does not get solved with primefaces ajax, you can use the native ajax provided by jsf have a look at it.It works, i have done many such things with it.
Instead of using a hidden input you could take advantage of JSF and use a f:param or f:attribute.
Read this really fine article, under the brand of BalusC: http://balusc.blogspot.com/2006/06/communication-in-jsf.html .

How to call a Javascript function on render in JSF 1.2/Richfaces 3.3?

We have an a4j:outputPanel that is ajaxRendered. Is there a way to call a javascript function each time it is (re)rendered? I know that we could put a call in every element that could possibly submit with oncomplete, but that really isn't practicably maintainable.
Details:
JSF 1.2
Richfaces 3.3
Example (oncomplete isn't actually available on the outputPanel tag):
<a4j:outputPanel ajaxRendered="true" oncomplete="myJSFunc()">
<h:outputText value="Test-aroo" />
</a4j:outputPanel>
<!-- other inputs, buttons and stuff -->
Update Might the jQuery library be able to help (it's built into RichFaces)? I'm looking at using .live() to maybe register with the oncomplete event. I'll keep experimenting and update with progress.
Update I didn't get a chance to implement the jQuery solution, but as my answer shows below myJSFunc() can just be put directly inside the rendered tags.
A solution is to put the javascript in a script tag inside the outputPanel:
<a4j:outputPanel ajaxRendered="true">
<h:outputText value="Test-aroo" />
<script type="text/javascript">myJSFunc();</script>
</a4j:outputPanel>
You would need to call oncomplete on the component that fires the Ajax request. a4j:outputPanel doesn't have oncomplete attribute.

Resources