我目前正在我的WooCommerce cart.php页面上实现AJAX功能.其目标是使用户无需刷新整个页面即可应用优惠券.虽然我取得了进展,但我遇到了一个障碍--应用的优惠券没有像预期的那样更新购物车总数.

该问题的屏幕截图:

picture

Cart.php优惠券表格:

        <?php if ( wc_coupons_enabled() ) { ?>
        <form class="checkout_coupon mb-0" method="post">
            <h1 class="cart-small-title">Discount Code</h1>
            <div class="main_cou_nav">
                <p class="cc_code">Coupon Code</p>
                <div class="coupon">
                    <h3 class="widget-title"><?php echo get_flatsome_icon( 'icon-tag' ); ?> <?php esc_html_e( 'Coupon', 'woocommerce' ); ?></h3><label for="coupon_code" class="screen-reader-text"><?php esc_html_e( 'Coupon:', 'woocommerce' ); ?></label><input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" placeholder="<?php esc_attr_e( 'Enter Your Coupon code', 'woocommerce' ); ?>" /> <button type="button" class="is-form expand button<?php if ( fl_woocommerce_version_check( '7.0.1' ) ) { echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ); } ?>" id="apply_coupon" name="apply_coupon" value="<?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?>"><?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?></button>
                  <?php do_action( 'woocommerce_cart_coupon' ); ?>
                  <div id="custom-coupon-notice"></div>
                </div>
            </div>
        </form>


        <?php } ?>

Unctions.php:

function enqueue_my_custom_script() {
  wp_enqueue_script(
    'ajax-script-cart', // Handle for your script
    get_stylesheet_directory_uri() . '/js/custom-cart.js', // Path to your script
    array('jquery'), // Dependencies (jQuery as an example)
    '6.0.0', // Version number
    true // Load in the footer
  );

  wp_localize_script(
    'ajax-script-cart', // Handle for your script
    'wc_cart_params', // Name for the JavaScript object
    array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) // Data to pass to the script
  );
}

add_action('wp_enqueue_scripts', 'enqueue_my_custom_script');


function ajax_apply_coupon_cart() {
  if(!isset($_POST['coupon_code']) || empty($_POST['coupon_code'])) {
    wp_send_json(['success' => false, 'data' => ['message' => 'No coupon code provided']], 200);
    return;
  }

  $coupon_code = sanitize_text_field($_POST['coupon_code']);

  if(!WC()->cart->has_discount($coupon_code)) {
    $coupon_id = wc_get_coupon_id_by_code($coupon_code);

    if(!$coupon_id) {
      wp_send_json(['success' => false, 'data' => ['message' => sprintf(__('Coupon  does not exist!', 'woocommerce'), $coupon_code)]], 200);
      return;
    }

    WC()->cart->apply_coupon($coupon_code);
    wp_send_json_success(['message' => sprintf(__('Coupon  applied successfully.', 'woocommerce'), $coupon_code)], 200);
  } else {
    wp_send_json_error(['message' => sprintf(__('Coupon  is already applied!', 'woocommerce'), $coupon_code)], 200);
  }
}

add_action('wp_ajax_ajax_apply_coupon_cart', 'ajax_apply_coupon_cart');
add_action('wp_ajax_nopriv_ajax_apply_coupon_cart', 'ajax_apply_coupon_cart');

-Custom-ajax.js:

console.log("Cart script is working")

jQuery(document).on('click', '#apply_coupon', function () {
  console.log("button working as well")
  var code = jQuery('#coupon_code').val();

  data = {
    action: 'ajax_apply_coupon_cart',
    coupon_code: code
  };

  jQuery.post(wc_cart_params.ajax_url, data, function (returned_data) {
    console.log("Data returned from server: ", returned_data); // Log returned data for debugging.
    if(returned_data.success) {
      jQuery('#custom-coupon-notice').html(returned_data.data.message).removeClass('woocommerce-error').addClass('woocommerce-message').show();
    } else {
      jQuery('#custom-coupon-notice').html(returned_data.data.message).removeClass('woocommerce-message').addClass('woocommerce-error').show();
    }
    jQuery(document.body).trigger('updated_wc_div'); // Update the cart page after applying the coupon
  })
    .fail(function (jqXHR) {
      console.error(jqXHR); // Log the entire jqXHR object for debugging.
      var errorData = jqXHR.responseJSON;
      var errorMessage = errorData && errorData.message ? errorData.message : 'An unknown error occurred';
      jQuery('#custom-coupon-notice').html(errorMessage).addClass('woocommerce-error').show();
    });
});

