Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 4 Create Dynamic formArray inside array using reactive forms

Tags:

forms

angular

Here, we are creating dynamically form array's inside array.

Below is the sample structure of expected result given below.

{
  "optionsRadios": null,
  "Package_Title": null,
  "HotelData": [
    {
      "Htitle": "",
      "HDescription": "",
      "hotelStar": "",
"RoomData": [
    {
      "Hotel_Room_Type": ""
    },
    {
      "Hotel_Room_Type": ""
    }
  ]
    }
  ]

}

I want to create HotelData Dynamically, within that HotelData array i want to create RoomData array fields also dynamically.

I created HotelData fields by the following codes:

    export class AddPackageComponent implements OnInit {
    ngOnInit() {
            this.invoiceForm = this._formBuild.group({
    Package_Title: [],
                HotelData: this._formBuild.array([this.addRows()])
    })
    }
    addRows() {
            return this._formBuild.group({
                Htitle: [''],
                HDescription: [''],
                hotelStar: ['']
            });

        }
addHotel() {
            const control: FormArray = this.invoiceForm.get(`HotelData`) as FormArray;
            control.push(this.addRows());
        }
    }
like image 947
paruvelly Vishwanath Avatar asked Sep 01 '17 09:09

paruvelly Vishwanath


1 Answers

You are on the right track, we just need to add some more code...

addRows need the form array RoomData, and here we also initially push an empty form group of room. If you don't want that, modify it.

addRows() {
  let group = this._formBuild.group({
    ...
    RoomData: this._formBuild.array([])
  });
  // push formgroup to array initially
  this.addRoom(group.controls.RoomData)
  return group;
}

addRoom looks like this:

addRoom(hotel:any) {
  let group = this._formBuild.group({
    Hotel_Room_Type: ['']
  })
  hotel.push(group)
}

addRoom is also the method we are calling from template when we want to add a new room to a hotel. Remember to pass the current hotel as parameter from template.

As for adding a new hotel, your addHotel stays the way you have it now.

Then over to your template, the relevant part should look something like this:

<div formArrayName="HotelData">
  <div *ngFor="let hotel of invoiceForm.get('HotelData').controls; let i = index" [formGroupName]="i" >
    <!-- form controls here -->
    <button (click)="addRoom(hotel.get('RoomData'))">Add Room</button>
    <div formArrayName="RoomData">
      <div *ngFor="let room of hotel.get('RoomData').controls; let j = index" [formGroupName]="j">
        <!-- form controls here -->
      </div>
    </div>
  </div>
</div>

Finally, here's a Demo: http://plnkr.co/edit/7tcLcnzALew3oKGenjwK?p=preview

like image 168
AT82 Avatar answered Oct 14 '22 01:10

AT82