Angular 4 Form Array Dynamically Adding And Removing Form Fields.
What I love most about the Angular is handling the forms the way you want. There are two types of forms in Angular. You can easily handle validations and many other things using these forms
1. Template Drive Forms
Using template driven forms you can even use the power of 2 way data binding. (Awesomeness of 2 way data binding is that irrespective of the form getting submitted or not you can collect the data, using this feature I have created multi step wizard. Hiding and showing the divs at the same time using Angular animation making them look like they are sliding.)
That is the power of Angular template driven forms. But here we are going to discuss in detail about Reactive Forms.
2. Reactive Forms : Dynamically Adding And Removing Form Fields
Angular 4 Form Array Dynamically Adding And Removing Form Fields.
Approach of the Reactive forms is quite different compared to the template-driven forms. Here, we are going to create and initialise the form control objects in our component. These objects will hold the state of the form. Later, we bind them to the form control elements in the template.
Form Control objects always will be listening to the input control values, and they are immediately reflected in the object’s state.
This is how we are going to create form and form control objects using reactive forms
import {FormControl, FormArray, FormGroupDirective, NgForm, Validators, FormGroup, FormBuilder} from '@angular/forms';
invoiceForm: FormGroup;
@Component({
selector: 'app-generateinvoice',
templateUrl: './generateinvoice.component.html',
styleUrls: ['./generateinvoice.component.css']
})
export class GenerateinvoiceComponent implements OnInit {
invoiceForm: FormGroup;
constructor( private formBuilder: FormBuilder,
public dataService:DataService, public router:Router) {
this.createForm();
}
createForm(){
this.invoiceForm = this.formBuilder.group({
'name': ['', Validators.required],
'invoiceparticulars': this.formBuilder.array([]),
});
}
get invoiceparticularsArray(): FormArray{
return this.invoiceForm.get('invoiceparticulars') as FormArray;
}
addInvoiceParticulars(){
let fg = this.formBuilder.group(new InvoiceParticulars());
this.invoiceparticularsArray.push(fg);
}
deleteInvoiceParticulars(idx: number, val) {
console.log(val,idx);
this.invoiceparticularsArray.removeAt(idx);
}
}
As you can see in the above code createForm function will create form with form control objects they will store the states and handle necessary validations. You can even use here your custom validations also.
For the html part I am particularly going to focus on invoiceparticulars FormArray. How we will dynamically add and delete form fields. As you can see in the above code addInvoiceParticulars function whenever the button click happens new form fields are created at the front end formcontrol objects are pushed into the array.
Same thing with deleteInvoiceParticulars for that particular index of the formcontrol object. we will remove it from array at the sametime formfield will be deleted from the front end.
Angular 4 Form Array Dynamically Adding And Removing Form Fields
<form [formGroup]="invoiceForm" (keydown.enter)=
"$event.preventDefault()" (ngSubmit)=
"createInvoice(invoiceForm.value)" class="form-horizontal">
<div formArrayName="invoiceparticulars">
<div *ngFor="let invoiceparticular of invoiceForm.controls.invoiceparticulars.controls; let idx = index" [formGroupName]="idx">
<div class="row form-group">
<div class="col- xs-3 col-sm-3 col-md-3">
<legend>
<strong>Purpose {{idx}} :</strong>
</legend>
<select #othersval class="form-control" formControlName="purpose">
<option value="Item1">Item1</option>
<option value="Item2">Item2</option>
<option value="Item3">Item3</option>
</select>
</div>
<div class="col-xs-4 col-sm-4 col-md-4">
<legend>
<strong>Particulars</strong>
</legend>
<input class="form-control" type="text" formControlName="particulars" />
</div>
<div class="col-xs-3 col-sm-3 col-md-3 ">
<legend>
<strong>Amount</strong>
</legend>
<input class="form-control" type="text" formControlName="amount" />
</div>
<div class="row" style="margin-top:1rem;">
<div class="col-xs-3 col-sm-3 col-md-3 ">
<button type="button" mat-raised-button color="primary"
style="background-color:rgb(223, 49, 49)"
(click)="deleteInvoiceParticulars(idx, othersval.value)">Delete</button> </div>
</div>
<hr>
</div>
</div>
<button type="button" mat-raised-button color="primary"
(click)="addInvoiceParticulars()" >Add Invoice Particulars</button>
</div>
</div>
</form>
Now I think it is completely clear by looking at the html code Add Invoice Particulars creates the necessary form fields and Delete will delete the particular form field.
Guys is there any specific topic you want me to write blog on please post it in the comments.
I hope it helped
Happy Coding..!