Skip to content
  1. Компоненты
  2. msAltCart

msAltCart

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

Осторожно

Компонент некорректно работает с другими компонентами, меняющими ключи товаров в корзине, например, с msPromoCode2.

Внимание

Перед установкой компонента убедитесь, что у вас уже установлены pdoTools, SendIt, miniShop2.

Подсказка

Данный компонент может заменить и основную корзину. В нём есть поддержка стандартных JS событий из miniShop2. Однако совместимость с другими дополнениями не тестировалась, поэтому применение этого кейса может привести к поломке какой-либо функциональности, предоставляемой другими компонентами, в том числе связанным с оформлением заказов.

Системные требования

  1. miniShop2 >= 3.0.7
  2. SendIt >= 2.0.2
  3. PHP >= 7.4 (работа на PHP 8 не тестировалась, но IDE ошибок не нашла).

Возможности

  1. Вывод любого количества корзин на одной страницы.
  2. Динамическое обновление всех корзин.
  3. Каждая корзина может иметь собственный шаблон.
  4. Изменение опций в корзине.
  5. JS API для программного управления корзиной.
  6. Получение статуса и состава корзины на фронте.
  7. Изменение логики работы посредством JS событий.
  8. Есть поддержка модификаций msOptionsPrice2.
  9. Кастомизация поля ввода количества.

Особенности

  1. Компонент заменяет стандартный класс-обработчик корзины на свой.
  2. Компонент делает метод getProductKey() публичным.
  3. Компонент добавляет плагин на событие msOnCreateOrder, меняющий имя товара на имя модификации, если таковая была выбрана.

Базовое использование

Добавим динамическую корзину, которая будет появляться из-за экрана слева в элементе offcanvas.

Внимание

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

Осторожно

Одновременное использование стандартных для miniShop2 атрибутов и атрибутов данного компонента недопустимо. Исключение можно сделать только для класса ms2_form

Порядок действий

  1. Создаём чанк-обёртку(wrapper).
  2. Создаём чанк товара(row) (опционально).
  3. В шаблоне вызываем сниппет getCarts.
  4. Вставляем плейсхолдер там, где должна быть динамическая корзина.
  5. Пользуемся.

Чанк-обертка(wrapper)

fenom
<div data-msac-rows class="{!$rows ? 'd-none':''}">
    {$rows}
</div>
<div class="col-12 {!$rows ? 'd-none':''}" data-msac-totals>
    <div class="row">
        <p class="col-5 mb-3 h6">Сумма: <br><span  data-msac-prop="total_cost">{$total.cost}</span> {'ms2_frontend_currency' | lexicon}</p>
        <p class="col-3 mb-3 h6">Вес: <br><span data-msac-prop="total_weight">{$total.weight}</span> {'ms2_frontend_weight_unit' | lexicon}</p>
        <p class="col-4 mb-3 h6">Кол-во: <br><span data-msac-prop="total_count">{$total.count}</span> {'ms2_frontend_count_unit' | lexicon}</p>
        <div class="col-6">
            <button class="btn btn-danger" type="button" data-si-form data-si-preset="cart_clean" data-si-event="click">
                {'ms2_cart_clean' | lexicon}
            </button>
        </div>
        <div class="col-6">
            <a href="{179 | url}" class="btn btn-primary">Оформить заказа</a>
        </div>
    </div>
</div>

<div class="alert alert-warning {$rows ? 'd-none':''}" data-msac-empty>
    {'ms2_cart_is_empty' | lexicon}
</div>

Этот чанк содержит три отдельных блока обозначенных соответствующими атрибутами.

Список товаров

data-msac-rows - блок вывода списка товаров, если не указан - товары выведены не будут.

fenom
<div data-msac-rows class="{!$rows ? 'd-none':''}">
    {$rows}
</div>

Суммарные значения

data-msac-totals - блок вывода суммарных значений цены, веса и количества.

fenom
<div class="col-12 {!$rows ? 'd-none':''}" data-msac-totals>
    <div class="row">
        <p class="col-5 mb-3 h6">Сумма: <br><span  data-msac-prop="total_cost">{$total.cost}</span> {'ms2_frontend_currency' | lexicon}</p>
        <p class="col-3 mb-3 h6">Вес: <br><span data-msac-prop="total_weight">{$total.weight}</span> {'ms2_frontend_weight_unit' | lexicon}</p>
        <p class="col-4 mb-3 h6">Кол-во: <br><span data-msac-prop="total_count">{$total.count}</span> {'ms2_frontend_count_unit' | lexicon}</p>
        <div class="col-6">
            <button class="btn btn-danger" type="button" data-si-form data-si-preset="cart_clean" data-si-event="click">
                {'ms2_cart_clean' | lexicon}
            </button>
        </div>
        <div class="col-6">
            <a href="{179 | url}" class="btn btn-primary">Оформить заказа</a>
        </div>
    </div>
