如何使用 SnipCart 创建分层自定义属性 select 框?

How do I create tiered custom attribute select boxes with SnipCart?

我希望为产品设置两个自定义属性,其中第二个自定义属性具有取决于第一个属性的独特选项 selected。

我的特殊情况是销售具有许多不同格式和尺寸的艺术品,其中尺寸的价格会根据select编辑的格式而有所不同(即:打印、装框、Canvas, 等等).

显而易见的替代方法是为每种格式提供不同的产品列表,而不是使用双下拉菜单。但是,这不是我想要做的理想情况。

这是文档中为单个 select 框和自定义属性提供的代码:

<label>Frame color</label>
<select id="frame_color">
  <option value="Black">Black</option>
  <option value="Brown">Brown</option>
  <option value="Gold">Gold</option>
</select>
<button
  id="starry-night"
  class="snipcart-add-item"
  data-item-id="starry-night"
  data-item-price="79.99"
  data-item-url="/paintings/starry-night"
  data-item-description="High-quality replica of The Starry Night by the Dutch post-impressionist painter Vincent van Gogh."
  data-item-image="/assets/images/starry-night.jpg"
  data-item-name="The Starry Night"
  data-item-custom1-name="Frame color"
  data-item-custom1-options="Black|Brown|Gold"
  data-item-custom2-name="Gift note">
  Add to cart
</button>
<script>
const button = document.querySelector('#starry-night')
const select = document.querySelector('#frame_color')
select.addEventListener('change', () => {
  // Sets the default frame color when adding the item
  button.setAttribute("data-item-custom1-value", select.value)
})
</script>

这可以通过在幕后拥有多种产品来实现,但让用户看起来只有一种产品(每件商品)。然后,根据第一个选择框更改可见的产品(和自定义属性选择框)。

我是新手,所以可能有更简单的方法来完成此操作,但这是我想出的并且效果很好。此外,我在此代码中使用了一点 jQuery,因此需要修改才能在没有它的情况下工作。

<style>
.hidden{
  display:none;
}
</style>

<select id="item-1">
    <option value="1">Type 1</option>
    <option value="2">Type 2</option>
</select>

<div id="type-1-1" class="item-content-1">
    <select id="size-1-1">
        <option value="8x8 ()">8x8 ()</option>
        <option value="12x12 (0)">12x12 (0)</option>
        <option value="20x20 (0)">20x20 (0)</option>
    </select>
    <button id="add-to-cart-1-1" class="snipcart-add-item"
        data-item-id="product-1-1"
        data-item-price="0.00"
        data-item-url="https://example.com"
        data-item-description="Product 1 type 1 description"
        data-item-image="/img.jpg"
        data-item-name="Product 1 type 1"
        data-item-custom1-name="Size"
        data-item-custom1-options="8x8 ()[+50.00]|12x12 (0)[+100.00]|20x20 (0)[+200.00]"
        data-item-custom1-value="8x8 ()"
        data-item-custom1-required="true">Add To Cart
    </button>
</div>

<div id="type-1-2" class="item-content-1 hidden">
    <select id="size-1-2">
        <option value="8x8 ()">8x8 ()</option>
        <option value="12x12 (0)">12x12 (0)</option>
        <option value="20x20 (0)">20x20 (0)</option>
    </select>
    <button id="add-to-cart-1-2" class="snipcart-add-item"
        data-item-id="product-1-2"
        data-item-price="0.00"
        data-item-url="https://example.com"
        data-item-description="Product 1 type 2 description"
        data-item-image="/img.jpg"
        data-item-name="Product 1 type 2"
        data-item-custom1-name="Size"
        data-item-custom1-options="8x8 ()[+90.00]|12x12 (0)[+170.00]|20x20 (0)[+300.00]"
        data-item-custom1-value="8x8 ()"
        data-item-custom1-required="true">Add To Cart
    </button>
</div>

