2

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.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Amira
  • 3,184
  • 13
  • 60
  • 95

1 Answers1

8

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.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • it open the URL but like that 'http://localhost:8081/JavaServerFaces/faces/%5BURL%5D%20:%20http://www.mkyong.com/jsf2/how-to-add-row-in-jsf-datatable/' i just want this http://www.mkyong.com/jsf2/how-to-add-row-in-jsf-datatable/ – Amira Oct 02 '12 at 11:52
  • Then the URL is apparently not valid. It must start with http:// and so on. Pass it to `new URL()` constructor and catch the exception. If caught, then the URL is invalid. – BalusC Oct 02 '12 at 11:54
  • i don't want this to appear before the URL the 'localhost:8081/JavaServerFaces/faces because it's an external url .thanks – Amira Oct 02 '12 at 11:56
  • Didn't you understand my previous comment? The URL must start with `http://`. Otherwise it's obviously relative to the current URL. You can validate it with `new URL(url)` and then check if it doesn't throw an exception. You could if necessary manually prefix the `http://` to the URL when the enduser didn't enter it. – BalusC Oct 02 '12 at 12:00
  • I believe the OP means he doesn't want the 'localhost...' part in the URL... @AmiraGL: You should probably open another question for that, detailing how you are obtaining this URL. – Elias Dorneles Oct 02 '12 at 12:13
  • @eljunior: OP used a scheme-relative URL `www.mkyong.com/etc...`, thus without `http://` prefix. If you pass this to `window.open()`, it becomes relative to the current request URL. The OP needs to ensure that it's an absolute URL such as `http://www.mkyong.com/etc...`. – BalusC Oct 02 '12 at 12:19
  • hi it's me again i tried it like this but it didn't work for me i put it in edits – Amira Oct 02 '12 at 13:18
  • Just don't try wrong code which I haven't suggested at all. Please don't edit wrong code into an answer which is supposed to show correct code only. Edit your own question instead if you really need to. Once again, the URL has to start with `http://`. Do you **understand** what this means and how to fix it? Where have you learnt basic web development and basic Java? – BalusC Oct 02 '12 at 13:37
  • As of Primefaces 7.0, the call would be: PrimeFaces.current().executeScript(). – Greg Noe Oct 19 '22 at 19:13