Disable one dropdown when a specific option of another is selected - ajax

I have two dropdowns in one form. The first contains those options:
String[] decisions = {"acceptée", "rejettée"};
When "rejettée" is selected, I would like to disable the second dropdown.
Here is the relevant code of the two dropdowns:
<p:selectOneMenu required="true" requiredMessage="veuillez choisir une decision" id="dec" value="#{editCommandController.myCom.decision}">
<f:selectItems value="#{editCommandController.decisions}" />
</p:selectOneMenu>
<p:selectOneMenu id="etat" value="#{editCommandController.myCom.etat}">
<f:selectItems value="#{editCommandController.etats}" />
</p:selectOneMenu>
How can I achieve this?

Try this:
<h:outputLabel for="dec" value="Decision : " />
<p:selectOneMenu required="true"
requiredMessage="veuillez choisir une decision" id="dec"
value="#{editCommandController.myCom.decision}">
<f:selectItems value="#{editCommandController.decisions}" />
<p:ajax update="etat" event="change"/>
</p:selectOneMenu>
<p:message for="dec" display="icon" />
<h:outputLabel for="etat" value="Etat : " />
<p:selectOneMenu id="etat" value="#{editCommandController.myCom.etat}" disabled="#{editCommandController.myCom.decision eq 'rejettée'}">
<f:selectItems value="#{editCommandController.etats}" />
</p:selectOneMenu>
<p:message for="etat" display="icon" />
To set to some default value on change, try this:
<h:outputLabel for="dec" value="Decision : " />
<p:selectOneMenu required="true"
requiredMessage="veuillez choisir une decision" id="dec"
value="#{editCommandController.myCom.decision}" valueChangeListener="#{editCommandController.vclistener}">
<f:selectItems value="#{editCommandController.decisions}" />
<p:ajax />
</p:selectOneMenu>
<p:message for="dec" display="icon" />
<h:outputLabel for="etat" value="Etat : " />
<p:selectOneMenu id="etat" value="#{editCommandController.myCom.etat}" disabled="#{editCommandController.myCom.decision ne 'rejettée'}">
<f:selectItems value="#{editCommandController.etats}" />
</p:selectOneMenu>
<p:message for="etat" display="icon" />
And then in the backing bean add the selectItem if not already present otherwise you can skip it:
public static List<SelectItem> etats = new ArrayList<SelectItem>() { {
add(new SelectItem("Cheese", "Cheese"));
add(new SelectItem("Pickle", "Pickle"));
add(new SelectItem("Mustard", "Mustard"));
add(new SelectItem("Lettuce", "Lettuce"));
}};
public void vclistener(ValueChangeEvent e){
if(e.getNewValue().equals("rejettée")){
EditCommandController.etats.add(0, new SelectItem("Ketchup", "Ketchup"));
myCom.setEtat("Ketchup");
}
RequestContext.getCurrentInstance().update("etat");
}
public List<SelectItem> getEtats() {
return etats;
}
public void setEtats(List<SelectItem> etats) {
EditCommandController.etats = etats;
}

Related

Dialog on PrimeFaces does not update and calculate date difference

