【Angular】ReactiveFormsModulesを使ったフォーム作成とバリデーションチェック

2021年12月11日

前回までは、FormsModuleを使うことによるフォームについて紹介していましたが、
今回はReactiveFormsModuleを使ったフォームを作っていこうと思います。
何が違うかというと、正直ほぼ同じことが出来ます。あまり違いはありません。
後、ReactiveFormsModulesに搭載されているバリデーションチェック機能についても紹介していきます。

スポンサーリンク

app.module.tsでモジュールをインポートする

まずReactiveFormsModulesを利用できるようにモジュールをインポートする必要があります。

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

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

@NgModule({
  declarations: [
    AppComponent,
    RingoComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [RingoComponent]
})
export class AppModule { }

FormsModuleと同様に @angular/forms からインポートしてきて、
NgModuleデコレータのimportsにReactiveFormsModulesを追加しましょう。

コンポーネントでReactiveFormsModulesを使う

これでReactiveFormsModulesを使う準備は整ったので、実際にコンポーネントで使っていきましょう。
例えばHTMLをこのように修正したとします。

<p>ringo works!</p>
<p>入力された項目を表示:</p>
<p> 林檎:{{inputText1}}</p>
<p> 梨 :{{inputText2}}</p>
<p> 蜜柑:{{inputText3}}</p>

<form [formGroup]="Group" (ngSubmit)="onClick()">
    <p>林檎</p>
    <input type="text" formControlName="ringo">
    <p>梨</p>
    <input type="text" formControlName="nashi">
    <p>蜜柑</p>
    <input type="text" formControlName="mikan"><br>
    <input type="submit" value="click">
</form>

各入力フィールドにformControlNameを設定していますね。
そしてformタグにformGroupを定義しています。
後述するtsファイルの方を見ていただくとよく分かるのですが、このコンポーネントには「Group」というFormGroupがあり、その中に「ringo」「nashi」「mikan」というFormControlがあります。
ここの入力フィールドでは、それぞれで3つのFormControlに入力していることになります。

次にtsファイルについてですが、

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-ringo',
  templateUrl: './ringo.component.html',
  styleUrls: ['./ringo.component.css']
})
export class RingoComponent implements OnInit {
  inputText1:String;
  inputText2:String;
  inputText3:String;
  Group:FormGroup;

  constructor() {
    this.inputText1 = "";
    this.inputText2 = "";
    this.inputText3 = "";
    this.Group = new FormGroup({
      ringo: new FormControl(''),
      nashi: new FormControl(''),
      mikan: new FormControl('')
    });
  }

  ngOnInit(): void {
  }

  onClick(){
    this.inputText1 = this.Group.get('ringo')?.value;
    this.inputText2 = this.Group.get('nashi')?.value;
    this.inputText3 = this.Group.get('mikan')?.value;
  }

}

上から見ていきましょう。
「import { FormControl, FormGroup } from '@angular/forms’;」でFormControl、FormGroupをインポートしています。
「Group:FormGroup;」でこのクラスのプロパティとしてFormGroupを用意しており、さらにコンストラクタの中でFormGroup内にFormControlを3つ設定しています。
FormControlの設定において「ringo: new FormControl(")」としていますが、ここの引数として設定している値が、このFormControlの初期値となります。
そして、onClick()に定義されている通り、入力ボタン押下によって、入力フィールドの入力値がコンポーネントのプロパティinputText1、2、3に設定され、
HTMLファイルの上部にあるinputText1、2、3を出力される部分に反映されるということになります。

実際に画面に表示したものを見てみましょう。

まず初期表示において、このように画面が描画されます。
次に各入力フィールドに適当な文字を入れてボタンを押下すると、

このように入力内容が画面上部の出力エリアに表示されます。
これがFormControl、FormGroupを使ったフォームの基本的な書き方になります。

補足:初期値について

「ringo: new FormControl(")」の引数として設定している値が、このFormControlの初期値となるといいましたが、
では逆に何らかの初期値を設定した場合どうなるかというと、画面表示時に入力フィールドにその初期値が入った状態で表示されます。
例えば、FormGroupの初期化処理の部分を以下のように編集したとします。

    this.Group = new FormGroup({
      ringo: new FormControl('林檎'),
      nashi: new FormControl(''),
      mikan: new FormControl('')
    });

この状態で画面を表示するとこうなります。

フォームに初期値を設定したいときは、こんな感じで作ってみてください。

バリデーションチェック

初めに書いたようにFormGroup、FormControlにはバリデーションチェックの機能が搭載されています。
ここではその使い方を紹介していきます。
例えば、tsファイルをこんな感じで修正したとします。

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-ringo',
  templateUrl: './ringo.component.html',
  styleUrls: ['./ringo.component.css']
})
export class RingoComponent implements OnInit {
  inputText1:String;
  inputText2:String;
  inputText3:String;
  Group:FormGroup;

