Фильтрация пиццы по ингредиентам - PullRequest
0 голосов
/ 16 октября 2019

У меня есть кнопки, где вы можете выбрать, какие ингредиенты фильтровать

//index.html

<div class="submenu">
    <input type="checkbox" class="filter-item" id="olive" onclick="filter()" />
    <label for="olive">
        <img alt="olive" src="img/png/pizza/olive.png" />
    </label>
    <input type="checkbox" class="filter-item" id="shrimp" onclick="filter()" />
    <label for="shrimp">
        <img alt="shrimp" src="img/png/pizza/shrimp.png" />
    </label>
    <input type="checkbox" class="filter-item" id="mushroom" onclick="filter()" />
    <label for="mushroom">
        <img alt="mushroom" src="img/png/pizza/champion.png" />
    </label>
    <input type="checkbox" class="filter-item" id="pepperoni" onclick="filter()" />
    <label for="pepperoni">
        <img alt="pepperoni" src="img/png/pizza/pepperoni.png" />
    </label>
    <footer id="filter-text">no filter applied</footer>
</div>

И пункты меню (пиццы)

//index.html

<div class="menu-container">
    <img id="olive-pizza" class="menu-item olive" alt="olive" />
    <img id="pepperoni-pizza" class="menu-item pepperoni" alt="pepperoni" />
    <img id="shrimp pizza" class="menu-item shrimp" alt="shrimp" />
    <img class="menu-item mushroom" alt="mushroom" />
    <img class="menu-item olive pepperoni" alt="olive, pepperoni" />
    <img class="menu-item olive shrimp mushroom" alt="olive, shrimp, mushroom" />
</div>

Я хочу отобразить все пиццы, которые включают все выбранные ингредиенты. Например, если выбраны ингредиенты из оливок и креветок, отображаются только пиццы, которые по крайней мере имеют оба этих класса.

Моя идея состоит в том, чтобы поместить все выбранные ингредиенты в массив itemsToFilter, а затем сравнить каждый элемент в этом массиве. классы каждой пиццы, а затем отобразить «оставшиеся» пиццы.

Вот функция:

var itemsToFilter = [];

//HTMLCollections, not arrays
ingredients = document.getElementsByClassName("filter-item"); 
pizzas = document.getElementsByClassName("menu-item");

function filter() {
    for (var i = 0; i < ingredients.length; i++) {
        if (ingredients[i].checked == true) {
            //add checked item to array itemsToFilter
            if (itemsToFilter.includes(ingredients[i].getAttribute("id")) == false) {
                itemsToFilter.push(ingredients[i].getAttribute("id"));
            }
        } else {
            //remove unchecked item from array itemsToFilter
            for (var y = itemsToFilter.length - 1; y >= 0; y--) {
                if (itemsToFilter[y] === ingredients[i].getAttribute("id")) {
                    if (itemsToFilter.includes(ingredients[i].getAttribute("id")) == true) {
                        itemsToFilter.splice(y, 1);
                    }
                }
            }
        }
        //show pizzas with classes that match items in array itemsToFilter
        for (var i = 0; i < pizzas.length; i++) {
            for (y in itemsToFilter) {
                if (pizzas[i].classList.contains(itemsToFilter[y]) == false) {
                    if (pizzas[i].classList.contains("show") == true) {
                        pizzas[i].classList.remove("show");
                    }
                    break;
                } else {
                    pizzas[i].classList.add("show");
                }
            }
        }
    }
}

Это работает в некоторой степени. Он работает только с первым ингредиентом, «оливковым», где он правильно добавляет шоу класса, однако он не удаляет класс, когда флажок снят. Другие ингредиенты даже не добавляются в массив itemsToFilter.

У кого-нибудь есть подход?

Ответы [ 2 ]

0 голосов
/ 16 октября 2019

Я переписал ваш код и внес некоторые изменения:

var itemsToFilter = [];

//HTMLCollections, not arrays
ingredients = document.getElementsByClassName("filter-item"); 
pizzas = document.getElementsByClassName("menu-item");

function filter() {
    // Here you have always only the selected ingredients
    let selectedIngredients = ingredients.filter(ingredient => ingredient.checked === true);

    if(selectedIngredients.length === 0) {
        pizzas.forEach(pizza => {
             pizza.classList.add("show");
        });
    } else {
        pizzas.forEach(pizza => {
            let hasAllIngredients = true;
            selectedIngredients.forEach(ingredient => {
                if(!pizza.classList.includes(ingredient.getAttribute("id"))) {
                    hasAllIngredients = false;
                }
            });

            if(hasAllIngredients) {
                pizza.classList.add("show");
            } else {
                pizza.classList.remove("show");
            }
        });
    }
}
0 голосов
/ 16 октября 2019

... Я случайно поместил цикл for, который показывает пиццу внутри цикла for, который проходит через кнопки ингредиентов. Я переместил его на один шаг, а также переместил часть, которая удаляет класс show из пиццы перед циклом for, который зацикливает массив itemsToFilter, поскольку он не будет удалять класс show, если массив был пустым. Благодарю всех вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...