
В любом магазине должен быть удобный доступ к товарам. И если их много, то не обойтись без фильтров. Покупатель должен быть способен выбрать нужный товар по цене, свойствам и характеристикам.
HTML
Для начала стоит сделать разметку страницы и собственно фильтров. Вот как это примерно выглядит:
<aside class="grid_3"> <form id="filter_form" method="get" action=""> {% for property in collection.properties %} <ul> <li class="topp"><span class="arowcont"></span> </li> {% for characteristic in property.characteristics %} <li class="subss"> <input style="display: none" id="char" type="checkbox" name="characteristics[]" value="" {% if characteristic.current? %}checked{% endif %}> <a class="paramfilter" id="har"> ()</a> </li> {% endfor %} </ul> {% endfor %} {% for option in collection.options %} <ul> <li class="topp"><span class="arowcont"></span> </li> {% for value in option.values %} <li class="subss"> <input style="display: none" id="char" type="checkbox" name="options[][]" value="" {% if value.selected %}checked{% endif %}> <a class="paramfilter" id="har" style="cursor: pointer;" > ()</a> </li> {% endfor %} </ul> {% endfor %} <ul class="noopul"> <li class="topp"><span class="arowcont"></span> Цена</li> <li><input type="text" id="priceslider" name="priceslider" value="" /></li> <input type="hidden" id="price_min" name="price_min" /> <input type="hidden" id="price_max" name="price_max" /> </ul> </form> </aside> <div class="grid_9"> {% paginate collection.products by 9 %} <div class="catalog negative-grid products"> <div class="titlecont"> <h1 class="page_title catalogtitle"></h1> </div> {% for product in collection.products %} {% include 'show_product' %} {% endfor %} </div> {% if paginate.parts.size > 0 %} <div class="pagination"> <ul> <li class="prev">{% if paginate.previous.title %}<a href="">←</a>{% else %}<span>←</span>{% endif %}</li> {% for part in paginate.parts %} <li {% if paginate.current_page == part.title %} class="curent" {% endif %}><a href=""></a></li> {% endfor %} <li class="next">{% if paginate.next.title %}<a href="">→</a>{% else %}<span>→</span>{% endif %}</li> </ul> </div> <p class="pagination_info">Показаны товары -</p> {% endif %} {% endpaginate %} </div>
Вначале мы видим боковую колонку, где в виде списков представлены свойства и характеристики товаров. Далее отдельный список станного вида для цены. Каждому пункту списков соответствуют ссылка и скрытый инпут.
Логика
Для начала установим слайдер фильтра по цене. Скачать и установить его можно отсюда.
Чтобы все было красиво фильтры будут работать не просто так, а через AJAX.
Напишем функцию запроса. Будем получать html с определенного url и обновлять нужные части страницы: блок товаров и блок переключения страниц.
run_filter = (url) -> show_preloader() $.ajax url: url type: "GET" dataType: "html" success: (response) -> $('.products').html $(response).find('.products').html() $('.pagination').html $(response).find('.pagination').html() hide_preloader()
Функция клика на фильтре. Выбираем из id нужное свойство и записываем в нужный input. Меняем цвет ссылки, форму преобразуем в url и вызываем функцию ссвязи с сервером.
$( ".paramfilter" ).on 'click', (e) -> e.preventDefault(); this_c = $("#c#{ $(@).attr 'id' }") if this_c.prop 'checked' this_c.attr 'checked', false $(@).css 'color','#7b7b7b' else this_c.attr 'checked', true run_filter "?#{ $('#filter_form').serialize()
Обработка листалки страниц. Берем url ссылки и отправляем на сервер. Этот контент динамический, поэтому событие ‘click’ регистрируем особым образом.
$("body").on "click", ".pagination a", -> run_filter $(@).attr "href"
Инициализируем фильтр по цене и установим обработчик события finish. Когда изменение диапазона заканчивается, записываем значения в input и отправляем форму.
$("#priceslider").ionRangeSlider type: "double" grid: true min: "" max: "" from: "" to: "" postfix: ('{{ "1"| money}}').slice(1) onFinish: (data) -> $this = $("#priceslider") value = $this.prop("value").split ";" $('#price_min').val value[0] $('#price_max').val value[1] run_filter "?#{ $('#filter_form').serialize() }"
Итог
Полный код скрипта будет выглядеть так:
$ -> run_filter = (url) -> show_preloader() $.ajax url: url type: "GET" dataType: "html" success: (response) -> $('.products').html $(response).find('.products').html() $('.pagination').html $(response).find('.pagination').html() hide_preloader() $( ".paramfilter" ).on 'click', (e) -> e.preventDefault(); this_c = $("#c#{ $(@).attr 'id' }") if this_c.prop 'checked' this_c.attr 'checked', false $(@).css 'color','#7b7b7b' else this_c.attr 'checked', true run_filter "?#{ $('#filter_form').serialize() }" $("body").on "click", ".pagination a", -> run_filter $(@).attr "href" $("#priceslider").ionRangeSlider type: "double" grid: true min: "" max: "" from: "" to: "" postfix: ('{{ "1"| money}}').slice(1) onFinish: (data) -> $this = $("#priceslider") value = $this.prop("value").split ";" $('#price_min').val value[0] $('#price_max').val value[1] run_filter "?#{ $('#filter_form').serialize() }"
Внешне все должно выглядеть примерно так:
Вроде все работает, но для увеличения производительности стоит скомпилировать CoffeeScript в JavaScript. Вот итоговый код:
