Display name of colour variant selected on Shopify - shopify

On this page I have some swatches that when selected they don't display the variant name.
Basically, I need to add a paragraph text under the variant swatches that indicate the name of the variant selected...
I'm not good on javascript and online I didn't found any complete guide about that
Thanks a lot for your help!

That looks like a theme I've seen before. If I recall correctly, that theme uses a file called swatch.liquid to make those colour circles. I'm writing this answer using a version of a swatch file that I happen to have on hand, so the specific code may not be exactly what your theme has, but hopefully I'll be able to help you find what you need.
Here is the code from my swatch.liquid file that prints out the swatches. (This is roughly the bottom half of the swatch.liquid file, found in the snippets folder)
<div class="product-options">
<div class="swatch clearfix" data-option-index="{{ option_index }}">
<div class="header">
{% assign values = '' %}
{% for variant in product.variants %}
{% assign value = variant.options[option_index] %}
{% unless values contains value %}
{% assign values = values | join: ',' %}
{% assign values = values | append: ',' | append: value %}
{% assign values = values | split: ',' %}
<div data-value="{{ value | escape }}" class="swatch-element {% if is_color %}color {% else %}size {% endif %}{{ value | handle }} {% if variant.available %}available{% else %}soldout{% endif %}">
<input id="swatch-{{ option_index }}-{{ value | handle }}" type="radio" name="option-{{ option_index }}" value="{{ value | escape }}"{% if forloop.first %} checked{% endif %} {% unless variant.available %}disabled{% endunless %} />
{% if is_color %}
<label for="swatch-{{ option_index }}-{{ value | handle }}" style="background-color: {{ value | split: ' ' | last | handle }};">
<img class="crossed-out" src="{{ 'soldout.png' | asset_url }}" />
</label>
{% else %}
<label for="swatch-{{ option_index }}-{{ value | handle }}">
{{ value }}
<img class="crossed-out" src="{{ 'soldout.png' | asset_url }}" />
</label>
{% endif %}
</div>
{% endunless %}
{% if variant.available %}
<script>
jQuery('.swatch[data-option-index="{{ option_index }}"] .{{ value | handle }}').removeClass('soldout').addClass('available').find(':radio').removeAttr('disabled');
</script>
{% endif %}
{% endfor %}
</div>
</div>
</div>
That looks a bit messy, I know - so let's try and find the part that you'll want to modify.
Here's the part from the above example that prints the swatch element when the swatch is a colour:
{% if is_color %}
<label for="swatch-{{ option_index }}-{{ value | handle }}" style="background-color: {{ value | split: ' ' | last | handle }};">
<img class="crossed-out" src="{{ 'soldout.png' | asset_url }}" />
</label>
{% else %}
In between those <label> tags you should be able to add any text that you need - such as a <span class="swatch-color-name">{{ value }}</span>
Adding extra HTML in here may throw off the current styles of your page, so you may need to add some extra CSS rules to apply to any elements you add to get things to line up nicely again.
Hope this helps!
NB: If you're using Chrome, there's a useful extension called "Search All" that lets you search your entire Shopify theme if you're having trouble finding the file that needs to be edited. Searching for keywords like 'color' or 'variant.options' should help point you in the right direction.

Related

Metfields - Shopify - Code Snippet (trying to add product color swatch via metafield and Code Snippet)

