Search code examples
angularformsinput

Disable/enable button based on change of value Angular


I have a form with different input fields including input[type="file"] and input[type="checkbox"]. I get values of input form fields with get request from backend and I store them in company variable.

ngOnInit(): void {
    this.generateForm();

    this.companyService.getCompany().subscribe((response: Company) => {
      this.company = response;

      this.settingsForm.setValue({
        ...this.company,
        certificateUrl: [this.company.certificateUrl],
      });
    });
  }

I first generate form and then get my response from get request so I could set my company variable to the response and set value of form based on values I got. The problem is I want to enable button in html whenever my form is valid and changed. So button should be disabled when no change is made based on previous value. For example: If we have field name with value 'myName' and I type into input 'my' button should be enabled because change is made comparing to previous value. If I type back 'myName' it should be disabled because value is the same as previous. Same should happen if field is empty and user types in something and for fields type file and checkbox.

This is how I'm currently trying to do it.

inputChanged: boolean = false

ngOnInit() {
    this.settingsForm.valueChanges.subscribe((currentValue) => {
      if (JSON.stringify(currentValue) !== JSON.stringify(this.company)) {
        this.inputChanged = true;
      } else {
        this.inputChanged = false;
      }
    });
}
////

 <button
          [disabled]="!inputChanged || !settingsForm.valid"
          class="btn btn-md text-light"
        >
          Save
        </button>

This is my form

<form class="mt-4" [formGroup]="settingsForm" (ngSubmit)="saveChanges()">
    <div class="row">
      <div class="col-6">
        <div class="form-group">
          <label class="form-label fw-bold">ID</label>
          <input
            formControlName="identificationNumber"
            type="text"
            class="form-control"
          />
        </div>
        <div class="form-group d-none">
          <label class="form-label fw-bold">Id</label>
          <input formControlName="id" type="text" class="form-control" />
        </div>
        <div class="form-group d-none">
          <label class="form-label fw-bold">Country</label>
          <input formControlName="country" type="text" class="form-control" />
        </div>

        <div class="form-group">
          <label class="form-label fw-bold"
            >P</label
          >
          <input formControlName="tin" type="text" class="form-control" />
 
        </div>
        <div class="form-group">
          <label class="form-label fw-bold">Name</label>
          <input formControlName="name" type="text" class="form-control" />
        </div>
      </div>
      <div class="col-6">
        <div class="form-group">
          <label class="form-label fw-bold">City</label>
          <input formControlName="city" type="text" class="form-control" />
        </div>

        <div class="form-group">
          <label class="form-label fw-bold">Address</label>
          <input formControlName="address" type="text" class="form-control" />
        </div>
        <div class="form-group">
          <label class="form-label fw-bold">Postal code</label>
          <input
            formControlName="postalCode"
            type="text"
            class="form-control"
          />
        </div>
        <div class="form-check ms-1">
          <label class="form-check-label fw-bold">Vat</label>
          <input
            formControlName="inVat"
            type="checkbox"
            class="form-check-input"
            [checked]="company?.inVat"
          />
        </div>
      </div>
    </div>

    <div class="row align-items-end justify-content-between">
      <div class="col-8">
        <app-file-upload
          [company]="company"
          formControlName="certificateUrl"
        ></app-file-upload>
      </div>

      <div class="col-4">
        <button
          [disabled]="!inputChanged || !settingsForm.valid"
          class="btn btn-md text-light"
        >
          Save changes
        </button>
      </div>
    </div>
  </form>

But it doesn't work. How can I fix this?


Solution

  • I found a solution using objectHash. First install it with npm i -D @types/hash.

    import * as objectHash from 'object-hash';
    
    this.settingsForm.valueChanges.subscribe((currentValue) => {
          if (objectHash.sha1(currentValue) !== objectHash.sha1(this.company)) {
            this.inputChanged = true;
          } else {
            this.inputChanged = false;
          }
        });
    
    ////
    <button
        [disabled]="!inputChanged || !settingsForm.valid"
        class="btn btn-md text-light"
        >
        Save
    </button>