Dialog on PrimeFaces does not update and calculate date difference in my dialog page.
Dialog page:
<p:dialog id="GrupoCreateDlg" widgetVar="GrupoCreateDialog" modal="true" resizable="false" appendTo="#(body)" header="#{bundle.CreateGrupoTitle}">
<h:form id="GrupoCreateForm">
<h:panelGroup id="display">
<p:panelGrid columns="2" rendered="#{grupoController.selected != null}">
<p:outputLabel value="#{bundle.CreateGrupoLabel_grupo}" for="grupo" />
<p:inputText id="grupo" value="#{grupoController.selected.grupo}" title="#{bundle.CreateGrupoTitle_grupo}" required="true" requiredMessage="#{bundle.CreateGrupoRequiredMessage_grupo}"/>
<p:outputLabel value="#{bundle.CreateGrupoLabel_usuario}" for="usuario" />
<p:inputText id="usuario" value="#{grupoController.selected.usuario}" title="#{bundle.CreateGrupoTitle_usuario}" required="true" requiredMessage="#{bundle.CreateGrupoRequiredMessage_usuario}"/>
<p:outputLabel value="#{bundle.CreateGrupoLabel_clave}" for="clave" />
<p:inputText id="clave" value="#{grupoController.selected.clave}" title="#{bundle.CreateGrupoTitle_clave}" required="true" requiredMessage="#{bundle.CreateGrupoRequiredMessage_clave}"/>
<p:outputLabel value="#{bundle.CreateGrupoLabel_detalle}" for="detalle" />
<p:inputText id="detalle" value="#{grupoController.selected.detalle}" title="#{bundle.CreateGrupoTitle_detalle}" />
<p:outputLabel value="#{bundle.CreateGrupoLabel_fechainicio}" for="fechainicio" />
<p:calendar id="fechainicio" pattern="dd/MM/yyyy" value="#{grupoController.selected.fechainicio}" title="#{bundle.EditGrupoTitle_fechainicio}"
locale="es" showOn="button" showButtonPanel="true"/>
<p:outputLabel value="#{bundle.CreateGrupoLabel_fechafin}" for="fechafin" />
<p:calendar id="fechafin" pattern="dd/MM/yyyy" value="#{grupoController.selected.fechafin}" title="#{bundle.EditGrupoTitle_fechafin}"
locale="es" showOn="button" showButtonPanel="true">
<p:ajax event="change" update="dias"/>
</p:calendar>
<p:outputLabel value="Dias"/>
<h:outputText id="dias" value="#{grupoController.calcularFechas()}">
<f:convertNumber type="number"/>
</h:outputText>
<p:outputLabel value="#{bundle.CreateGrupoLabel_incidencia}" for="incidencia" />
<p:selectBooleanCheckbox id="incidencia" value="#{grupoController.selected.incidencia}" />
<p:outputLabel value="#{bundle.CreateGrupoLabel_fechaincidencia}" for="fechaincidencia" />
<p:calendar id="fechaincidencia" pattern="dd/MM/yyyy" value="#{grupoController.selected.fechaincidencia}" title="#{bundle.EditGrupoTitle_fechaincidencia}"
locale="es" showOn="button" showButtonPanel="true"/>
<p:outputLabel value="#{bundle.CreateGrupoLabel_fechaavisocaducidad}" for="fechaavisocaducidad" />
<p:calendar id="fechaavisocaducidad" pattern="dd/MM/yyyy HH:mm:ss" value="#{grupoController.selected.fechaavisocaducidad}" title="#{bundle.EditGrupoTitle_fechaavisocaducidad}"
locale="es" showOn="button" showButtonPanel="true"/>
</p:panelGrid>
<p:commandButton actionListener="#{grupoController.create}" value="#{bundle.Save}" update="display,:GrupoListForm:datalist,:growl" oncomplete="handleSubmit(args,'GrupoCreateDialog');"/>
<p:commandButton value="#{bundle.Cancel}" onclick="GrupoCreateDialog.hide()"/>
</h:panelGroup>
</h:form>
</p:dialog>
Groupo controller:
public int calcularFechas() throws ParseException {
diasDuracion = 0;
try {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date fechaFinal = selected.getFechainicio();
Date fechaInicial = selected.getFechainicio();
diasDuracion = (int) ((fechaFinal.getTime() - fechaInicial.getTime()) / 86400000);
System.out.println("Hay " + diasDuracion + " dias de diferencia");
} catch (NullPointerException e) {
e.printStackTrace();
}
return diasDuracion;
}
The HTML must be show the difference between date initial and finish (on days) in the outputText.
What's wrong?
The outputText dias must be update without close the dialog page.
I copy and paste your stuff into my project and edit it like that:
Put the calcularFechas() into
<p:ajax event="change" update="dias" listener="#{grupoController.calcularFechas()"/>
and write a method
getCalcularFechas(){ ...
}
It worked for me like that because the listener was called after the event was fired.

<p:selectOneMenu> onChange event doesn't reload form

I trying to use the onChange event of selectOneMenu, but it doesn't work and the form is not reloaded bye the data chosen when I add onChange attribue.
Can someone tell me how can I handle the onChange event of ?
Here is my view:
<p:panel id="cubeId" header="Cube" widgetVar="toggleable>
<h:form id="CubeIdForm">
<p:panelGrid columns="2">
<p:outputLabel value="Cube Name: "></p:outputLabel>
<p:inputText value="#{cubeMan.cub.name_cube}"></p:inputText>
<p:outputLabel value="Description: "></p:outputLabel>
<p:inputText value="#{cubeMan.cub.description_cube}"></p:inputText>
<p:outputLabel value="Caption: "></p:outputLabel>
<p:inputText value="#{cubeMan.cub.caption_cube}"></p:inputText>
<p:outputLabel value="Cache: "></p:outputLabel>
<p:selectBooleanCheckbox value="#{cubeMan.cub.cache}"></p:selectBooleanCheckbox>
<p:outputLabel value="Enabled : "></p:outputLabel>
<p:selectBooleanCheckbox value="#{cubeMan.cub.enabled}"
label="Activate Cube"></p:selectBooleanCheckbox>
<p:outputLabel value="Visible : "></p:outputLabel>
<p:selectBooleanCheckbox value="#{cubeMan.cub.visible}"></p:selectBooleanCheckbox>
<p:outputLabel value="Select Column: " />
<p:selectOneMenu value="#{cubeMan.name_cube}" id="cat">
<f:selectItem itemLabel="Select Column" itemValue="" />
<f:selectItems value="#{cubeMan.getColumnName()}" />
</p:selectOneMenu>
<p:outputLabel value="Select Cube: " />
<p:selectOneMenu value="#{cubeMan.name_cube}" id="cub">
<f:selectItem itemLabel="Select Cube" itemValue="" />
<f:selectItems value="#{cubeMan.AllCubs()}" />
<p:ajax event="change" listener="#{cubeMan.dUpdateCube}" update="#this" />
</p:selectOneMenu>
</p:panelGrid>
<p:commandButton value="Add" action="#{cubeMan.makeCube()}" update="#form">
<p:commandButton action="#{cubeMan.handleCube()}" /></p:commandButton>
</h:form>
</p:panel>
And here is the method in a request scoped bean:
public void dUpdateCube(AjaxBehaviorEvent event){
cubeService.update_cube(cub);
}
public void handleCube() {
cubeService.update_cube(cub);
}
When I change the menu, however, nothing is been printed.
How is this caused and how can I solve it?
I think you are talking about the selectOneMenu with id="cub".
You have to change the value of update of the p:ajax-element. With your current setting nothing gets updated. Try the following to update the whole form:
<p:ajax event="change" listener="#{cubeMan.dUpdateCube}" update="#form" />

