複数項目が関連するvalidationをどうする?
これも正確に言えばS2JSFではなくJSFの使い方、ということになるのか。たとえば画面上に0-100の整数値を入れる項目が2つあって、その合計は100にしなきゃいけない、みたいに複数の項目が関係するチェックをvalidatorで書けるのだろうか?
ためしに
<input type="text" id="ratio1" m:validator="#{registerAction.checkRatio}" m:value="#{userdataDto.ratio1}"> <input type="text" id="ratio2" m:validator="#{registerAction.checkRatio}" m:value="#{userdataDto.ratio2}">
として、registerActionに
public void checkRatio(FacesContext context, UIComponent component, Object value) throws ValidatorException { : }
を定義すれば入力値の検証フェーズで呼びだされる。ratio1のときは
Map map = context.getExternalContext().getRequestParameterMap();
String ratio2 = (String)map.get("form:ratio2");
とすればratio2の入力値は取り出せる。ratio1の入力値は引数valueに設定されているから、あとはこの2つでどうチェックするか、になるわけだ。しかしこの辺のコードがclientId("form:ratio2"など)に依存するのがなんともな...。あとエラーの場合、
FacesMessage mes = new FacesMessage(FacesMessage.SEVERITY_ERROR, "不正な比率", "合計が100になりません"); throw new ValidatorException(mes);
としたらratio1/ratio2の両方にメッセージがでるのか...。まぁこれはこれでいいか。
それならいっそActionクラスでやるほうが楽か?。その時点ではManagedBeanに変換後の値がセットされているし、clientIdを気にする必要はない。でもFacesMessageが使えない。だってアプリケーションのロジック実行のフェーズにいるわけだから、FacesContextにFacesMessageをaddMessageしても無視されてしまう。そうなると自分でどこかにエラーメッセージをセットするしかない。やっぱりDTOか。こういう場合はこうやる、という常套句みたいなコードはないのだろうか?