roopteja
roopteja

Reputation: 743

How to generate form elements using typescript classes and objects using Reactive Forms in angular

I have a class file as follows.

export class ClassA {
    description: string;
    type: string;
    order: number;
    constructor(descrption: string, type: string, order: number) {
        this.description = descrption;
        this.type = type;
        this.order = order;
    }
}

Now I want to create form elements(text boxes) using this class through type script. In my html page the code is as follows

<form [formGroup]="myForm">

</form>

In my typescript file i.e (.ts )file the code is as follows.

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'app';
  arr = Array<ClassA>();
  r1: ClassA;
  r2: ClassA;
  myForm:FormGroup;
  constructor() {
    this.r1 = new ClassA('description1', 'text', 1);
    this.arr.push(this.r1);
    this.r2 = new ClassA('description2', 'text', 2);
    this.arr.push(this.r2);
  }
  ngOnInit() {
    console.log(this.arr);
  }
}

Now using this formGroup how to make these class fields as input elements in form dynamically ?

Upvotes: 1

Views: 3772

Answers (2)

AVJT82
AVJT82

Reputation: 73357

What I would do, since you have a class and know how the build of the form should look like, I'd use it to push formgroups to a FormArray, so first build form, iterate your array and push each object to array as formGroup:

constructor(private fb: FormBuilder) {
  this.myForm = this.fb.group({
    formArray: this.fb.array([])
  });
  this.r1 = new ClassA('description1', 'text', 1);
  this.arr.push(this.r1);
  this.r2 = new ClassA('description2', 'text', 2);
  this.arr.push(this.r2);

  this.arr.forEach(x => {
    let formArr = this.myForm.controls.formArray as FormArray;
    this.arr.forEach(x => {
      formArr.push(this.fb.group({
        description: [x.description],
        type: [x.type],
        order: [x.order]
      }))
    })
  })
}

and if you want to push new object of class ClassA, you can do it like:

formArr.push(this.fb.group(new ClassA('desc3','type3',3)))

Then in template just iterate this form array:

<form [formGroup]="myForm">
  <div formArrayName="formArr">
    <div *ngFor="let item of myForm.get('formArr').controls; let i = index" [formGroupName]="i">
      <input formControlName="description" />
      <input formControlName="type" />
      <input formControlName="order" />
    </div>
  </div>
</form>

Hopefully this is something you are looking for! :)

StackBlitz

Upvotes: 2

Sandip Jaiswal
Sandip Jaiswal

Reputation: 3720

Just create a component and take a object as input. You can get all properties of a object by following code:

Object.keys(obj);

Above code will give you all keys of your object. Now create a formGroup and add FormControls. In Template use ngfor to render inputs.

Use following code:

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

@Component({
  selector: 'app-form',
  template: `
    <form [formGroup]="myForm">
      <div *ngFor="let formKey of objKeys">
        <input type="text" formControlName="{{formKey}}" />
      </div>

      {{myForm.value | json}}
    </form>
  `,
})
export class FormComponent  {
  public myForm: FormGroup;
  public myObj = {
    firstName: "",
    lastName: ""
  };
  public objKeys: string[] = [];
  constructor(private fb: FormBuilder) {
    this.objKeys = Object.keys(this.myObj);
    console.log(this.objKeys);
    this.myForm = fb.group({});
    Object.keys(this.myObj).forEach(key => {
    this.myForm.addControl(key, new FormControl(this.myObj[key]));      
    })
  }
}

Hope it will help

Upvotes: 0

Related Questions