Dialog on PrimeFaces does not update and calculate date difference - ajax

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.

Related

<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" />

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();
}

PrimeFaces dialog is validated only the first time it appears

JSF 2.2, PrimeFaces 3.5.
home.xhtml contains a tabview with nested dataTables and add/edit/delete buttons. Each button is supposed to call a dialog with a form and submit/cancel buttons.
The problem is that validation is processed only once (see screenshot) and if I press "Add" / "Cancel" the dialog just hides and no validation is made. And if I try to reopen it once again and input values and hit "Add" - it just skips validation and renders response. So, basically, it just makes a initial request (if I guessed right).
Console output for pressing "Add" with empty values 3 times. First click has been processed the way I want it, but the next ones are just hiding the dialog without any validation:
2014-01-24 17:56:09,590 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: RESTORE_VIEW 1
2014-01-24 17:56:09,628 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: APPLY_REQUEST_VALUES 2
2014-01-24 17:56:09,633 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: PROCESS_VALIDATIONS 3
2014-01-24 17:56:09,645 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: RENDER_RESPONSE 6
2014-01-24 17:56:13,127 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: RESTORE_VIEW 1
2014-01-24 17:56:13,128 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: RENDER_RESPONSE 6
2014-01-24 17:56:16,557 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: RESTORE_VIEW 1
2014-01-24 17:56:16,558 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: RENDER_RESPONSE 6
home.xhtml (dialogs are at the bottom of a page):
<?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>
<title>Home page</title>
<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>
<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" onclick="dlg1.hide()" update="#form">
<p:resetInput target="addUserDialog" />
</p:commandButton>
<p:commandButton value="Add" update="#form" immediate="false"
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>
</h:body>
</ui:component>
HomeBean:
#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.
}
I'd like to keep the dialog opened and validated each time user presses "Add" and not only once. Can anybody help me achieve this with my code or point me to the solution? (similar answered question with rating -1 didn't help me) Every answer is highly appreciated.
Thank you all.
Ok, guys. I found a solution by myself. What I did to make it work was giving a panelGrid element inside a form an id an updating panelGrid instead of a whole form.
So, "Add" button was changed to:
<p:commandButton value="Add"
update=":dlg1form:dt, :tab:users"
action="#{homeBean.addUser}"
oncomplete="if (!args.validationFailed) dlg1.hide()" />
and panelGrid, which contains input fields:
<h:form id="dlg1form">
<h:panelGrid columns="3" id="dt">
This helped me to validate input fields on every click and not just once.
Sincerely hope that this will help someone.
Cheers!
I had the same problem : having a update="#form" or update="yourFormName" inside my <p:commandButton> prevented the dialog from being kept when a validation error occured.
This might be due to the fact that including the update form command regenerate the whole dialog but doesn't trigger the dialogWidgetVar.show() js command.
I solved the issue by nesting a <p:fragment autoUpdate="true"> inside the dialog. Then, you can remove the update keyword inside the triggering commandButton since every component inside the fragment will be updated. The result is that the <p:dialog> and </p:dialog> tags are not replaced when the client receives the Ajax response. My working code is as follows :
<h:form id="locations_editer_creer">
<p:dialog id="location_dlg" widgetVar="locationDlg" header="#{msgs.LocationCreerNouvelle}" width="600" dynamic="false" closeOnEscape="true"
minimizable="true" maximizable="true" modal="true" >
<p:fragment autoUpdate="true">
your form inputs e.g. <p:inputText .../>
<p:commandButton id="OK" value="OK"
actionListener="#{locationsControleur.confirmer()}"
oncomplete="traiteRequeteCreationLoc(xhr, status, args)"
styleClass="ui-confirmdialog-yes" icon="ui-icon-check"/>
</p:fragment>
</p:dialog>
</h:form>
This technique is described inside the excellent PrimeFaces Beginner's Guide book by K. Siva Prasad Reddy (Packt Publishing), p. 54 : Partial Processing and Rendering using the Fragment component.
Hope this can help others.

Several PrimeFaces dialogs show up on validation error instead of single

I have JSF and PrimeFaces 3.5 web application.
Page home.xhtml contains a tabView component with 3 nested dataTables and buttons that perform add/edit/delete operations.
Every button calls a p:dialog with different form. Whenever one of the dialogs get validation error, all other dialogs are displayed too because their attribute is visible="#{facesContext.validationFailed}" (IMHO)
I need to display only one dialog which failed to validate untill user enters valid values or presses Cancel button (clears dialog form values).
Please, point me to the solution. I have spent over 20 hours trying. Every answer is highly appreciated.
Thank you.
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: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=":tab:form1:addUserDialog">
<p:resetInput target="addUserDialog" />
</p:commandButton>
<p:commandButton value="Add" update=":tab:users, :tab:form1:addUserDialog" process="#this"
onclick="if (args & & !args.validationFailed) dlg1.hide()" action="#{homeBean.addUser}"/>
</p:dialog>
<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: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=":tab:form2:addCompDialog">
<p:resetInput target="addCompDialog" />
</p:commandButton>
<p:commandButton value="Add" update=":tab:computers, :tab:form2:addCompDialog" process="#this"
onclick="if (args & & !args.validationFailed) dlg3.hide()" action="#{homeBean.addComputer}"/>
</p:dialog>
<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: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=":tab:form3:addAppDialog">
<p:resetInput target="addAppDialog" />
</p:commandButton>
<p:commandButton value="Add" update=":tab:applications, :tab:form3:addAppDialog" process="#this"
onclick="if (args & & !args.validationFailed) dlg5.hide()" action="#{homeBean.addApplication}"/>
</p:dialog>
<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: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 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/SETTERS
}
If you want to validate multiple fields within a single method, you could do the following:
Variant 1:
Remove the visible="#{facesContext.validationFailed}" from your dialogs.
Remove the required=true from your dialogs fields.
Change the button (to all of them, just an example) from your dialogs from
to
<p:commandButton value="Add" update=":tab:computers, :tab:form2:addCompDialog" process="#this" action="#{homeBean.addComputer}"/>
and take care of closing the dialog within the homeBean's addComputer method:
public String addComputer() {
// do some checks
if (everythingIsOk) {
RequestContext.getCurrentInstance().execute("dlg3.hide();");
}
}
Variant 2:
If you don't want to do multiple checks within the addComputer method, you could use #Validators, see a Primefaces Showcase. There you can control the visibility of the dialogs within the validate(FacesContext context, UIComponent component, Object value) throws ValidatorException method.
The first method groups the validation into one place.
The second variante is convenient because you can reuse the Validator classes.

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