To proste:) Musimy przekazać dodatkowo walidatorowi jako atrybut wartość z pierwszego pola.
Posługując się powyższym przykładem mamy formularz:
W drugim polu formularza podajemy walidator którym jest passwordValidator - jego implementacja zajmiemy się za chwilę. Jako atrybut o nazwie passwordId podajemy z formularza changepassword (to nazwa aktualnego formularza) pole password, czyli to powyżej.
<h:form id="changepassform">
<tr>
<td>Nowe hasło:</td>
<td>
<h:inputSecret id="password" value="#{userRegistrationBean.password}"
required="true" redisplay="false" />
</td>
</tr>
<tr>
<td>Powtórz:</td>
<td>
<h:inputSecret id="confirm" required="true" redisplay="false">
<f:validator validatorId="passwordValidator" />
<f:attribute name="passwordId" value="changepassform:password" />
</h:inputSecret>
</td>
</tr>
</h:form>
Teraz czas na klasę walidującą.
PasswordValidator.java
package com.wookasz.blogspot.jsfmultivalidator;Mam nadzięję, że komentarze w kodzie wystarczą by wyjaśnić sprawę ;-)
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
public class PasswordValidator implements Validator {
public void validate(FacesContext context, UIComponent component, Object value)
throws ValidatorException {
// pobranie atrybutu przekazanego w formularzu
String passwordId = (String)component.getAttributes().get("passwordId");
// odnalezienie odpowiedniego komponentu o tej nazwie
UIInput passwordInput = (UIInput)context.getViewRoot().findComponent(passwordId);
// pobranie wartości z tego komponentu
String password = (String) passwordInput.getValue();
String confirm = (String) value;
// sprawdzanie poprawnosci i ew. zrzucenie wyjątku
if (!password.equals(confirm)) {
throw new ValidatorException(new FacesMessage("Hasła nie są identyczne"));
}
}
}
Pozostaje jeszcze rejestracja walidatora w faces-config.xml:
<validator>
<validator-id>passwordValidator</validator-id>
<validator-class>
com.wookasz.blogspot.jsfmultivalidator.PasswordValidator
</validator-class>
</validator>
Wynik:



8 komentarze:
ostatnio zagryzając się w JSF troszkę - gryźliśmy to w ten sposób, że pierwszy komponent podpinaliśmy pod beana, który był jednocześnie walidatorem w takim formularzu. Ale ta metoda mnie bardziej przekonuje ;-)
Tomasz Bartczak
Racjonalny Developer
fajna rzecz, ostatnio też coś takiego robiłem ale hmmm troche naokoło ;).
Mam tylko jedną sugestie.
Mógłbyś umieścić pierwszy kod w <h:form id="changepassform">
...
</h:form>
Dwie linijki ale ułatwisz początkującym zrozumienie.
Pozdrawiam
Dzięki Dominiku za komentarz;) Poprawka przyjęta i wykonana. Oczywiście miałeś racje, to był błąd z mojej strony, że tego nie umieściłem ;-)
Pozdrawiam !
To może trochę off topic ale:
Jakie znacie sensowen zastosowania backing beanów, (czyli takich, których się używa do podstawiania całych UIComponentów)? Każdą tak naprawdę własność UIComponentu można wyliczyć przez expression i nie ma potrzeby obsługiwać programowo całego UIComponent - ja widzę jedno - używanie różnych UIComponentów w tym samym miejscu.
Tomasz Bartczak
Racjonalny Developer
Jakiś czas temu bawiłem się JSF, ale...
A ja rozdzieliłbym kontrolę na dwa typy - kontrola pojedynczego pola vs wielu pol w formularrzu - i obsługiwał je oddzielnie. Walidator pojedynczego pola wykonuje się przez validator, a całego formularza po jego zatwierdzeniu i walidacji w ziarnie zarządzanym (ang. backing bean). Wartości formularza przypisywane są do pojedynczego ziarna, albo zrobiłbym zależności między dwoma i wykonanie metody to wykonanie walidacji "biznesowej", np. dwa pola muszą mieć tą samą wartość, jak w przypadku pola z hasłem.
Jacek Laskowski
Notatnik Projektanta Java EE
Mnie się osobiście takie rozwiązanie Jacku nie podoba. To dawanie zadań komponentom które powinny mieć inne. Walidacją powinny zajmować się walidatory ;-)
To kwestia nazewnictwa czy funkcjonalności? Do sprawdzenia dokumentu używam kontroli ortografii a później jeszcze dokument trafia do recenzenta. To dwa różne typy kontroli - techniczna i merytoryczna (biznesowa). Tak ja to widzę. Poza tym z JSF dawno się pożegnałem, a ostatnia euforia Grailsem w ogóle wyczyściła mi pamięć o nim.
Jacek
ok, ten punkt widzenia do mnie bardziej przemawia ;-)
A co do Grails to dobrze, bo przez to sporo ciekawych rzeczy się u Ciebie w notatniku pojawia ^^
Prześlij komentarz