set a parameter in the url via post - jsf

I would like to set a parameter in the url via post but this page only perform a method and update the page with h: commandButton.
<h:commandButton value="Simular"
action="#{simulador.simular()}"
style="margin:0 4px 0 0;"
immediate="true">
<f:ajax render="#form" immediate="true"/>
</h:commandButton>
How can I achieve this?

URLs are only changed on synchronous requests. Adding a query string to URL is only possible on GET requests. Sending a redirect after POST is one way to create a synchronous GET request.
public String simular() {
// ...
return "page.xhtml?foo=42&faces-redirect=true";
}
This will redirect to /context/page.xhtml?foo=42.
If you actually don't need to perform any business logic in the action method based on the postback, then you can also just use a normal button instead of a command button.
<h:button value="Simular" outcome="page.xhtml">
<f:param name="foo" value="42" />
</h:button>

Related

How to redirect to a page after printing with primefaces Printer?

I have used the primefaces printer and wanted to redirect to previous page after printing.I used Printer like this:
<p:commandButton value="Print" type="button" title="Print" actionListener="#{currentpage.redirect}">
<f:ajax execute="#this"/>
<p:printer target="printer" />
</p:commandButton>
In redirect method of currentpage bean i deleted the record which works fine but if i try to redirect it to previous page it doesn't do anything.
public void redirect(ActionEvent actionevent) {
/* Deleted the record */
}
Please guide me if i can do this way or anyother way.
Thanks in advance.
There are several misconceptions in your code:
actionListener method can not fire a redirect. That could be done in action
An ajax request cannot fire a redirect. Ajax is meant to work as an asynchronous request to the server and get the desired result to the current view and handle the response to update the view without refreshing the page nor without navigating.
If using Primefaces components, you should work with them for efficiency in your page. For example, <p:commandButton> should work with <p:ajax> rather than <f:ajax>. But in this case, <p:commandButton> already has ajax capabilities built-in, so there's no need to use any of these ajax components.
After knowing this, you know that your design should change to this:
<p:commandButton value="Print" type="button" title="Print"
action="#{currentpage.redirect}" process="#this">
<p:printer target="printer" />
</p:commandButton>
And the method declaration to:
//parameterless
public void redirect() {
/* Deleted the record */
}
PrimeFaces let's you add behavior when the ajax request is complete by usage of oncomplete attribute. This attribute receives the name of a javascript function that will be invoked right when the ajax request finishes without problems. In this method, you can add the logic for your redirection:
<p:commandButton value="Print" type="button" title="Print"
action="#{currentpage.redirect}" process="#this" oncomplete="redirect()">
<p:printer target="printer" />
</p:commandButton>
<script type="text/javascript>
redirect = function() {
window.location.href = '<desired url>';
}
</script>

need to open url and pass hidden parameters (post request), primefaces

I am using primefaces. I need to open URL from my UI and pass login credentials and other parameters with that URL. How can I send the request to URL and pass parameters which are not visible. I tried the following:
1)
<p:menuitem value="report" url="http://someUrl" icon="ui-icon-document" ajax="false"
target="_blank" includeViewParams="true">
<f:param id="decorate" name="decorate" value="no" />
</p:menuitem>
2)
<h:outputLink value="http://someUrl" ajax="false" target="_blank" includeViewParams="true">
link
<f:viewParam id="decorate" name="decorate" value="no" />
</h:outputLink>
In these two cases I am trying to pass 'decorate' parameter. It is opening the URL but the parameter is not being passed.
HTML does not allow you to send POST parameters via a hyperlink, which is what an <h:outputLink> renders. You can use a <p:commandLink>, as explained below, to call JavaScript; it should look something like this:
<p:commandLink type="button" onclick="<javascript here>">
Here are two separate ways to achieve this:
Use a normal link to submit a form
JavaScript post request like a form submit

How to access POST parameters when validation failed

