【市場価値がわかる】エンジニア転職におすすめなサイト

【Angular】フォームコントロール・フォームグループを解説

AngularでformControl

フォームコントロール・フォームグループはどうやれば実装できる?

Angularには、FormControlとFormGroupを活用して簡単にフォームを作成できる機能があります。

この記事では、以下のことを解説します。

ポイント
  • フォームコントロール
  • フォームグループ
  • バリデーション
  • フォームの値を取得する

※AngularMaterialを導入済みなので、フォームもMaterialデザインのものを使用します。AngularMaterialの導入

※Anular14

Contents

フォームを追加する

今回作成するフォームは、名前・住所・電話番号・メールアドレス・パスワード・パスワード(確認用)のフォームです。

以下のように、フォームを作成するのに必要なFormControlやFormGroupなどをまずはimportしてください。

そして、constructorの前で、フォームの変数を書きます。そして、ngOnInitでFormControlをnewします。

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

@Component({
  selector: 'app-user-register',
  templateUrl: './user-register.component.html',
  styleUrls: ['./user-register.component.css']
})
export class UserRegisterComponent implements OnInit {
  public name: FormControl;
  public address: FormControl;
  public phone: FormControl;
  public email: FormControl;
  public password: FormControl;
  public passwordConfirm: FormControl;

  constructor() {}

  ngOnInit(): void {
    this.name = new FormControl('');
    this.address = new FormControl('');
    this.phone = new FormControl('');
    this.email = new FormControl('');
    this.password = new FormControl('');
    this.passwordConfirm = new FormControl('');
  }
}

new FormControlでフォームを追加したら、HTML側では以下のように[formControl]=”フォーム名”でフォームをセットできます。[formControl]ではなく、formControlNameでも代用できます。

<form class="form-field">
    <!-- 名前のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>名前</mat-label>
        <input matInput placeholder="名前を入力してください" [formControl]="name">
    </mat-form-field>

    <!-- 住所のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>住所</mat-label>
        <input matInput placeholder="住所を入力してください" [formControl]="address">
    </mat-form-field>

    <!-- 電話番号のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>電話番号</mat-label>
        <input matInput placeholder="電話番号を入力してください" [formControl]="phone">
    </mat-form-field>

    <!-- メールアドレスのフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>メールアドレス</mat-label>
        <input matInput placeholder="メールアドレスを入力してください" [formControl]="email">
    </mat-form-field>

    <!-- パスワードのフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>パスワード</mat-label>
        <input matInput placeholder="パスワードを入力してください" [formControl]="password">
    </mat-form-field>

    <!-- パスワード(確認用)のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>パスワード(確認用)</mat-label>
        <input matInput placeholder="パスワード(確認用)を入力してください" [formControl]="passwordConfirm">
    </mat-form-field>
    <button class="form-button" mat-raised-button color="primary" [disabled]="">登録する</button>
</form>

mat-form-fieldにappearance=”fill”をつけなければ、以下のようなフォームになります。

.form-field {
    width: 100%;
    padding: 50px;
}

mat-form-field {
    width: 80%;
    padding-bottom: 1rem;
}

.form-button {
    display: block;
    width: 80%;
}

mat-buttonが反映されない場合は、app.module.tsでMatButtonModuleをimportしているか確認しましょう。

バリデーションを設定する

簡単に書くフォームに必須バリデーションぐらいかけておきましょう。

Validatorsをimportしていることを確認してください。

そしたら、あとはnew FormControl(”)としたところにValidators.requiredを加え、HTMLにはmat-errorを追加します。

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

@Component({
  selector: 'app-user-register',
  templateUrl: './user-register.component.html',
  styleUrls: ['./user-register.component.css']
})
export class UserRegisterComponent implements OnInit {
  public name: FormControl;
  public address: FormControl;
  public phone: FormControl;
  public email: FormControl;
  public password: FormControl;
  public passwordConfirm: FormControl;

  constructor() {}

