Search code examples
javascripthtmldom-eventsdropdown

Dropdown click event not firing in HTML and JS code


Dropdown Click Event Not Being Triggered

I tried loading the listener after the DOM is loaded, for each option I added, neither seemed to work. It's a bit more complicated since I have images, so I'm not using the regular html dropdown and I'm also adding the options programmatically. Or sometimes, it'll submit the number 0 (I have no clue why) here's the codepen to see it working

and here's the raw js:

const wcaIdInput = document.getElementById('wcaIdInput');
const wcaIdList = document.getElementById('wcaIdList');
const dropdownList = document.getElementById('dropdown-list');

wcaIdInput.addEventListener('input', () => {
  const inputValue = encodeURIComponent(wcaIdInput.value.toLowerCase());

 dropdownList.addEventListener('click', (event) => {
  const clickedElement = event.target;
  console.log(clickedElement); 
});

fetch(`https://www.worldcubeassociation.org/api/v0/search/users?q=${inputValue}&persons_table=true`)
    .then(response => response.json())
    .then(data => {
      let top3 = [];
      for (let i = 0; i < 3 && i < data.result.length; i++) {
        top3.push({
          name: data.result[i].name,
          id: data.result[i].id,
          avatarUrl: data.result[i].avatar.url
        });
      }
      populateOptions(top3);
    })
    .catch(error => {
      console.error(error);
    });
});

// wcaIdList.addEventListener('change', (event) => {
//   wcaIdInput.value = event.target.value;
// });
document.addEventListener('click', (event) => {
  const clickedElement = event.target;
  if (dropdownList.contains(clickedElement)) {
    console.log(clickedElement);
  }
});

function populateOptions(options) {
  dropdownList.innerHTML = '';

  if (options.length > 1) {
    options.reverse().forEach(option => {
      const optionElement = document.createElement('li');
      optionElement.value = option.id;
      optionElement.innerHTML = `
        <img src="${option.avatarUrl}" alt="Avatar" width="40" height="40">
        <span class="bigger-text">${option.name}</span>
        <span class="smaller-text">${option.id}</span>
      `;
      optionElement.addEventListener('click', () => {
        console.log('yo what?');
        console.log('Clicked option:', optionElement); // New console log
        wcaIdInput.value = optionElement.value;
        hideDropdown();
        submitWcaId();
      });
      dropdownList.appendChild(optionElement);
    });

    dropdownList.style.display = 'block';
    dropdownList.style.top = `${wcaIdInput.offsetTop + wcaIdInput.offsetHeight}px`;
    dropdownList.style.left = `${wcaIdInput.offsetLeft}px`;
  } else if (options.length === 1) {
    const optionElement = document.createElement('li');
    optionElement.value = options[0].id;
    optionElement.innerHTML = `
      <img src="${options[0].avatarUrl}" alt="Avatar" width="40" height="40">
      <span class="bigger-text">${options[0].name}</span>
    `;
    console.log(optionElement);
    optionElement.addEventListener('click', () => {
      console.log("click moment!");
      console.log('Clicked option:', optionElement); // New console log
      wcaIdInput.value = optionElement.value;
      hideDropdown();
      submitWcaId();
    });
    dropdownList.appendChild(optionElement);

    // Show and position the dropdown list
    dropdownList.style.display = 'block';
    dropdownList.style.top = `${wcaIdInput.offsetTop + wcaIdInput.offsetHeight}px`;
    dropdownList.style.left = `${wcaIdInput.offsetLeft}px`;
  } else {
    hideDropdown();
  }
}
function hideDropdown() {
  dropdownList.style.display = 'none';
}

wcaIdInput.addEventListener('focus', () => {
  if (wcaIdInput.value.trim() !== '') {
    dropdownList.style.display = 'block';
  }
});

wcaIdInput.addEventListener('blur', () => {
  hideDropdown();
});

and html:

<!DOCTYPE html>
<html lang="en">
<head>
  ...
</head>
<body>
  <div class="container">
    <div class="dropdown">
      <input type="text" id="wcaIdInput" name="wcaIdInput" placeholder="WCA ID" autocomplete="off" autofocus>
      <ul id="dropdown-list"></ul>
    </div>
    <button id="submitBtn">Submit</button>
  </div>
  <div id="loading" style="display: none;">
    <div class="loader"></div>
  </div>
  <div id="error" class="error"></div>
  <div id="tableContainer"></div>
  <script src="js/upcoming.js"></script>
</body>
</html>

Solution

  • The following onBlur handler

    wcaIdInput.addEventListener('blur', () => {
      hideDropdown();
    });
    

    fires and hides the dropdown before clicking on an item happens.

    As a result, your click doesn't reach an item, and hence, click callback is not executed.

    Commenting out this handler solves the problem.

    You may want to remove this handler or use some other event to hide the dropdown.