Задать вопрос
@prokopn

Как сделать фильтр с чекбоксами?

Подскажите как сделать фильтр с чекбоксами? Изначально нужно что-бы было видно все блоки, при клике на чекбоксы они фильтровались, и если все чекбоксы обратно выключить то видны опять все блоки. У блоков может быть несколько тем, по которым нужно фильтровать. Спасибо!
  • Вопрос задан
  • 102 просмотра
Подписаться 1 Средний 1 комментарий
Пригласить эксперта
Ответы на вопрос 2
@kotoslav
Примерно так? Если выбранные темы есть в блоке, то он отображется.

/*Создадим массив из объектов, который будет содержать в себе ссылку на блок и темы содержащиеся в блоке
{
node: ...,
themes: [...]
}

*/
const blocks = Array.
from(document.querySelectorAll('.filter__column'))
.map((block) => {
	return {
  	node: block,
    themes: Array.from(block.classList)
    .filter( blockClass => blockClass.includes("filter__checkbox_filter"))
  }
});

/* Такую же операцию проведем с чекбоксами
{
node: ...,
theme: ...
}
*/
const inputs = Array.
from(document.querySelectorAll('.checkbox__input'))
.map((check) => {
	return {
  	node: check,
    theme: check.getAttribute("data-filter")
  }
});

//Функция которая будет вызываться при любом изменении чекбокса
function onCheckBoxChange() {
const checkedInput = inputs.filter(c => c.node.checked);
if (checkedInput.length == 0)
  {
    blocks.forEach(block => {block.node.classList.remove("_hidden-checkbox")}) //если фильтров не выбрано, то отображаем все элементы
  } else {
  	blocks.forEach(block => {block.node.classList.add("_hidden-checkbox")}); // иначе скроем все элементы
    let buffBlocks = [...blocks]; // Здесь собираем только те блоки, которые содержат нужные темы
    checkedInput.forEach(input => {
    	buffBlocks = buffBlocks.filter(block => {
      	return block.themes.includes(`filter__checkbox_${input.theme}`);
      });
    });
    buffBlocks.forEach(block => block.node.classList.remove("_hidden-checkbox")); //Отобразим блоки, которые соответствуют фильтру
  }
}

document.querySelector(".checkboxes").addEventListener("change", onCheckBoxChange);
Ответ написан
Комментировать
@ImagineTables
Если список фильтров статичный или есть возможность генерировать CSS (например, препроцессором), можно так:

body:has(input.filter[data-filter~="Filter1"]:checked) div.block[data-filter~="Filter1"],
body:has(input.filter[data-filter~="Filter2"]:checked) div.block[data-filter~="Filter2"],
body:has(input.filter[data-filter~="Filter3"]:checked) div.block[data-filter~="Filter3"]
{
    display: none;
}


У блоков есть атрибут data-filter с пробело-разделяемым списком фильтров. У чекбоксов-фильтров — аналогично. Чекинг любого чекбокса делает невидимыми все блоки, у которых совпадает хотя бы один фильтр с этим чекбоксом.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы