Product API
Описание
Модуль управления товарами на странице. Обеспечивает работу с количеством, артикулами (SKU), переключением характеристик, услугами и интеграцию с корзиной. Входит в состав минифицированного бандла темы assets/js/site.theme.min.js.
Инициализация
Тема автоматически инициализирует все элементы с классом js-product при загрузке страницы: для каждого создается экземпляр класса Product, который привязывается к элементу через свойство _productInstance.
Глобально доступны:
| Глобальный доступ | Описание |
|---|---|
window.waTheme.initProducts() | Инициализирует все .js-product на странице (уже инициализированные пропускаются) |
window.waTheme.initProductsInContainer(container) | Инициализирует .js-product внутри переданного контейнера — для динамически добавленной разметки |
window.waTheme.products | Данные товаров (SKU, валюта, единицы измерения), заполняются шаблонами темы |
Сам класс Product в глобальную область не экспортируется — доступ к экземпляру осуществляется через элемент:
const productElement = document.querySelector('.js-product');
const product = productElement._productInstance;
console.log(product.getCurrentSelectedSkuId());
Товары, добавленные на страницу динамически (ленивая подгрузка списков, смена сортировки или вида категории), тема переинициализирует сама — по событиям lazyload:items-loaded, category-sorting:products-updated и category-views:products-updated. Для своей динамической разметки вызывайте:
window.waTheme.initProductsInContainer(myContainer);
Требования к элементу товара:
-
Класс
js-product -
Форма с классом
js-product-form, внутри которой естьinput[name="product_id"]— из него берется ID товара -
Кнопка
.js-product-submit(или ссылка.js-product-link)
При инициализации автоматически настраиваются: обработчики SKU (радиокнопки, select-элементы и feature-кнопки), услуги, управление количеством (кнопки +/− и поле ввода) и отправка формы в корзину.
Публичные методы экземпляра
getCurrentSelectedSkuId()
Получает ID текущего выбранного артикула.
Порядок поиска:
-
Отмеченная радиокнопка (
.js-product-sku-input:checked) -
Select-элемент (
.js-product-sku-select) -
Поиск SKU по выбранным характеристикам (
findSKUByFeatures()) -
Скрытое поле
input[name="sku_id"](fallback)
Возвращает: string|null — ID выбранного SKU
Пример использования:
const currentSkuId = product.getCurrentSelectedSkuId();
console.log('Текущий SKU:', currentSkuId);
findSKUByFeatures()
Находит SKU, соответствующий выбранным характеристикам товара (для товаров с feature-based выбором).
Возвращает: объект SKU из window.waTheme.products[productId].skus или null
updatePrice(sku)
Обновляет цену товара в DOM по данным переданного SKU (учитывает price, compare_price и стоимость выбранных услуг).
Параметры:
sku(Object) — объект SKU изwindow.waTheme.products[productId].skus
updateStocks(sku)
Обновляет информацию о наличии товара по данным SKU.
Параметры:
sku(Object) — объект SKU
updateSubmitButton(sku)
Обновляет состояние кнопки отправки формы: кнопка блокируется, если SKU недоступен для заказа.
Параметры:
sku(Object) — объект SKU
updateQuantityField(sku)
Обновляет ограничения поля количества (min, max) по данным SKU: минимальное количество для заказа и остаток на складе (если остатки не игнорируются настройкой магазина).
Параметры:
sku(Object) — объект SKU
toggleSubmitQuantityBlocks()
Переключает видимость блоков количества и кнопки «В корзину» в зависимости от того, есть ли текущий SKU в корзине.
Логика работы:
-
Получает текущий SKU
-
Проверяет наличие товара в корзине
-
Если товар в корзине — скрывает блок
.products-submitи показывает.products-quantity, иначе наоборот
Пример использования:
// Вызывается автоматически при изменениях или из Cart API
product.toggleSubmitQuantityBlocks();
increaseQuantity()
Асинхронно увеличивает количество товара на один шаг: проверяет максимальные ограничения, учитывает шаг изменения количества, блокирует форму на время операции и сохраняет изменение через Cart API.
Возвращает: Promise
decreaseQuantity()
Асинхронно уменьшает количество товара на один шаг. При достижении минимума удаляет товар из корзины (с показом лоадера).
Возвращает: Promise
addToCart()
Асинхронно добавляет товар в корзину с текущим выбранным SKU, количеством и услугами (используется при отправке формы товара).
Возвращает: Promise
События
Экземпляр товара генерирует события на своем элементе (bubbles: true — их можно ловить и на document).
product:sku-changed
Срабатывает при переключении артикула.
document.addEventListener('product:sku-changed', (event) => {
const { sku, productId, productData } = event.detail;
console.log(`Товар ${productId}: выбран SKU ${sku.id}`);
});
| Поле detail | Описание |
|---|---|
sku | Объект выбранного SKU |
productId | ID товара |
productData | Данные товара из window.waTheme.products[productId] |
product:service-changed
Срабатывает при включении/выключении услуги к товару.
| Поле detail | Описание |
|---|---|
serviceId | ID услуги |
isEnabled | Включена ли услуга |
productId | ID товара |
servicesPrice | Суммарная стоимость выбранных услуг |
product:service-variant-changed
Срабатывает при выборе варианта услуги.
| Поле detail | Описание |
|---|---|
serviceId | ID услуги |
variantId | ID выбранного варианта |
variantPrice | Цена варианта |
productId | ID товара |
servicesPrice | Суммарная стоимость выбранных услуг |
SKU Management
Поддержка простых SKU
Радиокнопки:
<input type="radio" name="sku_id" class="js-product-sku-input" value="123">
<input type="radio" name="sku_id" class="js-product-sku-input" value="456">
Select-элементы:
<select name="sku_id" class="js-product-sku-select">
<option value="123">SKU 1</option>
<option value="456">SKU 2</option>
</select>
Поддержка feature-based SKU
Кнопки характеристик:
<button type="button"
class="js-product-sku-feature-option"
data-feature-id="6"
data-value="93">
Размер M
</button>
Select характеристик:
<select name="features[6]"
class="js-product-sku-feature-select"
data-feature-id="6">
<option value="93">Размер M</option>
<option value="94">Размер L</option>
</select>
Автоматическое переключение SKU
При изменении характеристик модуль:
-
Собирает выбранные значения всех характеристик
-
Находит соответствующий SKU в данных товара
-
Обновляет цену, наличие и состояние кнопок
-
Обновляет визуальное состояние feature-кнопок
-
Переключает блоки quantity/submit
-
Генерирует событие
product:sku-changed
Quantity Management
Элементы управления количеством
<div class="products-quantity js-product-quantity">
<input type="number" class="js-product-quantity-field" name="quantity" value="1">
<button class="js-product-quantity-decrease">-</button>
<button class="js-product-quantity-increase">+</button>
</div>
Обработка изменений количества
Кнопки +/−:
-
Автоматическая валидация границ
-
Учет шага изменения количества из данных SKU
-
Интеграция с Cart API для сохранения
Ручной ввод:
-
Валидация введенных значений
-
Автоматическая коррекция некорректных значений
Интеграция с Cart API
При удалении товара из корзины Cart API находит на странице все элементы .js-product с соответствующим data-product-id и автоматически вызывает:
productElement._productInstance.toggleSubmitQuantityBlocks();
Data-атрибуты
На контейнере товара используются следующие data-атрибуты:
| Атрибут | Описание |
|---|---|
data-product-id | ID товара для интеграции с корзиной |
data-product-name | Название товара |
data-product-price | Текущая цена |
data-product-compare-price | Зачеркнутая цена |
data-product-image | URL изображения товара |
Селекторы DOM-элементов
| Селектор | Описание |
|---|---|
.js-product | Контейнер товара |
.js-product-form | Форма товара |
.js-product-submit | Кнопка отправки формы |
.js-product-sku-input | Радиокнопки простых SKU |
.js-product-sku-select | Select простых SKU |
.js-product-sku-feature-option | Кнопки характеристик |
.js-product-sku-feature-select | Select характеристик |
.js-product-sku-feature-input | Скрытые поля характеристик |
.js-product-quantity | Контейнер управления количеством |
.js-product-quantity-field | Поле ввода количества |
.js-product-quantity-increase | Кнопка увеличения |
.js-product-quantity-decrease | Кнопка уменьшения |
Глобальные данные товара
Модуль использует данные из window.waTheme.products[productId], которые заполняются шаблонами темы:
{
currency: "RUB",
currency_data: {
code: "RUB",
fraction_divider: ".",
fraction_size: 2,
group_divider: " ",
pattern_html: "<span>%s ₽</span>"
},
features: {...}, // характеристики товара (для feature-based SKU)
sku_id: "123", // текущий SKU
skus: {...}, // все SKU товара
stock_unit_id: "1", // единица измерения
base_unit_id: "1",
units: {...}, // единицы измерения
fractional_config: {...}, // дробные значения
ignore_stock_count: false, // игнорировать остатки
affiliate_settings: {...} // настройки партнерской программы
}
Обработка ошибок
Асинхронные методы возвращают Promise; ошибки обрабатываются через try/catch:
try {
await product.increaseQuantity();
} catch (error) {
console.error('Ошибка изменения количества:', error);
// Разблокировка интерфейса происходит автоматически
}
Пример: реакция на смену артикула
Разместите код в блоке site.{имя_темы}_js (Сайт — Блоки):
{literal}
<script>
document.addEventListener('product:sku-changed', (event) => {
const { sku, productId } = event.detail;
console.log(`Товар ${productId}: выбран артикул ${sku.id}`);
});
</script>
{/literal}