Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 04.02.2023, 16:07
Новичок на форуме
Отправить личное сообщение для KuParty Посмотреть профиль Найти все сообщения от KuParty
 
Регистрация: 04.02.2023
Сообщений: 3

Фильтр категории-подкатегории-товары
Подскажите, пожалуйста, как сделать так чтобы при клике по категории появлялись её подкатегории (изначально не видны), а после клика по подкатегории уже фильтровались товары. Категории и подкатегории подтягиваются из БД. Сейчас получилось сделать только подкатегории и фильтрацию товаров. В JS полный ноль, всё собираю по кускам из сети. Помогите, пожалуйста.
Код у меня есть по ссылке: https://codepen.io/KuParty/pen/WNKPLbL Здесь тоже дублирую:
HTML:
Код:
  <header class="header">
            <div class="filter-category">
            <button class="button button_type_all" data-filter="all">All</button>
            <button class="button button_type_running" data-filter="running">Running</button>
            <button class="button button_type_flying" data-filter="flying">Flying</button>
        </div>
        <div class="filter">
            <button class="button button_type_cat" data-filter="cat">Cat</button>
            <button class="button button_type_dog" data-filter="dog">Dog</button>
            <button class="button button_type_bird" data-filter="bird">Bird</button>
        </div>
    </header>
    <main class="content">
        <div class="container">
            <div class="card cat running">Cat</div>
            <div class="card dog running">Dog</div>
            <div class="card bird flying">Bird</div>
            <div class="card dog running">Dog</div>
            <div class="card cat running">Cat</div>
            <div class="card bird flying">Bird</div>
            <div class="card bird flying">Bird</div>
            <div class="card dog running">Dog</div>
            <div class="card cat running">Cat</div>
        </div>
    </main>
CSS:
Код:
:root {
  --color-orange: #ffa728;
  --color-red: #e66c6e;
  --color-green: #a7d6bb;
  --color-blue: #1c4961;
  --color-sky: #58C9E2FF;
  --color-brown: #a56e47;
}

*,
*::after,
*::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: "Courier New", Courier, monospace;
  font-size: 16px;
  line-height: 1.2;
  background-color: #faebd7;
}

.header {
  padding: 20px 0;
  margin-bottom: 48px;
}

.filter {
  display: flex;
  justify-content: center;
  max-width: 1024px;
  margin: 0 auto;
}

.filter-category {
  display: flex;
  justify-content: center;
  max-width: 1024px;
  margin: 0 auto;
  padding-bottom: 20px;
}

.button {
  padding: 12px 24px;
  margin-right: 18px;
  cursor: pointer;
  color: white;
  text-transform: uppercase;
  font-weight: bold;
  border: 0;
  outline: none;
  border-radius: 0;
  position: relative;
}

.button:last-child {
  margin-right: 0;
}

.button:active {
  bottom: -1px;
}

.button_type_all {
  background-color: var(--color-orange);
}

.button_type_flying {
  background-color: var(--color-sky);
}

.button_type_running {
  background-color: var(--color-brown);
}

.button_type_cat {
  background-color: var(--color-green);
}

.button_type_dog {
  background-color: var(--color-red);
}

.button_type_bird {
  background-color: var(--color-blue);
}


.container {
  display: flex;
  flex-wrap: wrap;
  max-width: 1024px;
  margin: 0 auto;
}

.card {
  width: calc(33.3333333% - 72px);
  margin: 36px;
  height: 200px;
  line-height: 200px;
  text-align: center;
  color: white;
  font-weight: bold;
  font-size: 48px;
  overflow: hidden;
  transition: 0.5s all;
}

.cat {
  background-color: var(--color-green);
}

.dog {
  background-color: var(--color-red);
}

.bird {
  background-color: var(--color-blue);
}

.anime {
  transform: scale(0);
  opacity: 0;
}

.hide {
  animation-name: hide;
  animation-duration: 0.5s;
  animation-fill-mode: forwards;
}

@keyframes hide {
  0% {
    visibility: visible;
    height: 200px;
  }
  100% {
    visibility: hidden;
    width: 0;
    height: 0;
    max-width: 0;
    font-size: 0;
    margin: 0;
  }
}
JS:
function app() {
    const buttons = document.querySelectorAll('.button')
    const cards = document.querySelectorAll('.card')

    function filter (category, items) {
        items.forEach((item) => {
            const isItemFiltered = !item.classList.contains(category)
            const isShowAll = category.toLowerCase() === 'all'
            if (isItemFiltered && !isShowAll) {
                item.classList.add('anime')
            } else {
                item.classList.remove('hide')
                item.classList.remove('anime')
            }
        })
    }

    buttons.forEach((button) => {
        button.addEventListener('click', () => {
            const currentCategory = button.dataset.filter
            filter(currentCategory, cards)
        })
    })

    cards.forEach((card) => {
        card.ontransitionend = function () {
            if (card.classList.contains('anime')) {
                card.classList.add('hide')
            }
        }
    })
}

