0

I'm working on angular 4 form with Angular forms, how to dynamically add an input (checkbox) to the formArray after building the form.

ts:

signes_p = [
  { id: 'x1', name: 'bus' },
  { id: 'x2', name: 'car' }
];

ngOnInit() {
  const controls = this.signes_p.map(c => new FormControl(false));
  this.form = this.fb.group({
    signes: new FormArray(controls),
  });
}

addSigne(){
  if(this.new_signe && this.new_signe.trim().length>0){

    this.signes_p.push({
      id: this.new_signe,
      name: this.new_signe.replace(/^\w/, c => c.toUpperCase())
    })
  const controls = this.signes_p.map(c => new FormControl(false));
  const control = <FormArray>this.form.controls['signes'];
  var x = this.fb.group(controls[controls.length-1])
  control.push(x);
  }
}

html

<form [formGroup]="form" (ngSubmit)="onSubmit()">
      <div class="form-group" >
        <label for="signes" class="col-2 col-form-label" >Signes</label>  
          <div class="custom-control custom-checkbox" formArrayName="signes" *ngFor="let signe of form.controls.signes.controls; let i = index">
            <input type="checkbox" class="custom-control-input" [formControlName]="i" id="{{i}}">
            <label class="custom-control-label" for="{{i}}"> {{signes_p[i].name}}</label>
          </div>

          <div class="row" style="margin-top:20px;">
              <input class="form-control col-2" type="text" placeholder="Ajouter un autre..." [(ngModel)] = "new_signe" [ngModelOptions]="{standalone: true}" > 
              <a class="btn btn-success btn-sm" style="color: white;margin-left: 10px;" (click)="addSigne()"><i class="fa fa-plus" aria-hidden="true"></i></a>
          </div>        
      </div>
    ...
  <button class="btn btn-primary" type="submit" [disabled]="!form.valid">Enregistrer</button>   
</form>

i've also tried this medium_example, it caused these problems in html

control.registerOnChange is not a function

Must supply a value for form control with name: 'validator'.

Source link StackBlitz

2
  • Can you put this code in StackBlitz and share it? It would be easier to read the code then. Thanks! Commented Feb 18, 2019 at 2:26
  • Thanks for interacting this is the source code link StackBlitz Commented Feb 18, 2019 at 12:14

1 Answer 1

2

There were a few things, which should become clear in light of the code below... on your stackblitz, replace the code in the following 2 files - check the console.log for resolution to your error also.

replace the existing app.component.ts with the following

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

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

  form: FormGroup
  constructor(private fb: FormBuilder, ) { this.initiate(); }

  insertedID: string;
  insertedName: string;


  fields = this.fb.group({
    elementArray: this.fb.array([this.createElementData('1', 'car')])
  });

  initiate() {
    const newRow2 = this.createElementData('2', 'bus');
    this.elementArray.push(newRow2);
  }

  createNew() {
    const newRow = this.createElementData(this.insertedID, this.insertedName);
    this.elementArray.push(newRow);
  }

  get elementArray(): FormArray {
    return this.fields.get("elementArray") as FormArray;
  }

  createElementData(passedID, passedName): FormGroup {
    if (passedID == 0 || !passedID) {
      passedID = this.elementArray.length + 1;
    }
    return this.fb.group({
      id: [passedID],
      name: [passedName],
      statusVal: false
    });
  }

  showData() {
    if (this.fields.value.elementArray.length > 0) {
      console.log(this.fields.value.elementArray);
    }
  }

}

export class Element {
  id: string;
  name: string;
  statusVal: boolean;
}

replace the existing app.component.html with the following

<form [formGroup]="fields" class="example-form" (submit)="showData()">
  Signes:
  <div class='' formArrayName='elementArray' *ngFor="let item of fields.get('elementArray').controls; let i = index">
    <div [formGroupName]="i">
      <!-- <input type="text" formControlName="id" placeholder="Enter ID">  ID: [{{item.value.id}}] -->
      <input type="checkbox" formControlName="statusVal" placeholder="Enter Name">
      <!-- <input type="text" formControlName="name" placeholder="Enter Name"> -->{{item.value.name}}

    </div>
  </div>
  <div class="buttonDiv">
    <button type="submit" mat-raised-button color="primary">Enregistrer</button>
    <br/><br/> form status: <mark>{{fields.status}}</mark>
  </div>
</form>

<hr/>
<!-- <input type='text' [(ngModel)]="insertedID" placeholder="ID du nouveau véhicule" /> -->
<input type='text' [(ngModel)]="insertedName" placeholder="Ajouter un autre" />
<button mat-raised-button color="primary" (click)="createNew()"> Ajouter un nouveau véhicule et checkbox </button>

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.