Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
Angular TIPS

Angular TIPS

入力フォームに検証機能を実装するには?(form/input)

2018年1月10日

Angularにより拡張されている標準的な<form>/<input>要素を使って、検証機能付きの入力フォームを実装する方法を説明する。

  • このエントリーをはてなブックマークに追加

【対応バージョン】 Angular 5以降。v5時点で執筆しました。

 Angularでは、標準的な<form><input>要素を拡張しており、検証機能付きの入力フォームをコーディングレスで実装できます。さっそくですが、具体的な例を示します。

TypeScript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule}    from '@angular/forms';

import { AppComponent } from './app.component';

// 1FormsModuleモジュールを有効化
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule, FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
フォームを有効化するためのモジュール設定(app.module.ts)
TypeScript
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
  <!-- 2入力フォームを準備-->
  <form #myForm="ngForm" (ngSubmit)="show()">
    <div>
      <label for="name">名前:</label><br />
      <!-- 3検証用の属性を付与したinput要素 -->
      <input id="name" name="name" type="text" [(ngModel)]="user.name"
        required minlength="2" maxlength="10" #name="ngModel" />
      <!-- 4検証結果を参照 -->
      <span [hidden]="!name.errors?.required">
        名前は必須です。</span>
      <span [hidden]="!name.errors?.minlength">
        名前は2文字以上で入力してください。</span>
      <span [hidden]="!name.errors?.maxlength">
        名前は10文字以内で入力してください。</span>
    </div>
    <div>
    <label for="age">年齢:</label><br />
    <input id="age" name="age" type="number" [(ngModel)]="user.age"
      required #age="ngModel" />
    <span [hidden]="!age.errors?.required">
      年齢は必須です。</span>
    </div>
    <div>
      <label for="mail">メールアドレス:</label><br />
      <input id="mail" name="mail" type="email" [(ngModel)]="user.mail"
        required email #mail="ngModel" />
      <span [hidden]="!mail.errors?.required">
        メールアドレスは必須です。</span>
      <span [hidden]="!mail.errors?.email">
      メールアドレスは正しい形式で入力してください。</span>
    </div>
    <div>
      <label for="entry">入会希望日:</label><br />
      <input id="entry" name="entry" type="date" [(ngModel)]="user.entry"
        required date #entry="ngModel" />
      <span [hidden]="!entry.errors?.required">
        入会希望日は必須です。</span>
    </div>
    <div>
      <label for="memo">備考:</label><br />
      <textarea id="memo" name="memo" rows="5" cols="30"
       [(ngModel)]="user.memo" maxlength="10" #memo="ngModel">
      </textarea>
      <span [hidden]="!memo.errors?.maxlength">
        備考は10文字以内で入力してください。</span>
    </div>
    <div>
      <!-- 5エラーが存在する場合はボタンを無効化 -->
      <input type="submit" value="申込" 
        [disabled]="myForm.invalid" />  
    </div>
  </form>
