From 1b0a538fc3f0d54d9251b5d4b1c16ca91eed3e26 Mon Sep 17 00:00:00 2001 From: Josh Corbett Date: Wed, 8 May 2024 13:51:30 -0600 Subject: [PATCH 01/11] fix: :pencil2: rename function naming typo --- assets/product-info.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/product-info.js b/assets/product-info.js index 1fa35239125..e38e8da7974 100644 --- a/assets/product-info.js +++ b/assets/product-info.js @@ -16,7 +16,7 @@ if (!customElements.get('product-info')) { if (!this.input) return; this.quantityForm = this.querySelector('.product-form__quantity'); if (!this.quantityForm) return; - this.setQuantityBoundries(); + this.setQuantityBoundaries(); if (!this.dataset.originalSection) { this.cartUpdateUnsubscriber = subscribe(PUB_SUB_EVENTS.cartUpdate, this.fetchQuantityRules.bind(this)); } @@ -24,7 +24,7 @@ if (!customElements.get('product-info')) { const sectionId = this.dataset.originalSection ? this.dataset.originalSection : this.dataset.section; if (event.data.sectionId !== sectionId) return; this.updateQuantityRules(event.data.sectionId, event.data.html); - this.setQuantityBoundries(); + this.setQuantityBoundaries(); }); } @@ -37,7 +37,7 @@ if (!customElements.get('product-info')) { } } - setQuantityBoundries() { + setQuantityBoundaries() { const data = { cartQuantity: this.input.dataset.cartQuantity ? parseInt(this.input.dataset.cartQuantity) : 0, min: this.input.dataset.min ? parseInt(this.input.dataset.min) : 1, @@ -70,7 +70,7 @@ if (!customElements.get('product-info')) { .then((responseText) => { const html = new DOMParser().parseFromString(responseText, 'text/html'); this.updateQuantityRules(this.dataset.section, html); - this.setQuantityBoundries(); + this.setQuantityBoundaries(); }) .catch((e) => { console.error(e); From 9e2a4f0dfe5f865f657ea4aba8500ddffe68b9fa Mon Sep 17 00:00:00 2001 From: Josh Corbett Date: Thu, 9 May 2024 09:26:17 -0600 Subject: [PATCH 02/11] feat: :sparkles: initial auto variant disable TODO: When no variant is selected, the selected options still show the first value as selected --- locales/en.default.schema.json | 4 ++++ sections/featured-product.liquid | 7 +++++++ sections/main-product.liquid | 20 +++++++++++++++++--- snippets/buy-buttons.liquid | 24 ++++++++++++++++-------- snippets/product-variant-options.liquid | 10 +++++++--- snippets/product-variant-picker.liquid | 1 + 6 files changed, 52 insertions(+), 14 deletions(-) diff --git a/locales/en.default.schema.json b/locales/en.default.schema.json index 0957b3a22d3..1514cec3629 100644 --- a/locales/en.default.schema.json +++ b/locales/en.default.schema.json @@ -2415,6 +2415,10 @@ "hide_variants": { "label": "Hide other variants’ media after selecting a variant" }, + "auto_select_variant": { + "label": "Auto-select first available variant?", + "info": "If enabled, the first available variant will be selected by default." + }, "enable_video_looping": { "label": "Enable video looping" } diff --git a/sections/featured-product.liquid b/sections/featured-product.liquid index 3c31b962d02..693c6752b83 100644 --- a/sections/featured-product.liquid +++ b/sections/featured-product.liquid @@ -1450,6 +1450,13 @@ "default": false, "label": "t:sections.main-product.settings.hide_variants.label" }, + { + "id": "auto_select_variant", + "label": "t:sections.main-product.settings.auto_select_variant.label", + "type": "checkbox", + "default": true, + "info": "t:sections.main-product.settings.auto_select_variant.info" + }, { "type": "checkbox", "id": "enable_video_looping", diff --git a/sections/main-product.liquid b/sections/main-product.liquid index e57d05f1b72..2dc965ae270 100644 --- a/sections/main-product.liquid +++ b/sections/main-product.liquid @@ -66,7 +66,14 @@ > {%- endif -%} - {% assign variant_images = product.images | where: 'attached_to_variant?', true | map: 'src' %} + {% liquid + assign variant_images = product.images | where: 'attached_to_variant?', true | map: 'src' + assign selected_variant = product.selected_variant + if section.settings.auto_select_variant or product.variants.size == 1 + assign selected_variant = product.selected_or_first_available_variant + endif + %} +
@@ -191,7 +198,7 @@ {{ product.description }}
{%- endif -%} - {%- when 'sku' -%} + {%- when 'sku' and selected_variant -%}

{{ 'products.product.sku' | t }}: - {{- product.selected_or_first_available_variant.sku -}} + {{- selected_variant.sku -}}

{%- when 'custom_liquid' -%} {{ block.settings.custom_liquid }} @@ -2247,6 +2254,13 @@ "default": false, "label": "t:sections.main-product.settings.hide_variants.label" }, + { + "id": "auto_select_variant", + "label": "t:sections.main-product.settings.auto_select_variant.label", + "type": "checkbox", + "default": true, + "info": "t:sections.main-product.settings.auto_select_variant.info" + }, { "type": "checkbox", "id": "enable_video_looping", diff --git a/snippets/buy-buttons.liquid b/snippets/buy-buttons.liquid index 1cb004a8974..6d4e338e2fd 100644 --- a/snippets/buy-buttons.liquid +++ b/snippets/buy-buttons.liquid @@ -10,6 +10,14 @@ Usage: {% render 'buy-buttons', block: block, product: product, product_form_id: product_form_id, section_id: section.id, show_pickup_availability: true %} {% endcomment %} + +{% liquid + assign selected_variant = product.selected_variant + if section.settings.auto_select_variant or product.variants.size == 1 + assign selected_variant = product.selected_or_first_available_variant + endif +%} +
{%- if product != blank -%} {%- liquid @@ -54,8 +62,8 @@ {%- liquid assign check_against_inventory = true - if product.selected_or_first_available_variant.inventory_management != 'shopify' or product.selected_or_first_available_variant.inventory_policy == 'continue' + if selected_variant.inventory_management != 'shopify' or selected_variant.inventory_policy == 'continue' assign check_against_inventory = false endif - if product.selected_or_first_available_variant.quantity_rule.min > product.selected_or_first_available_variant.inventory_quantity and check_against_inventory + if selected_variant.quantity_rule.min > selected_variant.inventory_quantity and check_against_inventory assign quantity_rule_soldout = true endif -%} @@ -80,12 +88,12 @@ type="submit" name="add" class="product-form__submit button button--full-width {% if show_dynamic_checkout %}button--secondary{% else %}button--primary{% endif %}" - {% if product.selected_or_first_available_variant.available == false or quantity_rule_soldout %} + {% if selected_variant.available == false or quantity_rule_soldout or selected_variant == blank %} disabled {% endif %} > - {%- if product.selected_or_first_available_variant.available == false or quantity_rule_soldout -%} + {%- if selected_variant.available == false or quantity_rule_soldout -%} {{ 'products.product.sold_out' | t }} {%- else -%} {{ 'products.product.add_to_cart' | t }} @@ -117,13 +125,13 @@ {%- if show_pickup_availability -%} {{ 'component-pickup-availability.css' | asset_url | stylesheet_tag }} - {%- assign pick_up_availabilities = product.selected_or_first_available_variant.store_availabilities + {%- assign pick_up_availabilities = selected_variant.store_availabilities | where: 'pick_up_enabled', true -%} 0 %} + {% if selected_variant.available and pick_up_availabilities.size > 0 %} available {% endif %} data-root-url="{{ routes.root_url }}" diff --git a/snippets/product-variant-options.liquid b/snippets/product-variant-options.liquid index 67def0ec294..fb594bf6634 100644 --- a/snippets/product-variant-options.liquid +++ b/snippets/product-variant-options.liquid @@ -7,7 +7,6 @@ - block: {Object} block object. - picker_type: {String} type of picker to dispay - Usage: {% render 'product-variant-options', product: product, @@ -29,6 +28,11 @@ {%- liquid assign option_disabled = true + assign selected_variant = product.selected_variant + if section.settings.auto_select_variant or product.variants.size == 1 + assign selected_variant = product.selected_or_first_available_variant + endif + for option1_name in variants_option1_arr case option.position when 1 @@ -36,11 +40,11 @@ assign option_disabled = false endif when 2 - if option1_name == product.selected_or_first_available_variant.option1 and variants_option2_arr[forloop.index0] == value and variants_available_arr[forloop.index0] + if option1_name == selected_variant.option1 and variants_option2_arr[forloop.index0] == value and variants_available_arr[forloop.index0] assign option_disabled = false endif when 3 - if option1_name == product.selected_or_first_available_variant.option1 and variants_option2_arr[forloop.index0] == product.selected_or_first_available_variant.option2 and variants_option3_arr[forloop.index0] == value and variants_available_arr[forloop.index0] + if option1_name == selected_variant.option1 and variants_option2_arr[forloop.index0] == selected_variant.option2 and variants_option3_arr[forloop.index0] == value and variants_available_arr[forloop.index0] assign option_disabled = false endif endcase diff --git a/snippets/product-variant-picker.liquid b/snippets/product-variant-picker.liquid index 0ef83da1d22..bfe8c0ca5ba 100644 --- a/snippets/product-variant-picker.liquid +++ b/snippets/product-variant-picker.liquid @@ -6,6 +6,7 @@ - block: {Object} passing the block information. - product_form_id: {String} Id of the product form to which the variant picker is associated. - update_url: {Boolean} whether or not to update url when changing variants. If false, the url isn't updated. Default: true (optional). + Usage: {% render 'product-variant-picker', product: product, block: block, product_form_id: product_form_id %} {% endcomment %} From 126245cad7495f8c272d727a46326d328e97d389 Mon Sep 17 00:00:00 2001 From: Josh Corbett Date: Thu, 9 May 2024 11:04:56 -0600 Subject: [PATCH 03/11] feat: :sparkles: use `selected_variant` on product page --- sections/main-product.liquid | 74 ++++++++++++------------- snippets/product-variant-options.liquid | 6 +- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/sections/main-product.liquid b/sections/main-product.liquid index 2dc965ae270..faa262086f6 100644 --- a/sections/main-product.liquid +++ b/sections/main-product.liquid @@ -133,7 +133,7 @@
{%- assign product_form_installment_id = 'product-form-installment-' | append: section.id -%} {%- form 'product', product, id: product_form_installment_id, class: 'installment caption-large' -%} - + {{ form | payment_terms }} {%- endform -%}
@@ -144,9 +144,9 @@ id="Inventory-{{ section.id }}" role="status" > - {%- if product.selected_or_first_available_variant.inventory_management == 'shopify' -%} - {%- if product.selected_or_first_available_variant.inventory_quantity > 0 -%} - {%- if product.selected_or_first_available_variant.inventory_quantity + {%- if selected_variant.inventory_management == 'shopify' -%} + {%- if selected_variant.inventory_quantity > 0 -%} + {%- if selected_variant.inventory_quantity <= block.settings.inventory_threshold -%}

@@ -265,14 +265,14 @@ name="quantity" id="Quantity-{{ section.id }}" data-cart-quantity="{{ cart_qty }}" - data-min="{{ product.selected_or_first_available_variant.quantity_rule.min }}" - min="{{ product.selected_or_first_available_variant.quantity_rule.min }}" - {% if product.selected_or_first_available_variant.quantity_rule.max != null %} - data-max="{{ product.selected_or_first_available_variant.quantity_rule.max }}" - max="{{ product.selected_or_first_available_variant.quantity_rule.max }}" + data-min="{{ selected_variant.quantity_rule.min }}" + min="{{ selected_variant.quantity_rule.min }}" + {% if selected_variant.quantity_rule.max != null %} + data-max="{{ selected_variant.quantity_rule.max }}" + max="{{ selected_variant.quantity_rule.max }}" {% endif %} - step="{{ product.selected_or_first_available_variant.quantity_rule.increment }}" - value="{{ product.selected_or_first_available_variant.quantity_rule.min }}" + step="{{ selected_variant.quantity_rule.increment }}" + value="{{ selected_variant.quantity_rule.min }}" form="{{ product_form_id }}" > {%- liquid - assign volume_pricing_array = product.selected_or_first_available_variant.quantity_price_breaks | sort: 'quantity' | reverse - assign current_qty_for_volume_pricing = cart_qty | plus: product.selected_or_first_available_variant.quantity_rule.min + assign volume_pricing_array = selected_variant.quantity_price_breaks | sort: 'quantity' | reverse + assign current_qty_for_volume_pricing = cart_qty | plus: selected_variant.quantity_rule.min if cart_qty > 0 - assign current_qty_for_volume_pricing = cart_qty | plus: product.selected_or_first_available_variant.quantity_rule.increment + assign current_qty_for_volume_pricing = cart_qty | plus: selected_variant.quantity_rule.increment endif -%} {%- if product.quantity_price_breaks_configured? -%} - {%- if product.selected_or_first_available_variant.quantity_price_breaks.size > 0 -%} - {%- assign variant_price_compare = product.selected_or_first_available_variant.compare_at_price -%} + {%- if selected_variant.quantity_price_breaks.size > 0 -%} + {%- assign variant_price_compare = selected_variant.compare_at_price -%}

{%- if variant_price_compare -%}
@@ -311,7 +311,7 @@
{%- endif -%} {%- if current_qty_for_volume_pricing < volume_pricing_array.last.minimum_quantity -%} - {%- assign variant_price = product.selected_or_first_available_variant.price + {%- assign variant_price = selected_variant.price | money_with_currency -%} @@ -333,10 +333,10 @@ {%- endif -%}
{%- else -%} - {%- assign variant_price = product.selected_or_first_available_variant.price + {%- assign variant_price = selected_variant.price | money_with_currency -%} - {%- assign variant_price_compare = product.selected_or_first_available_variant.compare_at_price -%} + {%- assign variant_price_compare = selected_variant.compare_at_price -%}
{%- if variant_price_compare -%}
@@ -368,46 +368,46 @@ {%- endif -%}
- {%- if product.selected_or_first_available_variant.quantity_rule.increment > 1 -%} + {%- if selected_variant.quantity_rule.increment > 1 -%} {{- 'products.product.quantity.multiples_of' - | t: quantity: product.selected_or_first_available_variant.quantity_rule.increment + | t: quantity: selected_variant.quantity_rule.increment -}} {%- endif -%} - {%- if product.selected_or_first_available_variant.quantity_rule.min > 1 -%} + {%- if selected_variant.quantity_rule.min > 1 -%} {{- 'products.product.quantity.minimum_of' - | t: quantity: product.selected_or_first_available_variant.quantity_rule.min + | t: quantity: selected_variant.quantity_rule.min -}} {%- endif -%} - {%- if product.selected_or_first_available_variant.quantity_rule.max != null -%} + {%- if selected_variant.quantity_rule.max != null -%} {{- 'products.product.quantity.maximum_of' - | t: quantity: product.selected_or_first_available_variant.quantity_rule.max + | t: quantity: selected_variant.quantity_rule.max -}} {%- endif -%}
{%- if product.quantity_price_breaks_configured? -%} - {%- if product.selected_or_first_available_variant.quantity_price_breaks.size > 0 -%} + {%- if selected_variant.quantity_price_breaks.size > 0 -%} {{ 'products.product.volume_pricing.title' | t }}
  • - {{ product.selected_or_first_available_variant.quantity_rule.min }}+ - {%- assign price = product.selected_or_first_available_variant.price + {{ selected_variant.quantity_rule.min }}+ + {%- assign price = selected_variant.price | money_with_currency -%} {{- 'sections.quick_order_list.each' | t: money: price -}}
  • - {%- for price_break in product.selected_or_first_available_variant.quantity_price_breaks -%} + {%- for price_break in selected_variant.quantity_price_breaks -%} {%- assign price_break_price = price_break.price | money_with_currency -%}
  • @@ -420,7 +420,7 @@
  • {%- endfor -%}
- {%- if product.selected_or_first_available_variant.quantity_price_breaks.size >= 3 -%} + {%- if selected_variant.quantity_price_breaks.size >= 3 -%} {%- liquid - assign volume_pricing_array = product.selected_or_first_available_variant.quantity_price_breaks | sort: 'quantity' | reverse - assign current_qty_for_volume_pricing = cart_qty | plus: product.selected_or_first_available_variant.quantity_rule.min + assign volume_pricing_array = selected_variant.quantity_price_breaks | sort: 'quantity' | reverse + assign current_qty_for_volume_pricing = cart_qty | plus: selected_variant.quantity_rule.min if cart_qty > 0 - assign current_qty_for_volume_pricing = cart_qty | plus: product.selected_or_first_available_variant.quantity_rule.increment + assign current_qty_for_volume_pricing = cart_qty | plus: selected_variant.quantity_rule.increment endif -%} {%- if product.quantity_price_breaks_configured? -%} - {%- if product.selected_or_first_available_variant.quantity_price_breaks.size > 0 -%} - {%- assign variant_price_compare = product.selected_or_first_available_variant.compare_at_price -%} + {%- if selected_variant.quantity_price_breaks.size > 0 -%} + {%- assign variant_price_compare = selected_variant.compare_at_price -%}
{%- if variant_price_compare -%}
@@ -226,7 +230,7 @@
{%- endif -%} {%- if current_qty_for_volume_pricing < volume_pricing_array.last.minimum_quantity -%} - {%- assign variant_price = product.selected_or_first_available_variant.price + {%- assign variant_price = selected_variant.price | money_with_currency -%} @@ -248,10 +252,10 @@ {%- endif -%}
{%- else -%} - {%- assign variant_price = product.selected_or_first_available_variant.price + {%- assign variant_price = selected_variant.price | money_with_currency -%} - {%- assign variant_price_compare = product.selected_or_first_available_variant.compare_at_price -%} + {%- assign variant_price_compare = selected_variant.compare_at_price -%}
{%- if variant_price_compare -%}
@@ -283,46 +287,46 @@ {%- endif -%}
- {%- if product.selected_or_first_available_variant.quantity_rule.increment > 1 -%} + {%- if selected_variant.quantity_rule.increment > 1 -%} {{- 'products.product.quantity.multiples_of' - | t: quantity: product.selected_or_first_available_variant.quantity_rule.increment + | t: quantity: selected_variant.quantity_rule.increment -}} {%- endif -%} - {%- if product.selected_or_first_available_variant.quantity_rule.min > 1 -%} + {%- if selected_variant.quantity_rule.min > 1 -%} {{- 'products.product.quantity.minimum_of' - | t: quantity: product.selected_or_first_available_variant.quantity_rule.min + | t: quantity: selected_variant.quantity_rule.min -}} {%- endif -%} - {%- if product.selected_or_first_available_variant.quantity_rule.max != null -%} + {%- if selected_variant.quantity_rule.max != null -%} {{- 'products.product.quantity.maximum_of' - | t: quantity: product.selected_or_first_available_variant.quantity_rule.max + | t: quantity: selected_variant.quantity_rule.max -}} {%- endif -%}
{%- if product.quantity_price_breaks_configured? -%} - {%- if product.selected_or_first_available_variant.quantity_price_breaks.size > 0 -%} + {%- if selected_variant.quantity_price_breaks.size > 0 -%} {{ 'products.product.volume_pricing.title' | t }}
  • - {{ product.selected_or_first_available_variant.quantity_rule.min }}+ - {%- assign price = product.selected_or_first_available_variant.price + {{ selected_variant.quantity_rule.min }}+ + {%- assign price = selected_variant.price | money_with_currency -%} {{ 'sections.quick_order_list.each' | t: money: price -}}
  • - {%- for price_break in product.selected_or_first_available_variant.quantity_price_breaks -%} + {%- for price_break in selected_variant.quantity_price_breaks -%} {%- assign price_break_price = price_break.price | money_with_currency -%}
  • @@ -336,7 +340,7 @@
  • {%- endfor -%}
- {%- if product.selected_or_first_available_variant.quantity_price_breaks.size >= 3 -%} + {%- if selected_variant.quantity_price_breaks.size >= 3 -%}