Two consecutive events on button click in JSF - jsf

I have to perform two operations on button click.
call a method in a bean which will return a url and it will be set in some variable.
after that I have to open that url in another tab. I am using the action attribute of CommandButton and it is setting the URL value correctly, but how do I open that url as pdf in a new tab. i.e "URL of pdf should open in a new tab"
Code sample as follows:
<div class="form-options">
<h:commandButton value="Download Report" styleClass="btn btn-primary btn-icon buttonCustom" actionListener="#{reportBean.GenerateReport}">
</h:commandButton>
</div>

Hope I unterstood you right. This worked for me:
Provide the method generating the report and the URL in the actionListener-attribute of the commandButton (what you already did, according to your sample code).
Provide the method returning the URL in the action-attribute of the commandButton (it will be called after the actionListener-method).
For opening a new tab, add target="_blank in the parent <h:form> (taken from this questions answer)
XHTML-Code:
<h:form target="_blank">
<h:commandButton value="Show Report"
actionListener="#{reportBean.generateReport}"
action="#{reportBean.getUrl}" />
</h:form>
As this approach applies the target="_blank" to all non-ajax calls, here's another way using Javascript:
<h:form>
<h:commandButton value="Show Report"
actionListener="#{reportBean.generateReport}"
action="#{reportBean.getUrl}"
onclick="this.form.target='_blank'"/>
</h:form>
Java-Code:
public void generateReport(final ActionEvent evt) {
// ... generating report and setting url-variable
}
public String getUrl() {
return url;
}
If you have to forward to an external link, see this question

Use commandLink instead of commandButton..
When commandLink is used you need to provide value for target attribute as new window.
<h:commandLink target="new window">
Rest all the code will be as per your requirement.
Since the URL in which your report is present is already present in one of the variables you can use this variable from the bean in commandLink to provide the URL..
Elsewhile you can use an iframe also.It is generally used to display the report on the same page...