</div>

Пустая корзина

data-msac-empty - блок, который будет показан, если корзина пуста.

fenom
<div class="alert alert-warning {$rows ? 'd-none':''}" data-msac-empty>
    {'ms2_cart_is_empty' | lexicon}
</div>

Осторожно

Ни один из блоков не должен быть вложен в другой.

Очистка корзины

Поскольку для отправки данных на сервер используется SendIt, то для кнопки очистки корзины необходимо добавить следующие атрибуты:

  • data-si-form - без значения.
  • data-si-preset - со значением cart_clean.
  • data-si-event - со значением click, для очистки корзины по клику.
fenom
<button class="btn btn-danger" type="button" data-si-form data-si-preset="cart_clean" data-si-event="click">
    {'ms2_cart_clean' | lexicon}
</button>

Вывод данных

Также обратите внимание на атрибуты data-msac-prop, которые позволяют выводить любые данные из корзины по ключу, его нужно указать в качестве значения данного атрибута.

fenom
<span  data-msac-prop="total_cost">{$total.cost}</span>

Чанк товара(row)

Осторожно

Это опциональный чанк, если вам нужно вывести только общие значения, например в шапке, то не нужно указывать параметр row в сниппите getCarts

fenom
<div class="col-12 py-2" data-msac-product="{$key}">
    <div class="row align-items-center justify-content-between">
        <div class="col-12 mb-3 d-flex" style="gap:15px;">
            {if $thumb?}
                <img src="{$thumb}" alt="{$pagetitle}" title="{$pagetitle}"/>
            {else}
                <img src="{'assets_url' | option}components/minishop2/img/web/ms2_small.png"
                     srcset="{'assets_url' | option}components/minishop2/img/web/ms2_small@2x.png 2x"
                     alt="{$pagetitle}" title="{$pagetitle}"/>
            {/if}
            <form  data-si-form data-si-preset="cart_change" data-si-event="change" data-si-nosave>
                <input type="hidden" name="key" value="{$key}"/>
                {if $id?}
                    <a href="{$id | url}">{$pagetitle}</a>
                {else}
                    {$name}
                {/if}
                {'!msOptions' | snippet: [
                'options' => 'color',
                'product' => $id,
                'currentOptions' => $options,
                'tpl' => '@FILE chunks/selectoption.tpl'
                ]}
                <div class="small">
                    Размеры: {$options['size']}
                </div>
                <div class="small">
                    Вес: {$options['weight']}
                </div>
            </form>
        </div>
        <form class="col-10 mb-3" data-si-form data-si-preset="cart_change" data-si-event="change" data-si-nosave>
            <input type="hidden" name="key" value="{$key}"/>
            <div class="ms-input-number-wrap">
                <button class="ms-input-number-btn ms-input-number-minus btn btn-sm btn-secondary" type="button">&#8722;</button>
                <input class="ms-input-number-emulator" value="{$count}" name="count" data-msac-prop="count" type="text">
                <button class="ms-input-number-btn ms-input-number-plus btn btn-sm btn-secondary" type="button">&#43;</button>
            </div>
        </form>
        <form class="col-2 mb-3" data-si-form data-si-preset="cart_remove">
            <input type="hidden" name="key" value="{$key}">
            <button class="btn btn-sm btn-danger" type="button" data-si-event="click">&times;</button>
        </form>
        <div class="col-3 mb-3">
            <span class="text-nowrap">{$weight} {'ms2_frontend_weight_unit' | lexicon}</span>
        </div>
        <div class="col-6 mb-3">
            <span class="mr-2 text-nowrap">{$price | replace: ' ': '' | number: 0: '.': ' '} {'ms2_frontend_currency' | lexicon}</span>
            {if $old_price?}
                <s class="old_price text-nowrap">{$old_price | replace: ' ': '' | number: 0: '.': ' '} {'ms2_frontend_currency' | lexicon}</s>
            {/if}
        </div>
        <div class="col-3 mb-3">
            <span class="mr-2 text-nowrap"><span data-msac-prop="cost">{$cost | replace: ' ': '' | number: 0: '.': ' '}</span> {'ms2_frontend_currency' | lexicon}</span>
        </div>
    </div>
