[msAltCart] Динамическая корзина для MiniShop2
Приветствую! Предлагаю вашему вниманию современный вариант полюбившегося многим компонента msMCD. Как водится постарался учесть большинство популярных кейсов использования корзины: миникорзина в шапке, динамическая корзина сбоку, всплывающее окно с последним добавленным товаров, основная корзина. Подробности под катом.
Особенности
Использовать данный компонент как основную корзину чревато тем, что с некоторыми компонентами она может работать некорректно. Например msPromoCode2 ломает логику работы, так как его недрах генерируется некорректный ключ товара.
Так же при вызове на одной странице стандартной корзины и корзины компонента между ними не будет синхронизации.
Требования
PHP 7.4 и Modx 2.6-2.8
Зависимости
Быстрый старт
Подготовка чанков
Форме добавления товара в корзину нужно добавить атрибуты data-si-preset=«cart_add» data-si-form=«product-{$id}» data-si-nosave.
Кнопке в этой форме нужно установить type в значение button и добавить атрибут data-si-event=«click».
Родную разметку miniShop2 для формы и кнопки при этом следует удалить.
В отличие от оригинального чанка корзины, тут чанк разбит на два: обёртку и товар. Корневой элемент чанка товара должен содержать атрибут data-msac-product="{$key}".
Внутри коневого элемента можно разместить форму или несколько форм с изменяемыми полями, например количество и опции. Каждая такая форма должна иметь атрибуты
data-si-form=«change-options-{$key}» data-si-preset=«cart_change» data-si-event=«change» data-si-nosave. Атрибут data-si-form иметь произвольное,
но уникальное в рамках одной страницы значение.
Также внутри корневого элемента следует разместить форму удаления товара из корзины со следующими атрибутами data-si-form=«remove-{$key}» data-si-preset=«cart_remove».
Внутри этой формы должна быть кнопка с атрибутами type=«button» data-si-event=«click».
Для вставки изменяемых значений, например, стоимости товара, количества товара, картинки товара, общей стоимости корзины, общего веса, общего количества,
нужно чтобы каждый такой элементы был отдельным html элементом с атрибутом data-msac-prop. В качестве значения этого атрибута следует указывать ключ поля
cost, total_cost и т.д.
Внутри чанка-обёртки доступны следующие плейсхолдеры:
В стилях должен быть реализован класс d-none для скрытия элементов на страницы. Каждый из трёх блоков (data-msac-rows, data-msac-totals, data-msac-empty)
должен отображаться в зависимости от пустоты плейсхолдера $rows. Логика понятна: если товары есть ($rows непустой) показываем data-msac-rows, data-msac-totals
и скрываем data-msac-empty. И наоборот, когда нет товаров в корзине ($rows пустой) скрываем data-msac-rows, data-msac-totals и показываем data-msac-empty.
В комплекте есть примеры всех чанков, кому непонятно словесное описание — смотрите пример.
Вызов сниппета
В шаблонах, где необходимо выводить корзины нужно вызвать сниппет getCarts.
Данные можно передавать в формате JSON или в иде массива.
В этом же шаблоне ПОСЛЕ вызова необходимо добавить блоки для вывода корзин. Для вызова выше они будут такими
Быстрый переход к оформлению заказа
Если вы хотите, чтобы при добавлении в корзину всплывало окно с предложением оформить заказ, и при этом сайт использует Bootstrap можно использовать такой код
JS API для управления корзиной
Добавить товар
Компонент доступен на modstore
Спасибо за внимание!
Особенности
Использовать данный компонент как основную корзину чревато тем, что с некоторыми компонентами она может работать некорректно. Например msPromoCode2 ломает логику работы, так как его недрах генерируется некорректный ключ товара.
Так же при вызове на одной странице стандартной корзины и корзины компонента между ними не будет синхронизации.
Требования
PHP 7.4 и Modx 2.6-2.8
Зависимости
- SendIt v1.1.0 и выше (деинсталировать предыдущие версии и только потом обновлять)
- MiniShop2 4.0.0 и выше
- pdoTools 2.13.2 и выше
- Вывод любого количества корзин на одной страницы
- Динамическое обновление всех корзин
- Каждая корзина может иметь собственный шаблон
- Изменение опций в корзине
- JS API для программного управления корзиной
- Получение статуса и состава корзины на фронте
- Поддержка компонентов msOptionsPrice2 и msProductDiscounts
- Изменение логики работы посредством JS событий
Быстрый старт
- Установить компонент
- Подготовить чанки
- Вызвать некешированным сниппет getCarts
Подготовка чанков
Форме добавления товара в корзину нужно добавить атрибуты data-si-preset=«cart_add» data-si-form=«product-{$id}» data-si-nosave.
Кнопке в этой форме нужно установить type в значение button и добавить атрибут data-si-event=«click».
Родную разметку miniShop2 для формы и кнопки при этом следует удалить.
В отличие от оригинального чанка корзины, тут чанк разбит на два: обёртку и товар. Корневой элемент чанка товара должен содержать атрибут data-msac-product="{$key}".
Внутри коневого элемента можно разместить форму или несколько форм с изменяемыми полями, например количество и опции. Каждая такая форма должна иметь атрибуты
data-si-form=«change-options-{$key}» data-si-preset=«cart_change» data-si-event=«change» data-si-nosave. Атрибут data-si-form иметь произвольное,
но уникальное в рамках одной страницы значение.
Также внутри корневого элемента следует разместить форму удаления товара из корзины со следующими атрибутами data-si-form=«remove-{$key}» data-si-preset=«cart_remove».
Внутри этой формы должна быть кнопка с атрибутами type=«button» data-si-event=«click».
Для вставки изменяемых значений, например, стоимости товара, количества товара, картинки товара, общей стоимости корзины, общего веса, общего количества,
нужно чтобы каждый такой элементы был отдельным html элементом с атрибутом data-msac-prop. В качестве значения этого атрибута следует указывать ключ поля
cost, total_cost и т.д.
Внутри чанка-обёртки доступны следующие плейсхолдеры:
- $rows — список товаров, должен быть расположен внутри блока с атрибутом data-msac-rows
- $total — массив общих значений, должен быть расположен внутри блока с атрибутом data-msac-totals
В стилях должен быть реализован класс d-none для скрытия элементов на страницы. Каждый из трёх блоков (data-msac-rows, data-msac-totals, data-msac-empty)
должен отображаться в зависимости от пустоты плейсхолдера $rows. Логика понятна: если товары есть ($rows непустой) показываем data-msac-rows, data-msac-totals
и скрываем data-msac-empty. И наоборот, когда нет товаров в корзине ($rows пустой) скрываем data-msac-rows, data-msac-totals и показываем data-msac-empty.
В комплекте есть примеры всех чанков, кому непонятно словесное описание — смотрите пример.
Вызов сниппета
В шаблонах, где необходимо выводить корзины нужно вызвать сниппет getCarts.
{'!getCarts' | snippet: [
'tpls' => '{
"maincart": { "wrapper":"@FILE msac/cart.tpl","row":"@FILE msac/cartrow.tpl" },
"modal": { "wrapper":"@FILE msac/cartmodal.tpl","row":"@FILE msac/cartmodalrow.tpl" }
}'
]}
Он принимает один параметр tpls — список корзин, которые расположены в данном шаблоне с чанками для каждой.Данные можно передавать в формате JSON или в иде массива.
В этом же шаблоне ПОСЛЕ вызова необходимо добавить блоки для вывода корзин. Для вызова выше они будут такими
<div class="offcanvas-body" data-msac-cart="maincart" data-mspd-cart-wrap>
{'maincart' | placeholder}
</div>
<div class="modal-body" data-msac-cart="modal" data-mspd-cart-wrap>
{'modal' | placeholder}
</div>
Базовая настройка на этом закончена.Быстрый переход к оформлению заказа
Если вы хотите, чтобы при добавлении в корзину всплывало окно с предложением оформить заказ, и при этом сайт использует Bootstrap можно использовать такой код
document.addEventListener('DOMContentLoaded', e => {
const modalCartEl = document.getElementById('modalCart')
if (modalCartEl) {
const modalCart = new bootstrap.Modal(modalCartEl, {})
modalCartEl.addEventListener('hide.bs.modal', () => {
const rows = modalCartEl.querySelector(MsAltCart.config.rowsSelector);
rows && (rows.innerHTML = '');
})
document.addEventListener('si:send:after', (e) => {
if(['add', 'change'].includes(e.detail.result.data.action)){
const rows = modalCartEl.querySelector(MsAltCart.config.rowsSelector);
rows && (rows.innerHTML = '');
}
})
document.addEventListener('msac:row:add:after', e => {
if (e.detail.cartName === 'modal') {
modalCart.show();
}
})
document.addEventListener('msac:row:remove:before', e => {
if (e.detail.cartName === 'modal') {
modalCart.hide();
}
})
}
})
JS API для управления корзиной
Добавить товар
MsAltCart.add(30, 2, {
color: 'Оранжевый',
})
Удалить товарMsAltCart.remove('msb1906def283e69f84e5700559f51582c')
Изменить товарMsAltCart.change('msa6943f19b712772e2103beb283d615b4', 4, {
color: 'Оранжевый',
})
Очистить корзинуMsAltCart.clean()
Получить статус и состав корзиныconst promise = MsAltCart.status();
promise.then((result) => console.log(result));
Посмотреть как работает можно тутКомпонент доступен на modstore
Спасибо за внимание!
Поблагодарить автора
Отправить деньги
Комментарии: 10
1) Количество товара в корзине не обновляется без перезагрузки
2) если сменить в сайдбаре опцию, то количество уже изменить нельзя
2) если сменить в сайдбаре опцию, то количество уже изменить нельзя
Похоже ты там был, когда я как раз кое-что дорабатывал. Посмотри теперь.
Быстрая поддержка и отличный плагин!
Странный компонент, завести не смог)) купил установил и удалил))
Согласен, мои компоненты не для всех, они для тех, кто понимает, что делает.
С утра на свежею голову, вроде завел )). Все таки есть в документации не точности.
Конкретику в студию.
Видимо не дорос я до ваших компонентов))
Не работает у меня мой самописный плагин, который реагирует на событие msOnAddToCart и берет цену из другого поля, не price, в зависимости от контекста. С обычной корзиной, работает, кстати.
Не работает у меня мой самописный плагин, который реагирует на событие msOnAddToCart и берет цену из другого поля, не price, в зависимости от контекста. С обычной корзиной, работает, кстати.
Код плагина хотя бы показал.
<?php
switch ($modx->event->name) {
case 'msOnAddToCart':
// Проверка на контекст
if ($modx->context->key !== 'web') {
// Получаем текущие товары в корзине
$tmp = $cart->get();
// Получаем id добавленного продукта
foreach ($tmp as $key => $item) {
$productId = $item['id'];
$product = $modx->getObject('msProduct', $productId);
if ($product) {
// Получаем цену для монобренда "my_price_mono"
$newPrice = $product->get('my_price_mono');
// Проверяем, что цена задана и больше нуля
if (!empty($newPrice) && $newPrice > 0) {
// Устанавливаем новую цену
$tmp[$key]['price'] = $newPrice;
} else {
// Логгирование ошибки для пустой или некорректной цены
$modx->log(modX::LOG_LEVEL_ERROR, 'Invalid or empty my_price_mono for product ID ' . $product->get('id'));
}
}
}
// Сохраняем измененную корзину
$cart->set($tmp);
}
break;
}
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.