AngularJS TIPS
入力フォームに検証機能を実装するには?(form/input)
標準的な<input>要素を拡張して入力フォームに検証機能を付ける方法を説明する。
AngularJSでは、標準的な<input>
要素を拡張しており、検証機能付きの入力フォームをコーディングレスで実装できます。さっそくですが、具体的な例を示します。
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8" />
<title>AngularJS TIPS</title>
<body ng-controller="MyController">
<!--1フォームを用意-->
<form name="myForm" ng-submit="onsubmit()" novalidate>
<div>
<label for="name">名前:</label><br />
<!--2検証ルールを指定-->
<input id="name" name="name" type="text" ng-model="user.name"
required ng-minlength="2" ng-maxlength="10" />
<!--3検証エラーメッセージを表示-->
<span ng-show="myForm.name.$error.required">
名前は必須です。</span>
<span ng-show="myForm.name.$error.minlength">
名前は2文字以上で入力してください。</span>
<span ng-show="myForm.name.$error.maxlength">
名前は10文字以内で入力してください。</span>
</div>
<div>
<label for="age">年齢:</label><br />
<input id="age" name="age" type="number" ng-model="user.age"
required min="20" max="60" />
<span ng-show="myForm.age.$error.required">
年齢は必須です。</span>
<span ng-show="myForm.age.$error.min">
年齢は20以上で入力してください。</span>
<span ng-show="myForm.age.$error.max">
年齢は60以下で入力してください。</span>
</div>
<div>
<label for="mail">メールアドレス:</label><br />
<input id="mail" name="mail" type="email" ng-model="user.mail"
required />
<span ng-show="myForm.mail.$error.required">
メールアドレスは必須です。</span>
<span ng-show="myForm.mail.$error.email">
メールアドレスは正しい形式で入力してください。</span>
</div>
<div>
<label for="entry">入会希望日:</label><br />
<input id="entry" name="entry" type="date" ng-model="user.entry"
required />
<span ng-show="myForm.entry.$error.required">
入会希望日は必須です。</span>
<span ng-show="myForm.entry.$error.date">
入会希望日は正しい形式で入力してください。</span>
</div>
<label for="memo">備考:</label><br />
<textarea id="memo" name="memo" rows="5" cols="30"
ng-model="user.memo" ng-maxlength="10"></textarea>
<span ng-show="myForm.memo.$error.maxlength">
備考は10文字以内で入力してください。</span>
</div>
<div>
<!--4フォーム全体の検証が成功していればクリック可能に-->
<input type="submit" value="申込"
ng-disabled="myForm.$invalid" />
</div>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<script>
angular.module('myApp', [])
.controller('MyController', ['$scope', function($scope) {
$scope.onsubmit = function() {
console.log('名前:' + $scope.user.name);
console.log('年齢:' + $scope.user.age);
console.log('メールアドレス:' + $scope.user.mail);
console.log('入会希望日:' + $scope.user.entry);
console.log('備考:' + $scope.user.memo);
};
}]);
</script>
</body>
</html>
|
ポイントとなるのは、以下の点です。
1入力フォームを準備する
標準的なHTMLと同じく、フォームは<form>
要素で定義します。ただし、以下の点に注意してください。
- あとから検証結果を参照するために
name
属性(=フォームの名前)は必須 - HTML5の検証機能とバッティングしないよう、
novalidate
属性(=HTML5検証の無効化)は必須 - サブミット時の挙動は
ng-submit
属性で定義
ng-submit
属性は、<form>
要素でaction
属性(=ポスト先)が指定されない場合、サーバーへのデータ送信をキャンセルします。AngularJSアプリの場合、基本的にはイベントリスナーの中で$http
/$resource
サービスによってデータを送信しているはずなので*1、いちいちキャンセルしなくてよいのは便利です。
- *1 サンプルでは、単にログを出力するにとどめています。
2検証ルールを指定する
<input>
要素では、それぞれtype
属性に応じて、以下のような検証属性が用意されています。
type属性 | 属性 | 概要 |
---|---|---|
共通 | required | 必須であるか |
ng-required | 必須であるか(Angular式で指定) | |
number/date/time/datetime-local/month/week | min | 最小値 |
max | 最大値 | |
text/number/email/url/<textarea> | ng-minlength | 最小文字数 |
ng-maxlength | 最大文字数 | |
ng-pattern | 正規表現パターンに合致するか |
検証機能を利用する場合には、あとでエラー情報を参照するために、name
属性は必須です。
min
/max
属性に渡す日付/時刻値は、ISO-8601で規定された形式でなければなりません。date
(日付)であれば2015-08-05ですし、time
(時刻)であれば19:45:31、日付時刻(datetime-local
)であれば2015-08-05T19:45:31です。
3検証エラーメッセージを表示する
検証エラー情報はフォーム名.要素名.$error.検証名
で参照できます。例えばmyForm.name.$error.required
で「myForm
フォームのname
欄(名前)が空か(=必須検証がエラーであるか)」という意味になります。
利用できる検証名は、以下の通りです。
検証名 | 概要 |
---|---|
required | 必須検証 |
max | 最大値検証 |
min | 最小値検証 |
maxlength | 文字列の最大長検証 |
minlength | 文字列の最小長検証 |
pattern | 正規表現検証 |
number | 数値検証 |
url | URLのフォーマット検証 |
メールアドレスのフォーマット検証 | |
date | 日付のフォーマット検証 |
datetimelocal | 日付/時刻のフォーマット検証 |
time | 時刻のフォーマット検証 |
week | 週のフォーマット検証 |
month | 月のフォーマット検証 |
ここでは、$error変数をng-show属性に渡すことで、検証エラーがあった場合にだけ対応するメッセージを表示します。AngularJS 1.3以降では、エラーメッセージをより効率的に管理するためのng-messages/ng-message属性もありますが、こちらについては別稿「TIPS:式の真偽に応じて表示を切り替えるには?」で解説の予定です。
4フォーム全体の検証の成否を判定する
個々の検証項目ではなく、フォーム全体で何らかの検証エラーが発生しているかを判定するには、フォーム名.$invalid
を参照します。ここでは、この値をサブミットボタンのng-disabled
属性にセットすることで、検証エラーがある場合(=$invalid
プロパティがtrueである場合)にサブミットボタンを無効にしています。これによって、検証を全て通過した場合にだけ、サブミットできるボタンを作成できます。
ちなみに、その他にも、フォームの状態を監視するために、以下のようなプロパティが用意されています。
構文 | 概要 |
---|---|
フォーム名.$valid | フォーム配下の入力値が全て正しいか |
フォーム名.$pristine | フォームは変更されていないか |
フォーム名.$dirty | フォームが変更されているか |
フォーム名.要素名.$valid | 入力項目が正しい値であるか |
フォーム名.要素名.$invalid | 入力項目が不正な値であるか |
処理対象:ディレクティブ(Directive) カテゴリ:基本
API:input|ngSubmit(ng-submit)|ngShow(ng-show) カテゴリ:ng(コアモジュール) > directive(ディレクティブ)
※以下では、本稿の前後を合わせて5回分(第12回~第16回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
13. URL/メールアドレスからハイパーリンクを生成するには?(linky)
URL/メールアドレスの文字列データをアンカータグによるリンクに整形できるlinkyフィルターの基本的な使い方を説明する。
15. 式の真偽に応じて表示を切り替えるには?(ng-messages/ng-message)
条件式の値に応じてメッセージの表示/非表示を切り替えるために(例えばエラー時にメッセージ表示するなど)、ng-messages/ng-message属性を使用する方法を解説する。
16. 別ファイルやJavaScriptでメッセージを管理するには?(ng-message-include/ng-message-exp)
ng-messages属性で使用するメッセージを、ページ内でテンプレート化したり、外部ファイル化したりして効率的に管理する方法を説明する。