In Javascript, how can I check that DOM elements input has changed without hardcoding and comparing values?

Viewed 764

I have the following StimulusJS controller that aims to track certain required elements (flatckpickr date selectors).

Once all those date pickers' dates have been selected, I have to enable the submit button in a form.

I'm having problems tracking that all the required inputs have been inputed by the user and since this should be a reutilizable controller, I can't hardcode a value and compare against it.

What would be an effective way to check that all requiredTargets have received input from the user?

import { Controller } from 'stimulus';

export default class extends Controller {
  static targets = ["required", "deactivable"];

  toggle(){
    this.deactivableTargets.toggleAttribute("disabled");
  }

  connect() {
    
    this.requiredTargets.forEach((element) => {

      element.addEventListener('input', (event) => {

        console.log(`${element} changed`);

        //if (this.requiredTargets.inputed?) {
          toggle();
        }
      })
    })
  }
}
1 Answers

Technically inputs fields will have a value of an empty string ("") by default

You can use the JavaScript Array.every method to check that all required fields have been filled and are not equal to an empty string.

This will return true or false, and depending on what the case is, you can call the toggle() method

My Approach

On each flatpickr HTML input element, connect a Stimulus action method that fires on input event.

Let's call it handleInput in this case, so our HTML should look like this

<input
  data-<controller-name>-target="required"
  data-action="<controller-name>#handleInput"
  type="text"
  placeholder="Select Date.."
  data-input
>
<!-- replace <controller-name> with the actual stimulus controller name -->

Next, define the handleInput method in your controller like this

handleInput() {
  const isRequiredFilled = this.requiredTargets.every(el => el.value !== '');

  if (isRequiredFilled) {
    this.toggle();
  }
}

NB: input element has a default input event so you don't have to handle that yourself. See the documentation

Related