連載企画「AngularJS徹底解説」の第2回目は、Angularが備えている強力なフォームバリデーションについて解説します。
AngularJS の強力なフォームバリデーション
ご存知の通り、HTML5の仕様にもフォームバリデーションがあり、主要なモダンブラウザであれば既に実装されています。しかし、ブラウザに実装されたバリデーション機能は、まだ実践で使うには使い勝手がよいものとは言えません。もうしばらくは、プラグインやライブラリに頼ったり、または、自身で実装していく必要がありそうです。
今回からデモページを用意してみました。実際に動作していることを確認できます。レイアウト調整をしているため、本稿で掲載するサンプルコードとは多少異なること、ご了承ください。
各input要素のバリデーション
まず、Angularでのバリデーションは、双方向バインディングの特性を活かして、入力と同時にチェックを行うことができます。
例えば以下のように 記述することで、それぞれのテキストボックスに対して必須チェック・文字数チェックを行うことができます。
1 2 3 4 |
<form> <input type="text" ng-model="demoModel" ng-required="true"> <input type="text" ng-model="demoModel2" ng-maxlength="4"> </form> |
まずは、ng-required
とng-maxlength="4"
となっている箇所がバリデーションの定義です。とても簡単に記述することができます。
ただ上記のままでは、チェックがエラーだったとしても、何の変化もおきません。そこで、次はバリデーションチェックエラーの場合にエラーメッセージを出してみます。
先のサンプルに少し書き足して、以下のようなコードにします。
1 2 3 4 5 6 7 |
<form name="demoForm" novalidate> <input type="text" name="input3" ng-model="demoModel" ng-required="true"> <p ng-show="demoForm.input3.$error.required">入力必須です</p> <input type="text" name="input4" ng-model="demoModel2" ng-maxlength="4"> <p ng-show="demoForm.input4.$error.maxlength">4文字までです</p> </form> |
このように、実際バリデーションを利用するにあたっては、form要素にname属性とnovalidate属性を、各input要素にはname属性とng-model属性を定義することがほぼ必須となります。忘れずに定義するようにしましょう。
form要素のnovalidate属性は、ブラウザに実装されているバリデーション機能をOFFにするためです。またform、input共にname属性がついていますが、こうすることでバリデーションチェックの結果を取得することができます。
実行すると以下のようにエラーメッセージが表示されます。
ng-show
にそれぞれ渡している値がバリデーションチェックの結果です。それぞれの”form名”.”input名”.$errorというオブジェクトに保持されます。$error
の中にあるrequired
やmaxlength
はチェックエラーのときに、trueになります。エラーではない場合はfalseとなるため、これを利用してエラーメッセージの表示切り替えを行うことができます。
上記のサンプルでは、必須チェックのみ、文字数チェックのみでしたが、複数のバリデーションを定義することも可能です。
1 2 3 4 5 6 7 8 |
<form name="demoForm2" novalidate> <input type="text" name="input5" ng-model="demoModel5" ng-required="true" ng-minlength="4" ng-pattern="^[0-9]+$"> <p ng-show="demoForm2.input5.$error.required">入力必須です</p> <p ng-show="demoForm2.input5.$error.minlength">4文字以上です</p> <p ng-show="demoForm2.input5.$error.pattern">半角数値のみです</p> <p>demoForm.input5.$error.pattern : {{ demoForm.input4.$error }}</p> </form> |
このように、各エラーに対してをエラーメッセージを細かく設定することができます。逆に、エラーメッセージは1つだけ表示させたい場合もあります。以下のように、$invalid
を利用すると実現することができます。$invalid
は、複数定義したバリデーションのどれかひとつでもエラーであればtrueとなるためです。
1 2 3 4 |
<form name="demoForm2" novalidate> <input type="text" name="input6" ng-model="demoModel6" ng-required="true" ng-minlength="4" ng-pattern="/^[0-9]+$/"> <p ng-show="demoForm2.input6.$invalid">4文字以上の半角数字のみ(必須)</p> </form> |
取得可能なバリデーションチェックの結果を一部挙げると、
- “form名”.”input名”.$error
- 各バリデーションチェックエラーのプロパティを保持
- “form名”.”input名”.$valid
- 該当要素のバリデーションチェックが、エラーでないとき true
- “form名”.”input名”.$invalid
- 該当要素のバリデーションチェックが、エラーであるとき true
- “form名”.”input名”.$dirty
- 該当要素の値が初期値から変更があったとき true
- “form名”.$valid
- フォーム内の全要素に対して1つもバリデーションチェックエラーがないとき true
- “form名”.$invalid
- フォーム内の全要素に対して1つもバリデーションチェックエラーがあるとき true
となります。 この他にも input 要素が初期値かどうか、form が submit されたかどうかのフラグも取得可能です。
バリデーションによるクラスの付与
先述したとおり、Angular ではエラーであるかどうか等、true/falseのフラグを保持しています。これに加えて、各要素にクラスの付与も同時に行っています。
例えば、ng-required
を定義すると、ng-invalid-required
というクラスが要素に付与されます。Google Chrome Developer Tools等から確認することができます。
自動的にクラスが付与されるため、エラー時に「要素のボーダーを赤くする」など、スタイルを設定しておくこともできます。下記は、.ng-invalid(エラーの場合)のみ場合、初期表示時から赤く表示されてしまいます。
それを回避するために、.ng-dirty(初期値から変更があったかどうか)を併せて記述することで、ユーザが入力するまではエラーとして扱わないようにしています。
1 2 3 |
.ng-invalid.ng-dirty{ border: solid 1px red; } |
まとめ
今回はフォームのバリデーション機能について解説しました。自身であれこれ設定しなくても、かなり簡単に実装することがおわかりいただけたかと思います。
もちろん標準の機能では実現できないケースも出てくるでしょう。その際には、AngularUI の UI-Utils を利用することで複雑なバリデーションを実装することも可能です。
AngularUIのようにAngular用のプラグインも豊富に存在しているので、これらについても今後紹介していきたいと思います。
ng-japan 開催!
2015/3/21に日本で初めてとなる Angularのカンファレンス、ng-japanを開催します。 Angularの開発チームメンバーを招き、直接学ぶことができる場です(逐次通訳あります)。
そこで、CodeIQ さんから Angular について出題 させてもらいました。 ぜひ、解いてみてください。
HTML5 Experts.jpでも、特集企画を組んでその内容をお伝えする予定です。
3/5~3/6に開催された本家 ng-conf では、Angular 2などのセッションが話題になっており、これからも注目すべきフレームワークの1つと言えるでしょう。