HTML5Experts.jp

AngularJSの強力なフォームバリデーションを活用しよう

連載企画「AngularJS徹底解説」の第2回目は、Angularが備えている強力なフォームバリデーションについて解説します。

AngularJS の強力なフォームバリデーション

ご存知の通り、HTML5の仕様にもフォームバリデーションがあり、主要なモダンブラウザであれば既に実装されています。しかし、ブラウザに実装されたバリデーション機能は、まだ実践で使うには使い勝手がよいものとは言えません。もうしばらくは、プラグインやライブラリに頼ったり、または、自身で実装していく必要がありそうです。

今回からデモページを用意してみました。実際に動作していることを確認できます。レイアウト調整をしているため、本稿で掲載するサンプルコードとは多少異なること、ご了承ください。

各input要素のバリデーション

まず、Angularでのバリデーションは、双方向バインディングの特性を活かして、入力と同時にチェックを行うことができます。

例えば以下のように 記述することで、それぞれのテキストボックスに対して必須チェック・文字数チェックを行うことができます。

<form>
  <input type="text" ng-model="demoModel" ng-required="true">
  <input type="text" ng-model="demoModel2" ng-maxlength="4">
</form>

まずは、ng-requiredng-maxlength="4"となっている箇所がバリデーションの定義です。とても簡単に記述することができます。

ただ上記のままでは、チェックがエラーだったとしても、何の変化もおきません。そこで、次はバリデーションチェックエラーの場合にエラーメッセージを出してみます。

先のサンプルに少し書き足して、以下のようなコードにします。

<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の中にあるrequiredmaxlengthはチェックエラーのときに、trueになります。エラーではない場合はfalseとなるため、これを利用してエラーメッセージの表示切り替えを行うことができます。

上記のサンプルでは、必須チェックのみ、文字数チェックのみでしたが、複数のバリデーションを定義することも可能です。

<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となるためです。

<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>

取得可能なバリデーションチェックの結果を一部挙げると、

となります。 この他にも input 要素が初期値かどうか、form が submit されたかどうかのフラグも取得可能です。

バリデーションによるクラスの付与

先述したとおり、Angular ではエラーであるかどうか等、true/falseのフラグを保持しています。これに加えて、各要素にクラスの付与も同時に行っています。 例えば、ng-requiredを定義すると、ng-invalid-requiredというクラスが要素に付与されます。Google Chrome Developer Tools等から確認することができます。

自動的にクラスが付与されるため、エラー時に「要素のボーダーを赤くする」など、スタイルを設定しておくこともできます。下記は、.ng-invalid(エラーの場合)のみ場合、初期表示時から赤く表示されてしまいます。

それを回避するために、.ng-dirty(初期値から変更があったかどうか)を併せて記述することで、ユーザが入力するまではエラーとして扱わないようにしています。

.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つと言えるでしょう。