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"
>
Save
</button>
This is my form
<form [formGroup]="settingsForm" (ngSubmit)="saveChanges()">
<div >
<div >
<div >
<label >ID</label>
<input
formControlName="identificationNumber"
type="text"
/>
</div>
<div >
<label >Id</label>
<input formControlName="id" type="text" />
</div>
<div >
<label >Country</label>
<input formControlName="country" type="text" />
</div>
<div >
<label
>P</label
>
<input formControlName="tin" type="text" />
</div>
<div >
<label >Name</label>
<input formControlName="name" type="text" />
</div>
</div>
<div >
<div >
<label >City</label>
<input formControlName="city" type="text" />
</div>
<div >
<label >Address</label>
<input formControlName="address" type="text" />
</div>
<div >
<label >Postal code</label>
<input
formControlName="postalCode"
type="text"
/>
</div>
<div >
<label >Vat</label>
<input
formControlName="inVat"
type="checkbox"
[checked]="company?.inVat"
/>
</div>
</div>
</div>
<div >
<div >
<app-file-upload
[company]="company"
formControlName="certificateUrl"
></app-file-upload>
</div>
<div >
<button
[disabled]="!inputChanged || !settingsForm.valid"
>
Save changes
</button>
</div>
</div>
</form>
But it doesn't work. How can I fix this?
CodePudding user response:
You could make use of other reactive Form attributes
Using pristine
for example
A control is pristine if the user has not yet changed the value in the UI.
<button
[disabled]="settingsForm.pristine || settingsForm.invalid"
>Save</button>
if you need to be more specific in the control values, it becomes more tricky as comparing Javascript objects is not as trivial.
This question is a great deep dive
CodePudding user response:
The reactive form should have a valid and touched attribute and could be used as following.
<button
[disabled]="!settingsForm.touched || settingsForm.invalid"
>Save</button>