I'm trying to display a color-swatch on the product page in which clicking on a product's color redirects to another product url. The way I've done this is set-up the metafields in Shopify Settings (picture displayed below)
[1]: https://i.stack.imgur.com/RsSCa.png
And then created a Code Snippet in the theme's code called " linkedProducts.liquid", code displayed below:
{% assign linked = product.metafields.my_fields.linked_products | split: ',' %}
{% assign linkedcolors = product.metafields.my_fields.linked_products_colors | split: ',' %}
{% assign linkednames = product.metafields.my_fields.linked_products_names | split: ',' %}
{% assign size = linked | size %}
{% assign currentHandle = product.handle %}
{% if size > 0 %}
<div class="linkedColors custom_swatch_elements">
<label class="single-option-radio__label label-color_swatches" data-label="Color">
Color
</label>
<div class="swatch clearfix" data-option-index="1">
{% for i in (1..size) %}
{% assign index = i | minus:1 %}
{% assign color = linkedcolors[index] | strip %}
{% assign name = linkednames[index] | strip %}
{% assign url = linked[index] | strip %}
<a data-value="{{ color }}" class="swatch-element {% if currentHandle == url %}active{%endif%}" href="{{shop.url}}/products/{{url}}">
<label class=" linkedLabel text-center text-ellipsis" style="background:{{color}};"></label>
<div class="tooltip spacer-bottom text-center">{{ name }}</div>
</a>
{% endfor %}
</div>
</div>
{% endif %}
<style>
.linkedColors{
}
.linkedLabel{
cursor:pointer
}
.swatch-element.active{
border:1px solid #292929 !important;
}
</style>
The store theme used is debutify (v 4.9.0), store url https://miesha.com.au/collections/bottoms/products/aura-scrunch-black
As you can see, the product color swatch does not show (if you see color swatches there it is the native debutify color swatch addon (as shown when inspected).
Please do let me know if there is a solution to this as it is giving me a headache.

Display Items in Collection that Do Not Exist In Shopping Cart Shopify

I'm trying to iterate over items in the shopping cart and generate an upsell div with products NOT in the cart. Below is the code I have so far, but I run into issues when adding two items to cart running the loop twice generating the html twice. Any ideas on how to resolve it? I'm stumped.
{% for item in cart.items %} // iterates over items in cart
{% if item.product.id == 4456879040188 %} // checks if product id matches in item in cart
<div class="upsell-pop" style="text-align:center; width: 100%;">
<h4>Frequently bought together</h4>
{% for prod in collections.upsell.products %} // iterates products in collection upsell
{% unless prod.handle contains "product-name" %} // shows only prods that do not contain url handle
<div>
<span class="upsell-title">{{ prod.title }}</span>
<span class="upsell-price">{{ prod.metafields["meta"]["promo"] }} {{ prod.price | money }}</span>
<img src="{{ prod.featured_image | img_url: '200x' }}" />
<a class="btn-product" href="{{prod.url}}">View Product</a>
</div>
{% endunless %}
{% endfor %}
</div>
{% endif %}
{% endfor %}
Another thought is to somehow check to see if product is NOT in cart items inside to replace the existing "unless" statement, but not sure how to code it.
{% unless cart.items exist then %} // I know this is not correct syntax
<div>
<span class="upsell-title">{{ prod.title }}</span>
<span class="upsell-price">{{ prod.metafields["meta"]["promo"] }} {{ prod.price | money }}</span>
<img src="{{ prod.featured_image | img_url: '200x' }}" />
<a class="btn-product" href="{{prod.url}}">View Product</a>
</div>
{% endunless %}
On my mind, there are two steps here.
First, capture your cart content to get string to compare to when you loop through your upsell collection. This could be something like that:
{%- capture cart_items -%}
{% for item in cart.items %}
{{ item.product.handle }}{% unless forloop.last %} , {% endunless %}
{% endfor %}
{%- endcapture -%}
Then loop through your collection while checking your string does not contain the handle of the current product at each iteration:
{% for product in collections['upsell'].products %}
{% unless cart_items contains product.handle %}
{{ product.title }}
{% endunless %}
{% endfor %}
Remarks:
Snippet 1 => In line_item (here called item because it's shorter to write) object you may access product object attributes: item.product.product_attr_needed
Snippet 2 => To access directly a collection object using its handle you must use collections + square brackets containing collection handle + attribute. Here 'upsell' is the handle of your upsell collection.
Not tested but this should work.
HTH

Assigning a collection to a custom created collection page in Shopify?

I am using a free Venture theme on Shopify and i am trying to make a custom collection page.
I found a solution in stackoverflow but it was able to help someplace.
How to add collection.liquid to an existing page?
The summery of the solution is:
Copy everything that's in collection.liquid and paste it into a new snippet (let's say you call it collection-copy.liquid).
Then, in the page you want to add the collections page to, just add {% include 'collection-copy' %}
This solution worked well but there is one more issue for me. In the custom created page it says "Sorry, there are no products in this collection" In the customization of the same page there is a "collection" section. But in the "collection" section there is no option to choose a collection. There is only "Enable tag filtering" and "Enable sorting" check boxes.
Webpage: https://mottomfreedom.com/pages/less-is-more
Do you have any idea of assigning a collection with this custom created snippet?
{% paginate collections[settings.frontpage_collection].products by 20 %}
<div class="page-width">
<header class="grid medium-up--grid--table section-header small--text-center">
<div class="grid__item medium-up--one-half section-header__item">
<h1 class="section-header__title">
{{ collection.title }}
{% if current_tags %}
– {% assign title_tags = current_tags | join: ', ' %}
{{ title_tags }}
{% endif %}
</h1>
{% if collection.description != blank %}
<div class="section-header__subtext rte">
{{ collection.description }}
</div>
{% endif %}
</div>
<div class="grid__item medium-up--one-half medium-up--text-right section-header__item">
{% section 'collection-filters' %}
</div>
</header>
<div class="grid grid--no-gutters grid--uniform">
{% for product in collection.products %}
<div class="grid__item small--one- medium-up--one-third">
{% include 'product-card', product: product %}
</div>
{% else %}
{% comment %}
Add default products to help with onboarding for collections/all only.
The onboarding styles and products are only loaded if the
store has no products.
{% endcomment %}
{% if shop.products_count == 0 %}
<div class="grid__item">
<div class="grid grid--no-gutters grid--uniform">
{% assign collection_index = 1 %}
{% for i in (1..10) %}
{% case i %}
{% when 7 %}
{% assign collection_index = 1 %}
{% when 8 %}
{% assign collection_index = 2 %}
{% when 9 %}
{% assign collection_index = 3 %}
{% when 10 %}
{% assign collection_index = 4 %}
{% endcase %}
<div class="grid__item small--one-half medium-up--one-fifth">
<a href="/admin/products" class="product-card">
<div class="product-card__image-container">
<div class="product-card__image-wrapper">
<div class="product-card__image">
{% capture current %}{% cycle 1, 2, 3, 4, 5, 6 %}{% endcapture %}
{{ 'product-' | append: current | placeholder_svg_tag: 'placeholder-svg' }}
</div>
</div>
</div>
<div class="product-card__info">
<div class="product-card__name">{{ 'homepage.onboarding.product_title' | t }}</div>
<div class="product-card__price">
$19.99
</div>
</div>
<div class="product-card__overlay">
{% assign view_string_length = 'products.product.view' | t | size %}
<span class="btn product-card__overlay-btn {% if view_string_length > 8 %} btn--narrow{% endif %}">{{ 'products.product.view' | t }}</span>
</div>
</a>
</div>
{% assign collection_index = collection_index | plus: 1 %}
{% endfor %}
</div>
</div>
{% else %}
{% comment %}
If collection exists but is empty, display message
{% endcomment %}
<div class="grid__item small--text-center">
<p>{{ 'collections.general.no_matches' | t }}</p>
</div>
{% endif %}
{% endfor %}
</div>
{% if paginate.pages > 1 %}
<div class="pagination">
{{ paginate | default_pagination | replace: '« Previous', '←' | replace: 'Next »', '→' }}
</div>
{% endif %}
</div>
{% endpaginate %}
You are right about giving some time before accepting an answer :)) The solution worked but forced me to create 1 page and 4 liquid files per collection. And at the end, i figured out that some sections like "collection.list" doesn't directs to the page which i have created. I think you were talking about this at the beginning of the answer :)
After that, i found a much better solution. Just creating a new section.liquid file and placing it in "collection.liquid" with an "if" statement solved my problem.
{% if collection.handle == 'less-is-more' %}
{% section 'custom-featured-products-LESSisMORE' %}
{% endif %}
But in any way, i'm grateful for your interest. Thank you very much Dave.
It looks like there's nothing defining the collection variable anywhere.
I would suggest changing the beginning of your code snippet from:
{% paginate collections[settings.frontpage_collection].products by 20 %}
To:
{% assign collection = collections[settings.frontpage_collection] %}
{% paginate collection.products by 20 %}
There is an implicit collections variable whenever you're on a page that includes /collections/[something] in the URL, but when you're on a URL that's /page/[something], you have an implicit page variable in Liquid instead.
Note: if the collection set in your theme's value for settings.frontpage_collection isn't the one you want, you can possibly:
a. Change the value using the 'Customize' link beside your theme (most easily found on the /admin/themes page), useful if you're not going to use that setting for anything else;
b. Hard-code a collection handle, eg: collections['i-am-sure-this-will-never-change'], but hard-coded strings are ugly and should generally be avoided;
c. Create your own theme setting by adding an entry to config/settings_schema.json - see https://help.shopify.com/en/themes/development/theme-editor/settings-schema if you're still getting up to speed with custom theme settings; or
d. If all your content is in a section, you can use section settings (similar to theme settings) to make a variable that's tied specifically to just that block of code.
If you need to make these special pages for multiple collections, and each of these pages is largely reusing the same code, you can make your life easier by moving the common code to a snippet and passing variables to it from your page template. To do so:
Create a file in the 'snippets' folder of your theme. (For this example, let's say the file is called collection-in-page.liquid. We will be passing a collection into this snippet, so you can remove the assign statement.
In your page-specific template, figure out what the collection handle is going to be
a. This might be hard-coded, or it might be something you could look up by using metafields or tags on the page. Examples:
{% assign collection_handle = 'hardcoded-handle' %}, {% assign collection_handle = page.metafields.related_items.collection %}
In your page template, include the snippet you created. I find it helps to explicitly pass any variables I want to use, like so:
{% include 'collection-in-page', collection: collections[collection_handle] %}
Hope this helps!

Shopify Liquid. If line.title contains '<br>' statement is not working

We are using Shopify where we have an invoice page where product title and other data is showing.
My problem is that product.title is displaying <br> tag on the invoice page.
(On the product page title is displaying w/o <br> tag)
The reason for this is that product.title can only be entered via WYSIWYG. Where WYSIWYG encodes product.title into ASCII code and decodes product.title on the invoice page.
I am trying to find and replace/hide <br> tag inside product.title using Liquid string filter {{ product.title | replace: 'Awesome', 'Mega' }} with {% if %} statement and it is not working. If i'll change {% if line.title contains '<br>'%} to {% if line.title contains 'Dress'%} the code will replace Dress with white space.
Kindly find below part of my code.
Part of the code i added
{% if line.title contains '<br>'%} {{ line.title | replace: '<br>', ' ' }} {% endif %}
General code
<td class="order-list__product-description-cell" style="width:100%">
{% if line.product.title %} {% assign line_title = line.product.title %}
{% else %} {% assign line_title = line.title %} {% endif %}
<span class="order-list__item-title">
<!-- Replace if statement -->
{% if line.title contains '<br>'%} {{ line.title | replace: '<br>', ' ' }}
{% endif %}
<!-- Replace if statement -->
{{ line_title }} × {{ line.quantity }}
</span>
<br/> {% if line.variant.title != 'Default Title' %}
<span class="order-list__item-variant">{{ line.variant.title }}</span> {% endif %}
I would highly appreciate if you could please tell me what am i doing wrong and guide me on how to implement this in the right way.
Meanwhile waiting for Shopify to fix the issue of displaying tags in their app
If your title is showing like this:
This is a really, really, really,<br>really long product title!
Then Shopify is probably escaping your HTML tag, turning it into this under-the-hood:
This is a really, really, really,<br>really long product title!
If you update your {{ product.title }} code to: {{ product.title | replace: '<', '<' | replace: '>', '>' }} you should get the following:
This is a really, really, really,
really long product title!
Alternatively, if you want to remove the line break entirely, you could use either:
{{ product.title | replace: '<', '<' | replace: '>', '>' | remove: '<br>' }}
or:
{{ product.title | replace: '<br>', ' ' }}

Trying to target only frontpage collection to apply a style(Shopify)

OK, so I had asked a few weeks ago on the Shopify forum(slow responses) how to target just one product on a collection page so that there is no hover affect, but now I only want to target the frontpage collection and not my many other collection pages on the site.
Theme is Masonry and here is a snipet of the code I'm working with:
{% if settings.prod_block_display contains 'hover' %}
{% unless forloop.index == 1%}
<div class="hoverinfo{% if forloop.index == 1 %}no-overlay {% endif %}">
<a href="{{ product_url }}">
<div class="info-box">
<div class="title">{{ product-block.title }}</div>
<div class="price">
{% if product-block.compare_at_price_max > product-block.price %}
<span class="previously">{{ product-block.compare_at_price_max | money }}</span>
{% endif %}
{% if product-block.price_varies %}<span class="from">{{ 'products.listing.from' | t }}</span>{% endif %}
<span class="actual">{{ product-block.price | money }}</span>
</div>
</div>
</a>
</div>
{% endunless %}
{% endif %}
{% if settings.prod_block_qv and no_quick_buy == false %}
{% unless forloop.index == 1 %}
<div class="quick-buy-row{% if forloop.index == 1%}no-overlay {% endif %}">
{{ 'products.listing.quick_view' | t }}
</div>
{% endunless %}
{% endif %}
The "{% unless forloop.index == 1%}
" codes are the effects I only want to apply to the frontpage. Any help would be great!
You can add {{ collection.handle }} to classes of product divs where you want to apply the effect. Then in styles.css.liquid add a style for the collection handle (collection.handle) class as required.
What #HymnZ was trying to point to was that you can do things like in styles.liquid.css:
.frontpage .hoverinfo{
display:none;
}
and then in your template:
<div class="{{collection.handle}}">
<div class="hoverinfo">
...
</div>
</div>
This is the easiest way to use this strategy. What I was trying to add on was that you can potentially also use prefixes and suffixes on classes that concatenate with handles to offer more functionality. In styles:
.hide{
display:none;
}
.frontpage-show{
display:block;
}
and then in your template:
<div class="hide {{collection.handle}}-show">
Since most browsers support stacked selectors you probably don't need the -hide, -show variants but they can be helpful depending on how your mind works these things out. The sample above can be used to show/hide things for a variety of circumstances. e.g. you could target elements for a variety of collections:
.frontpage-show,
.collection1-show,
.frontpage.hide, /* these second two are the stacked equivalents to the -show variants */
.collection1.hide{
display:block;
}
Of course you can also do much of this in liquid itself:
{% assign showFor = "frontpage,collection1" |split ','%}
{% if showFor contains collection.handle %}
<div>Something limited</div>
{% endif %}
or
{% assign showFor = "frontpage,collection1" |split ','%}
<div class="{% if showFor contains collection.handle %}conditional{% endif %}">
Something limited
</div>