【问题标题】:Primefaces duplicate messages in dialog and pagePrimefaces 在对话框和页面中重复消息
【发布时间】:2015-06-11 09:06:09
【问题描述】:

我正在使用 Primefaces 5.2、JSF 2.2.10 和 Tomcat 7.0。

我有一个用户页面,其中包含其个人数据,以及一个允许该用户通过对话框更改其密码的按钮。

在页面中,我在对话框中使用了一个 p:messages 组件(id="messages")和其他 p:messages 组件(id="messagesDialog")。

要更改密码,用户必须输入当前密码和新密码。

当对话框字段验证失败时,我想在对话框消息组件(“messagesDialog”)中显示错误,而不是在页面消息组件(“messages”)中显示错误。

我怎么能得到它?

我尝试在控制器中使用一个字段,当对话框打开时它为真,当它关闭时为假。页面消息(“消息”)具有该字段的渲染属性。但没有成功。

这是我正在使用的代码:

XHTML 页面:

<p:messages id="messages" closable="true" 
    rendered="#{not userController.dialogChangePasswordOpened}" />

<h:form id="formUserData">
    <p:outputPanel styleClass="panelGrey">
        <!-- User data... -->

        <p:panelGrid styleClass="noBorders">
            <p:row>
                <p:column styleClass="colLabel">
                    <p:outputLabel id="labelChangePassword" for="changePassword"
                        value="#{msg['label.password']}"></p:outputLabel>
                </p:column>
                <p:column styleClass="colInput">
                    <p:commandButton id="changePassword"
                        value="#{msg['user.changePassword']}" 
                        actionListener="#{userController.openDialogChangePassword}"
                        update="messages formChangePassword">
                    </p:commandButton>
                </p:column>
            </p:row>
        </p:panelGrid>
    </p:outputPanel>
</h:form>


<!-- Dialog change password -->
<h:form id="formChangePassword">
    <p:dialog id="dlgChangePassword" modal="true"
        header="#{msg['user.changePassword.title']}"
        widgetVar="dlgChangePassword" styleClass="popUpPassword" closable="false">

        <p:messages id="messagesDialog" closable="true" autoUpdate="true"
            globalOnly="false" />
        <p:panelGrid styleClass="noBorders" id="panelChangePassword">
            <p:row>
                <p:column>
                    <p:outputLabel id="labelOldPassword" for="oldPassword"
                        value="#{msg['label.oldPassword']}" />
                </p:column>
                <p:column>
                    <p:password id="oldPassword"
                        value="#{userController.oldPassword}" required="true"
                        feedback="false">
                        <p:ajax update="messagesDialog" event="keyup"></p:ajax>
                    </p:password>
                </p:column>
            </p:row>
            <p:row>
                <p:column>
                    <p:outputLabel id="labelNewPassword" for="newPassword"
                        value="#{msg['label.newPassword']}" />
                </p:column>
                <p:column>
                    <p:password id="newPassword"
                        value="#{userController.newPassword}"
                        match="checkNewPassword"
                        required="true" feedback="true">
                    </p:password>
                </p:column>
            </p:row>
            <p:row>
                <p:column>
                    <p:outputLabel id="labelCheckNewPassword" for="checkNewPassword"
                        value="#{msg['label.checkNewPassword']}" />
                </p:column>
                <p:column>
                    <p:password id="checkNewPassword"
                        value="#{userController.newPassword}" required="true"
                        feedback="false">
                    </p:password>
                </p:column>
            </p:row>
            <p:row>
                <p:column rowspan="2">
                    <p:commandButton id="btnOK" value="#{msg['button.ok']}"
                        update="messages messagesDialog"
                        actionListener="#{userController.changePassword}">
                    </p:commandButton>
                    <p:commandButton id="btnCancel"
                        value="#{msg['button.cancel']}" immediate="true"
                        actionListener="#{userController.closeDialogChangePassword}" />
                </p:column>
            </p:row>
        </p:panelGrid>
    </p:dialog>
</h:form>

用户控制器:

private boolean dialogChangePasswordOpened;

public boolean isDialogChangePasswordOpened() {
    return dialogChangePasswordOpened;
}

public void setDialogChangePasswordOpened(boolean dialogChangePasswordOpened) {
    this.dialogChangePasswordOpened = dialogChangePasswordOpened;
}

public void openDialogChangePassword() {
    dialogChangePasswordOpened = true;
    resetChangePasswordFields();
    RequestContext.getCurrentInstance().execute("PF('dlgChangePassword').show()");
}

