【问题标题】:Woocommerce - Product Page - How to create AJAX on "Add To Cart" button?Woocommerce - 产品页面 - 如何在“添加到购物车”按钮上创建 AJAX?
【发布时间】:2014-11-11 15:00:50
【问题描述】:

我想在可以使用 AJAX 的产品页面上创建一个“添加到购物车”按钮。我该怎么做?当我在产品页面上添加到购物车时 - 它会刷新页面,如何通过 AJAX 使其工作?

存档上“快速查看”上的“添加到购物车”按钮由 ajax 工作 - 这很棒,但我怎样才能在产品页面上做同样的事情?

我想点击产品页面上的“带我回家”,然后 通过 ajax 将具有所选属性的产品添加到我的购物车中,然后打开该购物车(例如,当您将鼠标悬停在菜单上的包图片上时)并摇动包图片。

【问题讨论】:

    标签: php ajax wordpress woocommerce


    【解决方案1】:

    只需将以下属性添加到“添加到购物车”按钮即可启用 Ajax 按钮。

    <a href="<?php echo $product->add_to_cart_url() ?>" value="<?php echo esc_attr( $product->get_id() ); ?>" class="ajax_add_to_cart add_to_cart_button" data-product_id="<?php echo get_the_ID(); ?>" data-product_sku="<?php echo esc_attr($sku) ?>" aria-label="Add “<?php the_title_attribute() ?>” to your cart"> Add to Cart </a>
    

    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;" 属性是必需的。

    无需应用任何操作或过滤器。

    【讨论】:

    • 要与变体产品一起使用,请使用商品的变体 ID 和 sku。
    • 指定一个data-quantity属性传入数量
    • 最佳答案,我喜欢您使用 WooCommerce 的方式。
    • 如果您没有可用的 $sku,请使用 $product->get_sku()
    • 似乎 data-product_sku 属性不是强制性的。
    【解决方案2】:

    我们可以从存档页面使用 ajax。这很容易 -

    删除提交表单的旧按钮:

    remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
    

    从存档页面添加 ajax-link 到单个产品页面:

    add_action( 'woocommerce_single_product_summary', 'woocommerce_template_loop_add_to_cart', 30 );
    

    附: JS 回调。例如,您可以显示带有“返回商店”和“购物车”或“结帐”链接的弹出窗口

    $('body').on('added_to_cart',function(){
        // Callback -> product added
        //$('.popup').show();
    });
    

    【讨论】:

    • (1) 即使 AJAX 添加到购物车行为有效,我也不会触发 JS 回调。 (2) 当我使用 WooCommerce Products Add-On 插件向所有产品添加全局表单时,它会破坏您的解决方案。单页添加到购物车按钮恢复为 HTTP,全局表单不显示。
    • 这个解决方案的一个大问题是如果产品不可用,循环按钮会返回一个阅读更多链接。如果您单击此类产品,则会再次出现阅读更多按钮...某种错误。
    • 它为我移除了数量框。
    • 更不用说这对可变产品完全没用
    【解决方案3】:

    请从阅读本页开始:

    http://codex.wordpress.org/Plugin_API/Action_Reference/wp_ajax_(action)

    首先你需要在你的functions.php中添加一些代码,例如:

    add_action( 'wp_ajax_add_foobar', 'prefix_ajax_add_foobar' );
    add_action( 'wp_ajax_nopriv_add_foobar', 'prefix_ajax_add_foobar' );
    
    function prefix_ajax_add_foobar() {
       $product_id  = intval( $_POST['product_id'] );
    // add code the add the product to your cart
    die();
    }
    

    然后你必须添加一些javascript代码来触发添加到购物车并调用函数:

      jQuery( ".add-to-cart" ).each(function() 
    {
    
    
        var product_id = jQuery(this).attr('rel');
        var el = jQuery(this);
    
        el.click(function() {
    
                var data = {
                    action: 'add_foobar',
                    product_id: product_id
                };
    
                jQuery.post('/wp-admin/admin-ajax.php' , data, function(response) {
                    if(response != 0) {
                        // do something
                    } else {
                        // do something else
                    }
    
                });
    
    
            return false;
    
        });
    
    });
    

    这只是如何完成的一个示例。虽然它非常基础。此 javascript 检查具有类名 .a​​dd-to-cart 的链接并检查相应产品的 rel 属性。然后它将产品 ID 发送到 php 类。在那里您需要添加代码以将相应的产品添加到购物车。

    我建议您搜索更多有关该主题的内容,以使其适合您的需求。祝你好运。

    【讨论】:

    • 谢谢,你能说得更具体点吗?因为我不知道我需要添加什么......你能帮我吗?我没有改变任何东西 - 所以它适用于 woocommerce 的经典代码,你能给我一个代码来解决我的问题吗?谢谢,汤姆。
    【解决方案4】:

    Woocommerce 已经出现了。我认为解决方案现在很容易。如果我遗漏了什么,只需检查“启用 AJAX 添加到存档上的购物车按钮”并使用 woocommerce_template_loop_add_to_cart() 函数。

    复选框选项位于 Woocommerce > 设置 > 产品 > 常规下。

    然后只需在您希望输出按钮的任何位置使用woocommerce_template_loop_add_to_cart()

    如果您像我一样使用自定义循环,则需要确保将产品设为全局,以便 woocommerce_template_loop_add_to_cart() 工作。

    下面是一个使用函数的小例子:

    add_shortcode( 'buy_again' , 'msp_buy_again_shortcode' );
    function msp_buy_again_shortcode(){
        $order_items = msp_get_customer_unique_order_items( get_current_user_id() );
        echo '<div class="owl-carousel owl-theme">';
        foreach( $order_items as $id ){
            $product = wc_get_product( $id );
            global $product;
    
            if( ! empty( $product ) ){
                ?>
                <div class="card buy-again-product">
                    <a class="link-normal" href="<?php echo $product->get_permalink(); ?>">
                        <?php echo $product->get_image( 'woocommerce_thumbnail', array( 'class' => 'card-img-top' ) ) ?>
                        <div class="card-body">
                            <?php echo wc_get_rating_html( $product->get_average_rating(), $product->get_review_count() ) ?>
                            <h5><?php echo $product->get_name(); ?></h5>
                            <p><?php echo $product->get_price_html() ?></p>
                            <?php woocommerce_template_loop_add_to_cart(); ?>
                        </div>
                    </a>
                </div>
                <?php
            }
        }
        // loop and display buy again.
        // try to use the official woocommerce loop.
    
        echo '</div>';
    
    }
    

    【讨论】:

      【解决方案5】:

      将此代码复制到您的文件中。例如:my-theme-wc-single-ajax-add-cart.js

      function myThemeWc_SingleProductAddToCart(thisObj) {
          if (typeof($) === 'undefined') {
              var $ = jQuery.noConflict();
          }
      
          var thisForm = thisObj.closest('form');
          var button = thisForm.find('.button');
          var formUrl = thisForm.attr('action');
          var formMethod = thisForm.attr('method');
          if (typeof(formMethod) === 'undefined' || formMethod == '') {
              formMethod = 'POST';
          }
          var formData = new FormData(thisForm[0]);
          formData.append(button.attr('name'), button.val());
      
          button.removeClass('added');
          button.addClass('loading');
      
          myThemeWc_SingleProductCartAjaxTask = $.ajax({
              url: formUrl,
              method: formMethod,
              data: formData,
              cache: false,
              contentType: false,
              processData: false
          })
          .done(function(data, textStatus, jqXHR) {
              $(document.body).trigger('wc_fragment_refresh');
      
              $.when(myThemeWc_SingleProductCartAjaxTask)
              .then(myThemeWc_SingleProductUpdateCartWidget)
              .done(function() {
                  button.removeClass('loading');
                  button.addClass('added');
                  setTimeout(function() {
                      button.removeClass('added');
                  }, 2000);
              });
          })
          .fail(function(jqXHR, textStatus, errorThrown) {
              button.removeClass('loading');
          })
          .always(function(jqXHR, textStatus, errorThrown) {
              $('.cart').off('submit');
              myThemeWc_SingleProductListenAddToCart();
          });
      }// myThemeWc_SingleProductAddToCart
      
      
      function myThemeWc_SingleProductListenAddToCart() {
          if (typeof($) === 'undefined') {
              var $ = jQuery.noConflict();
          }
      
          $('.cart').on('submit', function(e) {
              e.preventDefault();
              myThemeWc_SingleProductAddToCart($(this));
          });
      }// myThemeWc_SingleProductListenAddToCart
      
      
      /**
       * Update WooCommerce cart widget by called the trigger and listen to the event.
       * 
       * @returns {undefined}
       */
      function myThemeWc_SingleProductUpdateCartWidget() {
          if (typeof($) === 'undefined') {
              var $ = jQuery.noConflict();
          }
      
          var deferred = $.Deferred();
      
          $(document.body).on('wc_fragments_refreshed', function() {
              deferred.resolve();
          });
      
          return deferred.promise();
      }// myThemeWc_SingleProductUpdateCartWidget
      
      
      var myThemeWc_SingleProductCartAjaxTask;
      
      
      // on page load --------------------------------------------
      jQuery(function($) {
          $(document.body).on('wc_fragments_refreshed', function() {
              console.log('woocommerce event fired: wc_fragments_refreshed');
          });
      
          myThemeWc_SingleProductListenAddToCart();
      });
      

      您可能需要将函数、变量前缀 myThemeWc_ 替换为您想要的。

      此代码使用原始的 WooCommerce 单一产品页面添加到购物车按钮,但停止其功能,然后使用 ajax 代替,保留表单中的所有值。

      然后将这个js文件入队。

      add_action('wp_enqueue_scripts', 'mythemewc_enqueue_scripts');
      function mythemewc_enqueue_scripts() {
          if (class_exists('\\WooCommerce') && is_product()) {
              wp_enqueue_script('mythemewc-single-product', trailingslashit(get_stylesheet_directory_uri()) . 'assets/js/my-theme-wc-single-ajax-add-cart.js', ['jquery'], false, true);
          }
      }
      

      您可能需要对 CSS 按钮进行编码,以使其显示加载、添加的图标。
      这是css。

      .woocommerce #respond input#submit.added::after, 
      .woocommerce a.btn.added::after, 
      .woocommerce button.btn.added::after, 
      .woocommerce input.btn.added::after,
      .woocommerce .single_add_to_cart_button.added::after {
          font-family: WooCommerce;
          content: '\e017';
          margin-left: .53em;
          vertical-align: bottom;
      }
      .woocommerce #respond input#submit.loading, 
      .woocommerce a.btn.loading, 
      .woocommerce button.btn.loading, 
      .woocommerce input.btn.loading,
      .woocommerce .single_add_to_cart_button.loading {
          opacity: .25;
          padding-right: 2.618em;
          position: relative;
      }
      .woocommerce #respond input#submit.loading::after, 
      .woocommerce a.btn.loading::after, 
      .woocommerce button.btn.loading::after, 
      .woocommerce input.btn.loading::after,
      .woocommerce .single_add_to_cart_button.loading::after {
          font-family: WooCommerce;
          content: '\e01c';
          vertical-align: top;
          font-weight: 400;
          position: absolute;
          right: 1em;
          -webkit-animation: spin 2s linear infinite;
          animation: spin 2s linear infinite;
      }
      

      【讨论】:

        【解决方案6】:

        您可以在单个产品中复制存档按钮的行为

        add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
        add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');      function woocommerce_ajax_add_to_cart() {
                    $product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($_POST['product_id']));
                    $quantity = empty($_POST['quantity']) ? 1 : wc_stock_amount($_POST['quantity']);
                    $variation_id = absint($_POST['variation_id']);
                    $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity);
                    $product_status = get_post_status($product_id);
        
                    if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id) && 'publish' === $product_status) {
        
                        do_action('woocommerce_ajax_added_to_cart', $product_id);
        
                        if ('yes' === get_option('woocommerce_cart_redirect_after_add')) {
                            wc_add_to_cart_message(array($product_id => $quantity), true);
                        }
        
                        WC_AJAX :: get_refreshed_fragments();
                    } else {
        
                        $data = array(
                            'error' => true,
                            'product_url' => apply_filters('woocommerce_cart_redirect_after_error', get_permalink($product_id), $product_id));
        
                        echo wp_send_json($data);
                    }
        
                    wp_die();
                }
        add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
        add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
        
        function woocommerce_ajax_add_to_cart() {
        
                    $product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($_POST['product_id']));
                    $quantity = empty($_POST['quantity']) ? 1 : wc_stock_amount($_POST['quantity']);
                    $variation_id = absint($_POST['variation_id']);
                    $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity);
                    $product_status = get_post_status($product_id);
        
                    if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id) && 'publish' === $product_status) {
        
                        do_action('woocommerce_ajax_added_to_cart', $product_id);
        
                        if ('yes' === get_option('woocommerce_cart_redirect_after_add')) {
                            wc_add_to_cart_message(array($product_id => $quantity), true);
                        }
        
                        WC_AJAX :: get_refreshed_fragments();
                    } else {
        
                        $data = array(
                            'error' => true,
                            'product_url' => apply_filters('woocommerce_cart_redirect_after_error', get_permalink($product_id), $product_id));
        
                        echo wp_send_json($data);
                    }
        
                    wp_die();
                }
        

        你可以在这里看到完整的教程

        https://quadmenu.com/add-to-cart-with-woocommerce-and-ajax-step-by-step/

        【讨论】:

          【解决方案7】:

          我在后端部分使用了这个插件https://wordpress.org/plugins/woo-ajax-add-to-cart/

          我没有使用产品页面,所以我修改了脚本以使用任何按钮:

          (function($) {
              $(document).on('click', '.btn', function(e) {
                  var $thisbutton = $(this);
          
                  try {
                      var href = $thisbutton.prop('href').split('?')[1];
          
                      if (href.indexOf('add-to-cart') === -1) return;
                  } catch (err) {
                      return;
                  }
          
                  e.preventDefault();
          
                  var product_id = href.split('=')[1];
          
                  var data = {
                      product_id: product_id
                  };
          
                  $(document.body).trigger('adding_to_cart', [$thisbutton, data]);
          
                  $.ajax({
                      type: 'post',
                      url: wc_add_to_cart_params.wc_ajax_url.replace(
                          '%%endpoint%%',
                          'add_to_cart'
                      ),
                      data: data,
                      beforeSend: function(response) {
                          $thisbutton.removeClass('added').addClass('loading');
                      },
                      complete: function(response) {
                          $thisbutton.addClass('added').removeClass('loading');
                      },
                      success: function(response) {
                          if (response.error & response.product_url) {
                              window.location = response.product_url;
                              return;
                          } else {
                              $(document.body).trigger('added_to_cart', [
                                  response.fragments,
                                  response.cart_hash
                              ]);
          
                              $('a[data-notification-link="cart-overview"]').click();
                          }
                      }
                  });
          
                  return false;
              });
          })(jQuery);

          【讨论】:

          • 嗨@Alecu,您提供的脚本正在运行,但控制台日志中有错误。它说“$thisbutton 未定义”
          【解决方案8】:

          信息:使用 WooCommerce 2.4.10 测试。

          嗯,我用另一种方式做到了,使用了从添加到购物车的 woocommerce 循环 (woocommerce/templates/loop/add-to-cart.php)

            global $product;
          
          echo apply_filters( 'woocommerce_loop_add_to_cart_link',
              sprintf( '<a href="%s" rel="nofollow" data-product_id="%s" data-product_sku="%s" data-quantity="%s" class="button %s product_type_%s">%s</a>',
                  esc_url( $product->add_to_cart_url() ),
                  esc_attr( $product->id ),
                  esc_attr( $product->get_sku() ),
                  esc_attr( isset( $quantity ) ? $quantity : 1 ),
                  $product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
                  esc_attr( $product->product_type ),
                  esc_html( $product->add_to_cart_text() )
              ),
          $product );
          

          但是问题是它只添加了 1 个数量,实际上,您可以在代码中看到列出的数量:1,所以我遇到了问题,直到我碰到 this guys who saved me

          ps。留下第一部分,它只为购物车中不需要超过 1 种产品的人添加了 1 种产品,但我为那些需要将超过 1 种产品添加到购物车的人添加了一个解决方案。

          【讨论】:

          • “拯救我的人”链接已损坏
          【解决方案9】:

          添加到购物车.js

          jQuery( document ).on( 'click', '.product_type_simple', function() { 
          
          var post_id = jQuery(this).data('product_id');//store product id in post id variable
          var qty = jQuery(this).data('quantity');//store quantity in qty variable
          
          jQuery.ajax({
              url : addtocart.ajax_url, //ajax object of localization
              type : 'post', //post method to access data
              data : 
              {
                  action : 'prefix_ajax_add_foobar', //action on prefix_ajax_add_foobar function
                  post_id : post_id,
                  quantity: qty
              },
          
              success : function(response){
          
                      jQuery('.site-header .quantity').html(response.qty);//get quantity
                      jQuery('.site-header .total').html(response.total);//get total
          
                      //loaderContainer.remove();
                      alert("Product Added successfully..");        
              }
          
          });
          
          return false;
          });
          

          【讨论】:

            【解决方案10】:

            要使 ajax woocomerce 在您需要的另一个页面上工作。 进入functions.php

            粘贴这个:

            remove_action ('woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30);
            
            add_action ('woocommerce_single_product_summary', 'woocommerce_template_loop_add_to_cart', 30);
            

            在footer.php最后粘贴这个:

            <script>
            $ ('body'). on ('add_to_cart', function () {
                 // Callback -> product added
                 // $ ('. popup'). show ();
            });
            </script>
            

            【讨论】:

            • 这不适用于可变产品。
            • 这也不适用于分组产品
            【解决方案11】:

            对我来说工作出色。我认为这是 Ajax 最简单的解决方案。

            <a href="<?php echo $product->add_to_cart_url() ?>" value="<?php echo esc_attr( $product->get_id() ); ?>" class="ajax_add_to_cart add_to_cart_button add-cart" data-product_id="<?php echo get_the_ID(); ?>" data-product_sku="<?php echo esc_attr($sku) ?>"> + Add to cart</a>
            

            【讨论】:

              【解决方案12】:

              我使用了Eh Jewel's answer,但在将产品添加到购物车后添加了一些自定义 JS。这样就完成了最终的 AJAX 过程,可以根据需要更新页面。

              为了完整起见,这里是我使用的 HTML 代码(与 Eh Jewel's 相同):

              <a href="<?php echo $product->add_to_cart_url() ?>" value="<?php echo esc_attr( $product->get_id() ); ?>" class="ajax_add_to_cart add_to_cart_button" data-product_id="<?php echo get_the_ID(); ?>" data-product_sku="<?php echo esc_attr($sku) ?>" aria-label="Add “<?php the_title_attribute() ?>” to your cart"> Add to Cart </a>
              

              那么对于自定义的JS位:

              $(window).on('load', function() {
                $('body').on( 'added_to_cart', function( added_to_cart, cart, cart_hash, button ){
                  // Put the functionality here. Debugging shows you what you have to work with:
                  console.log('added_to_cart object');
                  console.log(added_to_cart);
                  console.log('cart object');
                  console.log(cart);
                  console.log('cart_hash object');
                  console.log(cart_hash);
                  console.log('button object');
                  console.log(button);
                });
              });
              

              【讨论】:

                猜你喜欢
                • 2018-03-05
                • 2015-01-15
                • 2021-10-04
                • 2021-07-11
                • 2021-06-09
                • 1970-01-01
                • 2015-05-24
                • 2018-08-08
                • 1970-01-01
                相关资源
                最近更新 更多