ng-submit
フォームの送信には、submitボタンのng-clickを使う方法と、ng-submitを使う方法がある。ng-submitの利点は、submitボタンのクリック外に、テキストフィールドに入力後のreturnキーを押した場合にも発火すること。
FormController
formに名前を付けると、AngularJSは自動的にFormControllerを作成する。FormControllerにはフォームの名前でアクセスできる。
<form name="myForm">
<input type="text"
ng-model="username"
required
ng-minlength="4">
<input type="submit"
value="Submit"
ng-disabled="myForm.$invalid">
</form>
上のサンプルコードの場合、myForm.$invalid でmyFormのFormControllerの$invalidプロパティにアクセスしている。FormControllerには以下のプロパティがある。
$invalid: フォームのバリデーションが1つでも通らない場合にtrue
$valid: フォームの全てのバリデーションが通る場合にtrue
$pristine: ユーザの入力がまだ無い場合にtrue(pristineは「きれいな」という意味)
$dirty: ユーザ入力が行われた場合にtrue
$error: それぞれのフィールドにおけるエラーの詳細を保持する
エラーメッセージの表示
それぞれのフィールドに応じたエラーを取得するには、フィールドのname属性を設定する必要がある。以下では、name=”uname”のinputフィールドを作成している。
<form ng-submit="ctrl.submit()" name="myForm">
<input type="text"
name="uname"
ng-model="ctrl.user.username"
required
ng-minlength="4">
<span ng-show="myForm.uname.$error.required">
This is a required field
</span>
<span ng-show="myForm.uname.$error.minlength">
Minimum length required is 4
</span>
<span ng-show="myForm.uname.$invalid">
This field is invalid
</span>
<input type="submit"
value="Submit"
ng-disabled="myForm.$invalid">
</form>
{フォーム名}.{フィールド名}.$error.{バリデーション名}で、各バリデーションを通過しているか確認できる。
状態に応じたフォームのスタイリング
AngularJSは、フォームの状態に応じて以下のCSSクラスを追加する。
- $invalid: ng-invalid
- $valid: ng-valid
- $pristine: ng-pristine
- $dirty: ng-dirty
この他にもinputフィールドの状態に応じてCSSクラスが自動的に追加される(例えば、requiredが設定されているフィールドにはng-valid-requiredまたはng-invalid-requiredが追加される)。
ngModelOptions
AngularJS 1.3以降では、以下のオプションによってng-modelの挙動を制御できる。
updateOn
ng-modelの更新が行われるイベント名を指定する。
defaultならinputフィールドに固有のイベント、blurとすればinputフィールドからフォーカスが外れた時に更新が行われる。
複数のイベントの組み合わせも可能。
debounce
ユーザーが入力をやめてからモデルの値を更新するまでの待ち時間をミリ秒単位で指定する。
イベント毎に指定する場合は{“default”: 500, “blur”: 0}のようなオブジェクトを設定する。
allowInvalid
デフォルトではfalseになっており、AngularJSは、バリデーションに失敗している間はモデルに値を設定しない。allowInvalidをtrueにすると、バリデーションが失敗していてもモデルに値を設定する。
getterSetter
trueを設定すると、ng-modelの式を変数ではなくgetter/setterとして扱えるようになる。
ng-formによるフォームのネスト
通常のHTMLのformはネストすることができないが、AngularJSのng-formディレクティブはネストすることができる。
以下がネストしたフォームの例。profileをグループ化している。
<form novalidate name="myForm">
<input type="text" name="uname" ng-model="ctrl.user.username">
<ng-form name="profile">
<input type="text" name="firstName" ng-model="ctrl.user.profile.firstName">
<input type="text" name="lastName" ng-model="ctrl.user.profile.lastName">
</ng-form>
<input type="submit">
</form>