Как добавить в корзину вариативный товар через Ajax?
Подскажите пожалуйста,
как добавить в корзину вариативный товар через Ajax? Магазин на woocommerce.
Данный способ работает корректно, но без Ajax:
<button type="submit" class="single_add_to_cart_button button alt<?php echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ); ?>">В корзину</button> |
<button type="submit" class="single_add_to_cart_button button alt<?php echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ); ?>">В корзину</button>
Добавляю классы "ajax_add_to_cart add_to_cart_button" и атрибуты "data-product_id="<?php echo get_the_ID(); ?>"data-product_sku="<?php echo esc_attr($sku) ?>""
Ajax работает, но добавляет в корзину карточку товара без вариаций и артикула, только по ID карточки товара.
<button type="submit" class="single_add_to_cart_button button alt<?php echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ); ?> ajax_add_to_cart add_to_cart_button" data-product_id="<?php echo get_the_ID(); ?>"data-product_sku="<?php echo esc_attr($sku) ?>">В корзину</button> |
<button type="submit" class="single_add_to_cart_button button alt<?php echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ); ?> ajax_add_to_cart add_to_cart_button" data-product_id="<?php echo get_the_ID(); ?>"data-product_sku="<?php echo esc_attr($sku) ?>">В корзину</button>
Так понимаю, необходимо как-то получить данные вариации и передать вместо "data-product_id"
Буду благодарен за любую информацию.
Дополнительно
Вы добавили классы "ajax_add_to_cart" и "add_to_cart_button" в HTML-код кнопки, но не обработали их в JavaScript-коде, поэтому добавление вариативного товара в корзину не работает.
Ответы:
<button type="button" class="single_add_to_cart_button button alt<?php echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ); ?> add-to-cart-variation">В корзину</button> |
<button type="button" class="single_add_to_cart_button button alt<?php echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ); ?> add-to-cart-variation">В корзину</button>
Здесь мы добавили класс "add-to-cart-variation", который будет использоваться для привязки события Ajax.
JavaScript-код для отправки Ajax-запроса на сервер при нажатии на кнопку "В корзину":
jQuery(document).ready(function($) { $('body').on('click', '.add-to-cart-variation', function() { var variation_id = $(this).closest('form.cart').find('.variation_id').val(); var quantity = $(this).closest('form.cart').find('.quantity').val(); var product_id = $(this).closest('form.cart').find('input[name="product_id"]').val(); var data = { action: 'add_variation_to_cart', product_id: product_id, variation_id: variation_id, quantity: quantity }; $.ajax({ type: 'POST', url: wc_add_to_cart_params.ajax_url, data: data, success: function(response) { if (response) { $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $(this)]); } }, dataType: 'json' }); return false; }); }); |
jQuery(document).ready(function($) { $('body').on('click', '.add-to-cart-variation', function() { var variation_id = $(this).closest('form.cart').find('.variation_id').val(); var quantity = $(this).closest('form.cart').find('.quantity').val(); var product_id = $(this).closest('form.cart').find('input[name="product_id"]').val(); var data = { action: 'add_variation_to_cart', product_id: product_id, variation_id: variation_id, quantity: quantity }; $.ajax({ type: 'POST', url: wc_add_to_cart_params.ajax_url, data: data, success: function(response) { if (response) { $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $(this)]); } }, dataType: 'json' }); return false; }); });
Здесь мы добавили класс "add-to-cart-variation", который будет использоваться для привязки события Ajax.
JavaScript-код для отправки Ajax-запроса на сервер при нажатии на кнопку "В корзину":
jQuery(document).ready(function($) { $('body').on('click', '.add-to-cart-variation', function() { var variation_id = $(this).closest('form.cart').find('.variation_id').val(); var quantity = $(this).closest('form.cart').find('.quantity').val(); var product_id = $(this).closest('form.cart').find('input[name="product_id"]').val(); var data = { action: 'add_variation_to_cart', product_id: product_id, variation_id: variation_id, quantity: quantity }; $.ajax({ type: 'POST', url: wc_add_to_cart_params.ajax_url, data: data, success: function(response) { if (response) { $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $(this)]); } }, dataType: 'json' }); return false; }); }); |
jQuery(document).ready(function($) { $('body').on('click', '.add-to-cart-variation', function() { var variation_id = $(this).closest('form.cart').find('.variation_id').val(); var quantity = $(this).closest('form.cart').find('.quantity').val(); var product_id = $(this).closest('form.cart').find('input[name="product_id"]').val(); var data = { action: 'add_variation_to_cart', product_id: product_id, variation_id: variation_id, quantity: quantity }; $.ajax({ type: 'POST', url: wc_add_to_cart_params.ajax_url, data: data, success: function(response) { if (response) { $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $(this)]); } }, dataType: 'json' }); return false; }); });
Здесь мы использовали функцию jQuery ajax() для отправки POST-запроса на сервер WooCommerce с параметрами, такими как идентификатор вариации, количество и идентификатор товара.
Добавьте PHP-обработчик для Ajax-запроса на сервере WordPress:
add_action('wp_ajax_add_variation_to_cart', 'add_variation_to_cart'); add_action('wp_ajax_nopriv_add_variation_to_cart', 'add_variation_to_cart'); function add_variation_to_cart() { $product_id = intval($_POST['product_id']); $variation_id = intval($_POST['variation_id']); $quantity = intval($_POST['quantity']); $variation = array( 'variation_id' => $variation_id, 'quantity' => $quantity ); WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $variation); WC_AJAX::get_refreshed_fragments(); wp_die(); } |
add_action('wp_ajax_add_variation_to_cart', 'add_variation_to_cart'); add_action('wp_ajax_nopriv_add_variation_to_cart', 'add_variation_to_cart'); function add_variation_to_cart() { $product_id = intval($_POST['product_id']); $variation_id = intval($_POST['variation_id']); $quantity = intval($_POST['quantity']); $variation = array( 'variation_id' => $variation_id, 'quantity' => $quantity ); WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $variation); WC_AJAX::get_refreshed_fragments(); wp_die(); }
Здесь мы определяем две функции действий WordPress для обработки Ajax-запроса на сервере. Функция add_variation_to_cart() получает идентификатор товара, идентификатор вариации и количество, добавляет товар в корзину и возвращает обновленный фрагмент корзины.
После того как вы добавите все необходимые файлы и код в ваш проект, кнопка "В корзину" для вариативного товара будет работать через Ajax и добавлять товар в корзину без перезагрузки страницы.
Чтобы убедиться, что код работает корректно, убедитесь, что вы правильно добавили все файлы и код в ваш проект. Кроме того, убедитесь, что у вас установлен и активирован плагин WooCommerce и что ваша тема WordPress поддерживает WooCommerce.
- Данное решение добавляет в корзину, но данные обновляются только после ручной перезагрузки страницы.
Предполагаю, что в моем случае есть более простое решение.Есть кнопка которая добавляет товар в корзину (она добавляет корректно вариативный товар в корзину, но с перезагрузкой страницы):
<button type="submit" class="button ajax_add_to_cart add_to_cart_button" data-product_sku="<?php echo esc_attr($sku) ?>">В корзину</button>
<button type="submit" class="button ajax_add_to_cart add_to_cart_button" data-product_sku="<?php echo esc_attr($sku) ?>">В корзину</button>
Если добавляю в нее
<?php echo get_the_ID(); ?>
и привожу ее к такому виду Ajax работает, но добавляет товар по ID, не вариацию и не учитывает количество:
<button type="submit" class="button ajax_add_to_cart add_to_cart_button" data-product_id="<?php echo get_the_ID(); ?>" data-product_sku="<?php echo esc_attr($sku) ?>">В корзину</button>
<button type="submit" class="button ajax_add_to_cart add_to_cart_button" data-product_id="<?php echo get_the_ID(); ?>" data-product_sku="<?php echo esc_attr($sku) ?>">В корзину</button>
Предполагаю, что необходимо передать в submit вместо
get_the_ID
айдишник вариации, но не знаю как это сделать
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для вариативного товара WooCommerce недостаточно передать только
product_id. В корзину должен уйти ID родительского товара, ID конкретной вариации и массив выбранных атрибутов. Если хотя бы один атрибут не совпадает с вариацией, WooCommerce не сможет добавить товар корректно.Пример AJAX-обработчика:
add_action('wp_ajax_add_variation_to_cart', 'my_add_variation_to_cart'); add_action('wp_ajax_nopriv_add_variation_to_cart', 'my_add_variation_to_cart'); function my_add_variation_to_cart() { $product_id = absint($_POST['product_id'] ?? 0); $variation_id = absint($_POST['variation_id'] ?? 0); $quantity = max(1, absint($_POST['quantity'] ?? 1)); $variation = []; foreach ($_POST['variation'] ?? [] as $key => $value) { $variation[sanitize_key($key)] = sanitize_text_field($value); } $added = WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $variation); if (! $added) { wp_send_json_error(['message' => 'Не удалось добавить вариацию']); } wp_send_json_success([ 'fragments' => apply_filters('woocommerce_add_to_cart_fragments', []), 'cart_hash' => WC()->cart->get_cart_hash(), ]); }
На фронте берите
variation_idиз стандартной формы вариаций WooCommerce после выбора атрибутов. Не пытайтесь вычислять вариацию только по названию размера или цвета. Также проверьте, что атрибуты отправляются с ключами видаattribute_pa_colorилиattribute_size, ровно как в форме товара. После успешного добавления обновляйте мини-корзину или хотя бы показывайте пользователю сообщение.Если используете стандартный JS WooCommerce для вариаций, не дублируйте его логику. Подпишитесь на событие
found_variationи сохраняйте найденныйvariation_id. Тогда AJAX-кнопка будет отправлять уже проверенную вариацию. После добавления товара в корзину WooCommerce обычно ожидает обновления fragments; если тема показывает мини-корзину, без fragments пользователь не увидит изменения до перезагрузки. Для защиты добавьте nonce и проверяйте его в обработчике.