I have a form (heat index calculator) which take 2 inputs, dropdown and button, button is disabled if there is nothing in the inputs or if the inputs are invalid, everything works fine except when i type in both inputs valid arguments the button still appears disabled until i click out of the input. Is there way to enable the button as soon as i type valid argument in the input without having to click out of it to show ? and another similar issue is.. i have dropdown there with celsius and fahrenheit options, when selected F the minimum value user have to type is 80 and for C minimum is 26 and the issue is when i choose C for eg and type 50 and change my mind and select fahrenheit instead, the validation error doesnt show up.. i have to delete the value and if i type again the 50 now the error shows
this is html
<form [formGroup]="heatIndexForm" (ngSubmit)="onSubmit()">
<label >
<p >Air Temperature</p>
<div >
<p-inputNumber
[style]="{'height': '51px'}"
formControlName="temperature"
mode="decimal"
>
</p-inputNumber>
<div *ngIf="temperatureValidationFahrenheit">Temperature must be 80°F or higher!</div>
<div *ngIf="temperatureValidationCelsius" >Temperature must be 26°C or higher!</div>
</div>
<p-dropdown
[style]="{'height':'51px', 'paddingTop': '5px', 'marginLeft': '5px'}"
formControlName="selectedTemp"
(onChange)="selectionChanged()" [options]="temps"
optionLabel="units"></p-dropdown>
</label>
<label >
<p >Relative Humidity</p>
<div [style]="{'position': 'relative'}" >
<p-inputNumber [style]="{'height': '51px'}" mode="decimal"formControlName="humidity" ></p-inputNumber>
<div >%</div>
<div *ngIf="heatIndexForm.controls['humidity'].invalid">Humidity must be 0% - 100%</div>
</div>
</label>
<div >
<button
[disabled]="disableCalculateButton"
pButton
label="Calculate"></button>
<p-button label="Reset" (onClick)="reset()"></p-button>
</div>
</form>
form ts
export class HeatIndexComponent implements OnInit {
haveResult: boolean = false;
temps: Temperature[];
heatIndexForm: FormGroup;
constructor(
private heatIndexService: HeatIndexService,
private localStore: LocalService
) {
this.temps = [
new Temperature('Celsius', 'C'),
new Temperature('Fahreheit', 'F'),
];
}
ngOnInit(): void {
this.heatIndexForm = new FormGroup({
temperature: new FormControl(null, Validators.min(26)),
humidity: new FormControl(null, [Validators.max(100), Validators.min(0)]),
selectedTemp: new FormControl(new Temperature('Celsius', 'C')),
result: new FormControl(''),
resultComment: new FormControl(''),
});
}
get temperatureValidationFahrenheit() {
return (
this.heatIndexForm.controls['selectedTemp'].value.code === 'F' &&
this.heatIndexForm.controls['temperature'].invalid
);
}
get temperatureValidationCelsius() {
return (
this.heatIndexForm.controls['selectedTemp'].value.code === 'C' &&
this.heatIndexForm.controls['temperature'].invalid
);
}
get disableCalculateButton() {
return (
this.heatIndexForm.controls['temperature'].invalid ||
this.heatIndexForm.controls['humidity'].invalid ||
this.heatIndexForm.controls['temperature'].value == null ||
this.heatIndexForm.controls['humidity'].value == null
);
}
selectionChanged() {
this.haveResult = false;
const value = this.heatIndexForm.get('selectedTemp').value;
this.heatIndexForm.controls['temperature'].clearValidators();
if (value.code !== 'C') {
this.heatIndexForm.controls['temperature'].setValidators(
Validators.min(80)
);
}
if (value.code === 'C') {
this.heatIndexForm.controls['temperature'].setValidators(
Validators.min(26)
);
}
this.heatIndexForm.updateValueAndValidity();
}
i tried the button issue with template driven approach but same thing happened
CodePudding user response:
To enable and disable submit button as soon as you type, let angular validate the form for you instead of providing your own validator method disableCalculateButton()
. Add Validators.required
to temperature
and humidity
fields (instead of manually checking if they're null):
component.ts
temperature: new FormControl(null, [Validators.min(26), Validators.required]),
humidity: new FormControl(null, [Validators.max(100), Validators.min(0), Validators.required]),
And change [disabled]
value in submit button. to only display error message when field is populated, check if the form field has been touched
component.html
<div *ngIf="temperatureValidationFahrenheit &&
heatIndexForm.controls.temperature.touched">
Temperature must be 80°F or higher!
</div>
<div *ngIf="temperatureValidationCelsius &&
heatIndexForm.controls.temperature.touched">
Temperature must be 26°C or higher!
</div>
.
.
.
<div
*ngIf="heatIndexForm.controls['humidity'].invalid &&
heatIndexForm.controls.humidity.touched">
Humidity must be 0% - 100%
</div>
.
.
.
<button
[disabled]="heatIndexForm.invalid"
pButton
label="Calculate">
submit
</button>
Link to stackblitz
For your second issue unfortunatly I couldn't find any solution but I think defining a custom validator would help alot. Manging multiple error messages for one field with *ngIf
is a bit of trouble.