The button's status changes to disabled until I click outside the input field in Angular

I am currently facing an issue with a form (heat index calculator) that requires 2 inputs - a dropdown and a button. The button is disabled when there are no inputs or if the inputs are invalid. Everything works correctly, except for the fact that even when I enter valid arguments in both inputs, the button remains disabled until I click out of the input field. Is there a way to enable the button as soon as I enter a valid argument without having to click out of the input field? Another similar issue arises when I select Celsius or Fahrenheit options in the dropdown. When I choose Celsius and type in a value like 50, then change my mind and switch to Fahrenheit, the validation error doesn't appear unless I delete the value and re-enter it.

This is the HTML code:

<form [formGroup]="heatIndexForm" class="wrapper" (ngSubmit)="onSubmit()">
    <label class="temperature-row">
      <p class="temperature-input">Air Temperature</p>
      <div class="field col-12 md:col-4">
        <p-inputNumber
        [style]="{'height': '51px'}"
        formControlName="temperature"
        mode="decimal"
        class="form-control">
      </p-inputNumber>
      <div class="validation-error" *ngIf="temperatureValidationFahrenheit">Temperature must be 80&deg;F or higher!</div>
      <div class="validation-error" *ngIf="temperatureValidationCelsius" >Temperature must be 26&deg;C or higher!</div>
    </div>
      <p-dropdown
      class="form-control"
      [style]="{'height':'51px', 'paddingTop': '5px', 'marginLeft': '5px'}"
      formControlName="selectedTemp"
      (onChange)="selectionChanged()" [options]="temps"
      optionLabel="units"></p-dropdown>
    </label>
    <label class="humidity-row">
      <p class="humidity-input">Relative Humidity</p>
      <div [style]="{'position': 'relative'}" class="field col-12 md:col-4">
        <p-inputNumber   [style]="{'height': '51px'}" mode="decimal"formControlName="humidity" class="form-control"></p-inputNumber>
        <div class="percent">%</div>
        <div  class="validation-error" *ngIf="heatIndexForm.controls['humidity'].invalid">Humidity must be 0% - 100%</div>
      </div>
    </label>
    <div class="buttons">
      <button
      class="form-control"
      [disabled]="disableCalculateButton"
       pButton
       label="Calculate"></button>
      <p-button label="Reset" (onClick)="reset()"></p-button>
    </div>
  </form>

And here is the TypeScript code for the form:

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'),
    ];
  }

  // More code goes here...

I attempted to solve the button issue using template-driven approach but encountered the same problem.

Answer №1

To automatically enable or disable the submit button while typing, utilize Angular's form validation feature instead of creating your own validator method like disableCalculateButton(). Simply add Validators.required to the temperature and humidity fields:

component.ts

temperature: new FormControl(null, [Validators.min(26), Validators.required]),
humidity: new FormControl(null, [Validators.max(100), Validators.min(0), Validators.required]),

Adjust the [disabled] attribute in the submit button element to only show an error message when a field is filled out. Check if the form field has been touched:

component.html

<div class="validation-error" *ngIf="temperatureValidationFahrenheit && 
heatIndexForm.controls.temperature.touched">
          Temperature must be 80&deg;F or higher!
</div>
<div class="validation-error" *ngIf="temperatureValidationCelsius && 
heatIndexForm.controls.temperature.touched">
          Temperature must be 26&deg;C or higher!
</div>
.
.
.
<div
class="validation-error"
*ngIf="heatIndexForm.controls['humidity'].invalid &&
 heatIndexForm.controls.humidity.touched">
          Humidity must be 0% - 100%
</div>
.
.
.
<button
    class="form-control"
    [disabled]="heatIndexForm.invalid"
    pButton
    label="Calculate">
submit
</button>

Visit this stackblitz link for further details.

If you're facing another issue that requires multiple error messages for a single field, consider defining a custom validator as it may provide a solution to your problem more efficiently than handling errors with *ngIf.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to use Vuejs v-model for a complete form instead of individual inputs?

Note: This solution is applicable for Vue 2.X I am currently working on a unique Vue.js component that has the ability to generate "custom" forms. This component essentially functions as a standalone form with multiple input fields. Users have the option ...

Show User Input as a dynamic tool-tip in Highcharts

Is it possible to gather 12 user inputs through multiple text areas in a popup dialog box, and then use these inputs as tooltips for various points on a graph like the one shown in this demo: http://www.highcharts.com/demo/line-labels? I haven't found ...

Having trouble with installing Node Windows NPM?

I'm attempting to install a simple package in Node.js, but when I use the standard command, it indicates that it cannot find the file or directory (refer to the image below). Despite updating and re-installing npm, the issue persists. I am using Windo ...