  ngOnInit(): void {
    this.name = new FormControl('', Validators.required);
    this.address = new FormControl('', Validators.required);
    this.phone = new FormControl('', Validators.required);
    this.email = new FormControl('', Validators.required);
    this.password = new FormControl('', Validators.required);
    this.passwordConfirm = new FormControl('', Validators.required);
  }
}
<form class="form-field">
    <!-- 名前のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>名前</mat-label>
        <input matInput placeholder="名前を入力してください" [formControl]="name">
        <mat-error *ngIf="name.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- 住所のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>住所</mat-label>
        <input matInput placeholder="住所を入力してください" [formControl]="name">
        <mat-error *ngIf="name.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- 電話番号のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>電話番号</mat-label>
        <input matInput placeholder="電話番号を入力してください" [formControl]="name">
        <mat-error *ngIf="name.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- メールアドレスのフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>メールアドレス</mat-label>
        <input matInput placeholder="メールアドレスを入力してください" [formControl]="name">
        <mat-error *ngIf="name.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- パスワードのフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>パスワード</mat-label>
        <input matInput placeholder="パスワードを入力してください" [formControl]="name">
        <mat-error *ngIf="name.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- パスワード(確認用)のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>パスワード(確認用)</mat-label>
        <input matInput placeholder="パスワード(確認用)を入力してください" [formControl]="name">
        <mat-error *ngIf="name.errors?.['required']">必須です。</mat-error>
    </mat-form-field>
    <button class="form-button" mat-raised-button color="primary" [disabled]="">登録する</button>
</form>

登録するボタンを押したときに、フォームに何も入力されていなければ、必須です。とバリデーションエラーを起こします。

ただ、このように複数のフォームがある場合は、フォームをグループ化するのが良いです。

なぜならFormControlは、単一のフォームを制御しますが、フォーム全体である名前〜パスワード(確認用)までは面倒見ません。

グループ化することで、フォーム全体を管理できます。

グループ化したフォームで、名前のフォームでバリデーションエラーが起きていた場合にボタンを非活性にすることもできます。バリデーションエラーが解消されたら、動的に活性化されます。便利ですね。

フォームをグループ化する

フォームをグループ化します。

FormControlみたいに、new FormGroupし、フォーム名: フォームコントロールのようにセットすればOKです。

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

@Component({
  selector: 'app-user-register',
  templateUrl: './user-register.component.html',
  styleUrls: ['./user-register.component.css']
})
export class UserRegisterComponent implements OnInit {
  public registerForm: FormGroup;
  public name: FormControl;
  public address: FormControl;
  public phone: FormControl;
  public email: FormControl;
  public password: FormControl;
  public passwordConfirm: FormControl;

  constructor() {}

  ngOnInit(): void {
    this.name = new FormControl('', Validators.required);
    this.address = new FormControl('', Validators.required);
    this.phone = new FormControl('', Validators.required);
    this.email = new FormControl('', Validators.required);
    this.password = new FormControl('', Validators.required);
    this.passwordConfirm = new FormControl('', Validators.required);

    this.registerForm = new FormGroup({
      name: this.name,
      address: this.address,
      phone: this.phone,
      email: this.email,
      password: this.password,
      passwordConfirm: this.passwordConfirm,
    });
  }
}

HTML側では[formGroup]=”フォームグループ名”を追加します。

そして、ボタンには[disabled]を追加します。=trueの場合はボタン活性化、falseの場合は非活性

フォームグループでバリデーションエラーが発生しているか判定するには、フォームグループ名.invalidで実現できます。

<form class="form-field" [formGroup]="registerForm">
    <!-- 名前のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>名前</mat-label>
        <input matInput placeholder="名前を入力してください" [formControl]="name">
        <mat-error *ngIf="name.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- 住所のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>住所</mat-label>
        <input matInput placeholder="住所を入力してください" [formControl]="address">
        <mat-error *ngIf="address.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- 電話番号のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>電話番号</mat-label>
        <input matInput placeholder="電話番号を入力してください" [formControl]="phone">
        <mat-error *ngIf="phone.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- メールアドレスのフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>メールアドレス</mat-label>
        <input matInput placeholder="メールアドレスを入力してください" [formControl]="email">
        <mat-error *ngIf="email.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- パスワードのフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>パスワード</mat-label>
        <input matInput placeholder="パスワードを入力してください" [formControl]="password">
        <mat-error *ngIf="password.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- パスワード(確認用)のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>パスワード(確認用)</mat-label>
        <input matInput placeholder="パスワード(確認用)を入力してください" [formControl]="passwordConfirm">
        <mat-error *ngIf="passwordConfirm.errors?.['required']">必須です。</mat-error>
    </mat-form-field>
    <button class="form-button" mat-raised-button color="primary" [disabled]="registerForm.invalid">登録する</button>
</form>

バリデーションには、各フォームに必須のみ付けているので、初期画面遷移時は、必須チェックに引っかかって登録するボタンは非活性になります。

どれかでバリデーションエラーあっても登録するボタンは非活性

バリデーションエラーがなくなったら、登録するボタンは活性化

登録するボタンの送信イベント

登録するボタンを押したときに送信するイベントは簡単でHTML側でngSubmitを追加するだけです。

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

@Component({
  selector: 'app-user-register',
  templateUrl: './user-register.component.html',
  styleUrls: ['./user-register.component.css']
})
export class UserRegisterComponent implements OnInit {
  public registerForm: FormGroup;
  public name: FormControl;
  public address: FormControl;
  public phone: FormControl;
  public email: FormControl;
  public password: FormControl;
  public passwordConfirm: FormControl;

  constructor() {}

  ngOnInit(): void {
    this.name = new FormControl('', Validators.required);
    this.address = new FormControl('', Validators.required);
    this.phone = new FormControl('', Validators.required);
    this.email = new FormControl('', Validators.required);
    this.password = new FormControl('', Validators.required);
    this.passwordConfirm = new FormControl('', Validators.required);

    this.registerForm = new FormGroup({
      name: this.name,
      address: this.address,
      phone: this.phone,
      email: this.email,
      password: this.password,
      passwordConfirm: this.passwordConfirm,
    });
  }

  onSubmit() {
      console.log('クリック');
  }
}

以下のようにngSubmitを追加することで、登録するボタンを押したときにイベントが発生します。

追加:(ngSubmit)=”onSubmit()”

<form class="form-field" [formGroup]="registerForm" (ngSubmit)="onSubmit()">
    <!-- 名前のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>名前</mat-label>
        <input matInput placeholder="名前を入力してください" [formControl]="name">
        <mat-error *ngIf="name.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- 住所のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>住所</mat-label>
        <input matInput placeholder="住所を入力してください" [formControl]="address">
        <mat-error *ngIf="address.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- 電話番号のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>電話番号</mat-label>
        <input matInput placeholder="電話番号を入力してください" [formControl]="phone">
        <mat-error *ngIf="phone.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- メールアドレスのフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>メールアドレス</mat-label>
        <input matInput placeholder="メールアドレスを入力してください" [formControl]="email">
        <mat-error *ngIf="email.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- パスワードのフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>パスワード</mat-label>
        <input matInput placeholder="パスワードを入力してください" [formControl]="password">
        <mat-error *ngIf="password.errors?.['required']">必須です。</mat-error>
    </mat-form-field>

    <!-- パスワード(確認用)のフォーム -->
    <mat-form-field appearance="fill">
        <mat-label>パスワード(確認用)</mat-label>
        <input matInput placeholder="パスワード(確認用)を入力してください" [formControl]="passwordConfirm">
        <mat-error *ngIf="passwordConfirm.errors?.['required']">必須です。</mat-error>
    </mat-form-field>
    <button class="form-button" mat-raised-button color="primary" [disabled]="registerForm.invalid">登録する</button>
</form>

活性化されている登録するボタンを押したら、コンソールにクリックと表示されます。

フォームの値を取得する

フォームの値を取得するには、フォームコントロール.valueで取得できます。

  onSubmit() {
    console.log('クリック');
    // 名前のフォームの値を取得する
    const name = this.name.value;
    console.log(name);
  }

>>転職するのにおすすめのサイトはこちらをクリック
>>副業で稼ぐためにおすすめのサイトはこちらをクリック

スキルを売り買いするならココナラ

オンライン動画学習ならUdemy

コメント

コメントする

CAPTCHA


Contents
閉じる