`
})
export class AppComponent {
  // フォームのデフォルト値
  user = {
    name: '',
    age: 20,
    mail: 'dummy@example.com',
    entry: '2018-01-01',
    memo: ''
  };

  // サブミット時に入力値をログ出力
  show() {
    console.log('名前:' + this.user.name);
    console.log('年齢:' + this.user.age);
    console.log('メールアドレス:' + this.user.mail);
    console.log('入会希望日:' + this.user.entry);
    console.log('備考:' + this.user.memo);
  }
}
入力値検証の機能を備えたフォームの例(app.component.ts)

 入力値検証の機能を備えたフォームを実装するためのポイントは、以下の通りです。

1FormsModuleモジュールを有効化する

 Angularのフォーム機能を利用するには、FormsModuleを有効にしておく必要があります。これには、app.module.tsファイル(メインモジュール)で、@NgModuleデコレーターのimportsパラメーターにFormsModuleを追加してください。

2<form>要素で利用できる属性

 冒頭でも述べたように、Angularでは標準的な<form>要素を拡張し、フォーム制御のための機能を付与しています。入力値検証を実装するには、最低限、以下の属性を追加します。

No. 属性 概要
a #myForm="ngForm" ngFormディレクティブを変数に登録
b (ngSubmit)="show()" サブミット時の処理を登録
<form>要素で利用する属性

 aは、テンプレート参照変数です。ngFormディレクティブはAngularアプリでフォームを制御するためのディレクティブで、(例えば)入力値と、その検証結果を追跡するのもngFormディレクティブの役割です。ここでは、<form>要素に内部的に適用されたngFormディレクティブを、テンプレート参照変数myFormに代入して、後からフォームの情報――入力要素の状態(検証結果など)にアクセスできるようにしています。

 ngSubmitは、ngFormディレクティブで提供しているsubmitイベントです。bはEvent Bindingの一種で、サブミット時にshowメソッドを呼び出しなさい、という意味です。本稿では、showメソッドで入力値をログ出力しているだけですが、一般的には@angular/httpモジュールなどを利用してサーバーにデータ送信するようなコードを記述することになるはずです。

3<input>要素で利用できる属性

 <form>要素と同じく、<input><textarea>要素もまた、Angularによって機能拡張されており、入力値検証や入力要素そのものの状態管理などに関する機能が付与されています。利用できる主な属性を、以下にまとめておきます。

No. 属性 概要
a name 入力要素の名前
b [(ngModel)] 入力要素をバインドすべきプロパティ
c #xxxx="ngModel" ngModelディレクティブを変数に登録
d required 必須検証(trueで有効)
e maxlength 文字列長検証(値は最大長)
f minlength 文字列長検証(値は最小長)
g pattern 妥当な文字列パターン(値は許可する正規表現)
h email メールアドレス検証(trueで有効)
入力要素で利用する属性

 ngModel(b)は、フォームからの入力値とコンポーネントのプロパティとをひも付けるためのディレクティブです。詳しくは、別稿「TIPS:フォームの入力値をコンポーネントと同期するには?」も併せて参照してください。ngModelディレクティブを利用する場合には、Angularが入力要素を識別できるよう、name属性(a)は必須です。

 cは、<form>要素のときと同じく、テンプレート参照変数です。ngModelディレクティブを代入しておくことで、後から検証結果にアクセスできるようになります。

 d~hは具体的な検証ルールの指定です。requiredemail属性については値としてtrueを指定するだけで有効になりますが、それ以外の属性は検証内容に応じてパラメーターを渡してください。

4検証結果を参照する

 検証結果は「入力要素名.errors?.検証型」という式で検証できます。検証エラーが存在していればtrue、さもなければfalseを返します*1。検証型には、検証ルールに応じてrequiredmaxlengthminlengthpatternemailなどを指定できます。

 4であれば、「[hidden]="!name.errors?.required"」としているので、検証エラーがなければ(=検証に成功していれば)hidden属性をtrueにし、エラーメッセージを非表示します。

5フォーム全体の妥当性を確認する

 フォーム全体の入力値にエラーが存在するかどうかを確認するには、「フォーム名.invalid」とします。この例であれば、サブミットボタンのdisabledプロパティに「myForm.invalid」という式を渡すことで、入力値に不正(invalid)な値がある場合にはボタンを無効化しなさい、という意味になります。これで、全ての入力が正しい場合にだけ、フォームを送信できるようになるわけです。

 ちなみに、フォーム全体で入力値が正しいかをチェックするには、「フォーム名.valid」にアクセスします。同じように、入力要素単位にエラーの有無をチェックするには、「入力要素名.valid」「入力要素名.invalid」とします。

処理対象:ディレクティブ(Directive) カテゴリ:基本
API:NgForm(ngForm)|NgModel(ngModel) カテゴリ:@angular > forms > DIRECTIVE(ディレクティブ)
API:FormsModule カテゴリ:@angular > forms > CLASS(クラス)
API:@NgModuleデコレーター カテゴリ:ADVANCED > Angular Modules

※以下では、本稿の前後を合わせて5回分(第34回~第38回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

Angular TIPS
34. コンポーネントにスタイルシートを適用するには?(styles/StyleUrlsパラメーター)

@Componentデコレーターのstylesパラメーターを利用してコンポーネントにスタイルシートを適用する基本的な方法を解説。また、スタイルを外部ファイルにする方法も説明する。

Angular TIPS
35. 複数のスタイルプロパティをまとめて操作するには?(ngStyle)

ngStyleディレクティブを使って、要素に対して複数のスタイルプロパティをまとめて設定する方法を説明する。

Angular TIPS
36. 【現在、表示中】≫ 入力フォームに検証機能を実装するには?(form/input)

Angularにより拡張されている標準的な<form>/<input>要素を使って、検証機能付きの入力フォームを実装する方法を説明する。

Angular TIPS
37. フォームの状態を監視するには?(ngForm/ngModel)

Angularにより拡張されている標準的な<form>/<input>要素を使って、入力の有無を判定したり、サブミット済みかを判定したりと、その状態を監視する方法を説明する。

Angular TIPS
38. フォームにラジオボタンのリストを設置するには?

選択肢の中から1つを選択する「ラジオボタンのリスト」を設置するための基本的な方法を解説する。

サイトからのお知らせ

Twitterでつぶやこう!