Alexander Qiu
Alexander Qiu

Reputation: 117

addEventListener not working on document.createElement elements

I'm trying to build a simple signup form that does some basic validation on the username, including checking whether a given user name is taken and if so, a list of suggested usernames. A problem that I ran into was that the dynamically generated list of suggestions (anchor tags) won't take an event listener for some reason. Here is the sample code of this.

singup.html

<script type="module">
  import { check_username } from './signup.js';
  const username_input = document.getElementById('id_username');
  username_input.addEventListener('change', (event) => {
    check_username(event, check_url);
  }, false);
</script>

signup.js

export const check_username = async (event, url) => {
  ...
  // check username with server
  if (!data.unique) {
    error_flag = true;
    error_p.innerHTML = 'Username taken, please consider:<br>';
    for (let name of data.suggestions) {
      let child_elem = document.createElement('a');
      child_elem.innerHTML = `${name}`;
      error_p.appendChild(child_elem);
      error_p.innerHTML += ' ';
      child_elem.addEventListener('click', clickHandler, false);
    }
  }
}

According to some other posts, I tried adding the event listener both before and after the element has been added, i.e. before and after calling appendChild, but neither worked. Curiously, I tried adding the event listener in the browser console, and that worked like a charm. I ended up resolving this by adding the event listener to the body and checking whether the event.target is the element in question, but I'm curious to know why my initial approach didn't work to get a better understanding of things.

Upvotes: 0

Views: 1607

Answers (1)

Musa
Musa

Reputation: 97672

Setting the innerHTML of error_p replaces the content including all elements with their event handlers. Just insert a text node instead of a space with inner html

for (let name of data.suggestions) {
  let child_elem = document.createElement('a');
  child_elem.innerHTML = `${name}`;
  error_p.appendChild(child_elem);
  error_p.appendChild(document.createTextNode(' '));
  child_elem.addEventListener('click', clickHandler, false);
}

Upvotes: 2

Related Questions