Primefaces p:消息不会显示第一个FacesMessage

时间:2016-10-06 11:57:59

标签: jsf primefaces jsf-2

先决条件
  - JSF 2.1
  - Primefaces 5.2
  - Glassfish 3.1

故事
我创建了一个p:对话框,用于在p:messages元素上显示FacesMessages。需要此对话框,因为用户必须在继续之前使用“OK”-Button提交特定的FacesMessages。

对话

<p:outputPanel id="modalMessage">

    <p:dialog id="dlgMessageDialog" dynamic="true" style="z-index: 100"
        closable="false" widgetVar="wigVarMessageDialog" modal="true"
        appendTo="@(body)">

        <f:facet name="header">
            <h:outputText id="messageDialogHeader"
                value="#{messageDialogBean.header}" />
        </f:facet>

        <p:outputPanel id="modalMessagePanel">

            <h:form id="messageForm" enctype="multipart/form-data">

                <p:messages id="messages" escape="false" closable="false"
                    showDetail="true" autoUpdate="true"
                    for="#{messageDialogBean.messageDialogId}"></p:messages>

                <p:spacer height="20px"></p:spacer>

                <p:commandButton value="#{msg.btnOk}"
                    oncomplete="PF('wigVarMessageDialog').hide()" />

            </h:form>
        </p:outputPanel>
    </p:dialog>
</p:outputPanel>

Bean

@Named("messageDialogBean")
@SessionScoped
public class MessageDialogBean implements Serializable {

  private static final long serialVersionUID = 1L;
  private final String messageDialogId = "messageDialogId";
  private FacesMessage message = new FacesMessage();
  private String header = "test";

  public void showMessage(final String pHeader, final FacesMessage pMessage) {
    if (pMessage != null) {
        setHeader(pHeader);
        this.message = pMessage;
        show();
    }
  }

  public void showWarn(final String pHeader, final String pSummary, final String pDetail) {
    setHeader(pHeader);
    this.message = new FacesMessage(FacesMessage.SEVERITY_WARN, pSummary, pDetail);
    show();
  }

  public void showInfo(final String pHeader, final String pSummary, final String pDetail) {
    setHeader(pHeader);
    this.message = new FacesMessage(FacesMessage.SEVERITY_INFO, pSummary, pDetail);
    show();
  }

  public void showError(final String pHeader, final String pSummary, final String pDetail) {
    setHeader(pHeader);
    this.message = new FacesMessage(FacesMessage.SEVERITY_ERROR, pSummary, pDetail);
    show();
  }

  public void updateDialog() {
    RequestContext context = RequestContext.getCurrentInstance();
    context.update("mainForm:messageDialogHeader");
  }

  private void show() {
    updateDialog();
    RequestContext context = RequestContext.getCurrentInstance();
    context.execute("PF('wigVarMessageDialog').show();");
    FacesContext.getCurrentInstance().addMessage(this.messageDialogId, this.message);
  }

  public String getMessageDialogId() {
    return this.messageDialogId;
  }

  public void setHeader(final String pHeader) {
    this.header = pHeader;
  }

  public String getHeader() {
    return this.header;
  }

  public FacesMessage getLastMessage() {
    return this.message;
  }

}

必须提交的消息之一

this.messageDialogBean.showInfo("Title", "Summary", "Detail");

问题
第一次打开对话框时,对话框的p:messages元素不显示消息。打开并隐藏它后,一旦它显示所有进一步的FacesMessages就好了。

问题
到目前为止,当界面初始化为workarround时,我正在使用打开和关闭对话框。是否有人知道导致这个问题的原因以及如何正确解决这个问题?

感谢您的回答

1 个答案:

答案 0 :(得分:0)

首先,不允许将表单放在另一个表单中,如W3C XHTML规范中所述,“表单不得包含其他表单元素。”访问:https://www.w3.org/TR/xhtml1/#prohibitions

所以你的对话框不应该在主窗体内,你必须从窗体中对话,你的代码应该是这样的:

<form id="mainForm" >
    <!--your main page-->
</form>

<p:dialog id="dlgMessageDialog" >
    <h:form id="messageForm" enctype="multipart/form-data">
        <f:facet name="header">
            <h:outputText id="messageDialogHeader"
                          value="#{messageDialogBean.header}" />
        </f:facet>

        <p:messages id="messages" escape="false" closable="false"
                    showDetail="true" autoUpdate="true"
                    for="#{messageDialogBean.messageDialogId}"></p:messages>

        <p:spacer height="20px"></p:spacer>

        <p:commandButton value="#{msg.btnOk}"
                         oncomplete="PF('wigVarMessageDialog').hide()" />

    </h:form>
</p:dialog>

另外,你必须更新整个对话框,所以当打开对话框时,会自动更新消息:

context.update("dlgMessageDialog");