<select id="item-2">
    <option value="1">Type 1</option>
    <option value="2">Type 2</option>
</select>

<div id="type-2-1" class="item-content-2">
    <select id="size-2-1">
        <option value="8x8 ()">8x8 ()</option>
        <option value="12x12 (0)">12x12 (0)</option>
        <option value="20x20 (0)">20x20 (0)</option>
    </select>
    <button id="add-to-cart-2-1" class="snipcart-add-item"
        data-item-id="product-2-1"
        data-item-price="0.00"
        data-item-url="https://example.com"
        data-item-description="Product 2 type 1 description"
        data-item-image="/img.jpg"
        data-item-name="Product 2 type 1"
        data-item-custom1-name="Size"
        data-item-custom1-options="8x8 ()[+50.00]|12x12 (0)[+100.00]|20x20 (0)[+200.00]"
        data-item-custom1-value="8x8 ()"
        data-item-custom1-required="true">Add To Cart
    </button>
</div>

<div id="type-2-2" class="item-content-2 hidden">
    <select id="size-2-2">
        <option value="8x8 ()">8x8 ()</option>
        <option value="12x12 (0)">12x12 (0)</option>
        <option value="20x20 (0)">20x20 (0)</option>
    </select>
    <button id="add-to-cart-2-2" class="snipcart-add-item"
        data-item-id="product-2-2"
        data-item-price="0.00"
        data-item-url="https://example.com"
        data-item-description="Product 2 type 2 description"
        data-item-image="/img.jpg"
        data-item-name="Product 2 type 2"
        data-item-custom1-name="Size"
        data-item-custom1-options="8x8 ()[+90.00]|12x12 (0)[+170.00]|20x20 (0)[+300.00]"
        data-item-custom1-value="8x8 ()"
        data-item-custom1-required="true">Add To Cart
    </button>
</div>

<script>
    var item_count = 2; //number of items in shop
    var type_count = 2; //number of type subdivisions
    var i = 1;
    for (i = 1; i <= item_count; i++) {
        const type_select = document.querySelector('#item-' + i);
        const count = i
        type_select.addEventListener('change', () => {
            $('.item-content-' + count).addClass("hidden");
            $('#type-' + count + "-" + type_select.value).removeClass("hidden");
        });
        var ii = 1;
        for (ii = 1; ii <= type_count; ii++) {
            const addToCart = document.querySelector('#add-to-cart-' + i + "-" + ii);
            const size = document.querySelector('#size-' + i + "-" + ii);
            size.addEventListener('change', () => {
                addToCart.setAttribute("data-item-custom1-value", size.value);
            });
        };
    };
</script>

我相信你可以用 data-item-custom1-value:

data-item-custom1-name="Color"
data-item-custom1-options="Blue|Dark Gray|Light Gray"
data-item-custom1-value="Dark Gray"

然后用Javascript把data-item-custom1-value当一个select改成select的值。

完整示例

<div>
    <label for="color">Color</label>
    <select name="color" id="color">
        <option value="Blue">Blue</option>
        <option value="Dark Gray">Dark Gray</option>
        <option value="Light Gray">Light Gray</option>
    </select>
</div>

<button id="poster-cart-btn" class="snipcart-add-item btn btn-dark"
data-item-id="1"
data-item-price="9.95"
data-item-url="/"
data-item-name="Poster"
data-item-image="img/poster.png"
data-item-description="A pretty poster"
data-item-custom1-name="Color"
data-item-custom1-options="Blue|Dark Gray|Light Gray"
data-item-custom1-value="Blue">
    Add to cart
</button>
    
<script type="text/javascript">
    window.addEventListener('load', function() {
        document.getElementById('color').onchange = function() {
            const val = document.getElementById('color').value;
            document.getElementById('poster-cart-btn').setAttribute('data-item-custom1-value', val);
        }
    });
</script>

