Как добавить в корзину вариативный товар через Ajax?

Ссылка скопирована
1 ответ

Подскажите пожалуйста,
как добавить в корзину вариативный товар через 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 карточки товара.

&lt;button type="submit" class="single_add_to_cart_button button alt&lt;?php echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' .  wc_wp_theme_get_element_class_name( 'button' ) : '' ); ?&gt; ajax_add_to_cart add_to_cart_button" data-product_id="&lt;?php echo get_the_ID(); ?&gt;"data-product_sku="&lt;?php echo esc_attr($sku) ?&gt;"&gt;В корзину&lt;/button&gt;

&lt;button type="submit" class="single_add_to_cart_button button alt&lt;?php echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ); ?&gt; ajax_add_to_cart add_to_cart_button" data-product_id="&lt;?php echo get_the_ID(); ?&gt;"data-product_sku="&lt;?php echo esc_attr($sku) ?&gt;"&gt;В корзину&lt;/button&gt;

Так понимаю, необходимо как-то получить данные вариации и передать вместо "data-product_id"
Буду благодарен за любую информацию.

Дополнительно

Вы добавили классы "ajax_add_to_cart" и "add_to_cart_button" в HTML-код кнопки, но не обработали их в JavaScript-коде, поэтому добавление вариативного товара в корзину не работает.

Ответы:

&lt;button type="button" class="single_add_to_cart_button button alt&lt;?php echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ); ?&gt; add-to-cart-variation"&gt;В корзину&lt;/button&gt;

&lt;button type="button" class="single_add_to_cart_button button alt&lt;?php echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ); ?&gt; add-to-cart-variation"&gt;В корзину&lt;/button&gt;

Здесь мы добавили класс "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' =&gt; $variation_id,         'quantity' =&gt; $quantity     );     WC()-&gt;cart-&gt;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' =&gt; $variation_id, 'quantity' =&gt; $quantity ); WC()-&gt;cart-&gt;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.

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

    Есть кнопка которая добавляет товар в корзину (она добавляет корректно вариативный товар в корзину, но с перезагрузкой страницы):

    &lt;button type="submit" class="button ajax_add_to_cart add_to_cart_button"     data-product_sku="&lt;?php echo esc_attr($sku) ?&gt;"&gt;В корзину&lt;/button&gt;

    &lt;button type="submit" class="button ajax_add_to_cart add_to_cart_button" data-product_sku="&lt;?php echo esc_attr($sku) ?&gt;"&gt;В корзину&lt;/button&gt;

    Если добавляю в нее

    <?php echo get_the_ID(); ?>

    и привожу ее к такому виду Ajax работает, но добавляет товар по ID, не вариацию и не учитывает количество:

    &lt;button type="submit" class="button ajax_add_to_cart add_to_cart_button" data-product_id="&lt;?php echo get_the_ID(); ?&gt;" data-product_sku="&lt;?php echo esc_attr($sku) ?&gt;"&gt;В корзину&lt;/button&gt;

    &lt;button type="submit" class="button ajax_add_to_cart add_to_cart_button" data-product_id="&lt;?php echo get_the_ID(); ?&gt;" data-product_sku="&lt;?php echo esc_attr($sku) ?&gt;"&gt;В корзину&lt;/button&gt;

    Предполагаю, что необходимо передать в submit вместо

    get_the_ID

    айдишник вариации, но не знаю как это сделать

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Ольга Сеть Ответ

Для вариативного товара 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 =&gt; $value) {
        $variation[sanitize_key($key)] = sanitize_text_field($value);
    }
 
    $added = WC()-&gt;cart-&gt;add_to_cart($product_id, $quantity, $variation_id, $variation);
 
    if (! $added) {
        wp_send_json_error(['message' =&gt; 'Не удалось добавить вариацию']);
    }
 
    wp_send_json_success([
        'fragments' =&gt; apply_filters('woocommerce_add_to_cart_fragments', []),
        'cart_hash' =&gt; WC()-&gt;cart-&gt;get_cart_hash(),
    ]);
}

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 =&gt; $value) { $variation[sanitize_key($key)] = sanitize_text_field($value); } $added = WC()-&gt;cart-&gt;add_to_cart($product_id, $quantity, $variation_id, $variation); if (! $added) { wp_send_json_error(['message' =&gt; 'Не удалось добавить вариацию']); } wp_send_json_success([ 'fragments' =&gt; apply_filters('woocommerce_add_to_cart_fragments', []), 'cart_hash' =&gt; WC()-&gt;cart-&gt;get_cart_hash(), ]); }

На фронте берите variation_id из стандартной формы вариаций WooCommerce после выбора атрибутов. Не пытайтесь вычислять вариацию только по названию размера или цвета. Также проверьте, что атрибуты отправляются с ключами вида attribute_pa_color или attribute_size, ровно как в форме товара. После успешного добавления обновляйте мини-корзину или хотя бы показывайте пользователю сообщение.

Если используете стандартный JS WooCommerce для вариаций, не дублируйте его логику. Подпишитесь на событие found_variation и сохраняйте найденный variation_id. Тогда AJAX-кнопка будет отправлять уже проверенную вариацию. После добавления товара в корзину WooCommerce обычно ожидает обновления fragments; если тема показывает мини-корзину, без fragments пользователь не увидит изменения до перезагрузки. Для защиты добавьте nonce и проверяйте его в обработчике.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно