Angular Reactive Forms その5 フォームの内容を別のフォームにコピー

Reactive Formにて入力した内容を他のフォームにコピーする実装をします。ちなみに、今まで学んだ内容を組み合わせることでできます。

  • Angular Materialのフォームに入力することで関数呼び出し
  • 他のフォームに値をコピー
注意
本連載は、基本的に前回までの作業が終わっていることを前提としています。最初から試したい方は以前の記事も参考にしてください。また、今回から作成するWebページはESPPなどで必要な情報を入れると確定申告に必要な情報をだしてくれるものを目指しますが、確定申告に必要な情報を保証するようなものではないので、了承の上使用ください。
Angular Reactive Forms その4 ボタンによるフォームの変更やリセット

各種バージョンは以下のとおりです。

  • Angular CLI: 11.2.8
  • Node: 15.10.0
  • Angular Material: 11.2.8

今回の目標とソースコードについて

今回の目標です。

  • 購入日価格を入力し、購入価格が変更されていない場合には、購入日価格の値を購入価格に入れる。

以前行った、入力した内容から関数を呼び出す実装と一緒です。

参考 今回のソースコード

Angular Materialのフォームのサブスクライブ(再掲)

購入日価格を入力したあとに保存ボタンを押したことにより、コンポーネント内で関数を呼び出すようにコードを追加します。

main.component.ts
export class MainComponent implements OnInit, OnDestroy {
  ngOnInit(): void {
    const marketPriceControl = this.esppForm.get("marketPrice");
    if (marketPriceControl) {
      this.subscriptions.add(
        marketPriceControl.valueChanges
          .pipe(debounceTime(500))
          .subscribe(() => {
            this.copyToPurchasePrice()
            this.updateProfit()
          })
      );
    }
  }
}

これにより、購入日価格を入力し終え、0.5秒後にupdateProfiltcopyToPurchasePriceを呼び出す動作になっています。

フォームの内容を別のフォームにコピー

前節で作成したcopyToPurchasePriceを実装していきます。ここに、値をコピーするようなコードを入れます。

main.component.ts
export class MainComponent implements OnInit, OnDestroy {
  copyToPurchasePrice(): void {
    const marketPriceControl = this.esppForm.get("marketPrice");
    const purchasePriceControl = this.esppForm.get("purchasePrice");
    if (marketPriceControl && purchasePriceControl) {
      purchasePriceControl.setValue(marketPriceControl.value)
    }        
  }
}

これにより、購入日価格の値が購入価格にコピーされます。

ただ、このままだと購入価格が入力されていても上書きされてしまいます。そこで、購入価格をユーザがタッチしたのかどうか判別するようにします。

main.component.ts
export class MainComponent implements OnInit, OnDestroy {
  copyToPurchasePrice(): void {
    const marketPriceControl = this.esppForm.get("marketPrice");
    const purchasePriceControl = this.esppForm.get("purchasePrice");
    if (marketPriceControl && purchasePriceControl && purchasePriceControl.untouched) {
      purchasePriceControl.setValue(marketPriceControl.value)
    }        
  }
}

追加したのは、purchasePriceControl.untouchedの部分です。これにより、ユーザが購入価格を一度でもタッチした場合には、以下のように価格がコピーされなくなります。

変更点とまとめ

今回アプリケーションに加えた変更点は以下のとおりです。

  • 購入日価格を入力したときに関数を呼び出す
  • ユーザが購入価格を触っている場合には、何もしない
  • ユーザが触っていな場合には、購入日価格の値をコピーする

main.component.tsの変更点は以下のとおりです。

main.component.ts
--- a/src/app/main/main.component.ts
+++ b/src/app/main/main.component.ts
@@ -78,7 +78,10 @@ export class MainComponent implements OnInit, OnDestroy {
       this.subscriptions.add(
         marketPriceControl.valueChanges
           .pipe(debounceTime(500))
-          .subscribe(() => this.updateProfit())
+          .subscribe(() => {
+            this.copyToPurchasePrice()
+            this.updateProfit()
+          })
       );
     }
     const purchasePriceControl = this.esppForm.get("purchasePrice");
@@ -112,4 +115,12 @@ export class MainComponent implements OnInit, OnDestroy {
       purchasePrice: 0,
     });
   }
+
+  copyToPurchasePrice(): void {
+    const marketPriceControl = this.esppForm.get("marketPrice");
+    const purchasePriceControl = this.esppForm.get("purchasePrice");
+    if (marketPriceControl && purchasePriceControl && purchasePriceControl.untouched) {
+      purchasePriceControl.setValue(marketPriceControl.value)
+    }
+  }
 }

今回は以前までに習った内容を使って、フォームの内容をコピーしました。他にもReactiveFormsでできることはたくさんありますが、ReactiveFormsに関する内容はこれで終了です。

参考 今回のソースコード

次回は、Angular Materialのテーブルを変更して、入力した内容が追加されるようにします。

Angular Material Table データの追加

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA