• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
    • Questions
    • Teachers
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

170
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error