API

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 текущего выбранного артикула.

Порядок поиска:

  1. Отмеченная радиокнопка (.js-product-sku-input:checked)

  2. Select-элемент (.js-product-sku-select)

  3. Поиск SKU по выбранным характеристикам (findSKUByFeatures())

  4. Скрытое поле 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 в корзине.

Логика работы:

  1. Получает текущий SKU

  2. Проверяет наличие товара в корзине

  3. Если товар в корзине — скрывает блок .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
productIdID товара
productDataДанные товара из window.waTheme.products[productId]

product:service-changed

Срабатывает при включении/выключении услуги к товару.

Поле detailОписание
serviceIdID услуги
isEnabledВключена ли услуга
productIdID товара
servicesPriceСуммарная стоимость выбранных услуг

product:service-variant-changed

Срабатывает при выборе варианта услуги.

Поле detailОписание
serviceIdID услуги
variantIdID выбранного варианта
variantPriceЦена варианта
productIdID товара
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

При изменении характеристик модуль:

  1. Собирает выбранные значения всех характеристик

  2. Находит соответствующий SKU в данных товара

  3. Обновляет цену, наличие и состояние кнопок

  4. Обновляет визуальное состояние feature-кнопок

  5. Переключает блоки quantity/submit

  6. Генерирует событие 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-idID товара для интеграции с корзиной
data-product-nameНазвание товара
data-product-priceТекущая цена
data-product-compare-priceЗачеркнутая цена
data-product-imageURL изображения товара

Селекторы DOM-элементов

СелекторОписание
.js-productКонтейнер товара
.js-product-formФорма товара
.js-product-submitКнопка отправки формы
.js-product-sku-inputРадиокнопки простых SKU
.js-product-sku-selectSelect простых SKU
.js-product-sku-feature-optionКнопки характеристик
.js-product-sku-feature-selectSelect характеристик
.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}