33

I am building an app using Angular 4.0.2. How can I add a button to a form to add a new row of input and a delete button for a particular row to delete? I mean that I want a form something like this. I want my form to look something like this:

Form Image.

Here is my code:

add-invoice.component.html

    <h3 class="page-header">Add Invoice</h3>
    <form [formGroup]="invoiceForm">
      <div formArrayName="itemRows">
        <div *ngFor="let itemrow of itemRows.controls; let i=index" [formGroupName]="i">
          <h4>Invoice Row #{{ i + 1 }}</h4>
          <div class="form-group">
            <label>Item Name</label>
            <input formControlName="itemname" class="form-control">
          </div>
          <div class="form-group">
            <label>Quantity</label>
            <input formControlName="itemqty" class="form-control">
          </div>
          <div class="form-group">
             <label>Unit Cost</label>
             <input formControlName="itemrate" class="form-control">
          </div>
          <div class="form-group">
            <label>Tax</label>
            <input formControlName="itemtax" class="form-control">
          </div>
          <div class="form-group">
            <label>Amount</label>
            <input formControlName="amount" class="form-control">
          </div>
          <button *ngIf="i > 1" (click)="deleteRow(i)" class="btn btn-danger">Delete Button</button>
        </div>
      </div>
      <button type="button" (click)="addNewRow()" class="btn btn-primary">Add new Row</button>
    </form>
    <p>{{invoiceForm.value | json}}</p>

Here is my code for add-invoice.component.ts

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

@Component({
  selector: 'app-add-invoice',
  templateUrl: './add-invoice.component.html',
  styleUrls: ['./add-invoice.component.css']
})

export class AddInvoiceComponent implements OnInit {
  invoiceForm: FormGroup;

  constructor(
    private _fb: FormBuilder
  ) {
    this.createForm();
  }

  createForm(){
    this.invoiceForm = this._fb.group({
      itemRows: this._fb.array([])
    });
    this.invoiceForm.setControl('itemRows', this._fb.array([]));
  }

  get itemRows(): FormArray {
    return this.invoiceForm.get('itemRows') as FormArray;
  }

  addNewRow(){
    this.itemRows.push(this._fb.group(itemrow));
  }

  ngOnInit(){

  }
}
8
  • Code please, What have you tried? Commented Apr 20, 2017 at 12:49
  • I have been reading reactive forms docs on angular.io But nothing is working can you code it for me please. Commented Apr 20, 2017 at 12:52
  • 2
    I could, but this is not a coding service, you need to show us your effort. Commented Apr 20, 2017 at 12:53
  • Okk please wait I provide you Commented Apr 20, 2017 at 12:54
  • Please wait 10-15 minutes I'll compile and show you. Commented Apr 20, 2017 at 12:55

1 Answer 1

67

Here's a shortened version of your code:

When you init your form, you can add one empty formgroup inside your formArray:

ngOnInit() {
  this.invoiceForm = this._fb.group({
    itemRows: this._fb.array([this.initItemRows()])
  });
}

get formArr() {
  return this.invoiceForm.get('itemRows') as FormArray;
}

Then the function:

initItemRows() {
  return this._fb.group({
    // list all your form controls here, which belongs to your form array
    itemname: ['']
  });
}

Here is the addNewRow and deleteRow functions:

addNewRow() {
  this.formArr.push(this.initItemRows());
}

deleteRow(index: number) {
  this.formArr.removeAt(index);
}

Your form should look like this:

<form [formGroup]="invoiceForm">
  <div formArrayName="itemRows">
    <div *ngFor="let itemrow of formArr.controls; let i=index"  [formGroupName]="i">
      <h4>Invoice Row #{{ i + 1 }}</h4>
      <div>
        <label>Item Name</label>
        <input formControlName="itemname">
      </div>
      <button type="button" (click)="deleteRow(i)" *ngIf="formArr.controls.length > 1" >
        Delete
      </button>
    </div>
  </div>
  <button type="button" (click)="addNewRow()">Add new Row</button>
</form>

Here's a

DEMO

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

10 Comments

Is there any way to do this in template-driven form.
In this case I would though suggest you use model-driven form, it is much cleaner this way in my opinion.
I am posting another question just now. Please help me on that also. I will be really thankful to you.
Sure, I can take a look :)
It was just a going through the button. Bro, I am really thankful to you for this answer. I will surely buy you a beer when my first Salary will come. By the way, please go through stackoverflow.com/q/43528200/7882245
|

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.