Primefaces在对话框和页面

时间:2015-06-11 09:06:10

标签: jsf primefaces dialog duplicates messages

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

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

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

要更改密码,用户必须提供当前密码和新密码。

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

我怎么能得到它?

Detail image

我试图在控制器内部使用一个字段,当对话框打开时它是真的,当它关闭时是假的。页面消息("消息")具有该字段的呈现属性。但它没有成功。

这是我使用的代码:

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>

UserController中:

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));
    }
}

感谢。

4 个答案:

答案 0 :(得分:0)

您应该只更新要显示的消息:目前您执行&#39;更新=&#34;消息消息对话&#34;&#39;应该更新=&#34; messagesDialog&#34;

答案 1 :(得分:0)

你应该尝试添加一个globalOnly =&#34; true&#34;到p:带有id =&#34;消息&#34;的消息。您可以将globalOnly删除到对话框中的p:消息,因为它无论如何都默认为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));

在第一个参数(组件的id)上放置null意味着该消息将是全局的,并且将被p:消息捕获,其中globalOnly =&#34; true&#34;。

祝你好运!

答案 2 :(得分:0)

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

在你的对话框中你会做这样的事情:

<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" />

最重要的是,我不认为你实际上可以做你想要做的事情,但是你可以通过以不同的方式实现相同的结果来实现它。

我希望有所帮助。

答案 3 :(得分:0)

在主页面的p:消息中使用redisplay =“false”。但要实现此功能,必须在页面的p:消息之前包含对话框。

您可以使用模板定义区域以放置所有对话框并使用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">