• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Evaluaciones
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

177
Vistas
addEventListener within a class always gets executed on the first element

I have this code, it's about disabling and enabling a button of a form according to its check box input. It's getting executed on different pages, you can see the last two lines where I loop through the forms on the page, all works fine when there is one from in the page, however, on pages where there is more than one form, it doesn't matter which check box I check (second or third for instance) it always affects the first button.

you can notice there are two "console.log" statements, the first one returns the correct input element (so when there are two forms in the pages, you can see in the console the elements reference the correct inputs on the DOM), however, the second one always shows an element in the console referring to the first input in the DOM.

my guess is that there is something wrong with the way I add the event listener, any suggestions for making that work?

class Steps {    
  constructor(el) {
    this.el = el;
    this.bindDOM();
    this.bindStepEvents();
  }

  bindDOM() {
    this.checkboxSelectorStep = this.el.querySelector('.radio-selector-steps-enable');
    this.submit = this.el.querySelector('button[type=submit]');
  }

  bindStepEvents() {
    console.log(this.checkboxSelectorStep); // returns the correct element 
    this.checkboxSelectorStep.addEventListener('click', (ev) => {
      console.log(this.checkboxSelectorStep); // always returns the first element
      if (ev.target.checked) {
        this.submit.removeAttribute('disabled');
      } else {
        this.submit.setAttribute('disabled', '');
      }
    });
  }
}

const forms = Array.from(document.querySelectorAll('.radio-selector-steps-form'));
forms.map(form => new Steps(form));
<form method="get" class="radio-selector-steps-form">
  <input type="checkbox"
         name="checkbox-selector-step"
         id="checkbox-selector-step"
         class="radio-selector-steps-enable">
  <label for="checkbox-selector-step"><span>some text</span></label>
  <button type="submit" disabled="">button text</button>
</form>
<form method="get" class="radio-selector-steps-form">
  <input type="checkbox"
         name="checkbox-selector-step"
         id="checkbox-selector-step"
         class="radio-selector-steps-enable">
  <label for="checkbox-selector-step"><span>some text</span></label>
  <button type="submit" disabled="">button text</button>
</form>

almost 3 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

The problem was that both of the inputs had the same id, and the labels are referencing that id, so hitting the input itself works fine but whenever the label is being clicked the first listener gets called.

(due to styling, clicking the input was not possible for my case so I would always end up with the wrong behavior until I tried to create a SO snippet for it and caught the issue)

Hoping this might help someone.

almost 3 years ago · Juan Pablo Isaza Denunciar

0

You need to use querySelectorAll instead of querySelector

  bindDOM() {
    this.checkboxSelectorStep = this.el.querySelectorAll(STEPS_ENABLE_CHKBOX);
    this.submit = this.el.querySelector(STEPS_FORM_SUBMIT);
  }

  bindStepEvents() {
    console.log(this.checkboxSelectorStep);
    this.checkboxSelectorStep.forEach(function(elem) { 
      elem.addEventListener('click', (ev) => {
      console.log(this.checkboxSelectorStep);
      if (ev.target.checked) {
        this.submit.removeAttribute('disabled');
this.update(JSON.parse(this.steps[0].primaryInput.value))
      } else {
        this.submit.setAttribute('disabled', '');
      }
    });
});
almost 3 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda