使用Shopify

时间:2018-01-02 22:02:27

标签: javascript shopify variant

我一直在与Shopify商店达成共同请求,使用“Debut”主题为商店添加“添加到购物车按钮”。我们的目标是在点击“添加到购物车按钮”时自动更新购物车,而不会跳到购物车页面,以便在页面上保留客户,以方便使用。

现在通常这不是一个大问题,因为网上有很多关于这个主题的资料。我通常可以“google my way to freedom”

以下是我参考过的一些链接

https://ecommerce.shopify.com/c/ecommerce-design/t/adding-an-add-to-cart-button-to-collection-pages-in-debut-theme-433551

https://help.shopify.com/themes/customization/products/add-to-cart/stay-on-product-page-when-items-added-to-cart

将以下代码添加到 product-card-grid.liquid

时,“添加到购物车”按钮可正常工作
  <form method="post" action="/cart/add">
   <input type="hidden" name="id" value="{{ product.variants.first.id }}" />
   <input min="1" type="number" id="quantity" name="quantity" value="1"/>
   <input type="submit" value="Add to cart" class="btn" />
  </form> 

问题:

我遇到的问题是我的收藏页面使用侧边栏过滤器。代码无处不在,但在收集页面上。通过一些挖掘和一些检查,我发现这可能是因为侧栏/集合页面中的产品是从 theme.js 文件中的某些代码填充的。

现在这就是我绝对只是盲目飞行的地方,Javascript是我想要更熟悉的东西,但是就像花一些时间一样。

所以......通过仔细阅读theme.js文件我注意到的是,如果格式正确,可以将html添加到js。我能够插入它并获得“添加到购物车”按钮以显示在我的侧边栏/收藏页面中。小胜利!但是不太有用。

Collection Page Screenshot

点击“添加到购物车”按钮后,我收到以下错误

数组包含不允许的成员:id

Array contains... Error pic

