Conditional dropdown messaging in Shopify theme - shopify

I am trying to build in conditional messaging/labels in a variant (sizing) dropdown in a Shopify theme, based on availability. (paraphrase in the code snippet below - should give sizes and a message related to availability). I used a few different documentation links to get there:
https://shopify.dev/docs/themes/liquid/reference/objects/product_option
https://shopify.github.io/liquid-code-examples/example/product-variant-selector
And came up with the following, written in product_template.liquid:
<select id="ProductSelect-{{ forloop.index0 }}" data-index="option{{ forloop.index }}">
{%- if {{ product_option.name == "size" }} -%}
{%- for value in option.values -%}
{%- if product.variants[forloop.index0].available -%}
<option value="{{ value | escape }} - ships faster "{% if option.selected_value == value %} selected="selected"{% endif %}>
{{ value | escape }}
</option>
{%- else -%}
<option value="{{ value | escape }} - ships longer "{% if option.selected_value == value %} selected="selected"{% endif %}>
{{ value | escape }}
</option>
{%- endif -%}
{%- endfor -%}
{%- endif -%}
</select>
On trying to save I got this error: This file contains the following errors: Line 101 — Liquid syntax error: Unexpected character { in "{{ product_option.name == "size" }}"
I'm generally okay with Liquid, but Shopify objects haven't totally clicked just yet. What's going wrong here, and how do I select by the size variant?

Okay after checking the code finds the issue, you can't use the {{}} inside a condition check, these {{}} are used to output the liquid output. so simply your code is like this and works well.
<select id="ProductSelect-{{ forloop.index0 }}" data-index="option{{ forloop.index }}">
{%- if product_option.name == "size" -%}
{%- for value in option.values -%}
{%- if product.variants[forloop.index0].available -%}
<option value="{{ value | escape }} - ships faster "{% if option.selected_value == value %} selected="selected"{% endif %}>
{{ value | escape }}
</option>
{%- else -%}
<option value="{{ value | escape }} - ships longer "{% if option.selected_value == value %} selected="selected"{% endif %}>
{{ value | escape }}
</option>
{%- endif -%}
{%- endfor -%}
{%- endif -%}
</select>

Related

How to add Max Inventory, Limit Quantity Selector, and Callback Function on Prestige Theme in Shopify

My expectation of functionality would be that if a product has an available quantity of 2 that the quantity selector would max out at 2 and not allow the customer to select a qty of 5+ before clicking add to cart. Please help in out in figuring out that which files I should change in Sections and what additional code I should add to it. Thanks in advance!
<div class="no-js ProductForm__Option">
<div class="Select Select--primary">
{%- render 'icon' with 'select-arrow' -%}
<select id="product-select-{{ product.id }}" name="id" title="Variant">
{%- for variant in product.variants -%}
<option {% if variant == selected_variant %}selected="selected"{% endif %} {% unless variant.available %}disabled="disabled"{% endunless %} value="{{ variant.id }}" data-sku="{{ variant.sku }}">{{ variant.title }} - {{ variant.price | money }}</option>
{%- endfor -%}
</select>
</div>
</div>
{%- else -%}
<input type="hidden" name="id" data-sku="{{ selected_variant.sku }}" value="{{ selected_variant.id }}">
{%- endunless -%}
{%- if section.settings.show_quantity_selector -%}
{%- if show_option_label -%}
<span class="ProductForm__Label">{{ 'product.form.quantity' | t }}:</span>
{%- endif -%}
<div class="ProductForm__QuantitySelector">
<div class="QuantitySelector QuantitySelector--large">
{%- assign quantity_minus_one = line_item.quantity | minus: 1 -%}
<span class="QuantitySelector__Button Link Link--secondary" data-action="decrease-quantity">{% render 'icon' with 'minus' %}</span>
<input type="text" class="QuantitySelector__CurrentQuantity" pattern="[0-9]*" name="quantity" value="1" aria-label="{{ 'product.form.quantity' | t }}">
<span class="QuantitySelector__Button Link Link--secondary" data-action="increase-quantity">{% render 'icon' with 'plus' %}</span>
</div>
</div>
{%- else -%}
<input type="hidden" name="quantity" value="1">
{%- endif -%}
{%- if section.settings.show_inventory_quantity -%}
{%- assign hide_inventory_quantity_by_default = false -%}
{%- if selected_variant.inventory_management == blank or selected_variant.inventory_quantity <= 0 -%}
{%- assign hide_inventory_quantity_by_default = true -%}
{%- endif -%}
{%- if section.settings.inventory_quantity_threshold != 0 and selected_variant.inventory_quantity > section.settings.inventory_quantity_threshold -%}
{%- assign hide_inventory_quantity_by_default = true -%}
{%- endif -%}
<p class="ProductForm__Inventory Text--subdued" {% if hide_inventory_quantity_by_default %}style="display: none"{% endif %}>
{%- if section.settings.inventory_quantity_threshold == 0 -%}
{{- 'product.form.inventory_quantity_count' | t: count: selected_variant.inventory_quantity -}}
{%- else -%}
{{- 'product.form.low_inventory_quantity_count' | t: count: selected_variant.inventory_quantity -}}
{%- endif -%}
</p>
{%- endif -%}
</div>

Shopify Liquid attributes inside select tag

I want to ask that what are the following 2 attributes in side select tag. I searched them in theme.js file but they are not present there ?
data-product-select
data-free-shipping=true
<select name="id" class="no-js" data-product-select data-free-shipping=true >
{% for variant in product.variants %}
<option
{% if variant == current_variant %}selected="selected"{% endif %}
{% unless variant.available %}disabled="disabled"{% endunless %}
value="{{ variant.id }}" data-variant-name="{{ variant.title }}" data-variant-image="{{ variant.image.src | img_url }}"
data-sale={% if variant.compare_at_price > variant.price %}true {% else %}false{% endif %}
{% if thirty_days_after_publication > todays_date %}data-new-product=true{% endif %}>
{{ variant.title }}
</option>
{% endfor %}
</select>

How can I change dropdown selection based of radio buttons selection?

I have shopify application where user can choose different variants of products.
I'd like to change the product dropdown based on the selection of radio button, my product page looks like this.
I'd like to change the dropdown value based of the radio button selection.
This my dropdown code:
<select name="id" id="ProductSelect-{{ section_id }}" class="product-single__variants no-js">
{% for variant in product.variants %}
{% if variant.available %}
<option {% if variant == product.selected_or_first_available_variant %}
selected="selected" {% endif %}
value="{{ variant.id }}">
{{ variant.title }} - {{ variant.price | money_with_currency }}
</option>
{% else %}
<option disabled="disabled">
{{ variant.title }} - {{ 'products.product.sold_out' | t }}
</option>
{% endif %}
{% endfor %}
And this is my radio buttons code
<fieldset class="variant-input-wrap"
name="{{ option.name }}"
data-index="option{{ option_index }}"
id="ProductSelect-{{ section_id }}-option-{{ forloop.index0 }}">
{%- for value in option.values -%}
{%- assign product_available = true -%}
{%- if product.options.size == 1 -%}
{%- assign product_available = product.variants[forloop.index0].available -%}
{%- endif -%}
<div
class="variant-input"
data-index="option{{ option_index }}"
data-value="{{ value | escape }}">
<input type="radio"
{% if option.selected_value == value %} checked="checked"{% endif %}
value="{{ value | escape }}"
data-index="option{{ option_index }}"
name="{{ option.name }}"
class="variant__input-{{ section_id }}{% unless product_available %} disabled{% endunless %}{% if is_color %} variant__input--color-swatch-{{ section_id }}{% endif %}"
{% if is_color %} data-color-name="{{ value | escape }}"{% endif %}
{% if is_color %} data-color-index="{{ color_option_index }}"{% endif %}
id="ProductSelect-{{ section_id }}-option-{{ option.name | handleize }}-{{ value | url_encode }}">
{%- if is_color -%}
{%- assign color_image = value | handle | append: '.' | append: swatch_file_extension | asset_img_url: '50x' | prepend: 'https:' | split: '?' | first -%}
{%- assign color_swatch_fallback = value | split: ' ' | last | handle -%}
<label
for="ProductSelect-{{ section_id }}-option-{{ option.name | handleize }}-{{ value | url_encode }}"
class="variant__button-label color-swatch color-swatch--{{ value | handle }}{% unless product_available %} disabled{% endunless %}"
style="background-image: url({{ color_image }}); background-color: {{ color_swatch_fallback }};"
>
{{ value | escape }}
</label>
{%- else -%}
<label
for="ProductSelect-{{ section_id }}-option-{{ option.name | handleize }}-{{ value | url_encode }}"
class="variant__button-label{% unless product_available %} disabled{% endunless %}">{{ value | escape }}</label>
{%- endif -%}
</div>
{%- endfor -%}
</fieldset>
There are a number of different ways to go about this, most of which involve JavaScript. Below are two different approaches.
The ideal way to go about this would be to remove the <select> all together and use the Shopify Ajax API to add the item to the cart. By using this method, you can get the selected variant from the <radio> directly instead of the <select>.
The hacky way to do this would be to set the select visibility to hidden and use JavaScript to set the <select> selected <option> when a <radio> value is changed.

Shopify adding a class to an existing class if condition is true

Currently working on shopify theme and I'm trying to hide the sold out variants of a product. The theme is prestige if that matters or not.
I'm trying to do it the easy way since no other variants available works for me. What I'm trying to do is to add a class to an existing class if the product variant quantity is 0.
Example:
{% for variant in product.variants %}
{% if variant.inventory_quantity == 0 %}class{% endif %}{% endfor %}
How my code looks:
{%- for value in option.values -%}
<li class="HorizontalList__Item {% for variant in product.variants %}{% if variant.inventory_quantity < 1 %}{{ variant.inventory_quantity}}{% endif %}{% endfor %}">
<input id="option-{{ section.id }}-{{ forloop.parentloop.index0 }}-{{ forloop.index0 }}" class="SizeSwatch__Radio" type="radio" name="option-{{ forloop.parentloop.index0 }}" value="{{ value | escape }}" {% if value == option.selected_value %}checked="checked"{% endif %} data-option-position="{{ option.position }}">
<label for="option-{{ section.id }}-{{ forloop.parentloop.index0 }}-{{ forloop.index0 }}" class="SizeSwatch">{{ value }}</label>
</li>
{%- endfor -%}
I used {{variant.inventory_quantity }} to see what returns and it returns 0 for all. Then I removed {% if variant.inventory_quantity < 1 %} to see what's wrong and it returned all product variant quantity in my case 014673.
Because of the {%- for value in option.values -%} it checks all at once and it adds the class for all list even if the variant invetory quantity it's 0 or not.
Is there a way to append that class to the list outside the code if variant.inventory_quantity == 0?
Or something like if option is disabled to hide the list entirely? Because I'm checking if the variant is available or not here:
<select id="product-select-{{ product.id }}" name="id" title="Variant">
{%- for variant in product.variants -%}
<option {% if variant == selected_variant %}selected="selected"{% endif %} {% unless variant.available %}disabled="disabled"{% endunless %} value="{{ variant.id }}" data-sku="{{ variant.sku }}">{{ variant.title }} - {{ variant.price | money }}</option>
{%- endfor -%}
</select>
In my case the product variant 38 has quantity 0. Link to example https://lizzetstore.ro/collections/paltoane/products/palton-asimetric-negru
In that case if you are SURE that there will be a single variant you can do this.
<ul>
{%- for variant in product.variants -%}
<li {% unless variant.available %}class="soldout"{% endunless %}>
<input type="radio" name="id" value="{{variant.id}}" id="variant-{{variant.id}}" {% unless variant.available %} disabled{% endunless %}>
<label for="variant-{{variant.id}}">{{ variant.option1 }}</label>
</li>
{%- endfor -%}
</ul>
You don't need the select that you are generating. We are using the radio instead to pass the name="id" input.
Please have in mind that this will work only if you have a single option! This means that if you have an additional option it will not work properly.
But this is the way to do it without the use of any javascript.

How to set the default size selector to be unselected?

I'm looking to default my size variant selector to not select anything. Currently, it's selecting the smallest variant size. I want to change it so none of the variants are selected to start out with. Here's a perfect example on Urban Outfitters of how I want it to look. Shopify describes how to remove it from every theme but Brooklyn (which is what I'm using), but I'm thinking this would an easy fix to just have it not selected on anything. Here's my code.
<select name="id" id="ProductSelect" class="product-single__variants
no-js">
{% for variant in product.variants %}
{% if variant.available %}
<option {% if variant == product.selected_or_first_available_variant
%}
selected="selected" {% endif %}
data-sku="{{ variant.sku }}"
value="{{ variant.id }}">
{{ variant.title }} - {{ variant.price | money_with_currency }}
</option>
{% else %}
<option disabled="disabled">
{{ variant.title }} - {{ 'products.product.sold_out' | t }}
</option>
{% endif %}
{% endfor %}
</select>
If you are using the Button style selector just add the following code at the end of theme.js.liquid
This will reset the checkbox selection.
$(document).ready(function() {
$('.product-form__item input[type=radio]').prop('checked', false);
});