使用Shopify通过Javascript动态提取Variant id

问题描述 投票:1回答:1

我一直在与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>' ; }

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

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

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

诚挚

杰夫杰

编辑:

我快到了! (感谢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>

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

再次,谢谢你的时间

干杯!

javascript shopify variant
1个回答
1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.