推荐答案

默认情况下,在WooCommerce中,购物车中应用的优惠券已经通过AJAX制作,因此通常页面永远不会重新加载(删除优惠券或购物车项目时也是如此,更新数量时也是如此).

在您的情况下,您可能已经进行了太多的定制,因此不再启用默认的AJAX流程.

So the following may not work if Ajax cart refresh has been unintentionally disabled by you.

在您的代码中,可能缺少calculate_totals()个方法,以允许触发购物车计算更新.

function ajax_apply_coupon_cart() {
    if(!isset($_POST['coupon_code']) || empty($_POST['coupon_code'])) {
        wp_send_json(['success' => false, 'data' => ['message' => 'No coupon code provided']], 200);
        // return; // <== Not needed as wp_send_json() throws die();
    }
    $coupon_code = sanitize_text_field($_POST['coupon_code']);
  
    if(!WC()->cart->has_discount($coupon_code)) {
        $coupon_id = wc_get_coupon_id_by_code($coupon_code);
    
        if(!$coupon_id) {
            wp_send_json(['success' => false, 'data' => ['message' => sprintf(__('Coupon  does not exist!', 'woocommerce'), $coupon_code)]], 200);
            // return; // <== Not needed as wp_send_json() throws die();
        }
    
        $result = WC()->cart->apply_coupon($coupon_code); // Apply coupon
        
        if( $result ) {
            WC()->cart->calculate_totals(); // <=== Refresh totals (Missing)

            wp_send_json_success(['message' => sprintf(__('Coupon  applied successfully.', 'woocommerce'), $coupon_code)], 200);
        }
    } else {
        wp_send_json_error(['message' => sprintf(__('Coupon  is already applied!', 'woocommerce'), $coupon_code)], 200);
    }
}
add_action('wp_ajax_ajax_apply_coupon_cart', 'ajax_apply_coupon_cart');
add_action('wp_ajax_nopriv_ajax_apply_coupon_cart', 'ajax_apply_coupon_cart');

如果AJAX购物车更新仍然有效,这应该可以解决问题.

Php相关问答推荐

为什么PHP输出\n而不是实际创建一个新元素?

CodeIgniter AJAX表格提交中的CSRF token 再生问题

从WooCommerce Checkout Country Select2下拉列表中重新排序国家/地区

WooCommerce中仅在单一产品和产品档案页面中将小数设置为大写

从WC会话变量更改WooCommerce checkout 托运方法成本

WordPress插件和JSON不是有效的响应错误

使用MySQLi使用连接字符串设置字符集

移动应用:在PHP中忽略Cookie?

如何配置我的.env文件以在laravel的一个项目中连接两个不同的数据库?

根据WooCommerce的定制订单状态增加产品库存

服务器升级到新的mysql版本8.0.34后查询错误

在 WooCommerce 中应用优惠券时显示购物车商品折扣金额

根据小计向 WooCommerce Checkout 添加佣金

WooCommerce:如果订单总数为零,则隐藏本地取货运输选项

主机中未检索用户表数据

VS Code 对 PHP 上从父类继承的方法报告误报

如何使用不同的方法编写嵌套连接查询并将两列连接成一列在 laravel 查询生成器中

根据WooCommerce中选定的变体重量更改输入数量步值

带有 nginx 的 Symfony 不提供 .js 和 .css 文件

Laravel 自定义中间件:ERR_TOO_MANY_REDIRECTS