从 woocommerce_add_to_cart_fragments 传回的 Woocommerce 错误片段 [英] Woocommerce wrong fragments passed back from woocommerce_add_to_cart_fragments

查看:30
本文介绍了从 woocommerce_add_to_cart_fragments 传回的 Woocommerce 错误片段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个自定义的 WooCommerce 购物车,并且更新购物车项目的数量工作正常.唯一的问题是它不会自动刷新,只有在页面加载后才能工作.

我当前的代码,它使用 woocommerce_add_to_cart_fragments 钩子并使用传入的 $fragments 对象.根据我所看到的,这是正确的方法,但这不起作用,我已经调试过,对我来说问题似乎是 $fragments 我进入了hook 没有我原来的 html,而是一个看起来像这样的 html:

<ul class="woocommerce-mini-cart cart_list product_list_widget "><li class="woocommerce-mini-cart-item mini_cart_item"><a href=http://velosity-dev-wordpress.local/cart/?remove_item=92cc227532d17e56e07902b254dfad10&#038;_wpnonce=8ead5f2c51"class="移除 remove_from_cart_button";aria-label =删除此项目";data-product_id=92"data-cart_item_key=92cc227532d17e56e07902b254dfad10"data-product_sku=">&times;</a>

经过快速测试,woocommerce_cart 短代码输出似乎使用了 woocommerce 模板.因此,您可以尝试编辑子主题中的 Woocommerce Cart 模板文件以更改 HTML 输出.(如果您确实需要购物车 HTML 作为对自定义 ajax 调用的响应).

I'm creating a custom WooCommerce cart and updating the quantity of a cart item works correctly. The only problem is that it doesn't automatically refresh, only works after page load.

My current code, which uses the woocommerce_add_to_cart_fragments hook and uses the passed in $fragments object. According to what I've seen around this is the correct way to go, but this doesn't work and I've debugged and to me the problem seems to be that the $fragments I get in the hook doesn't have my original html but instead a html that looks like this:

<div class="widget_shopping_cart_content">

    <ul class="woocommerce-mini-cart cart_list product_list_widget ">
        <li class="woocommerce-mini-cart-item mini_cart_item">
            <a href="http://velosity-dev-wordpress.local/cart/?remove_item=92cc227532d17e56e07902b254dfad10&#038;_wpnonce=8ead5f2c51"
                class="remove remove_from_cart_button" aria-label="Remove this item" data-product_id="92"
                data-cart_item_key="92cc227532d17e56e07902b254dfad10" data-product_sku="">&times;</a> <a
                href="http://velosity-dev-wordpress.local/product/subber-one/">
                <img width="300" height="300"
                    src="http://velosity-dev-wordpress.local/wp-content/uploads/2021/09/mathilde-langevin-WxHJEMUnlIM-unsplash-300x300.jpg"
                    class="attachment-woocommerce_thumbnail size-woocommerce_thumbnail" alt="" loading="lazy"
                    srcset="http://velosity-dev-wordpress.local/wp-content/uploads/2021/09/mathilde-langevin-WxHJEMUnlIM-unsplash-300x300.jpg 300w, http://velosity-dev-wordpress.local/wp-content/uploads/2021/09/mathilde-langevin-WxHJEMUnlIM-unsplash-150x150.jpg 150w, http://velosity-dev-wordpress.local/wp-content/uploads/2021/09/mathilde-langevin-WxHJEMUnlIM-unsplash-100x100.jpg 100w"
                    sizes="(max-width: 300px) 100vw, 300px" />Subber One </a>
            <span class="quantity">2 &times; <span class="woocommerce-Price-amount amount"><bdi><span
                            class="woocommerce-Price-currencySymbol">&#36;</span>349.00</bdi></span></span>
        </li>
    </ul>

    <p class="woocommerce-mini-cart__total total">
        <strong>Subtotal:</strong> <span class="woocommerce-Price-amount amount"><bdi><span
                    class="woocommerce-Price-currencySymbol">&#36;</span>698.00</bdi></span>
    </p>


    <p class="woocommerce-mini-cart__buttons buttons"><a href="http://velosity-dev-wordpress.local/cart/"
            class="button wc-forward">View cart</a><a href="http://velosity-dev-wordpress.local/checkout/"
            class="button checkout wc-forward">Checkout</a></p>

I don't really know how to pass in the correct 'active' html in to this hook, so any pointer would be greatly appreciated! Big thanks in advance!

My custom cart html/php (inside a file called header-shopping-cart.php)

<div class="cart-items" id="cart-items">
    <?php foreach(WC()->cart->get_cart() as $cart_item_key => $cart_item) : ?>
    <div class="cart-item">
        <?php echo $cart_item['data']->get_image(); ?>
        <div>
            <h3><?php echo $cart_item['data']->get_title() ?></h3>
            <div class="quantity">
                <input type="number" id="quantity_614459a588590" class="input-text qty text" step="1" min="0" max=""
                    name="cart[<?php echo $cart_item_key ?>][qty]" value="<?php echo $cart_item['quantity']  ?>"
                    title="Qty" size="4" placeholder="" inputmode="numeric">
            </div>
            <div class="price"><?php echo $cart_item['data']->get_price_html() ?></div>
        </div>
    </div>
    <div class="divider"></div>
    <? endforeach; ?>
