1

I'm trying to create dynamic fields using this code

formInputfieldsForm: FormGroup[];

    defaultFields: any = [
        { inputType: 'textbox', inputValues: '' },
        { inputType: 'textbox', inputValues: '' },
      ]
    
     createForm(a?: any, b?: any, c?: any): FormGroup {
        return this.formService.group({
          "inputType": [b, Validators.required],
          "inputValues": [c, Validators.required],
        })
      }
    
     addFields(){
        this.defaultFields.forEach((ele, i) => {
          this.formInputfieldsForm.push(this.createForm(ele?.inputType, ele?.inputValues));
        });
      }

    createFieldsForm(): FormGroup {
    return this.formService.group({
      "inputType": [null, Validators.required],
      "inputValues": [null, Validators.required],
    })
  }

 
  addFields(){
    this.formInputfieldsForm.push(this.createFieldsForm());
  }

every time addFields is called new dynamic fields are created

in frontend i'm using loop to render elements like this

<div *ngFor="let expForm of formInputfieldsForm; let i = index;" [formGroup]="expForm">
 
<select class="hand_symbol" formControlName="inputType"  placeholder="Select Input Type">
                                                <option value="">Select</option>
                                                <option value="textbox">Textbox</option>
                                                <option value="dropdown">Drop Down</option>
                                                <option value="textarea">Textarea</option>
                                              </select>

<input class="form-control" formControlName="inputValues" type="text" placeholder="Enter Values" type="text">
</div>



<span title="Add" (click)="addFields()">add</span>

it is rendered now i need by default inputValues control should be disabled and if i select dropdown from select control then only it should be enabled

any solution Thanks

2
  • Hide control is a different behavior from disable control. You need to clarify the desired behavior, would also be great to provide an example like selecting which option to show/enable the control. Commented Jul 4, 2024 at 9:15
  • @YongShun Sorry u want to disable only input field by default and if i create using addFields method and if i select dropdown then it should be enabled Commented Jul 4, 2024 at 9:23

2 Answers 2

1

We can use (change) event to get the form group and validate if it should be enabled or disabled.

  dropdownChanged(index: number) {
    const formGroup = this.formInputfieldsForm.at(index);
    const values = formGroup.value;
    formGroup.get('inputValues')!.setValue(null);
    if (values.inputType === 'dropdown') {
      formGroup.get('inputValues')!.enable();
    } else {
      formGroup.get('inputValues')!.disable();
    }
  }

We can use a ternary condition check if the default value is dropdown and if we should enable/disable it.

  createForm(b?: any, c?: any): FormGroup {
    return this.fb.group({
      inputType: [b, Validators.required],
      inputValues: [
        b === 'dropdown' ? c : { value: c, disabled: true },
        Validators.required,
      ],
    });
  }

Full Code:

import { CommonModule } from '@angular/common';
import { Component, inject } from '@angular/core';
import {
  FormArray,
  FormBuilder,
  FormGroup,
  ReactiveFormsModule,
  Validators,
} from '@angular/forms';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';

@Component({
  selector: 'app-root',
  imports: [CommonModule, ReactiveFormsModule],
  standalone: true,
  template: `
    <div *ngFor="let expForm of getFields(); let i = index;" [formGroup]="expForm">
        <select class="hand_symbol" formControlName="inputType"  placeholder="Select Input Type" (change)="dropdownChanged(i)">
          <option value="">Select</option>
          <option value="textbox">Textbox</option>
          <option value="dropdown">Drop Down</option>
          <option value="textarea">Textarea</option>
        </select>
        <input class="form-control" formControlName="inputValues" type="text" placeholder="Enter Values" type="text">
    </div>
 
 
 
 <span title="Add" (click)="addFields()">add</span>
  `,
})
export class App {
  formInputfieldsForm: FormArray<any> = new FormArray<any>([]);
  fb = inject(FormBuilder);
  defaultFields: any = [
    { inputType: 'textbox', inputValues: '' },
    { inputType: 'textbox', inputValues: '' },
  ];

  getFields() {
    return this.formInputfieldsForm.controls as FormGroup[];
  }

  dropdownChanged(index: number) {
    const formGroup = this.formInputfieldsForm.at(index);
    const values = formGroup.value;
    formGroup.get('inputValues')!.setValue(null);
    if (values.inputType === 'dropdown') {
      formGroup.get('inputValues')!.enable();
    } else {
      formGroup.get('inputValues')!.disable();
    }
  }

  createForm(b?: any, c?: any): FormGroup {
    return this.fb.group({
      inputType: [b, Validators.required],
      inputValues: [
        b === 'dropdown' ? c : { value: c, disabled: true },
        Validators.required,
      ],
    });
  }

  ngOnInit() {
    this.addFieldsOnLoad();
  }

  addFieldsOnLoad() {
    this.defaultFields.forEach((ele: any, i: any) => {
      this.formInputfieldsForm.push(
        this.createForm(ele?.inputType, ele?.inputValues)
      );
    });
  }

  createFieldsForm(): FormGroup {
    return this.fb.group({
      inputType: [null, Validators.required],
      inputValues: [null, Validators.required],
    });
  }

  addFields() {
    this.formInputfieldsForm.push(this.createForm('', ''));
  }
}

bootstrapApplication(App);

Stackblitz Demo

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

9 Comments

Thanks for the answer when i declare formInputfieldsForm: FormArray<any> = new FormArray<any>([]); it gives error Type FormArray is not generic can you pls check
@user3653474 try removing the <any> might solve your issue
is this also possible with only form group we can disable without making it form array because of code changes
@user3653474 do consider form array because you will have the ability to get the status and other details of all the forms, but you can apply this same approach to array of form groups also
Yes it's working Thanks
|
1

Assuming formService is an instance of FormBuilder. When creating the form, the first item in the array is either the initial value, or an object with a value and a disabled property. To enable the control after the inputType value changed, you can subscribe to the value changes and call the enable() function of the control instance. Updated code:

createFieldsForm(): FormGroup {
  const formGroup = this.formService.group({
    "inputType": [null, Validators.required],
    "inputValues": [{ value: null, disabled: true }, Validators.required],
  });
  formGroup.inputType.valueChanges
    .pipe(take(1))
    .subscribe(() => formGroup.controls.inputValues.enable());
  return formGroup;
}

2 Comments

Thanks if i change dropdown values and select dropdown then i want to enable also can you pls let me know i have placed html component code
very, very, very old, but: stackoverflow.com/questions/47937639/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.