Каталог в интернет-магазине, переключаем внешний вид товаров одной кнопкой
На страницах нашего интернет-магазина встречаются 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. Серия статей с фильтрами показала, что эта идея с разбиением удачная, но хочу попробовать сделать статьи еще меньше и легче в изучении. Как это получится на практике, посмотрим вместе.
В общем, следите за обновлениями, скоро посты начнут выходить чаще. В ближайшее время я также планирую наконец-таки сделать подписку на новые статьи, так что следить за новыми статьями станет проще.
Все об интернет-магазинах
- Демо интернет-магазина
- Корзина интернет-магазина. С чего все началось
- Оформляем заказ на клиенте и сервере
- Добавляем доставку
- Фильтры и сортировки на клиенте и сервере
- Урок 0. Вводный
- Урок 1. Структура базы данных
- Урок 2. Структура проекта и верстка
- Урок 3. Сбор данных на клиенте и отправка на сервер
- Урок 4. Пишем базовый php-код и sql-запросы
- Урок 5. Прием данных с сервера и рендеринг на клиенте
- Урок 6. Заключительный, дорабатываем некоторые штрихи
- Сравнение товаров
- Постраничная навигация по товарам
- Преобразуем каталог, переключаем внешний вид товаров одной кнопкой
- Отправка sms при оформлении заказа
- Админка интернет-магазина на vue.js - серия уроков
- Авторизация на сессиях. Делаем логин в админке
- Docker для начинающих. Докеризуем интернет-магазин
Истории из жизни айти и обсуждение кода.