</div>

My JS function (inside custom.js)

jQuery(function ($) {
  $(document).on("change", "input.qty", function () {
    var $thisbutton = $(this);
    var cart_item_key = $(this)
      .attr("name")
      .replace(/cart\[([\w]+)\]\[qty\]/g, "$1");
    var item_quantity = $(this).val();
    var currentVal = parseFloat(item_quantity);

    $.ajax({
      type: "POST",
      url: cart_qty_ajax.ajax_url,
      data: {
        action: "my_cart_qty",
        cart_item_key: cart_item_key,
        quantity: currentVal,
      },
      success: function (response) {
        jQuery(document.body).trigger("added_to_cart", [response.fragments, response.cart_hash, $thisbutton]);
      },
    });
  });
});

My php-functions (inside functions.php)

<?php    
function enqueue_cart_qty_ajax() {
        wp_register_script( 'my_cart_qty-ajax-js', get_template_directory_uri() . '/js/custom.js', array( 'jquery' ), '', true );
        wp_localize_script( 'my_cart_qty-ajax-js', 'cart_qty_ajax', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
        wp_enqueue_script( 'my_cart_qty-ajax-js' );
    }
    add_action('wp_enqueue_scripts', 'enqueue_cart_qty_ajax');
    
    function ajax_my_cart_qty() {
        // Set item key as the hash found in input.qty's name
        $cart_item_key = $_POST['cart_item_key'];
        $quantity = $_POST['quantity'];
    
        // Get the array of values owned by the product we're updating
        $threeball_product_values = WC()->cart->get_cart_item( $cart_item_key );
        // Get the quantity of the item in the cart
        $threeball_product_quantity = apply_filters( 'woocommerce_stock_amount_cart_item', apply_filters( 'woocommerce_stock_amount', preg_replace( "/[^0-9\.]/", '', filter_var($_POST['quantity'], FILTER_SANITIZE_NUMBER_INT)) ), $cart_item_key );
        // Update cart validation
        $passed_validation  = apply_filters( 'woocommerce_update_cart_validation', true, $cart_item_key, $threeball_product_values, $threeball_product_quantity );
    
        // Update the quantity of the item in the cart
        if ( $passed_validation ) {
            WC()->cart->set_quantity( $cart_item_key, $threeball_product_quantity, true );
        }
    
        // Refresh the page
        echo do_shortcode( '[woocommerce_cart]' );
    
        die();
    }
    add_action('wp_ajax_my_cart_qty', 'ajax_my_cart_qty');
    add_action('wp_ajax_nopriv_my_cart_qty', 'ajax_my_cart_qty');
    
    //Responsive cart
    add_filter( 'woocommerce_add_to_cart_fragments', 'ajaxify_components', 10, 1 );
    function ajaxify_components( $fragments ) {
        ob_start();
    ?>
    <div class="cart-items" id="cart-items">
        <?php foreach(WC()->cart->get_cart() as $cart_item_key => $cart_item) : ?>
        <div class="cart-item">
            <?php echo $cart_item['data']->get_image(); ?>
            <div>
                <h3><?php echo $cart_item['data']->get_title() ?></h3>
                <div class="quantity">
                    <input type="number" id="quantity_614459a588590" class="input-text qty text" step="1" min="0" max=""
                        name="cart[<?php echo $cart_item_key ?>][qty]" value="<?php echo $cart_item['quantity']  ?>"
                        title="Qty" size="4" placeholder="" inputmode="numeric">
                </div>
                <div class="price"><?php echo $cart_item['data']->get_price_html() ?></div>
            </div>
        </div>
        <div class="divider"></div>
        <? endforeach; ?>
    </div>
    <?php
        $fragments['#cart-items'] = ob_get_clean();
    
        return $fragments;
    }

Hope someone can give me a pointer in the right direction. Thanks!

解决方案

I just tested your code, and it seems to work:

  • On click, the ajax is made and my cart content is updated
  • the echo do_shortcode( '[woocommerce_cart]' ); is not working atm, as it thinks the cart is empty (and returns "empty cart" HTML message). But I don't see why you need the complete woocommerce cart HTML as a response here. Also, you use the response in tour JS as an object, but returning the do_shortcode will return a raw HTML string only.
  • the AJAX ends, and jQuery(document.body).trigger("added_to_cart") is called, which trigger the Woocommere cart fragment to refresh. As the AJAX call shortcode response is "wrong", the response object is not correct, but we can still trigger the event. Just make sure your custom listener handle the "no parameter" case
  • the cart fragment is refreshed, with your custom HTML

Take care about your <? endforeach; ?> that misses the <?php.

EDIT: After a quick test, it seems the woocommerce_cart shortcode output uses the woocommerce templates. So you could try to edit the Woocommerce Cart template files in your child theme to change the HTML output. (if you really need the cart HTML as the response to your custom ajax call).

这篇关于从 woocommerce_add_to_cart_fragments 传回的 Woocommerce 错误片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