Здравствуйте, есть код для фильтрации элементов на сайте. Вроде все работает, но возникла следующая проблема:
допустим, я выбираю в фильтре "Девочка"->"Обувь". Элемент с таким сочетанием только один. При этом там есть еще два параметра - "Размер" и "Цвет". Что надо добавить, чтобы эти два параметра тоже дизейблились?
Код прилагаю:
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;
}