How To Open A Pop-up Using Jsf Without It Being Blocked By The Browser
Solution 1:
When you try to open a new window in JavaScript, which is not directly triggered by a user action (like a click), but in for example a callback triggered after executing JSF ajax requests, it is blocked by the browser.
This behavior is described in the following question: jquery window.open in ajax success being blocked.
As a workaround you could open a window before the JSF ajax request. In case of a command button using the JSF HTML tags this can be done by using:
<h:commandButton ... onclick="prepareWindow()"/>
The onclick
will be rendered as is. But, when you are using PrimeFaces, you cannot use:
<p:commandButton ... onclick="prepareWindow()"/>
PrimeFaces wraps the onclick
resulting in indirect execution, so the pop-up is blocked.
Anyhow, with some extra hacks you could get this working with some sort of button which looks like a PrimeFaces button. But the number of hacks was getting too much.
I opted to use a p:dialog
with an iframe
instead. To start of, if you are using p:layout
, don't place the dialog in any of the layout units.
The dialog:
<p:dialogheader="Preview"widgetVar="previewDlg"modal="true"width="1000"height="600"dynamic="true"><iframesrc="about:blank"class="previewIframe"style="position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;border:0"></iframe></p:dialog>
The button:
<p:commandButton value="Show"
...
onclick="PF('previewDlg').show()"
action="#{myBean.showPreview('previewIframe')}"/>
The action:
publicvoidshowPreview(String iframeClass) {
...
RequestContext.getCurrentInstance().execute(js);
}
The JavaScript function:
functionmyFunction(iframeClass, url, selector) {
var iframe = $("iframe[class=" + iframeClass + "]")[0];
iframe.contentDocument.location = "about:blank";
var req = newXMLHttpRequest();
req.open("GET", url, true);
req.onreadystatechange = function() {
if (req.readyState === XMLHttpRequest.DONE) {
iframe.contentDocument.open();
iframe.contentDocument.write(req.responseText);
iframe.contentDocument.close();
iframe.contentDocument.addEventListener(
"DOMContentLoaded",
function() { /* Some code highlighting the selector */ },
false
);
}
}
req.send();
}
Solution 2:
There is an easy way out. Open an empty popup onclick (directly induced by the user, hence not blocked) and redirect the window to the updated model after the ajax data has been submitted:
<p:commandButton value="open popup" process="@form"
onclick="myNamespace.openPreview()"
oncomplete="myNamespace.relocatePreview()"/>
This is what your js should look like:
myNamespace.openPreview = function () {
myNamespace.prev = window.open('', '_blank');
}
myNamespace.relocatePreview = function () {
myNamespace.prev.location = 'preview.xhtml?faces-redirect=true';
}
Post a Comment for "How To Open A Pop-up Using Jsf Without It Being Blocked By The Browser"