Требование в этом случае следующее:
- Диалоговое окно открывается при нажатии на кнопку «Изменить пароль».
- Диалоговое окно содержит два компонента ввода (Пароль и Повторите пароль) и несколько кнопок (Отмена, Сброс и Отправить).
Компонент повторного ввода пароля не имеет проверки.
Компонент ввода пароля проверяется только тогда, когда диалоговое окно открыто.
Чтобы выполнить пункт 4, я решил отображать пароль только при открытом диалоговом окне; иначе не визуализируется.
<p:commandButton
id="changePasswordButton"
value="Change Password"
actionListener="#{changePasswordBean.renderNewPasswordComponent()}"
update="newPassword"
oncomplete="PF('changePasswordDialog').show();"/>
<p:dialog id="changePasswordDialogId" widgetVar="changePasswordDialog">
<p:password
id="newPassword"
value="#{changePasswordBean.newPassword}"
rendered="#{changePasswordBean.getRenderNewPasswordComponent()}"
match="repeatPassword">
<f:validator validatorId="foo.bar.PasswordValidator"/>
</p:password>
<p:password id="repeatPassword"/>
<p:commandButton
value="Submit"
immediate="false"
validateClient="true"
process="@this newPassword repeatPassword"
actionListener="#{changePasswordBean.hideNewPasswordComponent()}"
update="newPassword repeatPassword"
oncomplete="if(!args.validationFailed) { PF('changePasswordDialog').hide(); }"/>
<p:commandButton type="reset" value="Reset"/>
<p:commandButton
value="Cancel"
immediate="true"
validateClient="false"
actionListener="#{changePasswordBean.hideNewPasswordComponent()}"
update="newPassword repeatPassword"
oncomplete="PF('changePasswordDialog').hide();"/>
</p:dialog>
Поддерживающий компонент:
@ViewScoped
public class ChangePasswordBean {
private String newPassword;
private boolean renderNewPasswordComponent = false;
public boolean getRenderNewPasswordComponent() {
return renderNewPasswordComponent;
}
public void renderNewPasswordComponent() {
renderNewPasswordComponent = true;
}
public void hideNewPasswordComponent() {
renderNewPasswordComponent = false;
}
}
К сожалению, это не работает. Поле нового пароля не отображается должным образом при открытии диалогового окна.
Однако, если я обновлю окно браузера и нажму кнопку «Изменить пароль» во второй раз, поле нового пароля отобразится правильно.
Если я нажму кнопку «Отмена» или «Отправить», диалоговое окно закроется. После этого, если я нажму кнопку «Изменить пароль» еще раз, поле нового пароля снова отобразится правильно. Это продолжается взад и вперед до бесконечности и является желаемым поведением.
Однако, если я нажимаю кнопку «Отмена» или «Отправить» (которая закрывает диалоговое окно), обновляю окно браузера и нажимаю кнопку «Изменить пароль», поле нового пароля отображается неправильно.
Таким образом, кажется, что кнопка «Изменить пароль», кнопка «Отправить» и кнопка «Отмена» не обновляют компонент ввода нового пароля. После прочтения порядка выполнения событий при нажатии PrimeFaces p:commandButton показалось, что у меня все настроено правильно. ActionListener выполняется перед обновлением, которое выполняется до завершения. Установка точек останова на ChangePasswordBean#renderNewPasswordComponent()
и ChangePasswordBean#hideNewPasswordComponent()
показывает, что прослушиватели действий выполняются. Установка точки останова на ChangePasswordBean#getRenderNewPasswordComponent()
показывает, что компонент пароля проверяет, должен ли он отображаться. Но этот метод выполняется как до, так и после запуска actionListener.
Вот последовательность вызовов метода actionListener при нажатии кнопки «Изменить пароль»:
- ChangePasswordBean#getRenderNewPasswordComponent() (возвращает false)
- ChangePasswordBean#renderNewPasswordComponent() (устанавливает значение true)
- ChangePasswordBean#getRenderNewPasswordComponent() (возвращает true)
- ChangePasswordBean#getRenderNewPasswordComponent() (возвращает true)
- ChangePasswordBean#getRenderNewPasswordComponent() (возвращает true)
- ChangePasswordBean#getRenderNewPasswordComponent() (возвращает true)
Не уверен, почему компонент пароля проверяет, должен ли он отображаться (№ 1) до того, как actionListener установит для рендеринга значение true (№ 2). Но похоже, что компонент пароля снова проверяет, должен ли он отображаться четыре раза после выполнения actionListener (например, в № 3, № 4, № 5 и № 6). Похоже ли это на правильный порядок выполнения?
Если порядок выполнения правильный, то, возможно, обновление происходит не в нужное время в последовательности или вообще не происходит. Как мне проверить на стороне сервера, выполняется ли обновление?
Или, возможно, есть что-то совершенно другое, что я упускаю из виду или неправильно понимаю?