Richard
Richard

Reputation: 8945

Angular8 form input fields disabled

I am using Angular8 and have a form used to update a product. My problem however is this forms input fields and submit button is disabled. Can anyone advise what I am doing wrong? I would expect to be able to edit the input fields text and submit the form.

html:

<div class="bodyClass">
    <h1>{{title | titlecase}}</h1>
    <div class="card">
        <div class="card-body">
            <form *ngIf="angForm && productData" [formGroup]="angForm" novalidate>
                <div class="form-group">
                    <label class="col-md-4">Product Name</label>
                    <input type="text" class="form-control" formControlName="name" #name/>
                </div>
                <div *ngIf="angForm.controls['name'].invalid && (angForm.controls['name'].dirty || angForm.controls['name'].touched)"
                    class="alert alert-danger">
                    <div *ngIf="angForm.controls['name'].errors.required">
                        Product Name is required.
                    </div>
                </div>
                <div class="form-group">
                    <button (click)="updateProduct(name.value)" type="submit" class="btn btn-primary"
                        [disabled]="angForm.invalid">
                        Update Product
                    </button>
                </div>
            </form>
        </div>
    </div>
</div>

component:

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Observable } from 'rxjs';
import { PermissionsService } from '../../services/permissions.service';
import { Permissions } from '../../model/permissions';
import { ProductsService } from '../../services/products.service';
import { DataService } from '../../services/data.service';
import { Product } from '../../model/product';

@Component({
  selector: 'app-productsupdate',
  templateUrl: './productsupdate.component.html',
  styleUrls: ['./productsupdate.component.css']
})
export class ProductsupdateComponent implements OnInit {

  angForm: FormGroup;
  private permissionsObservable: Observable<Permissions>; 
  private showData: boolean = true;
  private title: string;
  private productData: Product;

  constructor(private _permissionsService: PermissionsService, private _productService: ProductsService,
              private dataService: DataService, private fb: FormBuilder) {
                this.createForm();
  }

  ngOnInit() {
    this.title = 'Update Product';
    if (this.dataService.serviceData) {
      console.log(this.dataService.serviceData);
      this.productData = this.dataService.serviceData; 
    }
  }

  ngDoCheck() {
    if (this.productData) {
      this.angForm.get('name').setValue(this.productData.name);
    }
  }

  createForm() {
    this.angForm = this.fb.group({
      name: ['', Validators.required ],
      decription: ['', Validators.required ],
      status: ['', Validators.required ]
    });
  }

  updateProduct() {
    console.log('submit');
  }
}

Screenprint:

You can see that the button is disabled and the input text is non-editable

You can see that the button is disabled and the input text is non-editable.

Upvotes: 3

Views: 589

Answers (1)

AVJT82
AVJT82

Reputation: 73357

You are using ngDoCheck, so everytime angular runs it, for example when you are trying to type, and productData is populated,

this.angForm.get('name').setValue(this.productData.name);

is run, and thus always setting the value making it seem that you cannot edit the field.

Since this can also be a race condition, as forms are asynchronous, I suggest building the form after getting value to productData (if getting value). So remove the createForm() function from constructor and add it later on:

if (this.dataService.serviceData) {
  console.log(this.dataService.serviceData);
  this.productData = this.dataService.serviceData; 
}
this.createForm();

Modify the createForm function a bit:

createForm() {
  this.angForm = this.fb.group({
    name: [this.productData.name || '', Validators.required ],
    description: [this.productData.description || ''],
    status: [this.productData.status || '']
  });
}

Upvotes: 4

Related Questions