直接在购物车中编辑和保存Shopify订单项属性

时间:2019-05-10 23:42:02

标签: javascript json shopify liquid

我想直接使用/cart/change.js在购物车中编辑/保存Shopify订单项属性,而不必返回到产品页面重新输入信息。订单项属性由名称/值组成。

每个购物车项目最多具有3个订单项属性名称(“场合”,“其他注释”,“随身携带的卡”),每个对应的值都是唯一的。

See this screenshot as example

我似乎无法使它与多个购物车项目或多个属性名称/值一起使用。由于每个属性值ID都是属性值本身,因此我尝试为每个值创建动态ID,以便可以唯一地定位每个购物车商品属性并覆盖现有值。但是,我似乎无法弄清楚该怎么做。

例如,为了编辑property-name,我想执行以下操作:

$('.cart-line-item-update').on('click', function() {
  const $this = $(this);
  const dataIndex = $this.data('index');
  const item = cart_items[dataIndex - 1];
  item.properties['property-name'] = $('#dynamic-property-value').val();
  jQuery.ajax({
    url: '/cart/change.js',
    dataType: 'json',
    data: {
      line: dataIndex,
      properties: item.properties
    }
  }).done(function() {
    window.location.reload()
  })
});

<script>
    var cart_items = {{cart.items | json}} 
</script>

{% if property_size > 0 %}
  {% assign loop_index = forloop.index %}
  {% for p in item.properties %}
    {% assign first_character_in_key = p.first | truncate: 1, '' %}
    {% unless p.last == blank or first_character_in_key == '_' %}
      <div class="accordion-container collapse-all cart-line-item-accordion">
        <input type="checkbox" title="Expand for more information" checked>
        <h2 class="accordion-title">
          <span id="{{ item.product_id }}-{{ p.first | handleize }}">{{ p.first }}:</span>
          <i class="accordion-icon"></i>
        </h2>
        <div class="accordion-content">

          <div class="saved-textarea visible">
            {{ p.last }}
          </div>
          <textarea id="{{ item.product_id }}-{{ p.first | handleize }}-textarea" class="update-textarea autosize new-property">{{ p.last }}</textarea>

          <div class="cart-line-item-btns">
            <a class="cart-item-remove cart-line-item-edit" title="Edit content">Edit</a>
            <a class="cart-item-remove cart-line-item-update" title="Save changes" data-index="{{loop_index}}">Update</a>
          </div>
        </div>
      </div>
    {% endunless %}
  {% endfor %}
{% endif %}

预期结果: 每个购物车商品的属性值都会保存(覆盖现有的json值)。

实际结果: 将仅更新并保存第一个购物车商品属性值。如果购物车中有多个项目,每个项目都有自己的值,它将不会保存该属性的后续实例,而将第一个实例覆盖它们。

这些值已经存在于json中,因为它们是在产品页面上创建并转移到购物车的。我只是不知道如何定位每个旧的json值以将其替换为新的。该脚本似乎以属性名的所有实例为目标,并用第一个值覆盖它们。

也许我缺少明显的东西。谁能帮忙吗?

1 个答案:

答案 0 :(得分:0)

我已经修改了代码,请尝试一下,它最终会起作用

首先,我修改了属性部分,添加了一些数据和包装器。

      {% if property_size > 0 %}
   <div class="propContainer">
  {% assign loop_index = forloop.index %}
  {% for p in item.properties %}
    {% assign first_character_in_key = p.first | truncate: 1, '' %}
    {% unless p.last == blank or first_character_in_key == '_' %}
      <div class="accordion-container collapse-all cart-line-item-accordion">
        <input type="checkbox" title="Expand for more information" checked>
        <h2 class="accordion-title">
          <span id="{{ item.product_id }}-{{ p.first | handleize }}">{{ p.first }}:</span>
          <i class="accordion-icon"></i>
        </h2>
        <div class="accordion-content">

          <div class="saved-textarea visible">
            {{ p.last }}
          </div>
          <textarea data-name="{{ p.first }}" id="{{ item.product_id }}-{{ p.first | handleize }}-textarea" class="propLine update-textarea autosize new-property">{{ p.last }}</textarea>

          <div class="cart-line-item-btns">
            <a class="cart-item-remove cart-line-item-edit" title="Edit content">Edit</a>
            <a class="cart-item-remove cart-line-item-update" title="Save changes" data-index="{{loop_index}}">Update</a>
          </div>
        </div>
      </div>
    {% endunless %}
  {% endfor %}
            </div>
{% endif %}

并将其放在购物车模板的末尾。

<script>

$('.cart-line-item-update').on('click', function() {
  const $this = $(this);
  const dataIndex = $this.data('index');
  var inputData = $this.closest('.propContainer').find('.propLine')

  var data = {
     line: dataIndex,
     properties: ''
   }
  var tempProperties = {}
  inputData.each(function(index, el) {
    tempProperties[$(el).data('name')] = $(el).val();
  });
  data.properties = tempProperties;

  jQuery.ajax({
    url: '/cart/change.js',
    dataType: 'json',
    data: data
  }).done(function() {
    window.location.reload()
  })
});
</script>