MOST的功能很好:
>成功验证后,表单将执行save方法;成功保存后,对话框关闭;打开后续记录会显示数据库中的正确记录信息.
>如果验证失败,提交的值将保持不变,对话框将保持打开状态并显示验证错误,修复无效字段并在成功保存时重新提交结果.
当p:commandButton调用的操作失败时,会出现问题.如果失败,对话框保持打开状态,并通过h:消息向用户显示“保存更改错误”;此外,提交的值仍然存在于输入字段中.当表单保持打开时,这很好(甚至是期望的) – 但是在关闭对话框并重新打开它时,提交的值仍然在文本字段中.这很糟糕,因为它给用户留下了保存成功的印象(因为对话框更新,h:messages组件现在是空白的).
到目前为止,我已经尝试了以下方法,其中没有一个解决了这个问题:
> 1.1)在打开的对话框中将包含表单的支持bean设置为bean的新实例.
> 1.2)由于bean现在是一个新实例,我还使用数据bean中的详细信息重新填充地址对象.
> 2.1)禁用对话框上的关闭按钮,并添加一个p:commandButton“取消”按钮,其中包含p:resetInput组件
它关闭对话框/重置表单. (对话框关闭,但已提交
形式中的值持续存在).
> 2.2)从这个p:commandButton调用一个方法,删除包含表单的支持bean的RequestMap.
> 2.3)尝试将按钮设置为immediate = true和immediate = false.
> 2.4)尝试使用设置为process = @ this的按钮,我用来关闭表单的类似策略以确保它将具有新的字段
重新开放.
您可以考虑将支持bean设置为新实例,并重新填充地址对象,我会看到一个新的形式,但是NOPE.
以下是一些来源:
mainform.xhtml的部分
<p:dialog id="dlgAddress" header="Address Edit" widgetVar="dialogAddress" dynamic="true" modal="false" closable="false" resizable="false" styleClass="dlgAddress" visible="#{addressform.showDlgAddress}"> <ui:include src="addressform.xhtml"/> </p:dialog>
addressform.xhtml
<h:form id="fDlgAddress"> <div id="addresses-container"> <h:messages id="msgDlgAddress" errorClass="errormsg" infoClass="infomsg1" layout="table"/> <h:panelGrid columns="1" styleClass="pgAddresses" rendered="#{!addressform.address.exists}"> <h:outputText value="No active #{addressform.address.atypCode} address found." styleClass="record-not-exists"/> <h:outputText value="Use the form below to create one."/> </h:panelGrid> <p:panelGrid columns="2" styleClass="pgDlgForm pgAddresses"> <h:outputLabel value="Address Type"/> <h:inputText id="atypCode1" value="#{addressform.address.atypCode}" disabled="true" rendered="#{addressform.address.exists}"/> <h:selectOneMenu id="atypCode2" value="#{addressform.address.atypCode}" rendered="#{!addressform.address.exists}"> <f:selectItems value="#{addressform.atypCodeList}" var="atyp" itemValue="#{atyp}" itemLabel="#{atyp}"/> </h:selectOneMenu> <h:outputLabel value="Street 1" for="street1"/> <h:inputText id="street1" value="#{addressform.address.addressLine1}"/> <h:outputLabel value="Street 2" for="street2"/> <h:inputText id="street2" value="#{addressform.address.addressLine2}"/> <h:outputLabel value="Street 3" for="street3"/> <h:inputText id="street3" value="#{addressform.address.addressLine3}"/> <h:outputLabel value="Street 4" for="street4"/> <h:inputText id="street4" value="#{addressform.address.addressLine4}"/> <h:outputLabel value="City" for="city"/> <h:inputText id="city" value="#{addressform.address.city}" required="true" requiredMessage="Please enter a city."/> <h:outputLabel value="State" for="statCode"/> <h:selectOneMenu id="statCode" value="#{addressform.address.stateCode}"> <f:selectItem itemLabel="Select State/Province" itemValue=""/> <f:selectItems value="#{states.statesList}" var="stat" itemValue="#{stat.statCode}" itemLabel="#{stat.statDesc}"/> </h:selectOneMenu> <h:outputLabel value="Zip Code" for="zipCode"/> <h:inputText id="zipCode" value="#{addressform.address.zip}"/> <h:outputLabel value="Country" for="natnCode"/> <h:selectOneMenu id="natnCode" value="#{addressform.address.nationCode}" required="true" requiredMessage="Please choose a nation."> <f:selectItem itemLabel="Select Country" itemValue=""/> <f:selectItems value="#{nations.nationsList}" var="natn" itemValue="#{natn.natnCode}" itemLabel="#{natn.natnDesc}"/> </h:selectOneMenu> <h:outputLabel value="From Date" for="fromDate"/> <p:calendar id="fromDate" value="#{addressform.address.fromDate}" showButtonPanel="true"/> <h:outputLabel value="To Date" for="toDate"/> <p:calendar id="toDate" value="#{addressform.address.toDate}" showButtonPanel="true"/> <h:outputLabel value="Inactivate" for="inactivateAddress" rendered="#{addressform.address.exists}"/> <h:selectBooleanCheckBox id="inactivateAddress" value="#{addressform.address.inactivate}" rendered="#{addressform.address.exists}"/> <h:outputLabel value="Delete" for="deleteAddress" rendered="#{addressform.address.exists}"/> <h:selectBooleanCheckBox id="deleteAddress" value="#{addressform.address.delete}" rendered="#{addressform.address.exists}"/> </p:panelGrid> </div> <div class="button-container"> <p:commandButton value="Save Changes" action="#{addressform.save}" type="submit" ajax="true" process="@form" update="@form"/> <p:commandButton value="Cancel" process="@this" onclick="dialogAddress.hide();"> <p:resetInput target="fDlgAddress"/> </p:commandButton> </div> </h:form>
Recorddetailsform(用于调用地址对话框的表单的辅助bean)
public void showDlgAddress(){ FacesContext ctx = FacesContext.getCurrentInstance(); ELResolver resolver = ctx.getApplication().getELResolver(); RecordDetails recordDetails = (RecordDetails) resolver.getValue(ctx.getELContext(),null,"recordDetails"); //Set addressform backing bean to new instance and load address into it from recordDetails resolver.setValue(ctx.getELContext(),"addressform",new Addressform()); Addressform addressform = (Addressform) resolver.getValue(ctx.getELContext(),"addressform"); addressform.setAddress(recordDetails.getAddress()); }
Addressform(地址表的辅助bean)
public void save() { FacesContext ctx = FacesContext.getCurrentInstance(); RequestContext rctx = RequestContext.getCurrentInstance(); ELResolver resolver = ctx.getApplication().getELResolver(); Records records = (Records) resolver.getValue(ctx.getELContext(),"records"); RecordDetails recordDetails = (RecordDetails) resolver.getValue(ctx.getELContext(),"recordDetails"); Mainform mainform = (Mainform) resolver.getValue(ctx.getELContext(),"mainform"); Person person = (Person) resolver.getValue(ctx.getELContext(),"person"); //Pretty lengthy sql stuff here. Commented out. Just wanted to display the display logic below for the dialog. if (errorMsg != null) {//If errorMsg is not null,then error occurred. showDlgAddress = true;//Ensures address dialog remains open in event of action error. queueErrorMessage(errorMsg); rctx.update("dlgAddress"); return;//break out of method on error. } else { showDlgAddress = false; rctx.update("dlgAddress"); } //If everything saves without error,repopulate address and update recordDetails dialog. recordDetails.populateAddress(records.getSelectedRecord()); mainform.updateDlgRecordDetails(); }
其他信息:
> JSF2
> Primefaces 3.5
> Tomcat 6.0
> Netbeans
解决方法
>将对话框放在表单中(dialogInputForm)
>添加属性update =“:dialogInputForm”
>将resetInput标记嵌套在打开对话框的按钮中,并将目标指定为刚刚创建的表单
commandButton:
<p:commandButton process="@this" actionListener="#{bean.prepare}" update=":dialogInputForm" oncomplete="thirdPartyDialog.show()" value="Open Input Dialog" > <p:resetInput target=":dialogInputForm" /> </p:commandButton>
以及包含对话的形式
<h:form id="dialogInputForm" > ... your dialog ... </h:form>