我有一个primefaces对话框,我可以在其中创建或更新Employee.
它会打开
它会打开
</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>
这是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>
现在这里是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(); }
如果现在,验证失败,对话框将不会隐藏.这是好的和期望的.它根据需要通过FacesMassages显示我创建的消息.如果我自己用“取消”-Button关闭对话框,对话框将按预期关闭.在cancel() – 方法中,对象Employee将被设置为Employee的新实例(this.newEmployee = new Employee()),如您所见.但是当我在验证失败后打开对话框时,对象“newEmployee”只包含旧值…为什么我的方法cancel()不起作用?我不明白.
解决方法
该问题与
JSF issue 1060有关,并在本Q& A:
How can I populate a text field using PrimeFaces AJAX after validation errors occur?中详细阐述
到目前为止,这种行为(遗憾的是)根据当前的JSF规范是正确的,这可以解决如下:在调用操作阶段,您需要收集包含在ajax渲染中但不在ajax执行中的UIInput组件,然后在它们上调用resetValue()
方法.这可以通过OmniFaces ResetInputAjaxActionListener
的帮助以通用和可重复使用的方式完成.