I am using Primefaces 4.0, JSF 2.1.11
I have a page with a button that calls a prime-faces dialog.show() and a dialog appears after filling it out click done and it refreshes the page with the new item added into a prime-faces dataTable. Everytime I click the button to open the dialog and fill it out then hit done my browser memory goes up. In automation testing once the dialog has been opened 125 times (our users could do this up to 800 times in a row) the browser runs out of memory. In IE8 at 125 items the memory usage was at 880 MB.
So my question is how do I prevent this?
more Info: Beans are viewscoped, using Glassfish 3, this issue happens in all browsers but worse in older browsers.
Steps I have taken:
1. I am doing a .show() .hide() each time on the dialog.
2. I have tried to call javascript to empty out the divs in the DOM without any success.
I have looked on primefaces issues and I dont see any memory leak reports, also if I let the page sit open the memory doesn't go up, its only when I am using the page and opening and closing the dialog.
UPDATE:
Here is some code
this form is outside the other form
<h:form id="lineItemForm">
<p:dialog id="addLineItemDialogId" widgetVar="lineItemDialog" header="Line item" width="900" resizable="false"
modal="true" showEffect="fade">
...
...
<p:commandLink value="Done"
onclick="actionStarted($(this))"
action="#{lineItemView.save}"
update=":wizardForm:lineItemWizardPanel"
oncomplete="actionComplete(); saveLineItem(args);"/>
</h:form>
The saveLineItem(args) is a javascript method that calls .hide() after validation check
Here is the call to .show() it is in the form wizardForm.
<h:form id="wizardForm"/>
...
...
<p:commandLink value="Add Item"
action="#{lineItemView.loadLineItemFromRequest(requisitionView.request)}"
process="#this"
update=":lineItemForm"
oncomplete="lineItemDialog.show()"/>
UPDATE So It ended up being a red hering. I removed the backend method call and the memory leak went away. It looks likes its the dataTable causeing the issue, with ajax. Looked it up and it is fixed in Primefaces 5
http://www.beyondjava.net/blog/primefaces-5/
I'll take a guess although I am not sure. Try structuring the code like this:
<h:body>
<h:form id="mainForm">
...
...
...
...
</h:form>
<p:dialog>
<h:form id="dialogForm">
...
</h:form>
</p:dialog>
</h:body>
And on the button you use to show the dialog use update="dialogForm".
I believe that if you update the dialog itself or one of its parents, it can result in several dialogs hiding each other. That might explain the memory usage. Besides it is best practise to have the dialogs in the end outside of the main form.
Related
I have 2 xhtml pages, one normal page with some data and button for calling modal dialog. Modal dialog includes second page with java applet ( tag). I've noticed that after I click submit button browser is freezed for a few seconds while Java is loading.
<p:dialog header="Page2" widgetVar="dlg4" modal="true" height="350" width="550" closable="true" resizable="true" draggable="false">
<ui:include src="itemSigning.xhtml" />
</p:dialog>
If I'm correct, primefaces works this way: when page 1 loads (that have some dialogs defined), every modal dialog defined in that page is loaded, right? Is there a way to tell modal dialog to load its content at the moment it is opened?
So, I when I press submit button, I would like modal dialog to be opened instantly and applet after I open dialog (and page 2 in it) so I can write some message to user like: "Wait for a moment until Java is loaded..."
I want to avoid browser window freezing for 2-3 seconds before modal dialog is opened (probably because Java is loading at that moment).
Is it possible?
Thanks
As per the Primefaces 5.1 User Guide Page 177
Tag: Dialog
Attribute: dynamic
Default: false
Type: Boolean
Description: Enables lazy loading of the content with ajax.
My application is managing software, and for user convenience, I want to allow them to open multiple tabs for changing parameters of more than one record at a time. But after finishing whatever they doing, the tabs stays open, and I got some complains about that. So basically my question is:
If there's any way to close browser tab that sends a request to method in my backing bean? for example:
JSF page:
<h:commandButton value="Public score"
action="#{assignmentBean.publicSelected()}">
</h:commandButton>
Bean method:
public void publicSelected() {
application.setAssignmentStatus(done);
dataAccess.mergeEntity(application);
}
is there any way to add something after merging command and close browser tab that activated method? Thanks for help
FULL CODE FOR SOLUTION I'm bad with mixing JS and JSF, so for any of you that are also bad at this I post full code solution using Tiago Vieira Dos Santos hint.
Now my button code looks like:
<h:commandButton value="Public score"
action="#{myBean.doThings}">
<f:ajax execute="#this" onevent="pop"/>
</h:commandButton>
plus on bottom of page I added code as follows:
<script type="text/javascript">
function pop(data){
if(data.status == "success"){
window.close();
}
}
</script>
now after method does what has to be done the window closes.
I think you can be use the javascript command Window.close() then you can put it on oncomplete tag or call in you managed bean using the FacesContext.
See more in this How to close current tab in a browser window?
Using an OutputLink and Javascript
<h:outputLink onclick="window.open('popup.faces', 'popupWindowName', 'dependent=yes, menubar=no, toolbar=no'); return false;" value="#">
<h:outputText value="open popup" />
</h:outputLink>
With this solution we got control over the appearance of the new browser window. And since there is no postback, there is no validation at all. This is the easiest way to open a new browser window when no model update is needed and no action has to be executed.
In order to implement a proper action handling we need to move the decision whether to open a new window to the action listener.
<h:commandLink actionListener="#{bean.openPopupClicked}" value="open popup" />
public void openPopupClicked(ActionEvent event) {
// code to open a new browser window goes here
}
I have this application written in JSF 2.0 facelets and it has the following code that supposed to display some content in an area which a jQuery slide controls, meaning that you press a button that displays that area and press it again to hide it
<f:ajax render="messageID">
<h:form id="myform" styleClass="form1" >
<h:message id="messageID" for="signinemail" class="messageforlogin"/>
<h:panelGrid styleClass="loginpanel" columns="2" cellspacing="4">
<h:outputText value="Email: "/>
<h:inputText class="textboxes" size="20" id="signinemail"
value="#{signinBean.email}"
validatorMessage="Invalid Email, Try Again">
<f:validateRegex pattern="\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*"/>
</h:inputText>
As you can see there is an error message that should be displayed if the email is not typed correctly, and as i said before this area is controlled with a jquery.slidetoggle function and button that makes it a slide to input the stuff in,
The thing is when the use presses the submit button(not shown here) the slide freezes and no error message is displayed,When i remove the "ajax" the message is displayed but the slide disappears and you have to press the toggle button again to see the slide with the error messages, i have done this in the same page but with out a slide and it wokrs very fine.
Is there away to display the slide and the error messages on it ???
The jQuery script which is responsible for setting the slides should be re-executed when the JSF ajax request completes, simply because the ajax response changes/replaces elements in the HTML DOM tree with new elements retrieved from the server which in turn of course do not contain those jQuery-initialized event handlers anymore. The jQuery script is not auto-executed everytime when the ajax request completes, but only whenever you refresh the page.
You just need to re-invoke your jQuery function in the JSF ajax event callback handler as follows:
jsf.ajax.addOnEvent(function(data) {
if (data.status == "success") {
yourjQueryFunctionWhichAddsTheSlideEvents();
}
});
An alternative is to use OmniFaces' <o:onloadScript>.
<o:onloadScript>yourjQueryFunctionWhichAddsTheSlideEvents();</o:onloadScript>
This way you also don't need a $(document).ready() anymore.
Strategy for p:fileDownload with dialog with loading
I am trying to make a loading bar after starting the download of a file. My download button is like this:
<p:commandButton id="btnFirstType"
styleClass="bt_princ"
value="Download File"
onclick="loading.show()"
ajax="false">
<p:fileDownload value="#{mbean.myFile}"/>
</p:commandButton>
<p:dialog modal="true"
widgetVar="loading"
header="Status"
draggable="false"
closable="false">
<p:graphicImage value="/loading.gif" />
</p:dialog>
And my MBean is like this:
public StreamedContent getMyFile(){
return this.getReport(Type.CSV); //I assure this works, debugged...
}
The problem is, after clicking the download button, if I start the loading dialog, the download doesn't occurr.
I thought about using p:poll to check a boolean variable so I know when the file has been generated, so I could show the dialog after clicking the button (like setting setTimeout with JavaScript), but this is maybe my mistake about how the whole thing happens. Any other suggestion?
PS1: Polling stops working after the file is downloaded, so I won't know when to close the dialod
PS2: I am using Primefaces 2.2 and can't update.
PS3: Found this workaround but 'it will' be on version 3, so I can't use it.
I did the same as suggested in the workaround posted on my question.
I downloaded the primefaces sources from my version, changed the FileDownloadActionListener class, added cookies in the response object and in my page I just started a process with setTimeout that would check cookies every 100 miliseconds, and when find it, delete it.
I'm using PrimeFaces 3.0 and JSF 2.0. In my webapp, I display a modal dialog over the page when the user's browser has been idle for a certain length of time and this triggers a session invalidation on the server side via an Ajax call. On the browser, the modal dialog displays a simple message that the session is terminated due to exceeding the idle time limit. This all works fine (see screenshot).
EDIT: Updated with "appendToBody" fix
Here is the code from my Facelet page:
<p:idleMonitor timeout="#{initParam[clientSideIdleThreshold]}">
<p:ajax
event="idle"
listener="#{logoutBean.idleListener}"
oncomplete="idleDialog.show()" />
<p:ajax
event="active"
listener="#{logoutBean.activeListener}" />
</p:idleMonitor>
<p:dialog
header="Session Exceeded Idle Limit"
widgetVar="idleDialog"
modal="true"
fixedCenter="true"
closable="false"
draggable="false"
resizable="false"
appendToBody="true"
height="200"
width="400">
<h:outputText value="Session Terminated" />
</p:dialog>
What I want to do is override the default opacity of the PrimeFaces dialog overlay and make it more opaque. Does anyone know how to do this?
I'm hoping that this can be accomplished by putting some CSS in the right place because I would really like to avoid writing any JavaScript to accomplish this.
The target browsers for the user environment are IE 6 and 7.
in your css:
.ui-widget-overlay {
opacity: 0.8;
}
or some other value :)
But you need to be sure the dialog you are showing is modal(<p:dialog modal="true"), otherwise no overlay will be shown.
Fortega's answer was correct for some browsers, but for IE 7 you need to use the following CSS:
.ui-widget-overlay {
filter:alpha(opacity=80); /* works in IE 7 */
opacity: 0.8; /* works in Firefox */
}
According to www.w3schools.com the opacity CSS attribute is non-standard but is proposed for inclusion in CSS3.