PrimeFaces 8.0 / 10.0.RC1: dialog form validation runs when processing form from other dialog - forms

I'm opening dialog1 from which I open dialog2, each have their own forms which are not nested in each other.
When I show dialog2 from a button inside the dialog1 form, submitting the dialog2 validates the dialog1 form - I do not want this.
When I show dialog2 from a button outside the dialog1 form, submitting the dialog2 doesn't run the dialog1 forms' validation.
I tested it on Primefaces 8.0 and 10.0.RC1, it behaves the same.
Why is this happening? Why does it matter where I show the dialog from?
Thank you.
sample code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<ui:composition
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
template="/template.xhtml">
<ui:define name="content">
<p:dialog appendTo="#(body)" widgetVar="dialog1" modal="true" header="dialog1"
showEffect="clip" closeOnEscape="true"
hideEffect="clip" responsive="true" width="700px" focus=":submitButtonForm:submitButton"
height="500">
<p:remoteCommand name="showDialog2" action="PF('dialog2').show();"/>
<h:form id="form1">
<p:outputPanel>
<p:outputLabel for="required1" value="dialog1value"/>
<p:inputText id="required1" required="true" value="#{test.dialog1value}"/>
<p:outputLabel for="dialog2value" value="dialog2value"/>
<p:inputText id="dialog2value" required="true" value="#{test.dialog2value}"/>
</p:outputPanel>
<p:commandButton value="show dialog2 from within form1 of dialog1 (dialog2 Submit then validates form1)"
onclick="PF('dialog2').show();"/>
</h:form>
<p:commandButton value="show dialog 2 from body of dialog1 (dialog2 Submit then DOES NOT validate form1)"
onclick="PF('dialog2').show();"/>
<f:facet name="footer">
<h:form id="submitButtonForm">
<p:commandButton partialSubmit="true"
id="submitButton" value="Submit" actionListener="#{test.dialog1Submit}"
update=":form1" process=":submitButtonForm,:form1"
style="float:right;margin-bottom: 20px;"/>
</h:form>
</f:facet>
</p:dialog>
<p:dialog appendTo="#(body)" widgetVar="dialog2" modal="true" header="dialog2"
showEffect="clip" closeOnEscape="true"
hideEffect="clip" responsive="true" width="700px" focus=":submitButtonForm:submitButton"
height="500">
<h:form id="form2">
<p:outputPanel>
<p:outputLabel for="required2" value="dialog2value"/>
<p:inputText id="required2" required="true" value="#{test.dialog2value}"/>
</p:outputPanel>
</h:form>
<f:facet name="footer">
<h:form id="submitButtonForm2">
<p:commandButton partialSubmit="true"
id="submitButton2" value="Submit" actionListener="#{test.dialog2Submit}"
update=":form2,:form1" process=":submitButtonForm2,:form2"
style="float:right;margin-bottom: 20px;"/>
</h:form>
</f:facet>
</p:dialog>
<p:commandButton value="show dialog 1" oncomplete="PF('dialog1').show();"/>
</ui:define>
</ui:composition>
</html>
import lombok.Getter;
import lombok.Setter;
import org.springframework.stereotype.Component;
import javax.faces.view.ViewScoped;
#Component
#ViewScoped
public class Test {
#Getter
#Setter
private String dialog1value, dialog2value;
public void dialog1Submit() {
System.out.println("dialog1 submitted");
}
public void dialog2Submit() {
System.out.println("dialog2 submitted");
}
}

Change your commandButton to return false to stop it from Submitting the AJAX form...
<p:commandButton
value="show dialog 2 from body of dialog1 (dialog2 Submit then DOES NOT validate form1)"
onclick="PF('dialog2').show();return false;"/>

Related

How to assign "addGlobalError()" to correct form if several forms exists

I have a login and a register form on one and the same page and I try to return the global error message only on the concerning form. How to I do that correctly?
import org.omnifaces.util.Messages;
// login class submit()
Messages.addGlobalError('Login failed');
// register class submit()
Messages.addGlobalError('Register failed');
<h:form id="login-form">
<h:messages globalOnly="true" />
// [...]
<h:commandButton value="Login" action="#{login.submit()}" />
</h:form>
<h:form id="register-form">
<h:messages globalOnly="true" />
// [...]
<h:commandButton value="Sign up" action="#{register.submit()}" />
</h:form>
That is a contradictory... you simply never assign a global error to a specific component (the form is a component).
Simply make an error that you assign to the id of the form by using
Messages.addError(id, error);
add a <h:message for="..."> where the for contains the id of the form.
Here is how your example should look like:
import org.omnifaces.util.Messages;
// login class submit()
Messages.addError('login-form', 'Login failed');
// register class submit()
Messages.addError('register-form', 'Register failed');
<h:form id="login-form">
<h:messages globalOnly="true" for="login-from" />
// [...]
<h:commandButton value="Login" action="#{login.submit()}"/>
</h:form>
<h:form id="register-form">
<h:messages globalOnly="true" for="register-from" />
// [...]
<h:commandButton value="Sign up" action="#{register.submit()}"/>
</h:form>

