maddness
maddness

Reputation: 41

Vanilla JS remove class from previous selection

Im working with this part of code

   <div class="single-select">
        <div class="single-title">
            <p class="title">User answear</p> <img src="../resources/chevron-down.svg" alt="">
        </div>
        <ul id="single-select-dropdown">
            <li class="option" id="option1">answear 1 <img src="../resources/checkmark.svg" alt=""></li>
            <li class="option" id="option2">answear 2 <img src="../resources/checkmark.svg" alt=""></li>
            <li class="option" id="option3">answear 3 <img src="../resources/checkmark.svg" alt=""></li>
        </ul>
    </div>

const dropdownOptions = document.querySelectorAll('.single-select .option');

dropdownOptions.forEach(option => option.addEventListener('click', handleOptionSelected));

function handleOptionSelected(e) {
    const newValue = e.target.textContent + ' ';
    const titleElem = document.querySelector('.single-title .title');
    titleElem.textContent = newValue;
    e.target.classList.add('active')
}

Everytime when i choose option JS should add to class list class 'active'. The point is that only single option can have this class on it. Can someone help me how to remove it everytime when i choose other option?

Upvotes: 1

Views: 200

Answers (3)

zer00ne
zer00ne

Reputation: 43990

  1. Wrap the callback in an anonymous function:

    //...
    option.addEventListener('click', function(e) {
      handleOptionSelected(e);
    });
    //...
    
  2. Then add a the following before the callback:

    //...
    //option.addEventListener('click', function(e) {
        dropdownOptions.forEach(option => option.classList.remove('active'));
    //  handleOptionSelected(e);
    //});
    //...
    

    Now whenever the user clicks an option, all options will remove the class .active -- then the callback handleOptionSelected() will add .active to the clicked option.


Demo

Note: A CSS pseudo-element was added to demonstrate that there is only one .option.active at a time.

const dropdownOptions = document.querySelectorAll('.single-select .option');

dropdownOptions.forEach(option => {
  option.addEventListener('click', function(e) {
    dropdownOptions.forEach(option => option.classList.remove('active'));
    handleOptionSelected(e);
  });
});

function handleOptionSelected(e) {
  const newValue = e.target.textContent + ' ';
  const titleElem = document.querySelector('.single-title .title');
  titleElem.textContent = newValue;
  e.target.classList.add('active');
}
.option::after {
  content: ' 'attr(class)
}
<div class="single-select">
  <div class="single-title">
    <p class="title">User answear</p> <img src="../resources/chevron-down.svg" alt="">
  </div>
  <ul id="single-select-dropdown">
    <li class="option" id="option1">answear 1 <img src="../resources/checkmark.svg" alt=""></li>
    <li class="option" id="option2">answear 2 <img src="../resources/checkmark.svg" alt=""></li>
    <li class="option" id="option3">answear 3 <img src="../resources/checkmark.svg" alt=""></li>
  </ul>
</div>

Upvotes: 1

SpiritOfDragon
SpiritOfDragon

Reputation: 1432

You have to iterate and remove the active class

const dropdownOptions = document.querySelectorAll('.single-select .option');

dropdownOptions.forEach(option => option.addEventListener('click', handleOptionSelected));

function removeActive() {
  [...dropdownOptions].some(function(option) {
    // we are using .some assuming you have only 1 active class at any given time. If you think you will have multiple active classes, you can use .forEach instead of .some
    const hasClass = option.classList.contains('active');
    if (hasClass) {
      option.classList.remove('active');
    }

    return hasClass;
  })
}

function handleOptionSelected(e) {
  const newValue = e.target.textContent + ' ';
  const titleElem = document.querySelector('.single-title .title');
  titleElem.textContent = newValue;
  removeActive();
  e.target.classList.add('active')
}
.active {
  color: green;
}
<div class="single-select">
  <div class="single-title">
    <p class="title">User answear</p> <img src="../resources/chevron-down.svg" alt="">
  </div>
  <ul id="single-select-dropdown">
    <li class="option" id="option1">answear 1 <img src="../resources/checkmark.svg" alt=""></li>
    <li class="option" id="option2">answear 2 <img src="../resources/checkmark.svg" alt=""></li>
    <li class="option" id="option3">answear 3 <img src="../resources/checkmark.svg" alt=""></li>
  </ul>
</div>

Upvotes: 0

Evert vd H.
Evert vd H.

Reputation: 343

Add this to your code

function handleOptionSelected(e) {
    const newValue = e.target.textContent + ' ';
    const titleElem = document.querySelector('.single-title .title');
    titleElem.textContent = newValue;

    // Add this part
    const listElem = document.getElementsByClassName('option');
    listElem.forEach(el => {
        el.classList.remove('active'));
    };

    e.target.classList.add('active');
}

Upvotes: 0

Related Questions