0

Creating an application with Angular and Reactive forms builder.

StackBlitz example

The form is prepopulated and within the form I am using form.array to build up a dynamic list of controls based on the data. I have disabled the fields as I want my form to be read-only initially. I have a button that triggers .enable on the controls, however as the dynamic controls in the form.array, I am not sure how I can enable these without specifying all of the controls index value.

ts file

  public createForm() {
    this.service.getmodel().subscribe((response) => {
      this.model = response;

      this.form = this.fb.group({
        type: new FormControl({ value: null, disabled: !this.isOwner }),
        items: this.fb.array(
          this.model.items.map((x) =>
            this.buildFields(x)
          )
        ),
      });
    });
  }

  buildFields(x: any): FormGroup {
    return new FormGroup({
      name: new FormControl({ value: x.name, disabled: !this.isOwner }),
      description: new FormControl({
        value: x.description,
        disabled: !this.isOwner,
      }),
      code: new FormControl({ value: x.code, disabled: !this.isOwner }),
    });
  }

  enable() {
    this.isOwner = true;
    const controls = ['type', 'items.description'];
    controls.map((x) => {
      this.form.get(x).enable({ onlySelf: true });
    });
  }

I am enabling the control "type" which enables a text input field, for the items in the form.array I have just added "items.description" - although I know this is incorrect as this value does not exist. It would be something like "items[0].description" but [0] could be any value determined by the length of the data.

html file

<div *ngIf="form">
  <form [formGroup]="form">
    <textarea
      formControlName="type"
      name="type"
      #type
      class="form-control"
      id="type"
      rows="6"
    ></textarea>
    <div formArrayName="items">
      <div
        *ngFor="let orgs of form.controls['items']?.controls; let i = index"
        [formGroupName]="i"
      >
        <input formControlName="name" placeholder="Item name" />
        <input formControlName="description" placeholder="Item description" />
        <input formControlName="code" placeholder="Item price" />
      </div>
      <button type="button" class="btn btn-success" (click)="enable()">
      Enable
    </button>

    </div>
  </form>

  <!-- <p>{{ form.value.items}}</p> -->
</div>

The end goal is to enable formControlName="name/description/code"

StackBlitz example

1 Answer 1

1

If I understood you correctly you are successfully enabling "type" but failing to enable name/description/code.

Remember your main FormGroup doesn't contain any name/description/code, it contains an another FormGroup called items, which contains your controls. First get the sub-form group from the main form, then you have access to the form controls.

Replace enable with this:

  enable() {
    this.isOwner = true;
    this.form.get('type').enable({ onlySelf: true });
    let items = this.form.get('items') as FormArray;
    items.controls.forEach(c => {
      c.enable({onlySelf: true});
    })
Sign up to request clarification or add additional context in comments.

Comments

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.