PrimeFaces - Validation error in 2nd dropdown (dependent selectOneMenus) - RequestScoped

The 2nd dropdown is being populated by AJAX, but there's validation error in it. Even if the list is populated correctly and a selection is made.
<h:form id="form">
<p:growl id="growl" showDetail="true" sticky="true" globalOnly="true" />
<h:panelGrid columns="3">
<p:outputLabel for="nome" value="Nome:" />
<p:inputText id="nome" value="#{estadoMB.estado.nome}" required="true" validatorMessage="Nome incorreto!" />
<p:message for="nome" />
<p:outputLabel for="sigla" value="Sigla:" />
<p:inputText id="sigla" value="#{estadoMB.estado.sigla}" maxlength="3" size="3" required="true" validatorMessage="Sigla incorreta!" />
<p:message for="sigla" />
<p:outputLabel for="continentes" value="Continente:" />
<p:selectOneMenu id="continentes" value="#{estadoMB.continenteId}" validatorMessage="Selecione um continente!"> <!-- required="# {not empty param[submit.clientId]}" binding="# {menuContinentes}" -->
<f:selectItem itemValue="" itemLabel="-- Selecione --" noSelectionOption="true" />
<f:selectItems value="#{continenteMB.continentes}" var="continente" itemLabel="#{continente.nome}" itemValue="#{continente.id}" />
<p:ajax event="change" listener="#{estadoMB.onPaisesChange}" update="paises" />
</p:selectOneMenu>
<p:message for="continentes" />
<p:outputLabel for="paises" value="País:" />
<p:selectOneMenu id="paises" value="#{estadoMB.pais.id}" validatorMessage="Selecione um país!"> <!-- required="# {not empty param[menuContinentes.clientId]or not empty param[submit.clientId]}" -->
<f:selectItem itemValue="" itemLabel="-- Selecione --" noSelectionOption="true" />
<f:selectItems value="#{estadoMB.paisesCarregados}" var="pais" itemLabel="#{pais.nome}" itemValue="#{pais.id}" />
</p:selectOneMenu>
<p:message for="paises" />
<p:commandButton action="#{estadoMB.save}" value="Salvar" update="#form" /> <!-- binding="# {submit}" -->
</h:panelGrid>
</h:form>
Method onPaisesChange:
public void onPaisesChange() {
if(pais != null) {
Map<String, Object> map = new HashMap<>();
map.put("id", getContinenteId());
paisesCarregados = paisBean.findWithNamedQuery("Pais.findByContinenteId", map);
}
else {
paisesCarregados = new ArrayList<>();
}
}
Already tried EL binding; required="true" in both and I got the same result.
I think it's not possible to do what I want using request scoped beans...

Multiple PrimeFaces dialogs on one page

