Employee Management2-(3)
employeeSearch.htmlの残りも見ていく。といってもEmployeeName, Job, Managerはスルー。その次のHireDate, Salaryは最初見たときちょっと微妙な感じがした。
<tr> <td class="label">HireDate</td> <td><input id="fromHiredate" type="text" m:value="#{employeeSearchDto.fromHiredate}"/> <span m:inject="h:message" m:for="fromHiredate" m:class="error"/>~ <input id="toHiredate" type="text" m:value="#{employeeSearchDto.toHiredate}"/> <span m:inject="h:message" m:for="toHiredate" m:class="error"/> </td> </tr> <tr> <td class="label">Salary</td> <td><input id="fromSal" type="text" m:value="#{employeeSearchDto.fromSal}" class="right"/> <span m:inject="h:message" m:for="fromSal" m:class="error"/>~ <input id="toSal" type="text" m:value="#{employeeSearchDto.toSal}" class="right"/> <span m:inject="h:message" m:for="toSal" m:class="error"/> </td> </tr>
validatorが無いのにmessageタグが用意されている。試しにHireDate/Salaryに"abc"とか入力して[search]をクリックすると
- "toHiredate": 正しい日付/時間を入力して下さい.
- "toSal": 正しい値を入力して下さい.
という具合にメッセージが表示される。validatorが無いのになんでチェックロジックが動くの?と思ったら、これはJSFの標準機能なのね(汗。JSFではmanaged-beanのプロパティが
- int型などのプリミティブ型
- BigDecimal, BigInteger, Date, Number型
の場合String型と相互に変換する標準のコンバータを適用してくれる(だから自分でやらなくてよい)。employeeSearchDto(examples.jsf.dto.EmployeeSearchDto)を見るとfromHiredate/toHiredateはjava.util.Dateで、fromSal/toSalはjava.lang.BigDecimal。だから標準コンバータでStringからそれぞれの型へ変換されるんだけど、この「標準コンバータの呼び出し」でもvalidationが行われる。つまり入力したデータ(String)がDate/BigDecimal型のデータとして解釈できなければエラーメッセージがセットされる。ちなみに上記プロパティをStringに変え、setter/getterもそれにあわせて変更すると、何を入れてももエラーにならない。なるほど。
しかしfaces-config.xmlには次のような定義がある。
<converter> <converter-for-class>java.util.Date</converter-for-class> <converter-class>org.seasar.jsf.convert.S2DateTimeConverter</converter-class> </converter>
何となく想像できたけど、調べてみるとやっぱりカスタムコンバータの指定。つまりこのアプリケーションでは「java.util.Date型に対してはorg.seasar.jsf.convert.S2DateTimeConverterというカスタムコンバータを使ってね」ということ。これが標準のDate型コンバータとどう違うかまでは調べていない。
話をvalidatorに戻すと、エラーメッセージの内容とか装飾を変える方法(これはCSSかな)も調べておく必要あるな。あと複数のvalidatorをグループ化して扱う方法(validators?)って無いのかな。さらにvalidator以外の任意の場所で、messageタグに対してメッセージをセットする方法も調査・要だな。だって項目間の関連チェックみたいなものは自分で書くんだろうしね。
そしてDepartment。ここに選択肢がセットされる仕組みはすでに見た。「賢い!」って思ったのが、managed-beanのプロパティ(この場合employeeSearchDto.deptno)に対応するアイテムが選択された状態で再表示されること。たとえばRESEARCHを選択した状態で、わざとSalaryへ非数値を入力して[search]をクリックするとエラーメッセージが表示されるんだけど、そのときDepartmentはRESEARCHになっている。わざわざ自分で"selected"をセットするようなコードを書かなくていいんだね。
<tr> <td class="label">Department</td> <td><select id="deptno" m:value="#{employeeSearchDto.deptno}" m:items="#{departmentDtoList}" m:itemValue="deptno" m:itemLabel="dname" m:nullLabel="Please select"> <option value="">Please select</option> <option value="10">ACCOUNTING</option> <option value="20">RESEARCH</option> <option value="30">SALES</option> <option value="40">OPERATIONS</option> </select> </td> <td><span m:inject="h:message" m:for="deptno" m:class="error"/></td> </tr>
最後は[create][search]ボタン。ここはaction属性でメソッドを呼び出している(MethodBinding)。onclickはプレビュー用だね。
<input type="button" value="create" m:action="#{employeeSearchAction.goEditForCreate}" onclick="location.href='employeeEdit.html'"/> <input type="button" value="search" m:action="#{employeeSearchAction.checkSearchCount}" onclick="location.href='employeeList.html'"/>
ということで、次はこのメソッドの中身だ。