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

3
  • Correct me if I'm wrong, so essentially you want the values of accountDetails to be set as the initial values of transferDetailsForm ? Commented Oct 29, 2018 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. Commented Oct 29, 2018 at 11:24
  • Ah, you might want to use FormArray, especially if your accountDetails array grows or shrinks in size -- see answer below Commented Oct 29, 2018 at 16:24

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.