Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Как реализовать фильтр? (https://javascript.ru/forum/dom-window/74038-kak-realizovat-filtr.html)

Янковиц 07.06.2018 13:03

Как реализовать фильтр?
 
Добрый день. Есть разметка. Упрощенно выглядит так:
<div id="ex-filter">
	<div class="ex-type">
		<ul>
			<li class="col-md-6" data-id="1" data-children="11, 12, 13"><a href="#">Актив</a> (4)</li>
			<li class="col-md-6" data-id="2" data-children="12, 14"><a href="#">Пассив</a> (2)</li>
		</ul>
	</div>
	<div class="ex-ex">
		<ul>
			<li class="col-md-6" data-id="11" data-parent="1"><a href="#">Горы</a> (4)</li>
			<li class="col-md-6" data-id="12" data-parent="2"><a href="#">Лес</a> (2)</li>
			<li class="col-md-6" data-id="13" data-parent="2"><a href="#">Пляж</a> (2)</li>
			<li class="col-md-6" data-id="14" data-parent="1, 2"><a href="#">Море</a> (2)</li>
		</ul>
	</div>
	<button class="ex-go">Фильтровать</button>
</div>

Нужно на jQuery реализовать фильтр. Разумеется, количество пунктов - заведомо не известно, что в первом, что во втором списке.
Работает так: кликаю по пункту "Актив", "Пассив" деактивируется (да и вообще все элементы из этого-же списка, если они есть). Скрипт анализирует во втором списке data-parent, сравнивает с data-id элемента по которому кликнули, и если в data-parent из второго списка нет data-id из первого списка, он тоже деактивируется (то есть "Лес" и "Пляж" в данном случае деактивируются(я думаю, просто на css сделать через динамическое добавление класса)). Повторное нажатие по этому же пункту списка, возвращает все назад.
Подскажите, как это реализовать. :(

рони 07.06.2018 13:07

Янковиц,
data-children зачем?

Янковиц 07.06.2018 13:09

Для обратной совместимости. Тот же принцип, только при нажатии на элементы второго списка, фильтруются элементы первого. Не исключаю, что они лишние. Просто, решил предоставить всё возможное, чтобы быстро решить проблему.

рони 07.06.2018 13:11

Цитата:

Сообщение от Янковиц
Для обратной совместимости.

не осилил

рони 07.06.2018 13:13

открывашка фильтр
 
:write: тут будет очередная открывашка :lol:
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  .act, .act a{
      background-color: rgba(0, 0, 255, 1);
      color: rgba(255, 255, 255, 1);
  }
  .ex-ex .act, .ex-ex .act a{
      background-color: rgba(255, 250, 205, 1);
      color: rgba(139, 69, 19, 1);
  }

  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script>
$(function() {
    var parent = $(".ex-type li"),
        child = $(".ex-ex li");
    parent.on("click", function(event) {
        event.preventDefault();
        var el = $(this);
        if(parent.not(el).is(".act")) return;
        parent.not(el.toggleClass("act")).removeClass("act");
        var id = el.data("id") + "";
        child.removeClass("act");
        if (el.is(".act")) child.filter(function() {
            var data = $(this).data("parent");
            data = (data + "").split(/\s*,\s*/);
            return data.indexOf(id) !== -1
        }).addClass("act");
    })
    child.on("click", function(event) {
        event.preventDefault();
        var el = $(this);
        if(child.not(el).is(".act")) return;
        child.not(el.toggleClass("act")).removeClass("act");
        var data = $(this).data("parent");
        data = (data + "").split(/\s*,\s*/);
        parent.removeClass("act");
        if (el.is(".act")) parent.filter(function() {
            var id = $(this).data("id") + "";
            return data.indexOf(id) !== -1
        }).addClass("act");
    })
});
  </script>
</head>

<body>
<div id="ex-filter">
	<div class="ex-type">
		<ul>
			<li class="col-md-6" data-id="1" data-children="11, 12, 13"><a href="#">Актив</a> (4)</li>
			<li class="col-md-6" data-id="2" data-children="12, 14"><a href="#">Пассив</a> (2)</li>
		</ul>
	</div>
	<div class="ex-ex">
		<ul>
			<li class="col-md-6" data-id="11" data-parent="1"><a href="#">Горы</a> (4)</li>
			<li class="col-md-6" data-id="12" data-parent="2"><a href="#">Лес</a> (2)</li>
			<li class="col-md-6" data-id="13" data-parent="2"><a href="#">Пляж</a> (2)</li>
			<li class="col-md-6" data-id="14" data-parent="1, 2"><a href="#">Море</a> (2)</li>
		</ul>
	</div>
	<button class="ex-go">Фильтровать</button>
</div>


</body>
</html>

Янковиц 07.06.2018 13:14

В смысле, что обратная зависимость. Прошу прощения за неточность. При нажатии на элементы второго списка, фильтруются элементы первого.

рони 07.06.2018 13:46

Янковиц,
код выше

рони 07.06.2018 13:55

Цитата:

Сообщение от Янковиц
При нажатии на элементы второго списка, фильтруются элементы первого.

добавил, логику кликов, если нужно, уточните сами.

Янковиц 07.06.2018 14:04

Спасибо большое. :dance: :thanks: Все отменно работает. Последний вопрос. При клике по элементу одного из списка (не важно, первый или второй), нужно сделать неактивными остальные элементы из этого же списка.

рони 07.06.2018 14:41

Цитата:

Сообщение от Янковиц
нужно сделать неактивными остальные элементы из этого же списка.

не понимаю, разве сейчас не так?

Янковиц 07.06.2018 14:46

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

рони 07.06.2018 15:09

Цитата:

Сообщение от Янковиц
Я имею в виду, чтобы на их невозможно было нажать курсором.

добавил

Янковиц 07.06.2018 15:30

Спасибо, и все же, как с добавлением-удалением классов сделать неактивность?

рони 07.06.2018 16:28

Янковиц,
:(
<!DOCTYPE html>

<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
    .act, .act a{
            background-color: rgba(0, 0, 255, 1);
            color: rgba(255, 255, 255, 1);
    }
    .ex-ex .act, .ex-ex .act a{
            background-color: rgba(255, 250, 205, 1);
            color: rgba(139, 69, 19, 1);
    }
    .noclick{
            pointer-events: none;
            opacity: .4;
    }

    </style>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script>
$(function() {
        var parent = $(".ex-type li"),
                child = $(".ex-ex li");
        parent.on("click", function(event) {
                event.preventDefault();
                var el = $(this);
                parent.not(el.toggleClass("act")).removeClass("act noclick");
                var id = el.data("id") + "";
                child.removeClass("act");
                if (el.is(".act")) {
                child.filter(function() {
                        var data = $(this).data("parent");
                        data = (data + "").split(/\s*,\s*/);
                        return data.indexOf(id) !== -1
                }).addClass("act");
                parent.not(el).addClass("noclick");
                }
        }).filter(".act").removeClass("act").click();
        child.on("click", function(event) {
                event.preventDefault();
                var el = $(this);
                child.not(el.toggleClass("act")).removeClass("act noclick");
                var data = $(this).data("parent");
                data = (data + "").split(/\s*,\s*/);
                parent.removeClass("act");
                if (el.is(".act")) {
                parent.filter(function() {
                        var id = $(this).data("id") + "";
                        return data.indexOf(id) !== -1
                }).addClass("act");
                child.not(el).addClass("noclick");
                }
        })
});
    </script>
</head>

<body>
<div id="ex-filter">
    <div class="ex-type">
        <ul>
            <li class="col-md-6 act" data-id="1" data-children="11, 12, 13"><a href="#">Актив</a> (4)</li>
            <li class="col-md-6" data-id="2" data-children="12, 14"><a href="#">Пассив</a> (2)</li>
        </ul>
    </div>
    <div class="ex-ex">
        <ul>
            <li class="col-md-6" data-id="11" data-parent="1"><a href="#">Горы</a> (4)</li>
            <li class="col-md-6" data-id="12" data-parent="2"><a href="#">Лес</a> (2)</li>
            <li class="col-md-6" data-id="13" data-parent="2"><a href="#">Пляж</a> (2)</li>
            <li class="col-md-6" data-id="14" data-parent="1, 2"><a href="#">Море</a> (2)</li>
        </ul>
    </div>
    <button class="ex-go">Фильтровать</button>
</div>


</body>
</html>

Янковиц 14.06.2018 10:48

Спасибо большое. Прошу прощения, что снова поднимаю свой вопрос.
Необходимо при загрузки вебстраницы запускать скрипт и проверять, есть ли активные элементы. Делаю так:
$(function() {
    var parent = $(".ex-type li"),
        child = $(".ex-ex li");
    function parent_filter( parent ) {
        event.preventDefault();
        var el = $(this);
        parent.not(el.toggleClass("act")).removeClass("act noclick");
        var id = el.data("id") + "";
        child.removeClass("act");
        if (el.is(".act")) {
        child.filter(function() {
            var data = $(this).data("parent");
            data = (data + "").split(/\s*,\s*/);
            return data.indexOf(id) !== -1
        }).addClass("act");
        parent.not(el).addClass("noclick");
        }
    }
    function children_filter( child ) {
        event.preventDefault();
        var el = $(this);
        child.not(el.toggleClass("act")).removeClass("act noclick");
        var data = $(this).data("parent");
        data = (data + "").split(/\s*,\s*/);
        parent.removeClass("act");
        if (el.is(".act")) {
        parent.filter(function() {
            var id = $(this).data("id") + "";
            return data.indexOf(id) !== -1
        }).addClass("act");
        child.not(el).addClass("noclick");
        }
    }
    parent.on("click", function(event) {
        var _this = jQuery(this);
        parent_filter(_this);
    })
    child.on("click", function(event) {
        var _this = jQuery(this);
        children_filter(_this);
    })
});

Однако, фильтр перестает работать. Подскажите, что я делаю не так? Проверял в console.log Почему-то, _this возвращает не DOM элемент.

Янковиц 14.06.2018 10:49

Соответственно
jQuery(window).on('load', function() { 
	parent_filter();
	children_filter();
});

Тоже не работает

рони 14.06.2018 11:44

Янковиц,
что такое "активный элемент" и что нужно сделать, если есть "активный элемент"?

Янковиц 14.06.2018 11:59

Активный элемент, это элемент в котором есть класс act

Янковиц 14.06.2018 12:02

Ранее, в предыдущем коде была выполнена фильтрация при клике по элементам. Теперь к этому нужно еще добавить: если пользователь переходит сразу на страницу, где уже есть "активный элемент" с классом act, необходимо, чтобы скрипт, без кликанья автоматически выполнялся.

рони 14.06.2018 12:09

Цитата:

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

добавлено
пост №14 строка 41

Янковиц 14.06.2018 12:38

Наверно я не так выразился.
Постараюсь описать: пользователь заходит на страницу. Средствами php в один из элементов фильтра вставляется класс act. Мне нужно просто как бы эмулировать клик при загрузке страницы. Скрипт должен проанализировать фильтр, если есть элемент с классом act (в одном из блоков или в обоих сразу), скрипт выполняет то же самое, как если бы по элементу кликнули.

P.S. я попробовал 41 строку, но ничего не поменялось :(

рони 14.06.2018 12:43

Янковиц,
здесь 41 строка работает?
класс стоит в элементе на строке 65


Часовой пояс GMT +3, время: 19:46.