As I understand, your problem is not about redirecting the result of the action to a new tab, instead you want to show a report (if my guessing is right, you're using a JasperReport and want to show it in PDF format). To do this, you must download the file to the client computer and then let the default editor/program on the client handle the file.
I won't go into details for file download, BalusC provides good info about this matter:
How to stream a file download in a JSF backing bean?
How to download a file stored in a database with JSF 2.0
The relevant part to show PDF (or any other) files in browser is the ContentType of the response. This will say to the browser how the file must be threatened. Some content type values
PDF: application/pdf
Excel: application/vnd.ms-excel
Microsoft Word: application/ms-word
More: Internet media type
In case I'm wrong and you don't want to show (download) the file and need to open the file in a new Window, you have two ways (resuming both #JanisK. and #AngelsandDemons answers):
Setting the target of the form as "_blank", but this way will do that all the performed actions will open a new tab/window.
<h:form target="_blank">
<h:commandButton ... />
</h:form>
Using a commandLink instead of a commandButton, where you can set the target only for this link requests.
<h:form>
<h:commandLink target="_blank" ... />
</h:form>

Related

JSF 1.2 to open external link in new tab. without distrubing current flow [duplicate]

I need to open a JSF page in a new window by POST on click of a <h:commandButton>. I know I can acheive this using the JavaScript. But I would like to achive this using JSF and not JavaScript.
How can I achieve this? I'm using JSF 2.0.
The only non-JS way is to set target="_blank" in the parent <h:form>.
<h:form target="_blank">
...
<h:commandButton value="Open in new Window" />
</h:form>
This however affects all non-ajax(!) actions which are performed in the very same form. So if you're smart, make the action which shouldn't open in a new window an ajax action. However, ajax is also JavaScript and you mentioned that you don't want to use JS (I hope you don't get shocked once you discover that PrimeFaces is actually full of JavaScript).
If you absolutely need to restrict it to a single action, then you really can't go around asking little help to JavaScript.
<h:form>
...
<h:commandButton value="Open in new Window" onclick="this.form.target='_blank'" />
</h:form>
When you restrict the target only to a single action, maybe you want to get the form in its initial state.
With the oncklick action you set the target of the form to a _blan page.
After the click, the page is opened in a new tab/page (triggers the action event).
At last, the onblur action is triggered and set the form again to its initial state (the rest of the buttons will open in the _self page)
With this code, you can restrict to only a h:commandbutton to open in a new page.
The rest of the buttons will be opened in the self page:
<h:commandButton
onclick="this.form.target='_blank'"
onblur="this.form.target='_self'"
id="listadoRebuts"
action="#{giaquaBusquedaCorte.abrirListadoRebuts}"
value="#{msg.seqVisorbtnRecibos}">
</h:commandButton>

How to open an arbitrary URL in new window using a PrimeFaces button

I have the below output link which does its job:
<h:outputLink value="#{verDocumentoController.url()}" target="_blank">
show document
</h:outputLink>
It opens an URL obtained as a bean property in a new window.
However, I'd like to turn the link into a button in PrimeFaces look'n'feel. I tried as below:
<p:commandButton value="show document" action="#{verDocumentoController.url()}"
onclick="form.target='_blank'" ajax="false" />
But it only reopens the current page in a new window and not the URL specified as bean property. How can I achieve this anyway?
The <p:commandButton> basically submits a POST request to the URL as specified by its parent <h:form>, which defaults indeed to the current request URL (you know, "postback"). The action attribute basically invokes a bean method and uses the returned value as navigation case outcome. An URL does not necessarily represent a sensible navigation case outcome.
Just use window.open() instead on a simple <p:button>.
<p:button value="show document"
onclick="window.open('#{verDocumentoController.url()}');return false;" />
You can also do this on a <p:commandButton>, but that's unnecessarily overcomplicated.

How to open a blank page for an external url with JSF, if target url must be initialy retained from server?

Primefaces 3.5.14, Omnifaces 1.6
Is there a component in JSF/Prime that looks like a button, but that allows to open a new blank page with an external link ? So unlike a normal link, on click the new page URL must be initialy retained from server and just then new page must be opened. Like a commanButton with an action attribute, where a string result of an action method determine the new url.
Of course I can use p:button as in Styling one JSF external link to make it look like a button but in that case I must update link generated by p:button, depending on actions made on the page every time. This is not always desirable.
You need target="_blank" on the parent form in order to submit into a new window and you need to invoke ExternalContext#redirect() (or OmniFaces' Faces#redirect()) in the action method in order to let the target window send a new GET request on the given URL. Importantly, when you use <p:commandButton> instead of <h:commandButton>, you also need to set ajax="false" because it doesn't respect target="_blank".
Thus, so:
<h:form target="_blank">
<p:commandButton value="Submit" action="#{bean.submit}" ajax="false" />
</h:form>
with
public void submit() throws IOException {
String redirectURL = determineItSomehow();
Faces.redirect(redirectURL);
}

Opening a new window if condition true in managed bean

I want to implement a situation where the user enter a URL, and if a specified condition is true in my managed bean this URL will be opened in a new web page.
I found this possibility:
The “h:link” tag is useful to generate a link which requires to interact with the JSF “outcome” , but lack of “action” support make it hard to generate a dynamic outcome.
The “h:commandLink” tag is suck, the generated JavaScript is really scary! Not recommend to use this tag, unless you have a solid reason to support. But it supports the “action” attribute, which is what “h:link” lack of.
The “h:outputLink” is useful to generate a link which does not require to interact with the JSF program itself.
At last, it will be perfect if the “action” attribute is added into the “h:link“.
But I didn't find a way to launch the open web page from my managed bean after the condition is verified.
I'm using JSF2.0, Facelets and PrimeFaces 3.4.
To open the target in a new window using one of those link components, you need to specify target="_blank" attribute, but this will already open the target in a new window at the moment you click the link and does thus not depend on the response. You basically need to open the target in a new window at the moment the response has been arrived. The only way is returning a JavaScript window.open() call to the response so that it get executed in the webbrowser.
In standard JSF, you could just render JavaScript's window.open() conditionally.
<h:form>
<h:inputText value="#{bean.url}" />
<h:commandButton value="submit" action="#{bean.submit}">
<f:ajax execute="#form" render="#form" />
</h:commandButton>
<h:outputScript rendered="#{bean.valid}">window.open('#{bean.url}')</h:outputScript>
</h:form>
with
private String url;
private boolean valid;
public void submit() {
valid = validate(url);
}
// ...
In PrimeFaces, you could use RequestContext#execute() to specify JavaScript code which needs to be executed on complete of the response.
<h:form>
<p:inputText value="#{bean.url}" />
<p:commandButton value="submit" action="#{bean.submit}" />
</h:form>
with
private String url;
public void submit() {
if (validate(url)) {
RequestContext.getCurrentInstance().execute("window.open('" + url + "')");
}
}
// ...
Unrelated to the concrete problem: the ranty statements which you cited there are seemingly written by someone who know nothing about HTTP/HTML basics (limitations of GET vs POST and so on). Please take them with a good grain of salt.

Open new window by POST using h:commandButton

I need to open a JSF page in a new window by POST on click of a <h:commandButton>. I know I can acheive this using the JavaScript. But I would like to achive this using JSF and not JavaScript.
How can I achieve this? I'm using JSF 2.0.
The only non-JS way is to set target="_blank" in the parent <h:form>.
<h:form target="_blank">
...
<h:commandButton value="Open in new Window" />
</h:form>
This however affects all non-ajax(!) actions which are performed in the very same form. So if you're smart, make the action which shouldn't open in a new window an ajax action. However, ajax is also JavaScript and you mentioned that you don't want to use JS (I hope you don't get shocked once you discover that PrimeFaces is actually full of JavaScript).
If you absolutely need to restrict it to a single action, then you really can't go around asking little help to JavaScript.
<h:form>
...
<h:commandButton value="Open in new Window" onclick="this.form.target='_blank'" />
</h:form>
When you restrict the target only to a single action, maybe you want to get the form in its initial state.
With the oncklick action you set the target of the form to a _blan page.
After the click, the page is opened in a new tab/page (triggers the action event).
At last, the onblur action is triggered and set the form again to its initial state (the rest of the buttons will open in the _self page)
With this code, you can restrict to only a h:commandbutton to open in a new page.
The rest of the buttons will be opened in the self page:
<h:commandButton
onclick="this.form.target='_blank'"
onblur="this.form.target='_self'"
id="listadoRebuts"
action="#{giaquaBusquedaCorte.abrirListadoRebuts}"
value="#{msg.seqVisorbtnRecibos}">
</h:commandButton>

Resources