  constructor() {
    this.inputText1 = "";
    this.inputText2 = "";
    this.inputText3 = "";
    this.Group = new FormGroup({
      ringo: new FormControl('',Validators.minLength(3)),
      nashi: new FormControl('',Validators.maxLength(3)),
      mikan: new FormControl('',Validators.required)
    });
  }

  ngOnInit(): void {
  }

  get ringo(){return this.Group.get("ringo");}
  get nashi(){return this.Group.get("nashi");}
  get mikan(){return this.Group.get("mikan");}

  onClick(){
    this.inputText1 = this.Group.get('ringo')?.value;
    this.inputText2 = this.Group.get('nashi')?.value;
    this.inputText3 = this.Group.get('mikan')?.value;
  }

}

まずは「import { FormControl, FormGroup, Validators } from '@angular/forms’;」でValidatorsをインポートしてきます。
ここのValidatorsというのがバリデーションチェックの機能であり、これを使っていくことになります。
FormControlの設定部分で、「ringo: new FormControl(",Validators.minLength(3)),」というように書かれていますが、この2つ目の引数の「 Validators.minLength(3) 」というのがバリデーションチェックの内容になります。
ちなみにこの場合は、ringoの文字数が3以上でないとエラーになります。

次にHTMLを修正して、エラーの場合はエラーメッセージが表示されるようにしましょう。

<p>ringo works!</p>
<p>入力された項目を表示:</p>
<p> 林檎:{{inputText1}}</p>
<p> 梨 :{{inputText2}}</p>
<p> 蜜柑:{{inputText3}}</p>

<form [formGroup]="Group" (ngSubmit)="onClick()">
    <p>林檎</p>
<p *ngIf="ringo?.invalid">3文字以上で入力してください。</p>
    <input type="text" formControlName="ringo">
    <p>梨</p>
<p *ngIf="nashi?.invalid">3文字以下で入力してください。</p>
    <input type="text" formControlName="nashi">
    <p>蜜柑</p>
<p *ngIf="mikan?.invalid">必須項目です。</p>
    <input type="text" formControlName="mikan"><br>
<input [disabled]="Group.invalid" type="submit" value="click">
</form>

<p>タグに設定されている「*ngIf="ringo?.invalid"」ですが、まず「*ngIf」はIf文のようなものです。
ここにある条件が満たされた場合のみこのタグは表示されます。
では条件ですが、「 “ringo?.invalid" 」これはtsファイルのほうで作成していたringo()メソッドをまず呼び出し、ringoのFormControlを取得します。
このFormControlのinvalidプロパティというのがあるのですが、これはバリデーションチェックがエラーならFalseになるプロパティになります。
また、<input>タグのボタンも同様に、FormGroup内に一つでもバリデーションエラーがある場合、disableとなるようにしています。

このようにバリデーションチェックとエラーメッセージを設定した状態の画面を表示するとこうなります。

バリデーションエラーとなるように入力すると、エラーメッセージが表示されていますね。
ボタンも押下できないようになっています。

色々なバリデーション

上の例では、文字数と必須項目のバリデーションだけ使いましたが、他にも色々と設定できます。

min()最小値チェックです。
引数に設定した数値以上の数値であることをチェックします。
max()最大値チェックです。
引数に設定した数値以下の数値であることをチェックします。
minLength()最小文字数チェックです。
引数に設定した数値以上の文字数であることをチェックします。
maxLength() 最大文字数チェックです。
引数に設定した数値以下の文字数であることをチェックします。
required必須項目チェックです。
何らかの入力値がないとエラーになります。
emailメールアドレスの形式であることをチェックします。
○○○○@××××みたいに間に@があることをチェックします。
pattern()引数に正規表現を記載し、それに当てはまることをチェックします。

終わりに

今回はFormControl、FormGroupのバリデーション機能を使ってバリデーションチェックを実施する方法を紹介していきました。
もちろんFormsModuleにもバリデーション機能がありますので、次の記事でそちらも紹介していきます。

スポンサーリンク

Angular開発

Posted by 社畜林檎