4. Validate処理を構築する前に検討すべきこと
さて、ここまで見てきた実装の分かりにくさをカバーしつつ、Eclipseプロブレムビューのようなユーザービリティを実現しようと思うのですが、処理を構築する前に検討すべきことがあります。大きく分けて3つです。
- 入力部品にValidateをセットする方法・手順。
- Validateを実行するタイミング
- エラーを解除するためのタイミング
これらのことを事前に検討しておくことは、ユーザーの操作感を統一するという意味でも大変重要です。
一つずつもう少し細かく見ていきます。
1. 入力部品にValidateをセットする方法・手順
前述のように、通常であれば、いちいちValidatorオブジェクトを生成して、それに各種プロパティをセットする必要があります。しかし、これでは動的にValidate処理を変えたい場合や、設計書からコーディングへの自動反映をする場合など、外部ロジックから挙動を変えたい場合を想定すると、非常に不利になります。
そこでここでは、<TextInput required="true"/>という具合に、該当部品のプロパティを変更するだけでValidateをセットできるようにする、ということにしたいと思います。
2. Validateを実行するタイミング
通常であれば、Validatorは対象の部品がValueCommitというイベントを発行した場合にValidate処理を実行します。これはつまり、値を入力し終わって、別の項目への入力を始めるタイミングです。
個人的な話で恐縮ですが、ユーザーの立場に立ったとき、私はこのタイミングが嫌いです。これだと、該当部品にカーソルをあててフォーカスインしたあと、他の部品に移っただけでもエラーになります。TABキーを押しすぎて、ちょっと行き過ぎてしまうこともありますし、画面上を適当にクリックしている時もあるのに、いちいちエラーだと怒られて、だいぶやかましく感じます。
ですので、Validate処理を行うのは、入力を一通り終えて、画面上での最後の操作、つまり「実行」や「送信」「次へ」といったボタンを押下したタイミングにしたいと思います。なお、筆者の経験上、ユーザーさんも、やはり最後のタイミングでエラー通知してもらう方を選ぶ傾向にあります。
3. エラーを解除するタイミング
入力/形式エラーとなり、ユーザーがそれを解決した後にエラー表示を解除するタイミングを決める必要があります。前述の(2)では、Validate処理を行うのは画面の最後、としましたが、解除するタイミングはそうはいきません。エラーを解決させたのに、解除されないのは大きなフラストレーションを生みます。解除はValueCommitのタイミングとしましょう。なお、最初のチェック処理も解除処理も、Validate処理を稼働させていることには変わりません。同じ処理を稼働させるタイミングをうまく切り分けてコントロールする必要があり、工夫が必要です。
5. フレームワーク機能構成の概要
本稿で紹介するフレームワーク機能の構成は、次のような図で表せます。

図中の処理について簡単に説明します。
- 入力部品が内部的に
Validateオブジェクトを生成し、シングルトンのValidateManagerクラスが持つ、validatorsListに格納する。 - 入力部品はvalidateのトリガーとなるイベントに対するリスナーを、シングルトンの
ValidateManagerクラスにセットし、イベント発行を契機に、validatorsListに格納されたValidatorを稼動させる。 - invalidエラーが発生する都度、シングルトンの
ValidateManagerクラスが持つerrorListに格納。このerrorListは画面上のDatagridにバインディングされている。 - トリガーが一度稼働すると、そこからは各Validaterが対象部品のValueCommitを契機に稼働するようになる。
次に、この機能を実装した簡単なコードを見てみましょう。
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:contorls="teppeistudio.validatorfooter.contorls.*"
layout="vertical" >
<mx:Script>
<![CDATA[
import teppeistudio.validatorfooter.managers.ValidatorManger;
]]>
</mx:Script>
<mx:Form>
<mx:FormItem label="入力部品">
<contorls:MyTextInput id="txi"
validatorRequired="true"
validateTrigger="{btn}"
validateTriggerEventType="{MouseEvent.CLICK}"/>
</mx:FormItem>
<mx:FormItem>
<mx:Button id="btn" label="submit"/>
</mx:FormItem>
</mx:Form>
<mx:DataGrid id="errorFooter"
width="100%" height="100"
dataProvider="{ValidatorManger.getInstance().errorList}"
itemClick="{ValidatorManger.getInstance().setFocusByListSelect(event)}" >
<mx:columns>
<mx:DataGridColumn dataField="fieldName" headerText="項目名" width="200"/>
<mx:DataGridColumn dataField="errorMessage" headerText="メッセージ" />
</mx:columns>
</mx:DataGrid>
</mx:Application>
Validateオブジェクトがなくなり、Validateに関して使うのは、ValidateMangerと各入力部品だということが分かると思います。
