Home > Net >  Button appears disabled until i click out of input in Angular
Button appears disabled until i click out of input in Angular

Time:12-19

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&deg;F or higher!</div>
      <div  *ngIf="temperatureValidationCelsius" >Temperature must be 26&deg;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&deg;F or higher!
</div>
<div  *ngIf="temperatureValidationCelsius && 
heatIndexForm.controls.temperature.touched">
          Temperature must be 26&deg;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.

  • Related