Primefaces 5.2 dialog form not submitting

I am using primefaces 5.2 dialog framework to popup a dialog from my backing bean. That dialog with a simple login form.
main.xhtml as:
<h:form prependId="false">
......
<p:commandButton value="#{apps['application.sec.login']}" immediate="true" actionListener="#{loginControlBean.fireLoginDialog}" icon="fa fa-fw fa-sign-in" />
.....
</h:form>
backing bean LoginControlBean.java as:
#Named(value = "loginControlBean")
#SessionScoped
public class LoginControlBean implements Serializable{
private static final Logger logger =Logger.getLogger(LoginControlBean.class.getName());
#Inject
private StaffSession staffSession;
/* ... get/set pairs ...*/
......
public void fireLoginDialog() {
Map<String,Object> options = new HashMap<String, Object>();
options.put("modal", true);
options.put("draggable", false);
options.put("resizable", false);
RequestContext.getCurrentInstance().openDialog("/sec/login", options, null);
}
.......
public void login(ActionEvent event) {
logger.info("Passed in information: User name: "+staffSession.getTempUserName()+" Password: "+staffSession.getTempPassword());
.......
}
login.xhtml as:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<h:outputStylesheet library="css" name="default.css"/>
<h:outputStylesheet library="css" name="cssLayout.css"/>
<title>Staff Login</title>
</h:head>
<h:body>
<ui:composition>
<h:form id="loginform">
<p:growl id="logingrowl" sticky="true" showDetail="true" life="60000" />
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="username" value="#{apps['application.sec.username']}" />
<p:inputText id="username" value="#{staffSession.tempUserName}" required="true" label="username" />
<h:outputLabel for="password" value="#{apps['application.sec.password']}" />
<p:password id="password" value="#{staffSession.tempPassword}" required="true" label="password" />
<f:facet name="footer">
<p:commandButton process="#form" value="Login" update="logingrowl" actionListener="#{loginControlBean.login}"/>
</f:facet>
</h:panelGrid>
</h:form>
</ui:composition>
</h:body>
</html>
dialog popup properly and when I input user name and password, then hit login button. I got exception in my backend(server side) log as:
####<Nov 2, 2016 5:20:10 PM AEDT> <Info> <com.longz.ozssc.web.staff.LoginControlBean> <macmini16g.tweedheadstorage.com.au> <OzsscWEBServer> <[ACTIVE] ExecuteThread: '5' for queue: 'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <> <49d77419-9b42-461a-92bb-25b06f512a63-0000001d> <1478067610444> <[severity-value: 64] [rid: 0] [partition-id: 0] [partition-name: DOMAIN] > <BEA-000000> <Passed in information: User name: null Password: null>
filled in fields in the form were bound to staffSession, but unfortunately, when I tried to access the values from backing bean staffSession, it is "null". Seems form submit is not working.
Any idea??
You didn't set the values of your input fields correctly.
value="#{staffSession.tempUserName}"
You need to add the bean to the values:
value="#{loginControllBean.staffSession.tempUserName}"

Primefaces v.5.3.5 confirm dialog render issue outside main h:form and inside main form is rendered but it is not working properly

I am using PF v.5.3.5 and JSF v.2.2.8. It is a frequent topic in SO. I noticed that there is a bug in PF v.5.3.5 documentation related to the appendTo attribute.
1st approach
The p:confirmDialog is rendered and commandbuttons are rendered but actions does not work and message is not rendered if it is placed inside of nested h:form.
2st approach
If I place this dialog outside of main h:form it is not rendered at all also if I add the global="true" attribute.
3st approach
The p:confirmDialog is rendered and commandbuttons are rendered but actions does not work and message is rendered if the nested h:form is removed.
<h:form>
...
<p:confirmDialog id="askSessionDialog1" widgetVar="askSessionDialog1" severity="alert"
appendTo="#(body)" rendered="#{treeData.askSessionDialogRendered}" visible="#{treeData.askSessionDialogRendered}">
<h:form>
<f:facet name="message">
<h:outputText value="#{msg.WEB_ADMIN_PAGES_TREESEGMENT_NOSESSION}" escape="false"/>
</f:facet>
<p:commandButton value="#{msg.WEB_BUTTONS_OK}" action="#{treeData.save(false, true)}" icon="fa fa-check"
update="#(form)" type="button" />
<p:commandButton value="#{msg.WEB_BUTTONS_CANCEL}" action="#{treeData.setAskSessionDialogRendered(false)}"
icon="fa fa-close" onclick="PF('askSessionDialog1.hide()')" update="#(form)" type="reset" />
</h:form>
</p:confirmDialog>
...
</h:form>
BECKEND PART
setAskSessionDialogRendered(true);
RequestContext.getCurrentInstance().update("treeSegmentForm askSessionDialog askTurnOffDialog askSessionDialog1 askTurnOffDialog1");
Thanks in advance for constructive posts and comments.
SOLVED
This is the best approach that works for me now.
<h:form>
...
<p:confirmDialog id="askSessionDialog" widgetVar="askSessionDialog" severity="alert"
appendTo="#(body)" rendered="#{treeData.askSessionDialogRendered}" visible="#{treeData.askSessionDialogRendered}">
<f:facet name="message">
<h:outputText value="#{msg.WEB_ADMIN_PAGES_TREESEGMENT_NOSESSION}" escape="false"/>
</f:facet>
<h:form>
<p:commandButton value="#{msg.WEB_BUTTONS_OK}" icon="fa fa-check" type="button" accesskey="o">
<p:ajax event="click" listener="#{treeData.save(false, true)}" oncomplete="PF('askSessionDialog').hide()"
update="#(form)" />
</p:commandButton>
<p:commandButton value="#{msg.WEB_BUTTONS_CANCEL}" icon="fa fa-close" type="reset" accesskey="c">
<p:ajax event="click" listener="#{treeData.setAskSessionDialogRendered(false)}"
onsuccess="PF('askSessionDialog').hide()" update="#(form)" />
</p:commandButton>
</h:form>
</p:confirmDialog>
...
</h:form>
BACKEND
setAskSessionDialogRendered(true);
RequestContext.getCurrentInstance().update("treeSegmentForm");
SPACIAL THANKS TO: #YagamiLight
He helped me to kick off my solution.

When adding "?faces-redirect=true" to the action, the input field is being lost in the redirection [duplicate]

This question already has answers here:
How to choose the right bean scope?
(2 answers)
Closed 6 years ago.
I am facing a proplem with the ?faces-redirect=true I want to show the follwoing link http://localhost:8080/FirstJSPApplication/home.xhtml in the url after clicking the submit button in the index.xhtml but when adding ?faces-redirect=true to action="home" I am losing the value of the input field and am just getting Welcome back in the home.xhtml without the value of the username input field.
How can I show home.xhtml in the url after clicking the submit button without losing the username?
MainBean
package com.firstApp;
import javax.faces.bean.ManagedBean;
#ManagedBean
public class MainBean {
private String username;
public MainBean() {
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
index.xhtml
<!DOCTYPE html>
<html xmlns="htpp://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Facelt Title</title>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="3">
<h:outputLabel value="username" for="username" />
<!-- value="#{mainBean.username}" -->
<h:inputText id="username" value="#{mainBean.username}" required="true" requiredMessage="#{msg['msg.username.validation']}" />
<h:message for="username" />
<f:facet name="footer">
<!-- '?faces-redirect=true"' add home.xhtml to the url-->
<h:commandButton value="Submit" action="home?faces-redirect=true" />
</f:facet>
</h:panelGrid>
</h:form>
</h:body>
</html>
home.xhtml
<!DOCTYPE html>
<html xmlns="htpp://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Home pages</title>
</h:head>
<h:body>
<!-- #{mainBean.username} -->
<h:outputLabel value="Welcome back #{mainBean.username}" style="font-size: 25px;"/>
<footer style="margin-top: 300px; border: 1px solid red;">
<h:outputLabel value="#{msg['page.footer.copyright']}"/>
</footer>
</h:body>
</html>
Ok the problem is solved if I add the following notation #SessionScoped to the MainBean class
#ManagedBean
#SessionScoped
public class MainBean {
}

synchronization validation and display of dialog in a PrimeFaces JSF2.0 form

I have a form with jsf2 and primefaces that contains a submit button that managed two things:
First: form validation with the update attribute and second launching a confirmation dialog box when validation succeeded and all of this are managed by:
update="myfieldset display"
so my problem is that when I click into the button validation: if validation don't succeeded : validation messages are displayed in the form : ok
but if the validation succeeded I must click a second time to display dialog box
anyone know how to solve this problem there?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<script type="text/javascript">
<!--
function effacer(formulaire){
for (var i=0; i<formulaire.length; i++){
if (formulaire.elements[i].type=="input" || formulaire.elements[i].type=="textarea" ) {formulaire.elements[i].value="";}
}
document.getElementById('contenu_input').value="";
}
//-->
</script>
<body>
<ui:composition template="./template_utilisateur.xhtml">
<ui:define name="content">
<h:form id="form" prependId="false" >
<p:fieldset id="myfieldset" legend="Nouveau message">
<p:messages id="msgs"/>
<h:panelGrid columns="3" style="margin-bottom:10px">
<h:outputLabel for="title" value="Titre : *"/>
<p:inputText id="title" style="width:340px;" value="#{messageController.titre}" required="true" requiredMessage="veuillez saisir un titre" label="Titre">
<f:validateLength minimum="10" />
</p:inputText>
<p:message for="title" display="icon"/>
<h:outputLabel for="city" value="Destinataire : *" />
<p:selectOneMenu id="city" value="#{messageController.destinataire}" label="Destinataire" required="true" requiredMessage="veuillez choisir au moins un destinataire" >
<f:selectItem itemLabel="Séléctionner déstinataire" itemValue="" />
<f:selectItems value="#{messageController.users}" />
</p:selectOneMenu>
<p:message for="city" id="msgSurname3" display="icon"/>
<h:outputLabel for="comm" value="Lié a La commande N° : " />
<p:selectOneMenu id="comm" label="Commande" value="#{messageController.idComm}" >
<f:selectItem itemLabel="Aucune commande" itemValue="" />
<f:selectItems value="#{messageController.id_c}" />
</p:selectOneMenu>
<p:message for="comm" id="msgSurnamse3" display="icon"/>
</h:panelGrid>
<h:outputLabel for="contenu" value="Contenu : *" />
<h:panelGrid columns="2">
<p:editor id="contenu" widgetVar="editer" value="#{messageController.message}" width="600" required="true" requiredMessage="Veuillez saisir le contenu du message" >
<f:validateLength minimum="10" />
</p:editor>
<p:message for="contenu" id="editorm" display="icon"/>
</h:panelGrid>
<h:panelGrid columns="3">
<p:commandButton id="submitButton" value="envoyer" update="myfieldset display" onclick="#{messageController.retournerDialog()}" icon="ui-icon-disk" />
<p:commandButton id="clearButton" type="reset" value="initialiser" onclick="editer.clear()"
icon="ui-icon-close" />
</h:panelGrid>
</p:fieldset>
<p:dialog header="Confirmation" widgetVar="dlg" showEffect="fade" hideEffect="fade" modal="true">
<h:panelGrid id="display" columns="1" cellpadding="4">
<h:outputText value="Titre : " />
<h:outputText value="#{messageController.titre}" id="model"/>
<h:outputText value="Déstinataire :" />
<h:outputText value="#{messageController.destinataire}" id="year"/>
<h:outputText value="Lié à la commande N° : " />
<h:outputText value="#{messageController.idComm}" id="manufacturer"/>
<h:outputText value="Contenu :" />
<h:outputText id="displxcay" value="#{messageController.message}" escape="false" />
</h:panelGrid>
</p:dialog>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>
and here the method to launch the dialog
public String retournerDialog(){
String retour = "";
if( getDestinataire() != "" && getMessage()!= "" && getTitre()!="" && getMessage().length()>9 && getTitre().length()>9){
retour="dlg.show()";
}
return retour;
}
thank you in advance
Update: thank you BalusC for your detailed response, I tested both of your answers but they don't work
here is the code of the button :
<p:commandButton id="submitButton" value="envoyer" update="myfieldset, display" action="#{messageController.showDialog}" icon="ui-icon-disk" />
and the managedBean :
private boolean showDialog;
public void showDialog() {
showDialog = true;
}
public boolean isShowDialog() {
return showDialog;
}
and with this code above the dialog doesn't appear even if validation is succeeded
: I think because action must return outcome string not boolean
and when I make :
<p:commandButton id="submitButton" value="envoyer" update="myfieldset, display" onclick="dlg.show();" icon="ui-icon-disk" />
it appear even if the validation failed
and to remind you
when I put a method above like this :
<p:commandButton id="submitButton" value="envoyer" update="myfieldset, display" onclick="#{messageController.retournerDialog()}" icon="ui-icon-disk" />
I have to click twice (I think one for validation and one for displaying dialog)for the dialog is displayed
also in the official documentation : they use this dialog with onclick attribute
do you have any other idea