I need to show the response page depending on some of the input fields. E.g. the tabid inputHidden below:
#{controllerBean.tabId}
...
<h:form id="edit">
<h:inputHidden value="#{controllerBean.tabId}" id="tabid" />
<h:inputText value="#{controllerBean.name}" id="name" />
</h:form>
But when some other input in the same form has validation error (e.g. the "name" inputText). The "controllerBean.tabId" value will not be assigned because JSF returns at validation stage.
I still need the tabId to show the page correctly and having 2 ideas in mind:
#{param['edit:tabid']}
or use binding:
#{tabId.value}
<h:inputHidden value="#{controllerBean.tabId}" id="tabid" binding="tabId" />
My question is, which of these 2 is the better or Best Practice? Or there are even better ways to do this?
update:
Note. In my specific case, the tabid is set by client javascript.
Server reply with a few items in the html.
Javascript put these items into different tabs on the page.
One of the tabs POST data to server with the current tabid in the form.
So my server need to know the tabid to show the response page with the correct tab selected.
You can add a lifecycle event listener to the component and pick the value from it. I'm going to recommend the preValidate listener:
<h:form id="edit">
<h:inputHidden value="#{controllerBean.tabId}" id="tabid">
<f:event type="preValidate" listener="#{controller.grabTabId}"/>
</h:inputHidden>
<h:inputText value="#{controllerBean.name}" id="name" />
</h:form>
This registers the listener to fire just before the validation phase of the request. You'll now have a listener defined in your backing bean to look like:
public void grabTabId(ComponentSystemEvent cse){
//obtain a reference to the component
HtmlInputHidden hiddenElement = (HtmlInputHidden)cse.getComponent();
//get the value from the component.
String hiddenValue = hiddenElement.getValue();
}
<h:form id="edit">
<h:inputHidden value="#{controllerBean.tabId}" id="tabid" />
<h:inputText value="#{controllerBean.name}" id="name" >
<p:ajax process="tabid" immediate="true" event="keyup" />
</h:inputText>
</h:form>
The above code will do is when the user put some value the value will be processed and will be set the managedBean. that what you want I think.
Another non-perfect way of accomplishing this is to move the validation logic to your action method. If validation fails, you just stop processing (and add an applicable FacesMessage). You just need to be aware that all model values will have been updated, and you can clear them if necessary.
Since updating model values on failed validation goes against the JSF lifecycle, I think any solution will be somewhat of a hack.

How to implement the image redirect with parameters?

This is the way how a commandButton realizes the redirect with parameters.
<h:commandButton value="Check" action="#{GetInfoBean.getInfo}">
<f:param name="ID" value="4"></f:param>
</h:commandButton>
When this commandButton get clicked, it will pass the parameter named ID with value 4. The managed bean GetInfoBean's method getInfo() will return the new url.
But now, my question is how can I implement this redirect process using image or graphicImage since it doesn't have the action attribute?
Wrap the image using a <h:commandLink>:
<h:commandLink value="Check" action="#{GetInfoBean.getInfo}">
<f:param name="ID" value="4"></f:param>
<h:graphicImage value="/your/image.png" />
</h:commandLink>

Keep url parameters after clicking <h:commandButton>

I've got a page which takes an id as a url parameter and uses it to get an object and display data about it. On this page we've got a modal which includes a file upload component, so we cannot use ajax to process the save. Instead we do this:
<rich:modalPanel domElementAttachment="parent" id="profilePanel" styleClass="popUp" resizeable="false" moveable="false" autosized="true" zindex="200" top="-10">
<a4j:form enctype="multipart/form-data" id="profilePanelFormId">
<q:box title="Edit Advocacy Profile" width="width6x" wantFocus="true">
<s:div id="profilePanelForm">
<rich:messages rendered="#{messagesUtil.errorsExist}"/>
<a4j:include viewId="/panel/advocacy/advocateProfileEdit.xhtml"/>
</s:div>
<h:commandButton id="cancel" immediate="true" value="Cancel" action="#{advocateManager.cancelEditCommitment}" styleClass="button cancel" tabindex="100"/>
<h:commandButton id="save" value="Save" action="#{advocateManager.saveCommitment}" styleClass="submit" tabindex="101"/>
</q:box>
</a4j:form>
</rich:modalPanel>
We populate the parameter in pages.xml like so:
<page view-id="/advocacy/advocateCommitmentView.xhtml" login-required="true">
<param name="confirmationCode" value="#{advocateManager.commitmentId}"/>
</page>
So far so good. The problem we're running into is when a user clicks save or cancel the url gets rewritten without the necessary id parameter. If the user then refreshes the page it throws errors because it doesn't have this key. Does anyone know how I can call my save method without using ajax and still keep the url parameter or intercept the call and add the parameter back in?
Put ?includeViewParams=true at the end of the action string.
This happens because <h:commandButton/> posts the form, and form posts do not include parameters in the URL. To add the parameters, create a navigation rule that redirects to the same page:
<navigation from-action="#{advocateManager.saveCommitment}">
<rule>
<redirect view-id="/same-page.xhtml" />
</rule>
</navigation>
When doing the redirect, page parameters are encoded and added to the URL. Note that this requires that #{advocateManager.commitmentId} is populated when the redirect is done.

Resources