Каталог в интернет-магазине, переключаем внешний вид товаров одной кнопкой

июнь 13 , 2017
Предыдущая статья Демо Исходники

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

Но давайте вспомним серьезные интернет-магазины. Многие из них предлагают на выбор несколько вариантов отображения товаров. Чаще всего встречается один вид с большими фото, второй кратким списком и третий - что-то среднее. Это очень удобно, так как предпочтения людей по виду каталога разные. А если такое могут сделать серьезные магазины, то чем мы хуже?

В этой статье мы создадим набор переключателей внешнего вида каталога (можно даже назвать это темами). И небольшим бонусом научимся сохранять это состояние в localStorage. Так как html-разметка товаров у нас находится в underscore-шаблонах, то задача предельно упрощается. Это будет самый короткий и простой урок по интернет-магазинам. Приступим.


Что будем делать?

Давайте сразу посмотрим, что получится в итоге. На странице Каталог с пагинацией слева от категорий мы добавим 3 кнопки-иконки, которые и будут переключать внешний вид каталога. Это будут такие варианты: вид с большими фото, компактный вид (как на каталоге с фильтрами) и краткий список без фото (как раз он на скриншоте).

Нам нужно будет завести 3 underscore-шаблона под каждый вид и подключать их в зависимости от нажатой кнопки. Начнем с верстки.


Добавляем кнопки-иконки

Мне опять лень верстать что-то самому, поэтому для иконок воспользуюсь готовым bootstrap. Верстка получится такая. Я привел весь блок целиком: и категории, и новые кнопки-переключалки. Второй кнопке добавим класс active, пусть по умолчанию у нас будет вид компактный. То есть такой же, который мы создали в предыдущем уроке про постраничную навигацию

    

Готовим underscore-шаблоны

Так, один шаблон у нас уже есть. Это script id="goods-template". Напоминаю, что он базируется в файле catalog-pag.html - с ним мы и будем работать. Давайте переименуем goods-template в goods-template-compact и добавим еще два. Делаем абсолютно по аналогии с уже созданным. Вот шаблон для первого вида с большими фото.

    

Назвали шаблон незатейливо - goods-template-big. Скажу по секрету, я его своровал с главной страницы index.html. Пришлось лишь немного исправить названия полей объектов, так как у нас данные возвращаются немного в другом формате, не как на главной. А классы вроде good-item__name оставляем как есть, стили для них мы написали еще в самом первом уроке про корзину

Осталось завести третий шаблон с кратким списком. Готового кода под него нет, но предлагаю не заморачиваться и написать что-то такое.

    

То есть просто выводим артикул, название товара и цену в строчку, не забыв нарисовать кнопку "Добавить в корзину". Никаких стилей специально делать не будем, для примера и так сойдет.

С шаблонами все, переходим на javascript.


Клиентский код для переключения внешнего вида каталога

Первое, добавляем новый элемент в объект ui

    var ui = {
        ...
        $themeBtn: $('.js-theme'),
        ...
    };

Второе, смотрим на переменную goodsTemplate, в которой у нас был записан единственный доселе шаблон. Теперь он у нас называется goods-template-compact, плюс есть еще 2 штуки. Давайте сделаем переменную goodsTemplate объектом, куда занесем все 3 шаблона.

    var goodsTemplate = {
        big: _.template($('#goods-template-big').html()),
        compact: _.template($('#goods-template-compact').html()),
        list: _.template($('#goods-template-list').html())
    }

Третье, в функции _bindHandlers нужно добавить обработчик клика на новые кнопки.

    // Привязка событий
    function _bindHandlers() {
        ...
        ui.$themeBtn.on('click', _changeTheme);
        ...
    }

Четвертое, реализация функции клика _changeTheme

    // Смена вида каталога (темы)
    function _changeTheme(e) {
        var $theme = $(e.target).closest('button');
        ui.$themeBtn.removeClass('active');
        $theme.addClass('active');

        _getData({
            resetPage: false
        });
    }

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

И пятое, в функции рендера каталога _renderCatalog нужно подставить шаблон с выбранным видом. В зависимости от нажатой кнопки. Это всего две строчки кода.

    // Рендер каталога
    function _renderCatalog(goods) {
        var theme = $('.js-theme.active').attr('data-theme');
        ui.$goods.html(goodsTemplate[theme]({goods: goods}));
    }

Вот и все! По сути всю работу за нас сделал underscore своими шаблонами. Как раз здесь и проявляется прелесть шаблонизации на клиенте. Очень приятная фишка с переключением обошлась нам довольно дешево в реализации.

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


Сохраняем выбранную тему в localStorage.

Сначала в функции смены вида каталога _changeTheme нужно записать выбранную тему в localStorage. Там добавилось всего 2 строки. Полный код функции теперь такой.

    // Смена вида каталога (темы)
    function _changeTheme(e) {
        var $theme = $(e.target).closest('button'),
            // НОВАЯ СТРОКА
            theme = $theme.attr('data-theme');
        ui.$themeBtn.removeClass('active');
        $theme.addClass('active');

        _getData({
            resetPage: false
        });

        // НОВАЯ СТРОКА
        localStorage.setItem('theme', theme);
    }

Теперь в функции init в самом начале, еще до загрузки и отрисовки каталога нужно вытащить тему из localStorage. Или, если там пока ничего нет, взять по умолчанию значение compact. Правим init

    // Инициализация модуля
    function init() {
        // НОВАЯ СТРОКА
        _setTheme();
        _getData({
            resetPage: true
        });
        _bindHandlers();
    }

Добавилась только первая строчка - вызов _setTheme();

Теперь реализация _setTheme

    // Устанавливаем тему, делаем нужную кнопку активной
    function _setTheme() {
        var theme = localStorage.getItem('theme') || 'compact';
        $('.js-theme[data-theme="' + theme + '"]').addClass('active');
    }

Запомнить данные в localStorage оказалось проще, чем сделать сами переключения. И последнее, в файле catalog-pag.html у второй кнопки уберите класс active - он будет ставиться через javascrpt.

А теперь полюбуемся на то, что получилось - демо с переключением вида каталога

P.S. Кстати, было бы неплохо сохранить в localStorage и количество товаров на странице, но предоставлю сделать это самим, аналогично с вышеразобранным примером :-)


Подводим итоги

А итоги таковы: небольшими усилиями мы реализовали весьма неплохой функционал. Что показательно, старый код не пришлось кардинально менять, встроить переключение вида каталога получилось довольно аккуратно. Всегда приятно добавлять новые фишки в проект, не ломая старого кода. И конечно, мы можем добавить сколько угодно вариантов отображения - шаблоны underscore легко позволяют это делать.


Немного планов на будущее

Как Вы могли заметить, тема интернет-магазинов после некоторого затишья начинает оживать. У меня появилось несколько интересных мыслей о новом и полезном функционале.

Возможно, статьи про магазин ждет небольшое изменение формата: есть мысль разбивать посты на очень короткие уроки, каждый из которых можно пройти минут за 5-10. Серия статей с фильтрами показала, что эта идея с разбиением удачная, но хочу попробовать сделать статьи еще меньше и легче в изучении. Как это получится на практике, посмотрим вместе.

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

Все об интернет-магазинах

Предыдущая статья Демо Исходники
Заходите в группу в контакте - https://vk.com/webdevkin
Анонсы статей, обсуждения интернет-магазинов, vue, фронтенда, php, гита.
Истории из жизни айти и обсуждение кода.
Как Вам статья? Оцените!