Как сделать фильтр с выбором нескольких значений на JS

document.querySelectorAll('[uk-filter-control]').forEach(item => {
  item.addEventListener('click', event => {
    event.preventDefault();
    handleFilterItems(item);
  });
});

function handleFilterItems(filterItem) {
  if (filterItem.getAttribute('uk-filter-control') === '' || filterItem.getAttribute('uk-filter-control') === '.all') {
    document.querySelectorAll('[uk-filter-control]').forEach(item => {
      item.classList.remove('active');
    });
  } else {
    document.querySelector('[uk-filter-control=".all"]').classList.remove('active');
  }
  if (filterItem.classList.contains('active')) {
      filterItem.classList.remove('active');
    // check if no other filter item is active
    if(!document.querySelectorAll('[uk-filter-control].active').length) {
      document.querySelector('[uk-filter-control=".all"]').classList.add('active');
    }
  } else {
    filterItem.classList.add('active');
  }
  
  handleFilterTeaser();
}

function handleFilterTeaser() {
  // hide all
  document.querySelectorAll('.all').forEach(item => {
    item.classList.add('hidden');
  });
  if (document.querySelectorAll('[uk-filter-control].active').length === 0) {
    document.querySelectorAll('.all').forEach(item => {
      item.classList.remove('hidden');
    });
  } else {
    document.querySelectorAll('[uk-filter-control].active').forEach(item => {
      let filterTag = item.getAttribute('uk-filter-control');
      document.querySelectorAll(filterTag).forEach(tag => {
        tag.classList.remove('hidden');
      });
    });
  }
  
}
ul, li {
  list-style: none;
  display: inline-block;
}
a {
  padding: 20px;
  &:hover {
    color: green;
  }
  &.active {
    color: tomato;
  }
}
.list {
  > div {
    background: grey;
    margin-bottom: 10px;
    color: #fff;
    padding: 10px;
  }
}
.hidden {
  display: none;
}
<div>
  <ul>
    <li>
      <a class="active" href="#" uk-filter-control=".all">all</a>
    </li>
    <li>
      <a href="#" uk-filter-control=".a">a</a>
    </li>
    <li>
      <a href="#" uk-filter-control=".b">b</a>
    </li>
    <li>
      <a href="#" uk-filter-control=".c">c</a>
    </li>
  </ul>
</div>
<div class="list">
  <div class="all a">all a 1</div>
  <div class="all b">all b 2</div>
  <div class="all a b">all a b 3</div>
  <div class="all b">all b 4</div>
  <div class="all a">all a 5</div>
   <div class="all c">all c 6</div>
</div>

https://codepen.io/slagrach/pen/VwBvbxr?editors=1010

Есть код не пойму как убрать пункт "All". Нужно сделать так чтоб при загрузке был выбран один элемент. Далее по нажатии можно выбрать еще либо убрать первый и выбрать другой в общем не так что нажали один другой пропал И еще как сделать чтоб выбранные элементы выводились в отдельном блоке

введите сюда описание изображения


Ответы (1 шт):

Автор решения: Andrei

Можно сделать вот таким способом:

let a = document.querySelectorAll('[uk-filter-control]');
for (let item of a) {
  if (item.classList.contains('active')) {
    let elements = document.querySelectorAll(item.getAttribute('uk-filter-control'));
    for (let el of elements) {
      el.classList.remove('hidden');
    }
  }
}


for (item of a) {
  item.addEventListener('click', e => {
    e.preventDefault();

    if (e.target.classList.contains('active')) {
      e.target.classList.remove('active');
      let elements = document.querySelectorAll(e.target.getAttribute('uk-filter-control'));
      for (let el of elements) {
        el.classList.add('hidden');
        if (el.classList.length > 1) {
          for (let cls of el.classList) {
            if (document.getElementById(cls) && document.getElementById(cls) != e.target) {
              let lnk = document.getElementById(cls);
              if (lnk.classList.contains('active')) {
                el.classList.remove('hidden');
              }
            }
          }
        }

      }

    } else {
      e.target.classList.add('active');
      let elements = document.querySelectorAll(e.target.getAttribute('uk-filter-control'));

      for (let el of elements) {
        el.classList.remove('hidden');
      }

    }
  });
}
ul,
li {
  list-style: none;
  display: inline-block;
}

a {
  padding: 20px;
}

a:hover {
  color: green;
}

a.active {
  color: tomato;
}

.list>div {
  background: grey;
  margin-bottom: 10px;
  color: #fff;
  padding: 10px;
}

.hidden {
  display: none;
}
<div>
  <ul>
    <li>
      <a href="#" uk-filter-control=".a" id='a' class="active">a</a>
    </li>
    <li>
      <a href="#" uk-filter-control=".b" id='b'>b</a>
    </li>
    <li>
      <a href="#" uk-filter-control=".c" id='c'>c</a>
    </li>
  </ul>
</div>
<div class="list">
  <div class="all a hidden">all a 1</div>
  <div class="all b hidden">all b 2</div>
  <div class="all a b hidden">all a b 3</div>
  <div class="all b hidden">all b 4</div>
  <div class="all a hidden">all a 5</div>
  <div class="all c hidden">all c 6</div>
</div>

По Вашей просьбе реализовал возможность добавления и удаления информационного сообщения о выбранном фильтре:

const choice = document.getElementById('choice');
const filterBtn = document.querySelectorAll('a');
const a = document.querySelectorAll('[uk-filter-control]');
for (let item of a) {
  if (item.classList.contains('active')) {
    let elements = document.querySelectorAll(item.getAttribute('uk-filter-control'));
    for (let el of elements) {
      el.classList.remove('hidden');

    }
    // Добавляем информацию о выбранном фильтре в момент
    // старта программы
    const span = document.createElement('SPAN');
    span.setAttribute('id', `f${item.textContent}`);
    span.textContent = item.textContent;
    choice.append(span);
  }
}


for (item of a) {
  item.addEventListener('click', e => {
    e.preventDefault();

    if (e.target.classList.contains('active')) {
      e.target.classList.remove('active');

      // Удаляем информацию о фильтре во время его выключения
      document.querySelector(`#f${e.target.textContent}`).remove();

      let elements = document.querySelectorAll(e.target.getAttribute('uk-filter-control'));
      for (let el of elements) {
        el.classList.add('hidden');
        if (el.classList.length > 1) {
          for (let cls of el.classList) {
            if (document.getElementById(cls) && document.getElementById(cls) != e.target) {
              let lnk = document.getElementById(cls);
              if (lnk.classList.contains('active')) {
                el.classList.remove('hidden');
              }
            }
          }
        }

      }

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

      // Добавляем информацию о фильтре во время его включения
      const span = document.createElement('SPAN');
      span.setAttribute('id', `f${e.target.textContent}`);
      span.textContent = e.target.textContent;
      choice.append(span);

      let elements = document.querySelectorAll(e.target.getAttribute('uk-filter-control'));

      for (let el of elements) {
        el.classList.remove('hidden');
      }

    }
  });
}
ul,
li {
  list-style: none;
  display: inline-block;
}

a {
  padding: 20px;
}

a:hover {
  color: green;
}

a.active {
  color: tomato;
}

.list>div {
  background: grey;
  margin-bottom: 10px;
  color: #fff;
  padding: 10px;
}

.hidden {
  display: none;
}
<div>
  <ul>
    <li>
      <a href="#" uk-filter-control=".a" id='a' class="active">a</a>
    </li>
    <li>
      <a href="#" uk-filter-control=".b" id='b'>b</a>
    </li>
    <li>
      <a href="#" uk-filter-control=".c" id='c'>c</a>
    </li>
  </ul>
</div>
<div id='choice'></div>
<div class="list">
  <div class="all a hidden">all a 1</div>
  <div class="all b hidden">all b 2</div>
  <div class="all a b hidden">all a b 3</div>
  <div class="all b hidden">all b 4</div>
  <div class="all a hidden">all a 5</div>
  <div class="all c hidden">all c 6</div>
</div>

→ Ссылка