我在 js 方面不是很好,是否可以给 .setAttribute 大于 1 的值来改变价格?非常感谢

 <select id="size-2-2">
    <option value="8x8 ()">8x8 ()</option>
    <option value="12x12 (0)">12x12 (0)</option>
    <option value="20x20 (0)">20x20 (0)</option>
</select>
<select id="color-2-3">
    <option value="color_1 ()">8x8 ()</option>
    <option value="color_2 (0)">12x12 (0)</option>
    <option value="color_3 (0)">20x20 (0)</option>
</select>

<button id="add-to-cart-2-2" class="snipcart-add-item"
    data-item-id="product-2-2"
    data-item-price="0.00"
    data-item-url="https://example.com"
    data-item-description="Product 2 type 2 description"
    data-item-image="/img.jpg"
    data-item-name="Product 2 type 2"
    data-item-custom1-name="Size"
    data-item-custom1-options="8x8 ()[+90.00]|12x12 (0)[+170.00]|20x20 (0)[+300.00]"
    data-item-custom1-value="8x8 ()"
    data-item-custom1-required="true" 
    data-item-custom2-name="Color"
    data-item-custom2-options="color_1 ()[+90.00]|color_2 (0)[+170.00]|color_3(0)[+300.00]"
    data-item-custom2-value="color_1 ()"
    data-item-custom2-required="true">Add To Cart
</button>

...
addToCart.setAttribute("data-item-custom1-value", size.value);
addToCart.setAttribute("data-item-custom2-value", size.value);
...

非常感谢@justin我修改了你的方法,对我来说效果很好!现在,snipcart 可以通过一个按钮获取 select 字段中的所有值。我知道有一种更好的方法可以加载“window.addEventListener” x 次。欢迎 post 更好更简单的解决方案。

<div>
    <label for="color-1">Color 1</label>
    <select name="Color select 1" id="color_1">
        <option value="color_1_1">0</option>
        <option value="color_1_2">+11</option>
        <option value="color_1_3">+111</option>
    </select>
    
    <label for="color-2">Color 2</label>
    <select name="Color select 2" id="color_2">
        <option value="color_2_1">0</option>
        <option value="color_2_2">+12</option>
        <option value="color_2_3">+112</option>
    </select>
    
    <label for="color-3">Color 3</label>
    <select name="Color select 3" id="color_3">
        <option value="color_3_1">0</option>
        <option value="color_3_2">+13</option>
        <option value="color_3_3">-113</option>
    </select>
    
</div>

<button id="poster-cart-btn" class="snipcart-add-item"
      data-item-id="1"
      data-item-price="0.00"
      data-item-url="/"
      data-item-name="Poster"
      data-item-image="img/poster.png"
      data-item-description="A pretty poster"
      data-item-custom1-name="Color 1"
      data-item-custom1-options="color_1_1|color_1_2[+11.00]|color_1_3[+111.00]"
      data-item-custom1-value="color_1_1"
      data-item-custom2-name="Color 2"
      data-item-custom2-options="color_2_1|color_2_2[+12.00]|color_2_3[+112.00]"
      data-item-custom2-value="color_2_1"
      data-item-custom3-name="Color 3"
      data-item-custom3-options="color_3_1|color_3_2[+13.00]|color_3_3[+113.00]"
      data-item-custom3-value="color_3_1">
      Add to cart
</button>
    
<script type="text/javascript">
    window.addEventListener('load', function() {
    
        document.getElementById('color_1').onchange = function() {
            const val = document.getElementById('color_1').value;
            document.getElementById('poster-cart-btn').setAttribute('data-item-custom1-value', val);
        }
         document.getElementById('color_2').onchange = function() {
            const val = document.getElementById('color_2').value;
            document.getElementById('poster-cart-btn').setAttribute('data-item-custom2-value', val);
        }
        
         document.getElementById('color_3').onchange = function() {
            const val = document.getElementById('color_3').value;
            document.getElementById('poster-cart-btn').setAttribute('data-item-custom3-value', val);
        }
    });
</script>