</div>

Внимание

Все данные отдельного товара должны располагаться внутри блока с атрибутом data-msac-product, которому в качестве значения нужно передать ключ товара в корзине.

Изменение опций

Если хотите, чтобы можно было менять какую-то опцию товара в динамической корзине, то следует обернуть select с нужной опцией в форму. Если нужно менять несколько опций, то можно каждую из них обернуть в отдельную форму или все в одну. При этом каждая форма обязательно должна иметь следующие атрибуты:

  • data-si-form - без значения.
  • data-si-preset - со значением cart_change
  • data-si-event - со значением change, чтобы обновление корзины происходило при изменении в форме.
  • data-si-nosave - без значения, чтобы выбранные значения не сохранялись. И скрытый input с именем key и значением равным ключу товара.
fenom
<form  data-si-form data-si-preset="cart_change" data-si-event="change" data-si-nosave>
    <input type="hidden" name="key" value="{$key}"/>
    {if $id?}
        <a href="{$id | url}">{$pagetitle}</a>
    {else}
        {$name}
    {/if}
    {'!msOptions' | snippet: [
    'options' => 'color',
    'product' => $id,
    'currentOptions' => $options,
    'tpl' => '@FILE chunks/selectoption.tpl'
    ]}
    <div class="small">
        Размеры: {$options['size']}
    </div>
    <div class="small">
        Вес: {$options['weight']}
    </div>
</form>

Изменение количества

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

fenom
<form class="col-10 mb-3" data-si-form data-si-preset="cart_change" data-si-event="change" data-si-nosave>
    <input type="hidden" name="key" value="{$key}"/>
    <div class="ms-input-number-wrap">
        <button class="ms-input-number-btn ms-input-number-minus btn btn-sm btn-secondary" type="button">&#8722;</button>
        <input class="ms-input-number-emulator" value="{$count}" name="count" data-msac-prop="count" type="text">
        <button class="ms-input-number-btn ms-input-number-plus btn btn-sm btn-secondary" type="button">&#43;</button>
    </div>
</form>

Удаление товара

Чтобы была возможность удалить отдельный товар из корзины, нужно добавить в чанк товара форму со следующими атрибутами:

  • data-si-form - без значения.
  • data-si-preset - со значением cart_remove

Внутри формы следует разместить скрытый input с именем key и значением равным ключу товара. А так же кнопку с типом button и атрибутом data-si-event="click".

fenom
<form class="col-2 mb-3" data-si-form data-si-preset="cart_remove">
    <input type="hidden" name="key" value="{$key}">
    <button class="btn btn-sm btn-danger" type="button" data-si-event="click">&times;</button>
</form>

Вывод свойств

Для динамического обновления свойств товара, каждый блок содержащий конкретное свойство должен иметь атрибут data-msac-prop со значением равным ключу свойства, для стоимости отдельного товара ключом будет cost.

fenom
<span data-msac-prop="cost">{$cost | replace: ' ': '' | number: 0: '.': ' '}</span>

Вызов сниппета

Сниппет getCarts имеет только один параметр tpls, который принимает в качестве значения строку в формате JSON.

fenom
{'!getCarts' | snippet: [
    'tpls' => '{ "maincart": { "wrapper":"@FILE msac/cart.tpl","row":"@FILE msac/cartrow.tpl" } }'
]}

Внимание

Сниппет следует вызывать некешированным

Вставка плейсхолдера

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

fenom
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvasExample" aria-labelledby="offcanvasExampleLabel">
    <div class="offcanvas-header">
        <h5 class="offcanvas-title" id="offcanvasExampleLabel">Корзина</h5>
        <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Закрыть"></button>
    </div>
    <div class="offcanvas-body" data-msac-cart="maincart" data-mspd-cart-wrap>
        {'maincart' | placeholder}
    </div>
</div>

Внимание

Обратите внимание, что имя плейсхолдера равно ключу в JSON в вызове сниппета, а сам плейсхолдер расположен внутри блока с атрибутами data-mspd-cart-wrap и data-msac-cart. При этом data-msac-cart обязательно должен иметь значение равное имени плейсхолдера.

Системные настройки

КлючОписаниеЗначение
msac_frontend_jsПуть к основным JS скриптамassets/components/msaltcart/js/web/default.js