Displaying nested objects within an object using React

Behold this interesting item: const [object, setObject] = useState ({ item1: "Greetings, World!", item2: "Salutations!", }); I aim to retrieve all the children from it. I have a snippet of code here, but for some reason, i ...

Issue Encountered in NodeJS While Processing Multiple GET Requests

I have been developing a web application that utilizes a database containing game data. When a user clicks on a game, a GET request is made to an API to retrieve additional information for the selected game. My goal is to ensure that users can access detai ...

Angular component with optional one-way binding for version 1.5 and above

Copied from the official AngularJS 1 documentation: To make a binding optional, simply add ?: <? or <?attr. What are the differences between the optional and non-optional one-way bindings? I can't seem to find the dissimilarities for the op ...

Utilizing Redux dispatch to uncheck checkboxes within renderOption with Material UI Autocomplete

In the Autocomplete component, I have a checkbox that is rendered in the renderOptions prop. By using the onChange function event: object, value: T | T[], reason: string), I can retrieve the list of selected options. The value parameter will provide me w ...

Tips on aligning three divs horizontally within a container while maintaining a height of 100%

UPDATE: The alignment has been corrected by adding floats. However, the height still doesn't fill 100%. Check out the new look: Image Link In my footer container, I want to arrange 3 columns (colored green, white, and red for clarity). Currently, the ...

Enhancing jQuery Functionality with Parameter Overrides

While it may seem like a simple question, I am new to writing jQuery plugins and could use some clarity on scope rules in JavaScript. My goal is to create a jQuery plugin that interacts with the Stack Overflow API. I have started exploring the Flair API f ...

Error: Unable to access the 'category_affiliation' property of null

After implementing a login function using redux state, I encountered an issue upon logging in. The error message TypeError: Cannot read properties of null (reading 'category_affiliation') is being displayed in my Sidebar.jsx file. It seems like t ...

Having trouble accessing the height of a div within an Iframe

Here is the issue I am facing: I need my iFrame to adjust its size based on a div within it, but every attempt to retrieve the size of this div results in 0. var childiFrame = document.getElementById("myDiv"); console.log(childiFra ...

Is it possible for dynamically created components to trigger output events?

My objective: Dynamically create components (completed) Enable dynamically created components to utilize "outputs" so that parent Components can listen for changes from the children. Here is a Plnkr showcasing what I am trying to achieve: Plnker -> ...

Auto Start Feature for jQuery Slider Function

Hey there, I currently have an image slider on my website that allows users to navigate through images by clicking on preview and next buttons. My query is: would it be possible to implement an auto start feature instead of having to click manually? Belo ...

Can you recommend any open source projects with exceptionally well-written Jasmine or Jasmine-Jquery tests?

Currently, I am in the process of learning how to test a new jquery plugin that I plan to develop. I'm curious if there are any notable Github projects like Jasmine or Jasmine-jquery with impressively crafted Jasmine tests that I could explore for in ...

Is it more efficient to wait for the server to respond, or should I update the client immediately

Today, I found myself contemplating an interesting question. As I work on developing a Single Page Application (SPA) using Angular, I am focusing on creating a calendar module similar to Google Calendar. This module will allow users to add, edit, and remov ...

Retrieve the values stored under the "kilos" key for every object in the dataset

Recently, I stumbled upon the following code snippet: data = [ 0: {kilos: 10}, 1: {other:1, kilos: 5}, 2: {other:2, kilos:6} ] After analyzing it, I realized that I need to extract all the values associated with the "kilos" keys and then calculat ...

The 'MutableRefObject<null>' type is lacking the following properties that are present in the 'Element' type

I'm eager to implement intersection observer in my React Typescript project. (https://www.npmjs.com/package/react-intersection-observer) However, I encountered an issue with setting the root: const root = useRef(null); const { ref, inView, entry } ...

Struggling with navigating JSON data in JavaScript and facing difficulties sorting the array

I am currently facing the challenge of organizing data obtained from an API using JavaScript. JavaScript Code to Retrieve Data: function getResults() { var url = $.getJSON("http://api.api.com&leagues=SOCENGPRE&lang=en&format=jsonp&cal ...

Is the iCheck feature designed to block all parent click events?

I've developed an "interaction tracker" system that collects anonymous data on clicked page elements. By implementing an event listener for clicks on the body, I can track interactions with any element on my site successfully. However, interestingly ...

Ways to Ensure a Property of an Object Remains Synced with Another

I'm dealing with the following Object structure: { a: "123" b: "$a" } In this setup, b should always be equal to the value of a. Any suggestions on how I can achieve this using JavaScript? ...