app()

Всё это сейчас прикручено к Jango таким образом:
Код:
<header class="header-filter">
        <div class="filter-category">
            <button class="button button_type_all" data-filter="all">Все</button>
            {% for sc in subcategories %}
                {% if sc.get_prods__count > 0 %}
                    <button class="button button_type_cat"
                            data-filter="{{ sc.slug }}">{{ sc.sub_cat_name }}</button>
                {% endif %}
            {% endfor %}
        </div>
    </header>
    <main class="content">
        <div class="container">
            {% for sc in subcategories %}
                {% if sc.get_prods__count > 0 %}
                    {% for p in prods %}
                        {% if p.subcategory_id == sc.pk %}
                            {% if p.photo %}
                                <div class="card {{ sc.slug }}">
                                    <a href="{{ p.get_absolute_url }}">
                                        {{ p.title }}
                                    </a>
                                </div>
                            {% endif %}
                        {% endif %}
                    {% endfor %}
                {% endif %}
            {% endfor %}
        </div>
    </main>

Последний раз редактировалось KuParty, 04.02.2023 в 17:38.
Ответить с цитированием
  #2 (permalink)  
Старый 04.02.2023, 17:38
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

фильтр по категориям
KuParty,
<!DOCTYPE html>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
        :root {
            --color-orange: #ffa728;
            --color-red: #e66c6e;
            --color-green: #a7d6bb;
            --color-blue: #1c4961;
            --color-sky: #58C9E2FF;
            --color-brown: #a56e47;
        }
        *,
        *::after,
        *::before {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: "Courier New", Courier, monospace;
            font-size: 16px;
            line-height: 1.2;
            background-color: #faebd7;
        }
        .header {
            padding: 20px 0;
            margin-bottom: 48px;
        }
        .filter {
            display: flex;
            justify-content: center;
            max-width: 1024px;
            margin: 0 auto;
        }
        .filter-category {
            display: flex;
            justify-content: center;
            max-width: 1024px;
            margin: 0 auto;
            padding-bottom: 20px;
        }
        .button {
            padding: 12px 24px;
            margin-right: 18px;
            cursor: pointer;
            color: white;
            text-transform: uppercase;
            font-weight: bold;
            border: 0;
            outline: none;
            border-radius: 0;
            position: relative;
        }
        .button:last-child {
            margin-right: 0;
        }
        .button:active {
            bottom: -1px;
        }
        .button_type_all {
            background-color: var(--color-orange);
        }
        .button_type_flying {
            background-color: var(--color-sky);
        }
        .button_type_running {
            background-color: var(--color-brown);
        }
        .button_type_cat {
            background-color: var(--color-green);
        }
        .button_type_dog {
            background-color: var(--color-red);
        }
        .button_type_bird {
            background-color: var(--color-blue);
        }
        .container {
            display: flex;
            flex-wrap: wrap;
            max-width: 1024px;
            margin: 0 auto;
        }
        .card {
            width: calc(33.3333333% - 72px);
            margin: 36px;
            height: 100px;
            line-height: 100px;
            text-align: center;
            color: white;
            font-weight: bold;
            font-size: 48px;
            overflow: hidden;
            transition: 0.5s all;
        }
        .cat {
            background-color: var(--color-green);
        }
        .dog {
            background-color: var(--color-red);
        }
        .bird {
            background-color: var(--color-blue);
        }
        .anime {
            transform: scale(0);
            opacity: 0;
        }
        .hide {
            animation-name: hide;
            animation-duration: 0.5s;
            animation-fill-mode: forwards;
            animation-delay: 0.6s;
        }
        @keyframes hide {
            0% {
                visibility: visible;
                height: 200px;
            }
            100% {
                visibility: hidden;
                width: 0;
                height: 0;
                max-width: 0;
                font-size: 0;
                margin: 0;
            }
        }
    </style>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            const header = document.querySelector('.header');
            header.addEventListener("click", function({
                target
            }) {
                if (target.closest('[data-filter]')) {
                    let categorys = target.dataset.filter;
                    const isShowAll = categorys == 'all'
                    categorys = categorys.split(',');
                    document.querySelectorAll('[data-filter]').forEach(elem => {
                        let keys = elem.dataset.filter;
                        const isKeyAll = keys == 'all';
                        keys = keys.split(',');
                        const isItemFiltered = isKeyAll || isShowAll || keys.some(key => categorys.includes(key));
                        elem.classList.remove("hide");
                        elem.classList.toggle("anime", !isItemFiltered);
                        if (!isItemFiltered) elem.classList.add("hide");
                    })
                };
            })
        })
    </script>
</head>
<body>
    <header class="header">
        <div class="filter-category">
            <button class="button button_type_all" data-filter="all">All</button>
            <button class="button button_type_running" data-filter="cat,dog">Running</button>
            <button class="button button_type_flying" data-filter="bird">Flying</button>
        </div>
        <div class="filter">
            <button class="button button_type_cat" data-filter="cat">Cat</button>
            <button class="button button_type_dog" data-filter="dog">Dog</button>
            <button class="button button_type_bird" data-filter="bird">Bird</button>
        </div>
    </header>
    <main class="content">
        <div class="container">
            <div class="card cat" data-filter="cat">Cat</div>
            <div class="card dog" data-filter="dog">Dog</div>
            <div class="card bird" data-filter="bird">Bird</div>
            <div class="card dog" data-filter="dog">Dog</div>
            <div class="card cat" data-filter="cat">Cat</div>
            <div class="card bird" data-filter="bird">Bird</div>
            <div class="card bird" data-filter="bird">Bird</div>
            <div class="card dog" data-filter="dog">Dog</div>
            <div class="card cat" data-filter="cat">Cat</div>
        </div>
    </main>
</body>
</html>

Последний раз редактировалось рони, 04.02.2023 в 17:41.
Ответить с цитированием
  #3 (permalink)  
Старый 04.02.2023, 17:52
Новичок на форуме
Отправить личное сообщение для KuParty Посмотреть профиль Найти все сообщения от KuParty
 
Регистрация: 04.02.2023
Сообщений: 3

рони
Спасибо за помощь. Но это немного не то. Я хотел чтобы все карточки и подкатегории DOG CAT BIRD изначально не были видны. После нажатия на категорию появлялись её подкатегории и карточки относящиеся к этим подкатегориям. При нажатии на подкатегорию фильтровались по ней.
Ответить с цитированием
  #4 (permalink)  
Старый 04.02.2023, 20:00
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

KuParty,
надо брать объект и отображать его текущее состояние, тогда будет что-то такое
Ответить с цитированием
  #5 (permalink)  
Старый 06.02.2023, 23:37
Новичок на форуме
Отправить личное сообщение для KuParty Посмотреть профиль Найти все сообщения от KuParty
 
Регистрация: 04.02.2023
Сообщений: 3

Сообщение от рони Посмотреть сообщение
надо брать объект и отображать его текущее состояние, тогда будет что-то такое
Спасибо, но, к сожалению, не смог разобраться, JS вообще не знаю(
Ответить с цитированием
  #6 (permalink)  
Старый 07.02.2023, 02:14
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

Сообщение от рони
надо брать объект и отображать его текущее состояние,
примерно так ... кликайте по названиям

<!DOCTYPE html>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            const data = {
                child: {
                    all: {
                        child: {
                            running: {
                                child: {
                                    cat: {
                                        child: {
                                            cat1: {
                                                title: 'mmm'
                                            },
                                            cat2: {
                                                title: 'ppp'
                                            }
                                        }
                                    },
                                    dog: {
                                        child: {
                                            dog1: {
                                                title: 'rrr'
                                            },
                                            dog2: {
                                                title: 'gav'
                                            }
                                        }
                                    }
                                }
                            },
                            flying: {
                                child: {
                                    bird: {
                                        child: {
                                            bird1: {
                                                title: 'fly'
                                            }
                                        }
                                    }
                                }
                            }
                        },
                    }
                },
                show: true
            }
            const createHtml = data => {
                let ul = document.createElement('ul');
                if (data.child) {
                    for (let key in data.child) {
                        let li = document.createElement('li');
                        li.textContent = key;
                        ul.append(li);
                        li.addEventListener("click", function(event) {
                            event.preventDefault();
                            event.stopPropagation();
                            data.child[key].show = !data.child[key].show;
                            create();
                        })
                        let el = data.child[key],
                            show = data.child[key].show;
                        if (typeof el == 'object' && show) li.append(createHtml(el))
                    }
                }
                if (data.title) {
                    let li = document.createElement('li');
                    li.textContent = `my name is ${data.title}`;
                    ul.append(li);
                }
                return ul
            }
            const create = () => {
                let html = createHtml(data);
                document.querySelector('.test').innerHTML = '';
                document.querySelector('.test').append(html)
            }
            create()
        })
    </script>
</head>
<body>
    <div class="test"></div>
</body>
</html>
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как отобразить множественный выбор select? Oscillococcinum Элементы интерфейса 20 21.10.2020 16:54
Применить фильтр к точкам на Яндекс карте Богдан94 Общие вопросы Javascript 0 10.08.2019 16:08
Доработать фильтр Андрей812 Работа 8 10.09.2018 15:42
Простенький фильтр smart-create Серверные языки и технологии 1 12.02.2017 06:56
Фильтр с помощью checkbox-ов... len-in Общие вопросы Javascript 6 16.01.2013 22:12