p:对话框中的清除表单在操作/方法调用失败后关闭

时间:2013-04-26 19:40:29

标签: forms jsf-2 primefaces dialog reset

我在通过AJAX提交的p:dialog组件中有一个表单。对话框中的表单是通过另一个ui:include .xhtml只包含表单及其组件(不,我不是嵌套表单;对话框本身不是任何形式)。包含页面的支持bean是'ViewScoped'。

大部分功能正常:

  • 成功验证后,表单将执行save方法;成功保存后,对话框关闭;打开后续记录会显示数据库中的正确记录信息。
  • 如果验证失败,提交的值仍然存在,对话框仍然打开并显示验证错误,修复无效字段并重新提交成功保存结果。

action调用的p:commandButton失败时,会出现此问题。如果失败,对话框将保持打开状态,并通过h:messages向用户显示“保存更改错误”;此外,提交的值仍然存在于输入字段中。当表单保持打开时,这很好(甚至是期望的) - 但是在关闭对话框并重新打开它时,提交的值仍然在文本字段中。这很糟糕,因为它给用户留下了保存成功的印象(由于对话框更新,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=trueimmediate=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(), null, "addressform", new Addressform());
        Addressform addressform = (Addressform) resolver.getValue(ctx.getELContext(), null, "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(), null, "records");
    RecordDetails recordDetails = (RecordDetails) resolver.getValue(ctx.getELContext(), null, "recordDetails");
    Mainform mainform = (Mainform) resolver.getValue(ctx.getELContext(), null, "mainform");
    Person person = (Person) resolver.getValue(ctx.getELContext(), null, "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的

2 个答案:

答案 0 :(得分:14)

试试这个:

  1. 将对话框放在表单(dialogInputForm)

  2. 添加属性update =“:dialogInputForm”

  3. 将resetInput标记嵌套在打开对话框的按钮中,并将目标指定为刚刚创建的表单
  4. 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>
    

答案 1 :(得分:1)

这对我有用,将这个ajax事件放置在对话框中。对话框关闭后,验证将被清除

<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:ajax event="close" update="dlgAddress" resetValues="true" />

</p:dialog>