Фильтрация элементов на сайте с помощью checkbox-ов
Здравствуйте, есть код для фильтрации элементов на сайте. Вроде все работает, но возникла следующая проблема:
допустим, я выбираю в фильтре "Девочка"->"Обувь". Элемент с таким сочетанием только один. При этом там есть еще два параметра - "Размер" и "Цвет". Что надо добавить, чтобы эти два параметра тоже дизейблились? Код прилагаю: const properties = ["Коллекция", "Пол", "Категория", "Размер", "Цвет"]; function Clothe(arr) { var clothe = new Map(); for (var i = 0; i < arr.length; ++i) { clothe.set(properties[i], arr[i]); } return clothe; } var DATA = [ // Girl Clothe(["NEW COLLECTION", "Девочка", "Брюки", "32", "Синий"]), Clothe(["NEW COLLECTION", "Девочка", "Худи", "36", "Розовый"]), Clothe(["OLD COLLECTION", "Девочка", "Обувь", "34", "Красный"]), Clothe(["NEW COLLECTION", "Девочка", "Куртка", "44", "Зеленый"]), Clothe(["OLD COLLECTION", "Девочка", "Футболка", "38", "Белый"]), Clothe(["NEW COLLECTION", "Девочка", "Шорты", "32", "Серый"]), ]; function print_clothes(data) { if (data.length !== 0) { var clothesDiv = document.createElement("div"); clothesDiv.className = "clothesDiv"; var clothes = document.createElement("ul"); clothes.setAttribute("class", "clothes"); clothesDiv.appendChild(clothes); document.getElementsByClassName('Product')[0].replaceChild(clothesDiv, document.getElementsByClassName('Product')[0].firstChild); for (var i = 0; i < data.length; ++i) { var CLOTHE = document.createElement("li"); var clothe = document.createElement("div"); var word_clothes = document.createElement("h3"); CLOTHE.setAttribute("class", "CLOTHE"); clothe.setAttribute("name", "clothe"); clothe.setAttribute("class", "clothe"); word_clothes.innerText = data[i].get(properties[0]); clothe.append(word_clothes); for (var j = 1; j < properties.length; ++j) { var prop = document.createElement("p"); prop.innerText = properties[j] + ": " + data[i].get(properties[j]); clothe.append(prop); } CLOTHE.append(clothe); clothes.append(CLOTHE); } } else { var div = document.createElement("div"); div.className = "resetFiltres"; document.getElementsByClassName('Product')[0].replaceChild(div, document.getElementsByClassName('Product')[0].firstChild); var noElemsText = document.createElement("h3"); noElemsText.innerText = "There is no matching items\nTry simpling your search"; reset(); var button = document.createElement("input"); button.setAttribute("type", "button"); button.setAttribute("value", "RESET"); button.className = "resetButton"; button.onclick = reset; div.appendChild(noElemsText); div.appendChild(button); } } print_clothes(DATA); function getFilterValues(propetry) { var values = new Set(); var aValues = new Array(); for (var clothe of DATA) { var key = clothe.get(propetry); if (!values.has(key)) { values.add(key) aValues.push(key); } } return aValues; } function reset() { FILTRES.forEach((fvalue, fkey, fmap) => { var cs = document.getElementsByName(fkey); var texts = document.getElementsByName("p" + fkey); var i = 0; fvalue.forEach((rvalue, rkey, rmap) => { cs[i].disabled = false; cs[i].checked = false; texts[i].className = "en"; ++i; rmap.set(rkey, false); }); }); print_clothes(DATA); } var FILTRES = new Map(); for (var property of properties) { var values = getFilterValues(property); var filterRows = new Map(); for (var value of values) { filterRows.set(value, false); } FILTRES.set(property, filterRows); } var block_filter = document.createElement("div") block_filter.className = "block_filter"; document.getElementsByClassName("filters")[0].append(block_filter); FILTRES.forEach((fvalue, fkey, fmap) => { var div = document.createElement("div"); div.className = fkey; var filterBlockTitle = document.createElement("h3"); filterBlockTitle.innerText = fkey; filterBlockTitle.className = "filterBlockTitle"; div.appendChild(filterBlockTitle); var filterBlock = document.createElement("div"); filterBlock.className = "block_"+fkey; div.appendChild(filterBlock); fvalue.forEach((rvalue, rkey, rmap) => { var label = document.createElement("label"); var checkbox = document.createElement("input"); var text = document.createElement("p"); text.setAttribute("class", "en"); text.setAttribute("name", "p" + fkey); text.innerText = rkey; checkbox.addEventListener("change", change); checkbox.value = rkey; checkbox.name = fkey; checkbox.type = "checkbox"; label.setAttribute("class", "label"); label.appendChild(checkbox); label.appendChild(text); filterBlock.appendChild(label); }); document.getElementsByClassName("block_filter")[0].appendChild(div); }); function allCheckboxesAreUnchecked() { var COUNT = 0; FILTRES.forEach((fvalue, fkey, fmap) => { var count = 0; fvalue.forEach((rvalue, rkey, rmap) => { if (!rvalue) { ++count; } }); if (count === fvalue.size) { ++COUNT; } }); if (COUNT === FILTRES.size) { return true; } else { return false; } } function activeAllCheckboxes() { FILTRES.forEach((fvalue, fkey, fmap) => { var checkboxes = document.getElementsByName(fkey); var texts = document.getElementsByName("p" + fkey); for (var i = 0; i < fvalue.size; ++i) { checkboxes[i].disabled = false; texts[i].className = "en"; } }); } //фильтрация function change(e) { //объект который был инициатором события var obj = e.target; FILTRES.get(obj.name).set(obj.value, obj.checked); if (allCheckboxesAreUnchecked()) { print_clothes(DATA); activeAllCheckboxes(); } else { var newData = new Array(); var changedPropertyName = obj.name; for (var data of DATA) { var matchFiltresCount = 0; FILTRES.forEach((strCbxs, property, fmap) => { var uncheckedCount = 0; var matchFound = false; strCbxs.forEach((checkbox, string, rmap) => { if (!checkbox) { ++uncheckedCount; } else { if (data.get(property) === string) { matchFound = true; } } }); if (uncheckedCount === strCbxs.size) { ++matchFiltresCount; } else { if (matchFound) { ++matchFiltresCount; } } }); if (matchFiltresCount === FILTRES.size) { newData.push(data); } } //устанавливаем фильтры кроме того, который изменили FILTRES.forEach((strCbxs, property, fmap) => { if (property !== changedPropertyName) { var checkboxes = document.getElementsByName(property); // checkboxes var texts = document.getElementsByName("p" + property); var matchFound = false; var i = 0; var nd = dataBasedOnFiltresExceptCurrent(property); strCbxs.forEach((checkbox, string, rmap) => { matchFound = false; for (var data of nd) { // todo if (data.get(property) === string) { matchFound = true; } } if (matchFound) { checkboxes[i].disabled = false; texts[i].className = "en"; } else { checkboxes[i].disabled = true; texts[i].className = "dis"; } ++i; }); } }); print_clothes(newData); } } //вернет массив данных, который формируется по всем фильтрам, кроме того который указан в property function dataBasedOnFiltresExceptCurrent(property) { var nd = new Array(); for (var data of DATA) { var matchFiltresCount = 0; FILTRES.forEach((strCbxs, prop, fmap) => { if (prop !== property) { var uncheckedCount = 0; var checkboxes = document.getElementsByName(prop); var i = 0; var matchFound = false; strCbxs.forEach((checkbox, string, rmap) => { if (!checkbox) { ++uncheckedCount; } else { if (data.get(prop) === string) { matchFound = true; } } ++i; }); if (uncheckedCount === strCbxs.size) { ++matchFiltresCount; } else { if (matchFound) { ++matchFiltresCount; } } } }); if (matchFiltresCount === FILTRES.size - 1) { nd.push(data); } } return nd; } |
Часовой пояс GMT +3, время: 08:38. |