How to set the default size selector to be unselected? - shopify

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);
});

Related

Conditional dropdown messaging in Shopify theme

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>

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>

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.

Shopify - Is it possible to filter by 'Vendor'

it seems Shopify only allows for filtering by tags. If you want to filter by Vendor (which is a standard Shopify Field) you first need to create tags with the same name and manually use those tags in the filter sidebar.
Is this correct? Seems very unnecessary and more importantly makes dynamic updates difficult.
After almost 2 days of trial and error, plus lots of digging into forums and the documentation, I came up with this bit of code to create a working Vendor filter.
Please note the following:
The classes and IDs were created by the Modular Shopify theme. I just reused them, please use the appropriate classes/IDs for your theme.
The Vendor filter does not work with the tag filter or with the sort by option. Those were hidden as explained below.
<div class="grid-filter block">
{% comment %} New Vendor Filter {% endcomment %}
<div class="tag-filter block">
<label for="#vendorFilter">Browse by Vendor</label>
<span class="selectArrow"></span>
<select class="vendorFilter filter" id="vendorFilter" onChange="window.location.href=this.value">
<option value="/collections/all">All</option>
{% for product_vendor in shop.vendors %}
{% if collection.current_vendor contains product_vendor %}
<option value="{{ product_vendor | url_for_vendor }}" selected>{{ product_vendor }}</option>
{% else %}
<option value="{{ product_vendor | url_for_vendor }}">{{ product_vendor }}</option>
{% endif %}
{% endfor %}
</select>
</div>
{% comment %} END New Vendor Filter {% endcomment %}
{% if show_filter == true and collection.current_vendor == blank %}
<div class="tag-filter block">
<label for="#tagFilter">{{ 'collections.tag_filtering.filter_label' | t }}</label>
<span class="selectArrow"></span>
<select class="tagFilter filter" id="tagFilter">
<option value="/collections/{{ collection.handle }}">{{ 'collections.tag_filtering.default_filter' | t }}</option>
{% for tag in collection.all_tags %}
{% if current_tags contains tag %}
<option value="/collections/{{ collection.handle }}/{{ tag | handle }}" selected>{{ tag }}</option>
{% else %}
<option value="/collections/{{ collection.handle }}/{{ tag | handle }}">{{ tag }}</option>
{% endif %}
{% endfor %}
</select>
</div>
{% endif %}
{% if show_sort_filter == true and collection.current_vendor == blank %}
<div class="collectionGrid-filter block">
<label for="#collectionFilter">{{ 'collections.sorting_dropdown.label' | t }}</label>
<span class="selectArrow"></span>
{% assign sort_by = collection.sort_by %}
<select class="filter" id="collectionFilter">
<option value="">{{ 'collections.sorting_dropdown.all' | t }}</option>
<option value="best-selling" {% if sort_by == "best-selling" %}selected{% endif %}>{{ 'collections.sorting_dropdown.best_selling' | t }}</option>
<option value="price-ascending" {% if sort_by == "price-ascending" %}selected{% endif %}>{{ 'collections.sorting_dropdown.price_ascending' | t }}</option>
<option value="price-descending" {% if sort_by == "price-descending" %}selected{% endif %}>{{ 'collections.sorting_dropdown.price_descending' | t }}</option>
<option value="title-ascending" {% if sort_by == "title-ascending" %}selected{% endif %}>{{ 'collections.sorting_dropdown.title_ascending' | t }}</option>
<option value="title-descending" {% if sort_by == "title-descending" %}selected{% endif %}>{{ 'collections.sorting_dropdown.title_descending' | t }}</option>
<option value="created-ascending" {% if sort_by == "created-ascending" %}selected{% endif %}>{{ 'collections.sorting_dropdown.created_ascending' | t }}</option>
<option value="created-descending" {% if sort_by == "created-descending" %}selected{% endif %}>{{ 'collections.sorting_dropdown.created_descending' | t }}</option>
</select>
</div>
{% endif %}
</div>
Here are the important things worth mentioning:
The onChange="window.location.href=this.value" is a bit of JavaScript necessary to grab the value from the vendor dropdown and to update the web address (URL).
The for product_vendor in shop.vendors is a bit of Liquid necessary to grab all vendors and provide them one at a time to the dropdown.
The if collection.current_vendor contains product_vendor is also a bit of Liquid necessary when the vendor filter is in use. It checks for an active vendor filter and selects it in the dropdown after the page has reloaded.
The {{ product_vendor | url_for_vendor }} provides the URL used by the JavaScript in #1 above.
The {{ product_vendor }} provides the actual vendor name to the list.
The and collection.current_vendor == blank tells the page to hide the Tag and Sort dropdowns if a vendor filter was selected.
Here are the Shopify Docs which really helped me. This assumes you already understand the for loop and if statements which are a basic component of programming.
Understanding shop.vendors
Understanding collection.current_vendor
Understanding url_for_vendor
Understanding product_vendor
Understanding blank
Shopify doesn't allow for filtration by vendor at the moment (while keeping the collection relation to the vendor).
This was mentioned in a recent live Q&A with Shopify and it was confirmed that they are testing this. More info can be seen here: https://youtu.be/MDqDIIyxIcU?t=2078
You have to stick with the tags for now.

Remove specific product option inside a dropdown

I wonder if is it possible to remove specific product option dropdown and display it inside a <p> tag or just a normal string? Imagine I have 3 product options:
Color
Size
Type
We all know that all those options will be displayed inside a dropdown menu. What about like I wanted to display the Size option as a normal string or text? How can we do that?
Here's an image to make it clearer.
product.liquid
<select name="id" id="ProductSelect" class="product-single__variants">
{% 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>
I just found the answer for this. I'll post it in here to help others with the same problem as I have.
In product.liquid:
<!-- product options -->
{% capture option_titles %}Size,Flavor{% endcapture %}
{% assign option_titles = option_titles | split:',' %}
{% for option in product.options %}
{% if option_titles contains option %}
{% capture option_index %}option{{ forloop.index }}{% endcapture %}
{% assign option_values = product.variants | map: option_index | uniq %}
{% if option == 'Flavor' and option_values.size > 1 %}
<label for="option">{{ option }}</label>
{{ option_values | join:', ' }}
{% elsif option_values.size == 1 %}
<label for="option">{{ option }}</label>
{{ option_values }}
{% endif %}
{% endif %}
{% endfor %}
<!-- end product options --->
You have to modify product.liquid template and instead of that drop down you have to create that as a LI or Text the you are set for that . 😃