I have a PrimeFaces <p:dialog>. The dialog has an input field and a command button. The command button posts the form without ajax (e.g. to upload a file via simple mode). If there is a validation error on the input field then the <p:message> in the dialog shows the error correctly, however the dialog closes because of the non-ajax postback. Because I am not using ajax, I can't really use the oncomplete trick to keep the dialog open as answered in Keep p:dialog open when a validation error occurs after submit.
What are my options to keep the dialog open (or reopen) after non-ajax submit if there was a validation error?
Make use of the dialog component's visible attribute. If this is set to true during render, then the page will render with the dialog opened.
E.g. if there's a postback and validation has failed:
<p:dialog ... visible="#{facesContext.postback and facesContext.validationFailed}">
Or if there are more forms in the same page and you'd like to check only if dialog's own form is been submitted:
<p:dialog ... visible="#{dialogForm.submitted and facesContext.validationFailed}">
<h:form binding="#{dialogForm}">
Note: the #{facesContext.validationFailed} works by default of course only if you make use of JSF builtin validation facilities (required="true", <f:validateXxx>, etc) and/or use fullworthy Validator implementations. It you're for example manually validating in action method and manually adding faces messages, then this will not work, unless you implicitly call FacesContext#validationFailed() yourself.
See also:
Difference between rendered and visible attributes of <p:dialog>
Related
A jsf page contains a form with a commandButton element like <h:commandButton action="#{bean.search}". This submit button will trigger a bean, which then will send more data back to this same jsf page.
Question: after the submit, is the jsf page fully loaded again? or is just the part containing the newly retrieved data reload and other parts are not loaded again?
By default JSF will fully reload the page. This can be tested by looking at the browser network developer tools while submitting the commandButton. If you intend to only render a part of the page - e.g. a label that outputs the result - you can do that by using AJAX.
For example if your commandButton is in a form, by adding
<f:ajax execute="#form" render="#form:result" />
within your commandButton tag, you can specify that only the contents of the form are processed by the server and only the label with the ID 'result' is rendered.
For further information take a look at this guide for AJAX in JSF: https://www.beyondjava.net/a-comprehensive-guide-to-jsf-ajax
You will see that the author shows the full page loading without AJAX.
Alternatively here is the official documentation for <f:ajax>:
https://jakarta.ee/specifications/faces/2.3/vdldoc/f/ajax.html
I have a PrimeFaces <p:dialog>. The dialog has an input field and a command button. The command button posts the form without ajax (e.g. to upload a file via simple mode). If there is a validation error on the input field then the <p:message> in the dialog shows the error correctly, however the dialog closes because of the non-ajax postback. Because I am not using ajax, I can't really use the oncomplete trick to keep the dialog open as answered in Keep p:dialog open when a validation error occurs after submit.
What are my options to keep the dialog open (or reopen) after non-ajax submit if there was a validation error?
Make use of the dialog component's visible attribute. If this is set to true during render, then the page will render with the dialog opened.
E.g. if there's a postback and validation has failed:
<p:dialog ... visible="#{facesContext.postback and facesContext.validationFailed}">
Or if there are more forms in the same page and you'd like to check only if dialog's own form is been submitted:
<p:dialog ... visible="#{dialogForm.submitted and facesContext.validationFailed}">
<h:form binding="#{dialogForm}">
Note: the #{facesContext.validationFailed} works by default of course only if you make use of JSF builtin validation facilities (required="true", <f:validateXxx>, etc) and/or use fullworthy Validator implementations. It you're for example manually validating in action method and manually adding faces messages, then this will not work, unless you implicitly call FacesContext#validationFailed() yourself.
See also:
Difference between rendered and visible attributes of <p:dialog>
I have a problem with open and close a primefaces dialog on error in a prerenderview event listener. I use the event listener to load data from a third-party system, which under some circumstances needs special authentication.
So far when the special authentication is required i set a property on a request scoped bean and use the visible property of the dialog to decide if the dialog should be visible or not.
<p:dialog widgetVar="#{name}" resizable="false" modal="true"
closable="false" id="#{name}Dialog" width="375"
useWindow="true"
visible="#{specialAuthenticationBean.authenticationRequired}">
Hint: #{name} is an include parameter.
Is this the recommended way to do it?
If yes how can i close the dialog when the cancel or ok button was clicked?
So far for the cancel button i tried this with the following code but without success.
<p:commandButton id="cancel" value="#{messages['cancel']}" onclick="#{name}.hide()" type="button" />
Any ideas?
UPDATE: I tried out different things and found the cause. The dialog did not close because there were three includes for the same dialog with different parameters, but the visible-condition was true for all three dialogs.
And now i ask myself if it is really necessary to have three instances of the same dialog, only because the login buttons execute different actions (bean methods). What i really want to do is after one bean method invocation leads to open the authentication dialog, execute the same bean method again after submit the correct authentication data in the authentication dialog.
I have a JSF page that includes a tree form tag which is rendered depending on some bean property. There are two buttons for next and previous page. I want to skip form validation on the button which goes to the previous page.
I tried the following ways to disable the validation:
Set h:commandButton immediate="true"
Change button by a4j:commandButton ajaxSingle="true" rerender="someparts"
It does not work. Why does the navigation fail when I want to skip validation?
immediate="true" does skip the validation. Make sure you have redeployed successfully, and the there aren't any errors.
I solve problem using a4j:commandButton ajaxSingle="true" reRender=":outhercomponent:formconteningcomponent:component"
reRender needs absolute path to component even if component id unique
I am trying to popup a window when someone clicks a button on the data table.
<h:commandButton
action="#{cacheController.popupDetails}"
immediate="false"
onclick="popup()"
value="View Details"
styleClass="submit">
</h:commandButton>
The associated popup function is
function popup() {
window.open('RDDetails.jsf','popupWindow', 'dependent=yes, menubar=no, toolbar=no, height=500, width=400');
}
Now in the new 'RDDetails.jsf" file, I am trying to access the same managedBean cacheController. But the problem is, the pop-up window and JSF lifecycle is not in sync. As a result, the popup first displays blank and when I refresh, it pulls out the proper data.
Is there anyway I can click on a button which will do some processing in the managed bean and then opens a pop up which rerieves the processed data from the managed bean.
I am using JSF 1.1.
You're here basically firing two independent requests: one associated with the form submit and other which opens the RDDetails.jsf in a popup. You'll need to combine this in one request. You can achieve this in basically two ways:
Get rid of the onclick and just add target="_blank" to the <h:form> so that it get submitted into a new window/tab.
Block the default action by adding return false; to the onclick and do the business logic in the constructor of the bean associated with RDDetails.jsf. The only (major) caveat is here that the model won't be updated with the form fields. Thus, you'll need to pass the form fields as request parameters of the popup URL manually with help of JavaScript. You can then make use of managed property entries in the faces-config.xml to inject the GET request parameters into the model.
First way is obviously the easiest, but this doesn't give you a "fullworthy" popup/modal dialog. The second way is a bit harder (unless you've already a good grasp on both JavaScript and JSF). I would then consider to look for a component library which provides a ready-to-use popup component.
See my example:
<h:commandLink action="#{controller.myAction}" onmousedown="document.forms['idform'].target='_blank';">
I'm using jsf 1.1