public void closeDialogChangePassword() {
    dialogChangePasswordOpened = false;
    resetChangePasswordFields();
    RequestContext.getCurrentInstance().execute("PF('dlgChangePassword').hide()");
}

public void resetChangePasswordFields() {
    this.newPassword = "";
    this.oldPassword = "";
}

public void changePassword(ActionEvent actionEvent){
    try{
        usuarioService.changePassword(this.userAuthenticated.getName(),this.oldPassword, this.newPassword);
        FacesContext.getCurrentInstance().addMessage("messages",
                new FacesMessage(FacesMessage.SEVERITY_INFO,
                        "Password has been changed correctly.", null));
        closeDialogChangePassword();
    } catch (Exception e) {
        FacesContext.getCurrentInstance().addMessage("messagesDialog",
                new FacesMessage(FacesMessage.SEVERITY_ERROR,
                        "Error while changing the password.", null));
    }
}

谢谢。

【问题讨论】:

  • 这就是messages 的工作方式:它是全球性的,适用于所有排队的FacesMessages。如果你想定位你的消息,你必须使用message,在你排队消息时提供 id

标签: jsf primefaces dialog duplicates messages


【解决方案1】:

你应该只更新你想显示的消息:目前你做的 'update="messages messagesDialog"' 应该是 update="messagesDialog"

【讨论】:

【解决方案2】:

您应该尝试在 id="messages" 的 p:messages 中添加 globalOnly="true"。您可以将 globalOnly 删除到对话框中的 p:messages,因为它默认为 false。

要使这项工作发挥作用,请更改

FacesContext.getCurrentInstance().addMessage("messages",
                new FacesMessage(FacesMessage.SEVERITY_INFO,
                        "Password has been changed correctly.", null));

到这里:

FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_INFO,
                        "Password has been changed correctly.", null));

将 null 放在第一个参数(组件的 id)上意味着消息将是全局的,并且将被带有 globalOnly="true" 的 p:messages 捕获。

祝你好运!

【讨论】:

  • 谢谢@ochiboy,但现在我遇到了必填字段错误的问题。它们显示在两个消息组件中。
  • 尝试更改更新属性以仅更新对话框内的组件。您应该在显示对话框时排除更新组件
【解决方案3】:

我发现消除的唯一方法是在对话框中使用多个目标消息并关闭主页上的自动更新(并在我认为我需要逐个组件时添加更新。

在您的对话框中,您可以执行以下操作:

<p:messages id="messagesDialog1" autoUpdate="true" for="oldPassword" />
<p:messages id="messagesDialog2" autoUpdate="true" for="newPassword" />
<p:messages id="messagesDialog3" autoUpdate="true" for="checkNewPassword" />

请注意,您没有“包罗万象”的垃圾箱 - 但它们在用户看来仍然是合适的,因为它们会按照您认为合适的任何优先顺序排列在彼此之下。

在正确的页面上,您仍然可以将消息放入一个包罗万象的信息中,但您必须专门对其进行更新。我喜欢像这样将咆哮者和消息框分开:

<p:growl id="growler" showDetail="true" autoUpdate="false" sticky="false" severity="info,warn" />
<p:messages id="messages" showDetail="true" autoUpdate="false" closable="true" severity="error,fatal" />

然后,当我处理可能会生成错误消息的操作时,我只需在组件中更新它们:

<p:commandButton value="Do something" action=#{something.fun} update="myPanel growler messages" />

最重要的是,我认为您实际上不能做您想做的事情,但您可以让它看起来像是通过以不同的方式完成相同的结果。

希望对你有帮助。

【讨论】:

    【解决方案4】:

    在主页的 p:messages 中使用 redisplay = "false"。但要使其正常工作,您的对话框必须包含在页面的 p:message 之前。

    您可以使用模板定义一个区域来放置所有对话框并使用 ui:define 进行设置。

    模板:

    <ui:insert name="dialogs"/>
    <p:messages autoUpdate="true"  redisplay="false" id="msgs" showDetail="true" showSummary="false" closable="true"/>
    <ui:insert name="content" />
    

    页面:

    <ui:define name="dialogs">
     .... include your dialogs here .....
    </ui:define>
    <ui:define name="content">
     <h:form>
        ...
     </h:form>
    </ui:define>
    

    查看此链接:Don't redisplay messages already shown in dialog in <p:messages autoUpdate="true">

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 2013-05-22
      • 2013-11-11
      • 1970-01-01
      • 2016-04-24
      相关资源
      最近更新 更多