I'm working with Primefaces 5.2, JSF 2.2.10, and Tomcat 7.0.
I have a user page, with its personal data, and one button that allows that user to change its password through a dialog.
In the page, I'm using a p:messages component (with id="messages"), and other p:messages component (with id="messagesDialog") inside the dialog.
To change its password, the user has to introduce its current password, and the new one.
When the dialog fields fail their validation I'd like to show the errors inside the dialog messages component ("messagesDialog"), but not in the page messages component ("messages").
How could I get it?
I've tried to use a field inside the controller that it's true when the dialog is opened, and false when it's closed. The page messages ("messages") has the rendered attribute with that field. But it didn't work out.
This is the code I'm using:
XHTML page:
<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));
}
}
Thanks.
You should try adding a globalOnly="true" to the p:messages with id="messages". You can remove the globalOnly to the p:messages inside your dialog because it defaults to false anyway.
To make this work, change
to this:
Placing null on the first parameter (the id of the component) means that the message will be global and will be caught by p:messages with globalOnly="true".
Good Luck!