I am facing problems with dialog windows validation. On home.xhtml I have a tabview with 3 nested dataTables and CRUD buttons (see screenshot). Every button is supposed to call a dialog window with a form to add/edit entity. But whenever I fail to validate some field in any form - all other forms are displayed too:
I would like to validate and display only one dialog at a time and keep it displayed untill user presses "Cancel" button or inputs valid values and presses submit button. No other dialogs shold be opened at this time.
home.xhtml:
<?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">
<ui:component xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ex="http://java.sun.com/jsf/composite/nsobchuk">
<h:head>
<link rel="stylesheet" href="../css/style.css"/>
</h:head>
<h:body>
<h:form id="logout" class="logout" >
<h:commandButton action="#{loginBean.logout()}" value="logout"/>
</h:form>
<p:tabView id="tab" orientation="left">
<p:tab title="Users">
<h:form id="form1">
<h:panelGrid columns="9">
<p:commandButton type="button" value="Add" onclick="dlg1.show()"/>
<p:commandButton id="editUser" type="button" value="Edit" onclick="dlg2.show()" disabled="#{homeBean.selectedUser == null}"/>
<p:dialog id="editUserDialogerDialog" widgetVar="dlg2" header="Sorry" >
<h:outputText value="I didn't have enogh time to finish this functionality. Feel free to test other buttons."/>
</p:dialog>
<p:commandButton id="deleteUser" type="button" onclick="confirmation1.show()" value="Delete" disabled="#{homeBean.selectedUser == null}"/>
<p:confirmDialog message="Are you sure you want to delete user?" header="Confirmation"
severity="alert" widgetVar="confirmation1">
<p:commandButton value="Yes" update=":tab:users" process="#this" styleClass="ui-confirmdialog-yes" icon="ui-icon-check"
oncomplete="confirmation1.hide()" action="#{homeBean.deleteUser}" />
<p:commandButton value="No" onclick="confirmation1.hide()" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close"/>
</p:confirmDialog>
</h:panelGrid>
</h:form>
<p:dataTable id="users" var="user" value="#{homeBean.users}"
scrollable="true" scrollHeight="250" selectionMode="single"
selection="#{homeBean.selectedUser}" rowKey="#{user.userId}"
sortMode="single">
<p:ajax event="rowSelect" listener="#{homeBean.onUserRowSelect}" update=":tab:form1:deleteUser, :tab:form1:editUser"/>
<p:ajax event="rowUnselect" listener="#{homeBean.onUserRowUnselect}" update=":tab:form1:deleteUser, :tab:form1:editUser"/>
<p:column headerText="Login" sortBy="#{user.login}">
<h:outputText value="#{user.login}"/>
</p:column>
<p:column headerText="Password" sortBy="#{user.password}">
<h:outputText value="#{user.password}"/>
</p:column>
<p:column headerText="Role" sortBy="#{user.role}">
<h:outputText value="#{user.role}"/>
</p:column>
<p:column headerText="Name" sortBy="#{user.firstName}">
<h:outputText value="#{user.firstName}"/>
</p:column>
<p:column headerText="Surname" sortBy="#{user.lastName}">
<h:outputText value="#{user.lastName}"/>
</p:column>
</p:dataTable>
<ex:exporter target=":tab:users" fileName="Users"/>
</p:tab>
<p:tab title="Computers">
<h:form id="form2">
<h:panelGrid columns="9">
<p:commandButton type="button" value="Add" onclick="dlg3.show()"/>
<p:commandButton id="editComp" type="button" value="Edit" onclick="dlg4.show()" disabled="#{homeBean.selectedComputer == null}"/>
<p:dialog id="editCompDialog" widgetVar="dlg4" header="Sorry" >
<h:outputText value="I didn't have enogh time to finish this functionality. Feel free to test other buttons."/>
</p:dialog>
<p:commandButton id="deleteComp" type="button" onclick="confirmation2.show()" value="Delete" disabled="#{homeBean.selectedComputer == null}"/>
<p:confirmDialog message="Are you sure you want to delete this computer?" header="Confirmation"
severity="alert" widgetVar="confirmation2">
<p:commandButton value="Yes" update=":tab:computers" process="#this" styleClass="ui-confirmdialog-yes" icon="ui-icon-check"
oncomplete="confirmation2.hide()" action="#{homeBean.deleteComputer}"/>
<p:commandButton value="No" onclick="confirmation2.hide()" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close"/>
</p:confirmDialog>
</h:panelGrid>
</h:form>
<p:dataTable id="computers" var="computer" value="#{homeBean.computers}"
scrollable="true" scrollHeight="250" selectionMode="single"
selection="#{homeBean.selectedComputer}" rowKey="#{computer.computerId}"
sortMode="single" >
<p:ajax event="rowSelect" listener="#{homeBean.onCompRowSelect}" update=":tab:form2:editComp, :tab:form2:deleteComp"/>
<p:column headerText="Login" sortBy="#{computer.login}">
<h:outputText value="#{computer.login}"/>
</p:column>
<p:column headerText="Password" sortBy="#{computer.password}">
<h:outputText value="#{computer.password}"/>
</p:column>
<p:column headerText="Name" sortBy="#{computer.computerName}" >
<h:outputText value="#{computer.computerName}"/>
</p:column>
<p:column headerText="IP address" sortBy="#{computer.ipAddress}">
<h:outputText value="#{computer.ipAddress}"/>
</p:column>
</p:dataTable>
<ex:exporter target=":tab:computers" fileName="Computers"/>
</p:tab>
<p:tab title="Applications">
<h:form id="form3">
<h:panelGrid columns="9">
<p:commandButton type="button" value="Add" onclick="dlg5.show()"/>
<p:commandButton id="editApp" type="button" value="Edit" onclick="dlg6.show()" disabled="#{homeBean.selectedApplication == null}"/>
<p:dialog id="editAppDialog" widgetVar="dlg6" header="Sorry" >
<h:outputText value="I didn't have enogh time to finish this functionality. Feel free to test other buttons."/>
</p:dialog>
<p:commandButton id="deleteApp" type="button" onclick="confirmation3.show()" value="Delete" disabled="#{homeBean.selectedApplication == null}"/>
<p:confirmDialog message="Are you sure you want to delete this application?" header="Confirmation"
severity="alert" widgetVar="confirmation3">
<p:commandButton value="Yes" update=":tab:applications" process="#this" styleClass="ui-confirmdialog-yes" icon="ui-icon-check"
oncomplete="confirmation3.hide()" action="#{homeBean.deleteApplication}"/>
<p:commandButton value="No" onclick="confirmation3.hide()" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close"/>
</p:confirmDialog>
</h:panelGrid>
</h:form>
<p:dataTable id="applications" var="app" value="#{homeBean.applications}"
scrollable="true" scrollHeight="250" selectionMode="single"
selection="#{homeBean.selectedApplication}" rowKey="#{app.appId}"
sortMode="single" >
<p:ajax event="rowSelect" listener="#{homeBean.onAppRowSelect}" update=":tab:form3:editApp, :tab:form3:deleteApp"/>
<p:column headerText="Name" sortBy="#{app.appName}">
<h:outputText value="#{app.appName}"/>
</p:column>
<p:column headerText="Vendor" sortBy="#{app.vendorName}" >
<h:outputText value="#{app.vendorName}"/>
</p:column>
<p:column headerText="License required" sortBy="#{app.licenseRequired}">
<h:outputText value="#{app.licenseRequired}"/>
</p:column>
</p:dataTable>
<ex:exporter target=":tab:applications" fileName="Applications" />
</p:tab>
</p:tabView>
<h:form id="dlg1form">
<p:dialog id="addUserDialog" header="Add Dialog" modal="true" closable="false"
widgetVar="dlg1" width="620" visible="#{facesContext.validationFailed}" >
<h:panelGrid columns="3">
<h:outputLabel for="login" value="Login: "/>
<p:inputText id="login" value="#{homeBean.newUser.login}" required="true"
label="Login: " maxlength="20">
<f:validator binding="#{loginValidator}"/>
</p:inputText>
<p:message for="login"/>
<h:outputLabel for="password" value="Password: "/>
<p:password id="password" value="#{homeBean.newUser.password}" required="true"
feedback="true" label="Password: " maxlength="32"/>
<p:message for="password" />
<h:outputLabel for="firstName" value="First Name: "/>
<p:inputText id="firstName" value="#{homeBean.newUser.firstName}"
label="First Name: " maxlength="20"/>
<p:message for="firstName"/>
<h:outputLabel for="lastName" value="Last Name: "/>
<p:inputText id="lastName" value="#{homeBean.newUser.lastName}"
label="Last Name: " maxlength="20"/>
<p:message for="lastName"/>
<h:outputLabel for="role" value="Role: "/>
<p:selectOneMenu id="role" value="#{homeBean.newUser.role}" required="true" style="width: 80px;" >
<f:selectItem itemLabel="user" itemValue="ROLE_USER" />
<f:selectItem itemLabel="admin" itemValue="ROLE_ADMIN" />
</p:selectOneMenu>
<p:message for="role"/>
</h:panelGrid>
<p:commandButton value="Cancel" immediate="true" onclick="dlg1.hide()" update=":dlg1form:addUserDialog">
<p:resetInput target="addUserDialog" />
</p:commandButton>
<p:commandButton value="Add" update=":tab:users, :dlg1form:addUserDialog" process="#this"
onclick="if (args & & !args.validationFailed) dlg1.hide()" action="#{homeBean.addUser}"/>
</p:dialog>
</h:form>
<h:form id="dlg3form">
<p:dialog id="addCompDialog" header="Add Dialog" draggable="true" closable="false" modal="true"
widgetVar="dlg3" width="600" visible="#{facesContext.validationFailed}">
<h:panelGrid columns="3">
<h:outputLabel for="pclogin" value="Login: "/>
<p:inputText id="pclogin" value="#{homeBean.newComputer.login}" required="true"
label="Login: " maxlength="20">
<f:validator binding="#{loginValidator}"/>
</p:inputText>
<p:message for="pclogin"/>
<h:outputLabel for="pcpassword" value="Password: "/>
<p:password id="pcpassword" value="#{homeBean.newComputer.password}" required="true"
feedback="true" label="Password: " maxlength="32"/>
<p:message for="pcpassword" />
<h:outputLabel for="compName" value="Computer Name: "/>
<p:inputText id="compName" value="#{homeBean.newComputer.computerName}" required="true"
label="Computer Name: " maxlength="20"/>
<p:message for="compName"/>
<h:outputLabel for="ipaddress" value="IP address: "/>
<p:inputText id="ipaddress" value="#{homeBean.newComputer.ipAddress}" required="true"
label="IP address: " maxlength="20"/>
<p:message for="ipaddress"/>
</h:panelGrid>
<p:commandButton value="Cancel" immediate="true" onclick="dlg3.hide()" update=":dlg3form:addCompDialog">
<p:resetInput target="addCompDialog" />
</p:commandButton>
<p:commandButton value="Add" update=":tab:computers, :dlg3form:addCompDialog" process="#this"
onclick="if (args & & !args.validationFailed) dlg3.hide()" action="#{homeBean.addComputer}"/>
</p:dialog>
</h:form>
<h:form id="dlg5form">
<p:dialog id="addAppDialog" header="Add Dialog" draggable="true" closable="false" modal="true"
widgetVar="dlg5" width="600" visible="#{facesContext.validationFailed}">
<h:panelGrid columns="3">
<h:outputLabel for="appName" value="Name: "/>
<p:inputText id="appName" value="#{homeBean.newApplication.appName}" required="true"
label="Name: "/>
<p:message for="appName"/>
<h:outputLabel for="vendorName" value="Vendor: "/>
<p:inputText id="vendorName" value="#{homeBean.newApplication.vendorName}"
label="Vendor: " required="true" />
<p:message for="vendorName"/>
<h:outputLabel for="appLicense" value="Requires license: "/>
<p:selectOneMenu id="appLicense" value="#{homeBean.newApplication.licenseRequired}" required="true" style="width: 80px;" >
<f:selectItem itemLabel="True" itemValue="#{true}" />
<f:selectItem itemLabel="False" itemValue="#{false}" />
</p:selectOneMenu>
<p:message for="appLicense"/>
</h:panelGrid>
<p:commandButton value="Cancel" immediate="true" onclick="dlg5.hide()" update=":dlg5form:addAppDialog">
<p:resetInput target="addAppDialog" />
</p:commandButton>
<p:commandButton value="Add" update=":tab:applications, :dlg5form:addAppDialog" process="#this"
onclick="if (args & & !args.validationFailed) dlg5.hide()" action="#{homeBean.addApplication}"/>
</p:dialog>
</h:form>
</h:body>
</ui:component>
HomeBean.java:
package com.infostroy.adminportal.controller.bean;
import com.infostroy.adminportal.bean.BaseBean;
import com.infostroy.adminportal.model.Application;
import com.infostroy.adminportal.model.Computer;
import com.infostroy.adminportal.model.User;
import com.infostroy.adminportal.service.HibernateDBManager;
import java.io.IOException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
#Component
#Scope("session")
public class HomeBean extends BaseBean {
private static final String editUserBtn = "tab:form1:editUser";
private static final String deleteUserBtn = "tab:form1:deleteUser";
private static final String editCompBtn = "tab:form2:editComp";
private static final String deleteCompBtn = "tab:form2:deleteComp";
private static final String editAppBtn = "tab:form3:editApp";
private static final String deleteAppBtn = "tab:form3:deleteApp";
#Autowired
private HibernateDBManager hibernateDBManager;
private List<User> users;
private List<Computer> computers;
private List<Application> applications;
private User selectedUser, newUser;
private Computer selectedComputer, newComputer;
private Application selectedApplication, newApplication;
private RequestContext rc;
#Override
public void init() {
setUsers(hibernateDBManager.getAllUsers());
setComputers(hibernateDBManager.getAllComputers());
setApplications(hibernateDBManager.getAllApplications());
newUser = new User();
newComputer = new Computer();
newApplication = new Application();
rc = RequestContext.getCurrentInstance();
}
public void addUser() throws NoSuchAlgorithmException {
if (newUser != null && newUser.getPassword() != null) {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(newUser.getPassword().getBytes());
String hash = new BigInteger(1, md.digest()).toString(16);
newUser.setPassword(hash);
if (hibernateDBManager.insertUser(newUser)) {
users.add(newUser);
}
}
}
public void editUser() {
if (selectedUser != null) {
hibernateDBManager.updateUser(selectedUser);
users.set(users.indexOf(selectedUser), selectedUser);
selectedUser = null;
rc.update(deleteUserBtn);
rc.update(editUserBtn);
}
}
public void deleteUser() throws IOException {
if (selectedUser != null) {
if (hibernateDBManager.deleteUserById(selectedUser.getUserId()) > 0) {
users.remove(selectedUser);
selectedUser = null;
rc.update(deleteUserBtn);
rc.update(editUserBtn);
}
}
}
public void addComputer() {
if (newComputer != null && hibernateDBManager.insertComputer(newComputer)) {
computers.add(newComputer);
}
}
public void deleteComputer() {
if (selectedComputer != null) {
if (hibernateDBManager.deleteComputerById(selectedComputer.getComputerId()) > 0) {
computers.remove(selectedComputer);
selectedComputer = null;
rc.update(editCompBtn);
rc.update(deleteCompBtn);
}
}
}
public void addApplication() {
if (newApplication != null && hibernateDBManager.insertApplication(newApplication)) {
applications.add(newApplication);
}
}
public void deleteApplication() {
if (selectedApplication != null) {
if (hibernateDBManager.deleteApplicationById(selectedApplication.getAppId()) > 0) {
applications.remove(selectedApplication);
selectedApplication = null;
rc.update(editAppBtn);
rc.update(deleteAppBtn);
}
}
}
public void onUserRowSelect(SelectEvent event) {
setSelectedUser((User) event.getObject());
}
public void onUserRowUnselect(UnselectEvent event) {
setSelectedUser(null);
}
public void onCompRowSelect(SelectEvent event) {
setSelectedComputer((Computer) event.getObject());
}
public void onAppRowSelect(SelectEvent event) {
setSelectedApplication((Application) event.getObject());
}
//GETTERS etc.
}
Any ideas how this can be solved? How can I open and keep only one dialog opened untill it is validated? Every answer is highly appreciated. If you need some additional info - let me know and I will respond immidiately.
Thank you.
I was able to replicate the problem in my environment. In order to do that I've simplified your home.xhtml code (removing the managedbean references) and here is the changes to the dialogs that made them work:
<p:dialog id="addUserDialog" header="Add Dialog" modal="true" closable="false"
widgetVar="dlg1" width="620" >
<h:form id="dlg1form">
<h:panelGrid columns="3">
<h:outputLabel for="login" value="Login: "/>
<p:inputText id="login" required="true"
label="Login: " maxlength="20" >
</p:inputText>
<p:message for="login"/>
<h:outputLabel for="password" value="Password: "/>
<p:password id="password" required="true"
feedback="true" label="Password: " maxlength="32"/>
<p:message for="password" />
<h:outputLabel for="firstName" value="First Name: "/>
<p:inputText id="firstName"
label="First Name: " maxlength="20"/>
<p:message for="firstName"/>
<h:outputLabel for="lastName" value="Last Name: "/>
<p:inputText id="lastName"
label="Last Name: " maxlength="20"/>
<p:message for="lastName"/>
<h:outputLabel for="role" value="Role: "/>
<p:selectOneMenu id="role" required="true" style="width: 80px;" >
<f:selectItem itemLabel="user" itemValue="ROLE_USER" />
<f:selectItem itemLabel="admin" itemValue="ROLE_ADMIN" />
</p:selectOneMenu>
<p:message for="role"/>
</h:panelGrid>
<p:commandButton value="Cancel" immediate="true" onclick="dlg1.hide()" update="#form">
<p:resetInput target="addUserDialog" />
</p:commandButton>
<p:commandButton value="Add" update="#form"
oncomplete="if (args && !args.validationFailed) dlg1.hide()" />
</h:form>
</p:dialog>
<p:dialog id="addCompDialog" header="Add Dialog" draggable="true" closable="false" modal="true"
widgetVar="dlg3" width="600">
<h:form id="dlg3form">
<h:panelGrid columns="3">
<h:outputLabel for="pclogin" value="Login: "/>
<p:inputText id="pclogin" required="true"
label="Login: " maxlength="20">
</p:inputText>
<p:message for="pclogin"/>
<h:outputLabel for="pcpassword" value="Password: "/>
<p:password id="pcpassword" required="true"
feedback="true" label="Password: " maxlength="32"/>
<p:message for="pcpassword" />
<h:outputLabel for="compName" value="Computer Name: "/>
<p:inputText id="compName" required="true"
label="Computer Name: " maxlength="20"/>
<p:message for="compName"/>
<h:outputLabel for="ipaddress" value="IP address: "/>
<p:inputText id="ipaddress" required="true"
label="IP address: " maxlength="20"/>
<p:message for="ipaddress"/>
</h:panelGrid>
<p:commandButton value="Cancel" immediate="true" onclick="dlg3.hide()" process="#this" update="#form">
<p:resetInput target="addCompDialog" />
</p:commandButton>
<p:commandButton value="Add" update="#form"
oncomplete="if (args && !args.validationFailed) dlg3.hide()" />
</h:form>
</p:dialog>
<p:dialog id="addAppDialog" header="Add Dialog" draggable="true" closable="false" modal="true"
widgetVar="dlg5" width="600" >
<h:form id="dlg5form">
<h:panelGrid columns="3">
<h:outputLabel for="appName" value="Name: "/>
<p:inputText id="appName" required="true"
label="Name: "/>
<p:message for="appName"/>
<h:outputLabel for="vendorName" value="Vendor: "/>
<p:inputText id="vendorName"
label="Vendor: " required="true" />
<p:message for="vendorName"/>
<h:outputLabel for="appLicense" value="Requires license: "/>
<p:selectOneMenu id="appLicense" required="true" style="width: 80px;" >
<f:selectItem itemLabel="True" itemValue="#{true}" />
<f:selectItem itemLabel="False" itemValue="#{false}" />
</p:selectOneMenu>
<p:message for="appLicense"/>
</h:panelGrid>
<p:commandButton value="Cancel" immediate="true" onclick="dlg5.hide()" update="#form" process="#this">
<p:resetInput target="addAppDialog" />
</p:commandButton>
<p:commandButton value="Add" update="#form"
oncomplete="if (args && !args.validationFailed) dlg5.hide()"/>
</h:form>
</p:dialog>
Some notes:
I've noticed that you where testing validation onclick instead of oncomplete.
I've placed the form inside the dialog for no special reason, just habit.
I've removed the visible="#{facesContext.validationFailed}" because that won't be necessary.
The same happened with the process="#this" on add buttons, see more about Partial Process here.
Consider changing the cancel button logic to something like this:
<p:commandButton value="Cancel" action="#{viewMBean.clearUser}" oncomplete="dlg1.hide()" update="#form" process="#this" />
public void clearUser() {
newUser = new User();
}