以下是我希望可以修改的 theme.js 文件中的一些代码

    function runFilter() {
              typeFilter(typebxs);
              vendorFilter(vendorbxs);
              tagsFilter(tagbxs);
              optionsFilter(optionsbxs);
              colorFilter(colorbxs);
              sizeFilter(sizebxs);
              var has_price_filter = document.getElementById("sidebar-product-price").innerHTML;
              if ( has_price_filter == "true" ) { 
                priceFilter(pricebxs); 
              } else { 
                passedpricefiltertest = "true"; 
              }
              if ( passedtagfiltertest == "true"
                  && passedtypefiltertest == "true"
                  && passedpricefiltertest == "true"
                  && passedvendorfiltertest == "true"
                  && passedoptionsfiltertest == "true"
                  && passedcolorfiltertest == "true"
                  && passedsizefiltertest == "true" ) { 
                var money_sign = document.getElementById("money-sign").innerHTML; money_sign = money_sign.replace("0.00", "");
                if ( varaints_min_price != varaints_max_price ) { var price_string = money_sign + parseFloat((varaints_min_price)).toFixed(2) + "+" } else { var price_string = money_sign + parseFloat((varaints_min_price)).toFixed(2); }
                var product_url = collection_url +"products/"+ val.handle;
                var product_images_ratio = document.getElementById("product_images_ratio").innerHTML;
                var product_image_url =  val.images[0].src.replace(".jpg", "_600x600.jpg");
                product_image_url =  product_image_url.replace(".png", "_600x600.png");
                if (val.variants[0].available == true) { var sold_out = ''; } else { var sold_out = ' product-price--sold-out grid-view-item--sold-out'; }
                var string1 = '<div class="grid__item grid__item--' + sectionid + ' ' + grid_item_width + '"><div class="grid-view-item' + sold_out + '" data-section-id="section.id" data-section-type="collection-template"><div class="product-container"><div class="collection-product-overlay"><a class="grid-view-item__link" href="' + product_url + '">';
                if (product_images_ratio == "none") { var string2 = '<div style="display:none;" id="product-image-align">false</div><div style="display:none;" id="product-image-ratio">' + product_images_ratio + '</div><img class="grid-view-item__image" src="' + product_image_url + '" alt="">'; } else { var string2 = '<div class="image-bar__item box ratio-container lazyload product-grid-image"data-bgset="' + product_image_url + '" data-sizes="auto" data-parent-fit="contain" style="  background-size: contain;    background-color: transparent; background-attached:fixed; background-position: center; background-image: url("' + product_image_url + '");"></div><div style="display:none;" id="product-image-align">true</div><div style="display:none;" id="product-image-ratio">' + product_images_ratio + '</div>'; }
                if (show_vendor == "true") { var string3 = '<div style="" class="h4 grid-view-item__title collection-title_wrapper">' + val.title + '</div><div class="grid-view-item__vendor collection-title_wrapper">' + val.vendor + '</div>'; } else { var string3 = '<div style="" class="h4 grid-view-item__title collection-title_wrapper">' + val.title + '</div>'; }
                if ( val.variants[0].compare_at_price > val.variants[0].price ) { var string4 = '<div class="grid-view-item__meta collection-title_wrapper"><span class="visually-hidden">Regular price</span><s class="product-price__price" style="">' + money_sign + val.compare_at_price + '</s><span class="product-price__price product-price__sale" style="">' + price_string + '<span class="product-price__sale-label">Sale</span></span>'; } else { var string4 = '<div class="grid-view-item__meta collection-title_wrapper"><span class="product-price__price" style="">' + price_string + '</span>' + '<form  class="addtocart"method="post" action="/cart/add"><input type="hidden" name="id"  value="quantity" /><input min="1" type="number" id="{{ product.variants.first.id }}" name="quantity" value="1"/><input type="submit" value="Add to cart" class="btn" /></form>' ; }    
                if ( val.variants[0].available == true ) { var string5 = '</div></a></div></div></div></div>'; } else { var string5 = '<span class="product-price__sold-out" style="">Sold out</span></div></a></div></div></div>'; }    
                var string = string1 + string2 + string3 + string4 + string5;

                filteredProducts.push(val.title+val.id);
                productGrid[val.title+val.id] = [string];
                if (total_json_pages == counter2) {
                  if (counter3 == collectionLength) { 
                    circle.animate(1,{
                      duration: (100)
                    });


                                            debouncedPagintor();


                  }
                }
                if ( product_images_ratio != "none" ) {
                  var width = $( ".product-grid-image" ).width();
                  width = parseInt(width) * parseFloat(product_images_ratio) ;
                  $( ".product-grid-image" ).css( "height", width );
                }
              } else { 
                if (total_json_pages == counter2) { 
                  if (counter3 == collectionLength) { 


                                            debouncedPagintor();



                  }
                } 
              }
            }

            runFilter();

          }
        }


        $('.filter-update ~ .lbl, .filter-update ~ .cbx').unbind("click");
        $('.filter-update ~ .lbl, .filter-update ~ .cbx').on( "click", function() {
          debouncedfilterIt();
        });
      }

      var debouncedfilterIt = function() {
        filterIt();
      }
      var debouncedfilterIt = $.debounce( 250, false, debouncedfilterIt );
      var needsFilter = document.getElementById('sb-master-input-format-1');           

      function grabCollection() {  
   var show_vendor = document.getElementById("show_vendor").innerHTML;
   var grid_item_width = document.getElementById("grid_item_width").innerHTML;
   var sectionid = sectionId;
   var money_sign = document.getElementById("money-sign").innerHTML;
   money_sign = money_sign.replace("0.00", "");
   var filteredProducts = [];
   var jsonDataString = "";
   var jsonData = {};



   if (masterString[jsonsrc + "1"] == undefined) {
     if ( total_json_pages > 2 ) { 
       $( "#progress" ).show(); 
       circle.animate(1,{
duration: ((total_json_pages)*200)

});

您可以看到我在哪里插入了html来加载收藏页面上的按钮。我做的唯一修改就是插入包含在“form”标签中的html位。

我相信这个问题很可能会在特别长的代码行中找到。

来自该文件

if ( val.variants[0].compare_at_price > val.variants[0].price ) { var string4 = '<div class="grid-view-item__meta collection-title_wrapper"><span class="visually-hidden">Regular price</span><s class="product-price__price" style="">' + money_sign + val.compare_at_price + '</s><span class="product-price__price product-price__sale" style="">' + price_string + '<span class="product-price__sale-label">Sale</span></span>'; } else { var string4 = '<div class="grid-view-item__meta collection-title_wrapper"><span class="product-price__price" style="">' + price_string + '</span>' + '<form  class="addtocart"method="post" action="/cart/add"><input type="hidden" name="id"  value="quantity" /><input min="1" type="number" id="{{ product.variants.first.id }}" name="quantity" value="1"/><input type="submit" value="Add to cart" class="btn" /></form>' ; }

这是我第一次发帖。如果我错过了为此论坛设置格式的简单方法,我深表歉意。

我希望这已经足够了。我快到了吗?这是一个简单的修复吗?信息不足?

感谢您的时间!我希望这是足够彻底的,而不是太复杂。

此致

Jeff J

修改

我快到了! (感谢Darshit Patel!)在 theme.js 中将"{{ product.variants.first.id }}"更改为"'+ val.variants[0].id +'"摆脱了“数组包含未经许可的成员:id”错误并更新购物车,但它带我到购物车页面,似乎没有与 ajaxify-cart.liquid

互动

这是整个ajaxify-cart.liquid代码

<script>

/**
 * Module to ajaxify all add to cart forms on the page.
 *
 * Copyright (c) 2015 Caroline Schnapp (11heavens.com)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */
Shopify.AjaxifyCart = (function($) {

  // Some configuration options.
  // I have separated what you will never need to change from what
  // you might change.

  var _config = {

    // What you might want to change
    addToCartBtnLabel:             'Add to cart',
    addedToCartBtnLabel:           'Thank you!',
    addingToCartBtnLabel:          'Adding...',
    soldOutBtnLabel:               'Sold Out',
    howLongTillBtnReturnsToNormal: 1000, // in milliseconds.
    cartCountSelector:             '#CartCount, .cart-count, #cart-count a:first, #gocart p a, #cart .checkout em, .item-count',
    cartTotalSelector:             '#cart-price',
    // 'aboveForm' for top of add to cart form, 
    // 'belowForm' for below the add to cart form, and 
    // 'nextButton' for next to add to cart button.
    feedbackPosition:              'nextButton',

    // What you will never need to change
    addToCartBtnSelector:          '[type="submit"]',
    addToCartFormSelector:         'form[action="/cart/add"]',
    shopifyAjaxAddURL:             '/cart/add.js',
    shopifyAjaxCartURL:            '/cart.js'
  };

  // We need some feedback when adding an item to the cart.
  // Here it is.  
  var _showFeedback = function(success, html, $addToCartForm) {
    $('.ajaxified-cart-feedback').remove();
    var feedback = '<p class="ajaxified-cart-feedback ' + success + '">' + html + '</p>';
    switch (_config.feedbackPosition) {
      case 'aboveForm':
        $addToCartForm.before(feedback);
        break;
      case 'belowForm':
        $addToCartForm.after(feedback);
        break;
      case 'nextButton':
      default:
        $addToCartForm.find(_config.addToCartBtnSelector).after(feedback);
        break;   
    }
    // If you use animate.css
    // $('.ajaxified-cart-feedback').addClass('animated bounceInDown');
    $('.ajaxified-cart-feedback').slideDown();
  };
  var _setText = function($button, label) {
    if ($button.children().length) {
      $button.children().each(function() {
        if ($.trim($(this).text()) !== '') {
          $(this).text(label);
        }
      });
    }
    else {
      $button.val(label).text(label);
    }
  };
  var _init = function() {   
    $(document).ready(function() { 
      $(_config.addToCartFormSelector).submit(function(e) {
        e.preventDefault();
        var $addToCartForm = $(this);
        var $addToCartBtn = $addToCartForm.find(_config.addToCartBtnSelector);
        _setText($addToCartBtn, _config.addingToCartBtnLabel);
        $addToCartBtn.addClass('disabled').prop('disabled', true);
        // Add to cart.
        $.ajax({
          url: _config.shopifyAjaxAddURL,
          dataType: 'json',
          type: 'post',
          data: $addToCartForm.serialize(),
          success: function(itemData) {
            // Re-enable add to cart button.
            $addToCartBtn.addClass('inverted');
            _setText($addToCartBtn, _config.addedToCartBtnLabel);
            _showFeedback('success','<i class="fa fa-check"></i> Added to cart! <a href="/cart">View cart</a> or <a href="/collections/all">continue shopping</a>.',$addToCartForm);
            window.setTimeout(function(){
              $addToCartBtn.prop('disabled', false).removeClass('disabled').removeClass('inverted');
              _setText($addToCartBtn,_config.addToCartBtnLabel);
            }, _config.howLongTillBtnReturnsToNormal);
            // Update cart count and show cart link.
            $.getJSON(_config.shopifyAjaxCartURL, function(cart) {
              if (_config.cartCountSelector && $(_config.cartCountSelector).size()) {
                var value = $(_config.cartCountSelector).html() || '0';
                $(_config.cartCountSelector).html(value.replace(/[0-9]+/,cart.item_count)).removeClass('hidden-count');
              }
              if (_config.cartTotalSelector && $(_config.cartTotalSelector).size()) {
                if (typeof Currency !== 'undefined' && typeof Currency.moneyFormats !== 'undefined') {
                  var newCurrency = '';
                  if ($('[name="currencies"]').size()) {
                    newCurrency = $('[name="currencies"]').val();
                  }
                  else if ($('#currencies span.selected').size()) {
                    newCurrency = $('#currencies span.selected').attr('data-currency');
                  }
                  if (newCurrency) {
                    $(_config.cartTotalSelector).html('<span class=money>' + Shopify.formatMoney(Currency.convert(cart.total_price, "{{ shop.currency }}", newCurrency), Currency.money_format[newCurrency]) + '</span>');
                  } 
                  else {
                    $(_config.cartTotalSelector).html(Shopify.formatMoney(cart.total_price, "{{ shop.money_format | remove: "'" | remove: '"' }}"));
                  }
                }
                else {
                  $(_config.cartTotalSelector).html(Shopify.formatMoney(cart.total_price, "{{ shop.money_format | remove: "'" | remove: '"' }}"));
                }
              };
            });        
          }, 
          error: function(XMLHttpRequest) {
            var response = eval('(' + XMLHttpRequest.responseText + ')');
            response = response.description;
            if (response.slice(0,4) === 'All ') {
              _showFeedback('error', response.replace('All 1 ', 'All '), $addToCartForm);
              $addToCartBtn.prop('disabled', false);
              _setText($addToCartBtn, _config.soldOutBtnLabel);
              $addToCartBtn.prop('disabled',true);
            }
            else {
              _showFeedback('error', '<i class="fa fa-warning"></i> ' + response, $addToCartForm);
              $addToCartBtn.prop('disabled', false).removeClass('disabled');
              _setText($addToCartBtn, _config.addToCartBtnLabel);
            }
          }
        });   
        return false;    
      });
    });
  };
  return {
    init: function(params) {
        // Configuration
        params = params || {};
        // Merging with defaults.
        $.extend(_config, params);
        // Action
        $(function() {
          _init();
        });
    },    
    getConfig: function() {
      return _config;
    }
  }  
})(jQuery);

Shopify.AjaxifyCart.init();

</script>

{% comment %}
  If you want to animate your feedback message.
{% endcomment %}

{% comment %}
{{ '//cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.0/animate.min.css' | stylesheet_tag }}
{% endcomment %}

{{ '//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.css' | stylesheet_tag }}

<style>
.ajaxified-cart-feedback {
  display: block;
  line-height: 36px;
  font-size: 90%;
  vertical-align: middle;
}
.ajaxified-cart-feedback.success { 
  color: #3D9970;
}
.ajaxified-cart-feedback.error { 
  color: #FF4136; 
} 
.ajaxified-cart-feedback a {
  border-bottom: 1px solid;
}
</style>

我想知道是否有一个简单的解决方案。我不知所措。我会把这个问题作为一个新问题,但此时它似乎真的是“两个人”,因为它与我分享的所有信息有关。

再次,谢谢你的时间

干杯!

1 个答案:

答案 0 :(得分:1)

来自theme.js的这行代码'id =“{{product.variants.first.id}}”'是确切的问题。当你在任何.js文件中添加此行时,它不会呈现为液体但是它会将其渲染为String。 Theme.js是简单的.js文件不是液体,所以这个液体线将呈现为String。您需要更改该行,您的问题将得到解决。 您只需要在整个theme.js中将“{{product.variants.first.id}}”替换为“val.variants [0] .id”。