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

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.

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>

commandButton inactive after ajax rendering

I have a problem with these two commandButton : Join and Leave.
I want to hide Join if I click on leave and vice-versa.
When I put ajax on false, there is no problem (but all the page is refresh and I don't find this optimal).
But when ajax attribut is on true with specific updating (cf comment in the code), the rendering is good but the new button whitch appear become inactive. If I click on it, nothing happens (well it's seems the actionListener trigger but the view is not refreshed, I have to manual refresh to see the difference)
Thanks for reading.
<h:form id="formWaitingList" rendered="#{connexion.connected}" >
<p:commandButton id="Join"
actionListener = "#{connexion.joinWaitingList()}"
rendered="#{!connexion.waiting}"
ajax="false"
<!-- ajax="true"
update="Join,Leave"-->
value="Join"/>
<p:commandButton id="Leave"
value="Leave"
ajax="false"
<!-- ajax="true"
udpate="Join,Leave"-->
rendered="#{connexion.waiting}"
actionListener ="#{connexion.leaveWaitingList()}" />
</h:form>
It seems that you're not entirely familiar with HTML/JavaScript. You know, JSF is basically a HTML/JavaScript(/CSS) code generator. Ajax updating works basically like this in JavaScript:
After sending the ajax request to JSF via XMLHttpRequest, retrieve a XML response which contains all elements which needs to be updated along with their client IDs.
For every to-be-updated element, use document.getElementById(clientId) to find it in the current HTML DOM tree.
Replace that element by new element as specified in ajax XML response.
However, if a JSF component has not generated its HTML representation because of rendered="false", then there's nothing in the HTML DOM tree which can be found and replaced. That totally explains the symptoms you're "seeing".
You basically need to wrap conditionally rendered JSF components in a component whose HTML representation is always rendered and then reference it instead in the ajax update.
For example,
<h:form>
...
<h:panelGroup id="buttons">
<p:commandButton ... update="buttons" rendered="#{condition}" />
<p:commandButton ... update="buttons" rendered="#{not condition}" />
</h:panelGroup>
</h:form>
See also:
Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?

Two consecutive events on button click in 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>

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>

JSF 2.0 navigating on commandLink and commandButton doesn't work

I'm using JSF 2.0 and I have a problem with navigation after both commandLink and commandButton. I use following code:
<h:commandLink action="login?faces-redirect=true"
value="#{showElementBean.showElement()}"> Login </h:commandLink>
<h:commandButton action="login?faces-redirect=true" value="Move to login.xhtml" />
These tags are inside a form, login is just an example. Result of clicking on rendered controls is always POST with refresh of a current page. What do I wrong?
Edit:
According to comments of BalusC I' adding real code fragment:
<h:commandLink actionListener="#{showElementBean.showElement(element)}"
value="View" > </h:commandLink>
I have a page with a list of elements and I want to add links that leads to element view page. Thus I need to pass this element to a show page. I'm JSF primer, e.g. in Rails I'd use GET and URL params, but I don't know how to do it 'in JSF-way'.
There are a lot of possible causes for this behaviour. They are all cited in the following answer, along with solutions: commandButton/commandLink/ajax action/listener method not invoked or input value not updated.
However, in your particular case, you seem rather to be interested in plain GET requests instead of POST requests, as all you want is simple page-to-page navigation. In that case, you need a <h:link> or <h:button> instead:
<h:link outcome="login" value="Login" />
<h:button outcome="login" value="Move to login.xhtml" />
(I have no idea what you're trying to do with both #{showElementBean.showElement()} and Login as command link value, so I omitted the former)
See also:
When should I use h:outputLink instead of h:commandLink?
Refer this info: JSF HTML Tags
h:commandButton
The commandButton tag renders an HTML submit button that can be
associated with a backing bean or ActionListener class for event
handling purposes. The display value of the button can also be
obtained from a message bundle to support internationalization (I18N).
Example
<h:commandButton id="button1" value="#{bundle.checkoutLabel}" action="#{shoppingCartBean.checkout}" />
HTML Output
<input id="form:button1" name="form:button1" type="submit" value="Check Out" onclick="someEvent();" />
h:commandLink
The commandLink tag renders an HTML anchor tag that behaves like a
form submit button and that can be associated with a backing bean or
ActionListener class for event handling purposes. The display value of
the link can also be obtained from a message bundle to support
internationalization (I18N).
Example
<h:commandLink id="link1" value="#{bundle.checkoutLabel}" action="#{shoppingCartBean.checkout}" />
HTML Output
Check Out
Noticed that backing bean method is not called if the form is for file upload:
<h:form name="searchForm" enctype="multipart/form-data" method="post" action="/search">
I also faced with that issue and adding the
<h:form><h:commandLink></h:commandLink> </h:form>
solved my problem.

Resources