0

I am currently trying to submit synamically generated content from a table within my form. I am using Angular 6 to generate the form, but for the life of me I cannot figure out how to represent the dynamic content of the form within the FormGroup declaration.

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

  accountDetails = [{
    id: 1,
    name: 'Account 1',
    amountHeld: 5453.7,
    amountToTransfer: 0

  },
  {
    id: 2,
    name: 'Account 2',
    amountHeld: 5644.7,
    amountToTransfer: 0

  },
  {
    id: 3,
    name: 'Account 3',
    amountHeld: 42465.7,
    amountToTransfer: 0

  }
  ,{
    id: 4,
    name: 'Account 4',
    amountHeld: 1434.7,
    amountToTransfer: 0

  }
  ]

  transferDetailsForm = new FormGroup({
    transferType: new FormControl("", [Validators.required]),
  });


}


<form name="transferDetailsForm" [formGroup]="transferDetailsForm">
    <div class="row">
        <div class="form-group">

            <label class="required">Choose category of transfer </label>&nbsp;

              <div id="rbTradeCategorySelect" class="form-group" style="padding-left: 20px;">

                <label for="rbMove" class="radio-inline">
                  <input type="radio" value="SaleOrGift" (change)="changeTransferCategory($event)" formControlName="transferType" click-capture />
                  Sale or gift
                </label>&nbsp;

                <label for="rbLease" class="radio-inline">
                  <input type="radio" radio value="Lease" (change)="changeTransferCategory($event)" formControlName="transferType" click-capture />
                  Lease
                </label>&nbsp;
              </div>
            </div>
          </div>
          <table>
            <thead>
              <th>Account Name </th>
              <th>Account Balance</th>
              <th>Amount to Transfer</th>
            </thead>
            <tbody>
              <tr *ngFor='let a of accountDetails'>
                <td>{{a.name}}</td>
                <td>{{a.amountHeld}}</td>
                <td>
                  <input type="hidden" placeholder="{{a.id}}"/>
                  <input type="text" placeholder="{{a.amountToTransfer}}"/>
                </td>
              </tr>
            </tbody>
          </table>
   <button id="btnSubmit" class="btn btn-success btn-lg" (ngSubmit)="transferDetailsForm.valid"
                    click-capture>
                    Submit
                  </button>      
</form>

I have created the following mock up of my form in the hope that someone can help me.

https://stackblitz.com/edit/angular-yzumze

Mick Walker
  • 3,862
  • 6
  • 47
  • 72
  • Correct me if I'm wrong, so essentially you want the values of `accountDetails` to be set as the initial values of `transferDetailsForm` ? – jmdavalos Oct 29 '18 at 11:16
  • Not quite, I want to know how I include the account information (dynamically) as part of the form group, which will enable me to read any user submitted values on submit, at the moment it isnt part of my FormGroup() declaration. – Mick Walker Oct 29 '18 at 11:24
  • Ah, you might want to use `FormArray`, especially if your `accountDetails` array grows or shrinks in size -- see answer below – jmdavalos Oct 29 '18 at 16:24

1 Answers1

1

As I mentioned in the comments, you'd have to use FormArray for that. For a more detailed discussion on when to use FormArray vs FormGroup, check out: When to use FormGroup vs. FormArray?

Now, check out:

app.component.ts

...
...
...
transferDetailsForm: FormGroup;
results: Array<string>;

constructor(
  private formBuilder: FormBuilder,
) { }

ngOnInit() {
  this.transferDetailsForm = this.formBuilder.group({
    amountToTransferArray: this.buildFormArray(),
  });
}

buildFormArray(): FormArray {
  let arr = [];
  this.accountDetails.forEach(details => {
    arr.push([details.amountToTransfer, [Validators.required]]);
  });

  return this.formBuilder.array(arr);
}

get amountToTransferArray(): FormArray {
  return this.transferDetailsForm.get('amountToTransferArray') as FormArray;
}

onSubmit() {
  const formModel = this.transferDetailsForm.value;
  this.results = formModel;
}

app.component.html

<table>
  <thead>
    <th>Account Name </th>
    <th>Account Balance</th>
    <th>Amount to Transfer</th>
  </thead>
  <tbody>
    <tr *ngFor="let a of accountDetails; let index = index">
      <td>{{ a.name }}</td>
      <td>{{ a.amountHeld }}</td>
      <td>
        <input type="hidden" placeholder="{{ a.id }}"/>
        <input type="number" [formControl]="amountToTransferArray.controls[index]"/>
      </td>
    </tr>
  </tbody>
</table>
<button id="btnSubmit" class="btn btn-success btn-lg"
  (click)="onSubmit()">
  Submit
</button>

I've forked your stackblitz and modified it here: https://stackblitz.com/edit/angular-ib3kth

jmdavalos
  • 168
  • 6