Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   ajax фильтрация+навигация (https://javascript.ru/forum/dom-window/76537-ajax-filtraciya-navigaciya.html)

гуня 20.01.2019 19:56

ajax фильтрация+навигация
 
есть сайт с поиском товаров
поиск товаров сделан через history.pushstate get запросом+https://github.com/defunkt/jquery-pjax
плюс на форме есть такой элемент http://davidstutz.de/bootstrap-multiselect/
проблема в том что когда в браузере кликаешь назад\вперед все работает не так как хочется

до этого я использовать pjax submit и все работало отлично, но клиент захотел чтобы элемент http://davidstutz.de/bootstrap-multiselect/ не схлопывался после каждого изменения(т.е. делаем чек\анчек и товары фильтруются а элемент не схлопывается)

вопрос такой- как сделать чтобы этот элемент не схлопывался при ajax submit
или может есть либа которая возмет на себя всю работу по навигации и обновлению страницы
думаю что должны быть готовые решения

laimas 21.01.2019 07:13

Цитата:

Сообщение от гуня
как сделать чтобы этот элемент не схлопывался при ajax submit

При асинхронном запросе ничего и не изменяется, если только не обновить принудительно. Все проблемы от истории.

laimas 21.01.2019 08:00

гуня, скорее всего вы описываете поведение списка при щелчке вне его, что приводит к его закрытию, так?

гуня 21.01.2019 08:25

laimas,
список имеется ввиду этот элемент?http://davidstutz.de/bootstrap-multiselect/
он работает хорошо, когда нету перезагрузки страницы
но даже если есть pjax сабмит тогда схлопывается, что не нравится клиенту
для меня идеальное решение это сделать через pjax submit плюс чтобы список не схлопывался
в этом случае кнопки вперед\назад работают идеально

laimas 21.01.2019 08:38

Ajax к этому отношения не имеет, просто список теряет фокус и сворачивается. Устранить это можно переопределив поведение списка его методами, если таковое возможно. А перезагрузка страницы само собой будет отображать список свернутым. Раскрыть его можно либо по параметрам запроса в url, либо сервер должен возвращать эти параметры (при асинхронном запросе), также используя методы списка.

гуня 22.01.2019 01:49

кто хочет попробовать дать совет?
сайт скину в лс

гуня 22.01.2019 16:51

спасибо попробую
я еще пытался делать вызов
setinterval ({$('div.' + cssClass + ' .multiselect').parent().find('ul').show();}, 1);

но все равно мигание иногда проскакивает

гуня 22.01.2019 19:02

Malleys,
не помогло
перенес id page но форма все равно сбрасывается
если что на тесте обновил

гуня 22.01.2019 19:25

читал
я поменял в скрипте код обновления
new Pjax({
        elements: 'a[ajaxLink], li.page a, div.sorter a, form',
        selectors: ['#page1'],
        scrollTo: false,
        cacheBust: false
    });

гуня 22.01.2019 19:33

сделал как описано в 7 посте
теперь page перенесено
не помогло

гуня 22.01.2019 20:00

вижу
счас вылез баг- при первой загрузке чекбоксы схлопываются,дальше нормально работает
для проверки надо загрузить новую вкладку без параметров и выбрать чекбокс

гуня 22.01.2019 20:12

49 строка раскоментировал

Malleys 22.01.2019 20:38

Цитата:

Сообщение от гуня
задача сделать так чтобы не мигало

Пост №7
Вот упрощенно ваша структура
<div id="page">
    <form>
        <select></select>
    </form>
    <div class="row"></row>
</div>

Когда вы выбираете что-то в select, у вас происходит скачивание HTML-кода, который затем вставляется в элемент <div id="page">. Как видите, у вас происходит замена всего содержимого (включая форму с открытым <select>) на новое содержимое. (поэтому иногда подмигивает! у меня едва подмигивает 1 раз на 5 просмотров, это не так критично, в принципе здесь можно ничего не менять!)

Но всё-же вы можете не обновлять форму!
Тогда надо поменять структуру HTML на такую...
<div>
    <form>
        <select></select>
    </form>
    <div class="row" id="page"></row>
</div>
Обратите внимание, как я перенёс атрибут id! Тогда оно не мигает, поскольку не заменяется форма, но тогда нужно немного поправить ответ от сервера! (отрисовывать форму на сервере не надо, тогда!)

Цитата:

Сообщение от гуня
спасибо попробую
я еще пытался делать вызов
setinterval ({$('div.' + cssClass + ' .multiselect').parent().find('ul').show();}, 1);

но все равно мигание иногда проскакивает

UPD

Цитата:

Сообщение от гуня
не помогло
перенес id page но форма все равно сбрасывается
если что на тесте обновил

надо было сверху убрать id="page" и добавить вниз

а вы зачем-то и наверху оставили id="page" и вниз добавили id="page1"

у вас получилось так

<div id="page">
    <form>
        <select></select>
    </form>
    <div class="row" id="page1"></row>
</div>


а надо так
<div>
    <form>
        <select></select>
    </form>
    <div class="row" id="page"></row>
</div>


Читайте, что я пишу!!!

Цитата:

Сообщение от гуня
читал
я поменял в скрипте код обновления
new Pjax({
        elements: 'a[ajaxLink], li.page a, div.sorter a, form',
        selectors: ['#page1'],
        scrollTo: false,
        cacheBust: false
    });


UPD
А в тесте до сих пор показывает (в category.js строки 48-53)

new Pjax({
        elements: 'a[ajaxLink], li.page a, div.sorter a, form',
        selectors: ['#page'],
        scrollTo: false,
        cacheBust: false
    });


UPD
Теперь передвинулось на строки 65-70, но всё-равно тот же текст

UPD

Цитата:

Сообщение от гуня
сделал как описано в 7 посте
теперь page перенесено
не помогло

помогло!

Проще говоря, раскомментируйте 49 строчку в category.js

у вас в category.js строки 28-53 выглядит так
$(document).on('change', '#goods-filter :input, #goods-filter [type=hidden]', function() {



        /*interval = setInterval(function () {
            //$('div.' + cssClass + ' .multiselect').parent().find('ul').show();
            //cssClass = '';

            if (cssClass.length > 0) {
                console.log('setInterval');
                $('div.' + cssClass + ' .multiselect').parent().find('ul').show();
            }

            if (cssClass.length == 0) {
                clearInterval(interval);
            }
        }, 1);*/

        $('#goods-filter :submit').click();

        if (cssClass.length > 0) {
            //$('div.' + cssClass + ' .multiselect').parent().find('ul').show();
        }


    });


а надо так
$(document).on('change', '#goods-filter :input, #goods-filter [type=hidden]', function() {



        /*interval = setInterval(function () {
            //$('div.' + cssClass + ' .multiselect').parent().find('ul').show();
            //cssClass = '';

            if (cssClass.length > 0) {
                console.log('setInterval');
                $('div.' + cssClass + ' .multiselect').parent().find('ul').show();
            }

            if (cssClass.length == 0) {
                clearInterval(interval);
            }
        }, 1);*/

        $('#goods-filter :submit').click();

        if (cssClass.length > 0) {
*!*
            $('div.' + cssClass + ' .multiselect').parent().find('ul').show();
*/!*
        }


    });
или лучше так (если закомментированное не нужно!) а надо так
$(document).on('change', '#goods-filter :input, #goods-filter [type=hidden]', function() {
        $('#goods-filter :submit').click();

        if (cssClass.length > 0) {
            $('div.' + cssClass + ' .multiselect').parent().find('ul').show();
        }
    });


UPD

Цитата:

Сообщение от гуня
при первой загрузке чекбоксы схлопываются

я не понял, что это значит, но если раскомментировать 49 строчку то всё работает без мигания и сворачивания

Цитата:

Сообщение от гуня
надо загрузить новую вкладку без параметров и выбрать чекбокс

Ах, да! Заметил! То, что у вас в category.js на 55-57 строчках перенесите на 27

$(document).on('change', ':checkbox', function() {
        cssClass = $(this).closest('div.col-xs-3').data('css');
    });

то, что у вас на 55-57 строчках перенесите на 27 (у вас она до сих не перенесена)

гуня 23.01.2019 01:26

переписал для продакшена
вылезла новая ошибка
открываем вкладку, загружаем урл, фильтруем- все работает
затем кликаем на другую категорию, открываем чекбоксы и после первого клика идет схлопывание
на тесте обновил

гуня 23.01.2019 20:49

вроде разобрался
надо в событии pjax complete заново инициализировать pjax

гуня 24.01.2019 00:15

вылезла новая напасть
сперва отмечаем чекбоксы,затем кликаем назад в браузере
шлются бесконечные запросы
например сюда google-analytics.com/collect
хром показывает тысячи запросов

Malleys 24.01.2019 00:50

Я не нашёл никаких тысячу запросов, только пару десятков, да и то они шлются по любому поводу (мышка из браузера вышла, url поменялся)

а так у вас всё схлопывается, поскольку вы зачем-то наверх перенесли id="page", а внизу заменили на id="goods-list". (а надо внизу чтобы было id="page")

и то, что у вас на 55-57 строчках перенесите на 27 (у вас она до сих не перенесена)

гуня 24.01.2019 00:53

может файл закешировался
там счас новая версия скрипта

гуня 24.01.2019 01:06

вот что получил https://imgur.com/a/Ex0A5Y8

Malleys 24.01.2019 06:10

Цитата:

Сообщение от гуня
может файл закешировался

Да, так всё время и происходит!
Цитата:

Сообщение от гуня
сперва отмечаем чекбоксы,затем кликаем назад в браузере
шлются бесконечные запросы
например сюда google-analytics.com/collect
хром показывает тысячи запросов

не надо было в событии pjax:complete заново инициализировать pjax, т. е. у вас на каждый ответ регистрируется обработчик, который вызывается при следующем ответе.

В общем у вас там немного запутанно получилось... Я думаю, что состояние кнопок лучше восстанавливать из состояния, которое хранится в search params.

Короче удалите всё, что у вас сейчас есть в category.js, и замените на это...
$(function() {	
	new Pjax({
        elements: "form",
        selectors: ["#goods-list"],
        scrollTo: false,
        cacheBust: false
    });
	
	$(".price-range").each(function() {
        var $minPrice = $(this).find("#min");
        var $maxPrice = $(this).find("#max");
        var min = $(this).data("price-min") || 0;
        var max = $(this).data("price-max") || 1000000;

        $(this).ionRangeSlider({
            type: "double",
            grid: true,
            min: min,
            max: max,
            from: $minPrice.val(),
            to: $maxPrice.val(),
            postfix: " ₽",
            onFinish: function (data) {
                $minPrice.val(data.from).trigger("change");
                $maxPrice.val(data.to).trigger("change");
            }
        });
    });

    $(document).click(function () {
        $(".multiselect").parent().find("ul").prop("style", "");
    });

    $(document).on("change", "#goods-filter :input, #goods-filter [type=hidden]", function() {
        $("#goods-filter :submit").click();
		$(this).closest("div.col-xs-3").find(".multiselect").parent().find("ul").show();
    });

    document.addEventListener("pjax:complete", function () {
		updateFields();

		$("#tabster").tabs();
        $(".bxslider").bxSlider({
            pagerCustom: "#bx-pager",
            infiniteLoop: false
        });

        $("a[rel=gallery]").fancybox([]);
        $("#goods-filter").show();
    });
	
	updateFields();

    $(".sidebar-menu").show();
	
	function updateFields() {
		var q = $.deparam(location.search.replace(/^\?/,""));
		
		$("form select[name='brands[]']").val(q.brands);
		$("form select[name='brands[]']").multiselect("refresh");
		
		$("form input[name=latest]").val(q.latest || "0");
		$("form input[name=sale]").val(q.sale || "0");
		$("form input[name=popular]").val(q.popular || "0");
		$("form input[name=available]").val(q.available || "0");
		
		$("form .price-range").data("ionRangeSlider").update(q.price);
	}

    $(document).on("click", ".treeview li a", function() {
        var li = $(this).closest("li");
        $(".treeview a.selected").removeClass("selected");
        $(this).addClass("selected");

        if (li.hasClass("collapsable")) return;

        li.find("div.hitarea:first").swapClass("expandable-hitarea", "collapsable-hitarea");
        li.swapClass("lastExpandable", "lastCollapsable");
        li.swapClass("expandable", "collapsable");
        li.find("ul:first").toggle();
    });

    $(document).on("click", ".items a[ajaxLink]", function() {
        var link = $('.treeview a[href="' + $(this).attr('href') + '"]');

        if (!link.length) return false;

        var li = link.closest("li");

        $(".treeview a.selected").removeClass("selected");
        link.addClass("selected");

        if (li.hasClass("collapsable")) return;

        li.swapClass("lastExpandable", "lastCollapsable");
        li.swapClass("expandable", "collapsable");
        li.find("div.hitarea:first").swapClass("expandable-hitarea", "collapsable-hitarea");
        li.find("ul:first").toggle();
    });
});

гуня 24.01.2019 15:00

код обновил
теперь после фильтрации чекбоксами при клике на единицу товара не происходит переход по ссылке на сам товар

Malleys 24.01.2019 16:22

Может тогда строки 92-108 не нужно... Это не нужно
$(document).on("click", ".items a[ajaxLink]", function() {
        var link = $('.treeview a[href="' + $(this).attr('href') + '"]');

        if (!link.length) return false;

        var li = link.closest("li");

        $(".treeview a.selected").removeClass("selected");
        link.addClass("selected");

        if (li.hasClass("collapsable")) return;

        li.swapClass("lastExpandable", "lastCollapsable");
        li.swapClass("expandable", "collapsable");
        li.find("div.hitarea:first").swapClass("expandable-hitarea", "collapsable-hitarea");
        li.find("ul:first").toggle();
    });
У вас там на странице такого совпадения нет (строка 93), поэтому оно запрещает переходить (сторока 95)

гуня 24.01.2019 19:48

в таком случае переход будет с полной перегрузкой страницы а нужно без перегрузки

гуня 26.01.2019 19:23

кто подскажет куда копать?


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