Каким образом можно создать фильтр, в котором используются чекбоксы?

Как создать фильтр с чекбоксами, чтобы изначально отображались все блоки? При нажатии на чекбоксы необходимо, чтобы блоки отфильтровывались, а если все чекбоксы отключить, то снова показывались все блоки. Спасибо! <br/>
  • 4 декабря 2024 г. 0:13
Ответы на вопрос 2
Создание фильтра с чекбоксами, который контролирует отображение блоков на странице, можно реализовать с использованием HTML и JavaScript. Я приведу простой пример, чтобы иллюстрировать этот процесс.

### 1. HTML Структура
Сначала создадим простой HTML-код с чекбоксами и блоками, которые нужно будет фильтровать.

```html
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Фильтр с чекбоксами</title>
    <style>
        .item {
            margin: 10px;
            padding: 20px;
            border: 1px solid black;
        }
    </style>
</head>
<body>

    <h1>Фильтр с чекбоксами</h1>

    <div>
        <label><input type="checkbox" class="filter-checkbox" value="A" checked> Фильтр A</label>
        <label><input type="checkbox" class="filter-checkbox" value="B" checked> Фильтр B</label>
        <label><input type="checkbox" class="filter-checkbox" value="C" checked> Фильтр C</label>
    </div>

    <div id="items-container">
        <div class="item filter-A">Блок A1</div>
        <div class="item filter-B">Блок B1</div>
        <div class="item filter-A">Блок A2</div>
        <div class="item filter-C">Блок C1</div>
        <div class="item filter-B filter-C">Блок B2</div>
        <div class="item filter-A filter-C">Блок A3</div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const checkboxes = document.querySelectorAll('.filter-checkbox');
            const itemsContainer = document.getElementById('items-container');

            function filterItems() {
                let selectedFilters = Array.from(checkboxes)
                    .filter(checkbox => checkbox.checked) // Отбираем только отмеченные чекбоксы
                    .map(checkbox => 'filter-' + checkbox.value); // Получаем значения фильтров

                // Перебираем все элементы и показываем или скрываем в зависимости от выбранных фильтров
                const items = itemsContainer.children;
                Array.from(items).forEach(item => {
                    // Проверяем, есть ли у элемента один из выбранных фильтров
                    const hasFilter = selectedFilters.some(filter => item.classList.contains(filter));
                    if (selectedFilters.length === 0 || hasFilter) {
                        item.style.display = 'block'; // Показываем элемент
                    } else {
                        item.style.display = 'none'; // Скрываем элемент
                    }
                });
            }

            // Добавляем обработчик события для каждого чекбокса
            checkboxes.forEach(checkbox => {
                checkbox.addEventListener('change', filterItems);
            });

            // Изначально фильтруем элементы, чтобы отобразить все
            filterItems();
        });
    </script>

</body>
</html>
```

### 2. Объяснение кода
- **HTML**: Создаем чекбоксы и блоки, которые будем фильтровать. Каждый блок имеет классы, соответствующие фильтрам (например, `filter-A`, `filter-B` и т.д.).
- **CSS**: Добавляется базовый стиль для блоков.
- **JavaScript**:
  - Используем `DOMContentLoaded` для того, чтобы убедиться, что DOM полностью загружен перед выполнением скрипта.
  - Получаем все чекбоксы и контейнер с блоками.
  - Функция `filterItems` обрабатывает показ или скрытие блоков в зависимости от состояния чекбоксов.
  - Слушатели событий добавляются к каждому чекбоксу, чтобы реагировать на изменения.

### 3. Как это работает
1. При загрузке страницы отображаются все блоки, так как все чекбоксы по умолчанию включены.
2. При выборе любого чекбокса блоки фильтруются по их классам. Если чекбокс отключен, блоки с соответствующим классом скрываются.
3. Если все чекбоксы отключены, все блоки снова отображаются.

Этот простой пример можно расширить и настроить по вашему усмотрению для более сложных случаев использования.
Примерно так? Если выбранные темы есть в блоке, то он отображется. 

/*Создадим массив из объектов, который будет содержать в себе ссылку на блок и темы содержащиеся в блоке
{
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);
Похожие вопросы