Reputation: 39
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
Upvotes: 0
Views: 2274
Reputation: 15031
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>
Upvotes: 2