No Update of Fields after Validation error

I have a primefaces dialog in which I can create or update an Employee.
It will open by this
</p:dialog><p:dialog id="employeeEditDialog" header="#{msg.employeeEdit}"
widgetVar="dlgEmployeeEdit" resizable="false">
<p:ajax event="close" listener="#{employeeView.cancel}"
update=":showEmployees:liste" />
<ui:include src="/content/Employee/ShowEmployeeContent.xhtml" />
</p:dialog>
And here is the Dialog Page
<h:form id="editContent">
<p:growl id="growl" showDetail="true" sticky="false" life="5000" />
<p:focus id="focusEdit" for="emSalutation" />
<h:panelGrid columns="2" id="contentGrid">
<h:panelGrid columns="2" id="allgemein"> <h:outputText value="#{msg.id}" />
<h:outputText value="#{employeeView.newEmployee.id}" />
<h:outputText value="#{msg.salutation}" />
<p:selectOneMenu value="#{employeeView.newEmployee.salutation}"
id="emSalutation">
<f:selectItem itemLabel="" itemValue="" />
<f:selectItems value="#{employeeView.salutations}" var="salutations"
itemLabel="#{salutations.description}" itemValue="#{salutations}" />
</p:selectOneMenu>
<h:outputText value="#{msg.title}" />
<p:inputText value="#{employeeView.newEmployee.title}" id="emTitle" />
<h:outputText value="#{msg.name}" />
<p:inputText value="#{employeeView.newEmployee.name}" id="emName"
validatorMessage="#{msg.valName}" />
<h:outputText value="#{msg.prename}" />
<p:inputText value="#{employeeView.newEmployee.prename}"
id="emPrename" />
<h:outputText value="#{msg.loginname}" />
<p:inputText value="#{employeeView.newEmployee.loginname}"
validatorMessage="#{msg.valLogin}" />
<h:outputText value="#{msg.department}" />
<h:panelGrid columns="2" id="departmentGrid">
<p:selectOneMenu value="#{employeeView.selectedDepartment.id}"
id="emDepartment">
<f:selectItem itemLabel="" itemValue="" />
<f:selectItems value="#{employeeView.departmentList}"
var="department" itemLabel="#{department.description}"
itemValue="#{department.id}" />
</p:selectOneMenu>
<p:commandButton icon="ui-icon-disk" immediate="true"
oncomplete="dlgDepartmentAdd.show()"
update="departmentGrid, :departmentAddDialog">
</p:commandButton>
</h:panelGrid>
<h:outputText value="#{msg.position}" />
<h:panelGrid columns="2" id="positionGrid">
<p:selectOneMenu value="#{employeeView.selectedPosition.id}"
id="emPosition">
<f:selectItem itemLabel="" itemValue="" />
<f:selectItems value="#{employeeView.positionList}" var="position"
itemLabel="#{position.description}" itemValue="#{position.id}" />
</p:selectOneMenu>
<p:commandButton icon="ui-icon-disk" immediate="true" id="buttonPos"
oncomplete="dlgPositionAdd.show()"
update="positionGrid, :positionAddDialog">
</p:commandButton>
</h:panelGrid>
<h:outputText value="#{msg.phone}" />
<p:inputText value="#{employeeView.newEmployee.phone}" id="emPhone" />
<h:outputText value="#{msg.fax}" />
<p:inputText value="#{employeeView.newEmployee.fax}" id="emFax" />
<h:outputText value="#{msg.email}" />
<p:inputText value="#{employeeView.newEmployee.email}" id="emEmail"
validator="myEmailValidator" validatorMessage="#{msg.valEmail}" />
<h:outputText value="#{msg.employeedSince}" />
<p:calendar value="#{employeeView.newEmployee.employeedSince}"
id="emEmployeedSince" pattern="dd.MM.yyy" showOn="button" />
<h:outputText value="#{msg.employeedEnd}" />
<p:calendar value="#{employeeView.newEmployee.employeedEnd}"
id="emEmployeedEnd" pattern="dd.MM.yyy" showOn="button" />
<h:outputText value="#{msg.active}" />
<p:selectBooleanCheckbox value="#{employeeView.newEmployee.active}"
id="emActive" />
</h:panelGrid>
</h:panelGrid>
<h:panelGrid columns="3" class="buttonContent" id="button">
<p:commandButton value="#{msg.save}" id="saveButton" update="growl"
oncomplete="if ((!args.validationFailed)) dlgEmployeeEdit.hide()"
actionListener="#{employeeView.saveOrUpdateEmployee}" />
<p:commandButton value="#{msg.cancel}" immediate="true"
oncomplete="dlgEmployeeEdit.hide()"/>
<p:commandButton value="#{msg.delete}" immediate="true"
oncomplete="dlgEmployeeDelete.show()"
disabled="#{(employeeView.newEmployee.id == null) ? true : false}" />
</h:panelGrid>
<p:defaultCommand target="saveButton" /></h:form></html>
And now here are the two Methods which used in the Page:
/**
* Methode zum Speichern und Updaten eines Mitarbeiters
*/
public void saveOrUpdateEmployee() {
FacesContext context = FacesContext.getCurrentInstance();
try {
logger.debug("save aufgerufen " + this.newEmployee);
if (this.selectedDepartment.getId() == null) {
this.newEmployee.setDepartment(null);
}
else {
this.newEmployee.setDepartment(this.departmentHandler.getDepartmentById(this.selectedDepartment.getId()));
}
if (this.selectedPosition.getId() == null) {
this.newEmployee.setPosition(null);
}
else {
this.newEmployee.setPosition(this.positionHandler.getPositionById(this.selectedPosition.getId()));
}
this.employeeController.saveOrUpdate(this.newEmployee);
logger.info("Mitarbeiter erfolgreich gespeichert");
context.addMessage(null, new FacesMessage("Successful", "Mitarbeiter gespeichert "));
}
catch (Exception e) {
logger.error("Fehler beim Speichern des Mitarbeiters", e);
context.addMessage(null, new FacesMessage("Fehler beim Speichern des Mitarbeiters", e.getMessage()));
}
this.loadPersons();
}
/**
* Methode zum Abbrechen bei der Neuanlage/Änderung eines Mitarbeiters
* Felder leeren
*/
public void cancel() {
logger.debug("cancel()");
this.newEmployee = new Employee();
this.selected = new Employee();
this.selectedDepartment = new Department();
this.selectedPosition = new Position();
}
If now, validation failed, the dialog will not hide. This is OK and desired. It shows my created message via FacesMassages as required. If I then close the dialogbox by myself with the "cancel"-Button, dialog will close as expected. In the cancel()-method the object Employee will be set to a new instance of Employee (this.newEmployee = new Employee()) as you can see. But when I open the dialog after validation failure, the object "newEmployee" contains just the old values... Why does my method cancel()not work? I don't understand.
This problem is related to JSF issue 1060 and in detail elaborated in this Q&A: How can I populate a text field using PrimeFaces AJAX after validation errors occur?
To the point, this behaviour is (unfortunately) correct as per current JSF specification and this can be solved as follows: during the invoke action phase you need to collect UIInput components which are included in the ajax render, but not in the ajax execute, and then invoke resetValue() method on them. This can be in a generic and reuseable fashion be done with help of OmniFaces ResetInputAjaxActionListener.

Resources