Skip to content

Instantly share code, notes, and snippets.

@Monichre
Created November 15, 2018 19:10
Show Gist options
  • Save Monichre/7f010b9079e2ae8c5d7b5a4aa4d16128 to your computer and use it in GitHub Desktop.
Save Monichre/7f010b9079e2ae8c5d7b5a4aa4d16128 to your computer and use it in GitHub Desktop.
// SNIPPET
{% comment %}
Collection template, used on current_collection.liquid and current_collection.image.liquid
{% endcomment %}
<div class="compare-basket">
<button class="action action--button action--compare"><i class="fa fa-check"></i><span class="action__text">Compare</span></button>
</div>
{% assign current_collection = collections['model-1'] %}
<div class="view">
<header class="section-header text-center">
<h1>{{ current_collection.title }}</h1>
<!-- <hr class="hr--small"> -->
{% if current_collection.description != blank %}
<div class="grid">
<div class="grid__item">
<div class="rte">
{{ current_collection.description }}
</div>
</div>
</div>
{% endif %}
<div class="grid--full collection-sorting{% if section.settings.collection_sort_enable %} collection-sorting--enabled{% endif %}">
{% if section.settings.collection_sort_enable %}
{% include 'collection-sorting' %}
{% endif %}
</div>
{% if section.settings.collection_tags_enable %}
{% if current_collection.all_tags.size > 0 %}
{% if section.settings.collection_sort_enable %}
<hr class="hr--small">
{% endif %}
{% comment %}
To provide a 'catch-all' link at the top of the list,
check against the current_collection.handle, product type, and vendor.
{% endcomment %}
<ul class="tags tags--collection inline-list">
<li{% unless current_tags %} class="tag--active"{% endunless %}>
{% comment %}
Good for /collections/all collection and regular collections
{% endcomment %}
{% if current_collection.handle %}
<a href="/collections/{{ current_collection.handle }}">
{{ 'collections.general.all_of_collection' | t }}
</a>
{% comment %}
Good for automatic type collections
{% endcomment %}
{% elsif current_collection.current_type %}
<a href="{{ current_collection.current_type | url_for_type }}">
{{ 'collections.general.all_of_collection' | t }}
</a>
{% comment %}
Good for automatic vendor collections
{% endcomment %}
{% elsif current_collection.current_vendor %}
<a href="{{ current_collection.current_vendor | url_for_vendor }}">
{{ 'collections.general.all_of_collection' | t }}
</a>
{% endif %}
</li>
{% for tag in current_collection.all_tags %}
{% if current_tags contains tag %}
<li class="tag--active">
{{ tag | link_to_remove_tag: tag }}
</li>
{% else %}
<li>
{% comment %}
Use link_to_add_tag if you want to allow filtering
by multiple tags
{% endcomment %}
{{ tag | link_to_tag: tag }}
</li>
{% endif %}
{% endfor %}
</ul>
{% endif %}
{% endif %}
{% if section.settings.collection_tags_enable %}
<hr class="hr--small hr--clear">
{% endif %}
</header>
{% if section.settings.collection_products_grid == 'collage' %}
<div class="grid grid-collage product-card-grid">
{% comment %}
Loop through our products in the current current_collection.
See the snippet 'snippets/product-grid-collage.liquid'.
`is_reverse_row__product`, `three_row_index__product`, `collection_product_count`, and `divisible_by_three__product` are
all used by 'snippets/product-grid-collage.liquid'
{% endcomment %}
{% assign is_reverse_row__product = false %}
{% assign three_row_index__product = 0 %}
{% assign collection_product_count__product = current_collection.products.size %}
{% assign divisible_by_three__product = collection_product_count__product | modulo:3 %}
{% for product in current_collection.products %}
{% comment %} {% include 'product-grid-collage' %} {% endcomment %}
{% include 'product-grid-card' %}
{% else %}
{% if shop.products_count == 0 %}
{% comment %}
Add default products to help with onboarding for collections/all only
{% endcomment %}
{% include 'onboarding-featured-products' %}
{% else %}
{% comment %}
If collection exists but is empty, display message
{% endcomment %}
<div class="grid__item text-center">
<p>{{ 'collections.general.no_matches' | t }}</p>
</div>
{% endif %}
{% endfor %}
</div>
{% elsif section.settings.collection_products_grid == 'grid' %}
<div class="grid-uniform">
{% assign grid_item_width = 'medium--one-half large--one-third' %}
{% for product in current_collection.products %}
{% include 'product-grid-card' %}
{% else %}
{% if current_collection.handle == 'all' %}
{% comment %}
Add default products to help with onboarding for collections/all only
{% endcomment %}
{% include 'onboarding-featured-products' %}
{% else %}
{% comment %}
If collection exists but is empty, display message
{% endcomment %}
<div class="grid__item text-center">
<p>{{ 'collections.general.no_matches' | t }}</p>
</div>
{% endif %}
{% endfor %}
</div>
{% endif %}
{% if paginate.pages > 1 %}
{% include 'pagination' %}
{% endif %}
</div>
<section class="compare">
<button class="action action--close"><img src="{{ 'close-white.svg' | asset_url }} " alt='Close Comparison'/><span class="action__text action__text--invisible">Close comparison overlay</span></button>
</section>
<script src="{{ 'classie.js' | asset_url }} "></script>
<script>
(function() {
const viewEl = document.querySelector('.view')
const items = [].slice.call(document.querySelectorAll('.product-card'))
let basket;
// the compare basket
function CompareBasket() {
this.el = document.querySelector('.compare-basket');
this.compareCtrl = this.el.querySelector('.action--compare');
this.compareWrapper = document.querySelector('.compare'),
this.closeCompareCtrl = this.compareWrapper.querySelector('.action--close')
this.itemsAllowed = 3;
this.totalItems = 0;
this.items = [];
// compares items in the compare basket: opens the compare products wrapper
this.compareCtrl.addEventListener('click', this._compareItems.bind(this));
// close the compare products wrapper
var self = this;
this.closeCompareCtrl.addEventListener('click', function() {
// toggle compare basket
classie.add(self.el, 'compare-basket--active');
// animate..
classie.remove(viewEl, 'view--compare');
});
}
CompareBasket.prototype.add = function(item) {
// check limit
if( this.isFull() ) {
return false;
}
classie.add(item, 'product--selected');
// create item preview element
var preview = this._createItemPreview(item);
// prepend it to the basket
this.el.insertBefore(preview, this.el.childNodes[0]);
// insert item
this.items.push(preview);
this.totalItems++;
if( this.isFull() ) {
classie.add(this.el, 'compare-basket--full');
}
classie.add(this.el, 'compare-basket--active');
};
CompareBasket.prototype._createItemPreview = function(item) {
const self = this;
const removeComparisonIcon = document.createElement('img')
const preview = document.createElement('div')
preview.className = 'product-icon';
preview.setAttribute('data-idx', items.indexOf(item));
const removeCtrl = document.createElement('button');
removeCtrl.className = 'action action--remove';
removeCtrl.style.border = 'none'
removeComparisonIcon.src = "{{ 'close.svg' | asset_url }} "
removeCtrl.appendChild(removeComparisonIcon)
removeCtrl.addEventListener('click', function() {
self.remove(item);
});
console.log('item', item)
const productImageEl = item.querySelector('.img img').cloneNode(true);
preview.appendChild(productImageEl);
preview.appendChild(removeCtrl);
const productHandle = item.getAttribute('data-attr-handle');
const productTitle = item.getAttribute('data-attr-title');
const productFeaturedImage = item.getAttribute('data-attr-featured-image');
const productID = item.getAttribute('data-attr-productId');
const productDescription = item.getAttribute('data-attr-product-description');
preview.setAttribute('data-attr-handle', productHandle);
preview.setAttribute('data-attr-title', productTitle);
preview.setAttribute('data-attr-featured-image', productFeaturedImage);
preview.setAttribute('data-attr-productId', productID);
preview.setAttribute('data-attr-product-description', productDescription);
return preview;
};
CompareBasket.prototype.remove = function(item) {
classie.remove(this.el, 'compare-basket--full');
classie.remove(item, 'product--selected');
var preview = this.el.querySelector('[data-idx = "' + items.indexOf(item) + '"]');
this.el.removeChild(preview);
this.totalItems--;
var indexRemove = this.items.indexOf(preview);
this.items.splice(indexRemove, 1);
if( this.totalItems === 0 ) {
classie.remove(this.el, 'compare-basket--active');
}
// checkbox
var checkbox = item.querySelector('.action--compare-add > input[type = "checkbox"]');
if( checkbox.checked ) {
checkbox.checked = false;
}
};
CompareBasket.prototype._compareItems = function() {
var self = this;
// remove all previous items inside the compareWrapper element
[].slice.call(this.compareWrapper.querySelectorAll('div.compare__item')).forEach(function(item) {
self.compareWrapper.removeChild(item);
});
for(var i = 0; i < this.totalItems; ++i) {
const compareItemWrapper = document.createElement('div');
compareItemWrapper.className = 'compare__item';
const theProductID = this.items[i].getAttribute('data-attr-productId');
const compareItemEffectEl = document.createElement('div');
const compareItemTitle = document.createElement('h1');
const compareItemImage = document.createElement('img');
const compareItemDescription = document.createElement('p');
compareItemEffectEl.className = 'compare__effect';
compareItemTitle.innerHTML = this.items[i].getAttribute('data-attr-title');
compareItemDescription.innerHTML = this.items[i].getAttribute('data-attr-product-description');
compareItemImage.src = this.items[i].getAttribute('data-attr-featured-image');
compareItemEffectEl.appendChild(compareItemTitle)
compareItemEffectEl.appendChild(compareItemImage)
compareItemEffectEl.appendChild(compareItemDescription)
console.log(compareItemDescription)
console.log(this.items[i])
compareItemWrapper.appendChild(compareItemEffectEl);
this.compareWrapper.insertBefore(compareItemWrapper, this.compareWrapper.childNodes[0]);
}
setTimeout(function() {
// toggle compare basket
classie.remove(self.el, 'compare-basket--active');
// animate..
classie.add(viewEl, 'view--compare');
}, 25);
};
CompareBasket.prototype.isFull = function() {
return this.totalItems === this.itemsAllowed;
};
function init() {
// initialize an empty basket
basket = new CompareBasket();
initEvents();
}
function initEvents() {
items.forEach(function(item) {
var checkbox = item.querySelector('.action--compare-add > input[type = "checkbox"]');
checkbox.checked = false;
// ctrl to add to the "compare basket"
checkbox.addEventListener('click', function(ev) {
const plusSign = ev.target.parentElement.querySelector('.plus-sign')
plusSign.src = plusSign.src === "{{ 'check.svg' | asset_url }}" ? "{{ 'plus-rectangle.svg' | asset_url }}" : "{{ 'check.svg' | asset_url }}"
if( ev.target.checked ) {
if( basket.isFull() ) {
ev.preventDefault();
return false;
}
basket.add(item);
}
else {
basket.remove(item);
}
});
});
}
init();
})();
</script>
{% unless grid_item_width %}
{% assign grid_item_width = 'large--one-half medium--one-half' %}
{% endunless %}
{% unless width %}
{%- assign width = 310 -%}
{% endunless %}
{% unless height %}
{%- assign height = 415 -%}
{% endunless %}
{% assign on_sale = false %}
{% if product.compare_at_price > product.price %}
{% assign on_sale = true %}
{% endif %}
{% assign sold_out = true %}
{% if product.available %}
{% assign sold_out = false %}
{% endif %}
{% capture img_id_class %}ProductImage-{{ product.featured_image.id }}{% endcapture %}
{% capture img_wrapper_id %}ProductImageWrapper-{{ product.featured_image.id }}{% endcapture %}
{%- assign img_url = product.featured_image | img_url: '1x1' | replace: '_1x1.', '_{width}x.' -%}
{% assign colored_face_plates = product.variants %}
<div class="grid__item grid-product {{ grid_item_width }}{% if sold_out %} is-sold-out{% endif %}">
<div class="grid-product__wrapper">
<div class="grid-product__image-wrapper">
<div class='card product-card' data-attr-handle="{{product.handle}}" data-attr-title="{{product.title}}"
data-attr-productId="{{product.id}}" data-attr-product-description="{{product.description | escape}}" data-attr-featured-image="{{ product.featured_image | product_img_url}}">
<div class='card-content'>
<div class='top-bar'>
<span>
<b>{{ product.title }}</b>
</span>
<span>
<label class="action action--compare-add">
<input class="check-hidden" type="checkbox" />
<img class='plus-sign action action--compare-add' src="{{ 'plus-rectangle.svg' | asset_url }} "
data-attr-handle="{{product.handle}}" data-attr-title="{{product.title}}" data-attr-productId="{{product.id}}" data-attr-product-description="{{product.description | escape}}" data-attr-featured-image="{{ product.featured_image | product_img_url}}"
alt='Compare Product Plus Sign' />
<span class="action__text action__text--invisible">Add to compare</span>
</label>
</span>
</div>
<div class='img'>
{% if product.featured_image.src == blank %}
<img src="{{ product.featured_image.src | img_url: '1024x' }}" alt="{{ product.featured_image.alt | escape }}">
{% else %}
{% include 'image-style' with image: product.featured_image, small_style: true, width: width, height:
height, wrapper_id: img_wrapper_id, img_id_class: img_id_class %}
<div id="{{ img_wrapper_id }}" class="product--wrapper">
<div style="padding-top:{{ 1 | divided_by: product.featured_image.aspect_ratio | times: 100 }}%;">
<img class="product--image lazyload {{ img_id_class }}" src="{{ product.featured_image | img_url: '150x150' }}"
data-src="{{ img_url }}" data-widths="[180, 370, 590, 740, 900, 1080, 1296, 1512, 1728, 2048]"
data-aspectratio="{{ product.featured_image.aspect_ratio }}" data-sizes="auto" alt="{{ product.featured_image.alt | escape }}">
</div>
</div>
{% endif %}
</div>
</div>
<div class='card-description'>
<div class='title'>
{{ product.price | money_without_trailing_zeros }}
</div>
<div class='face-plates'>
{% assign colored_face_plates = product.variants %}
{% for variant in colored_face_plates %}
<span class="face-plate-wrap">
<span class="action__text action__text--invisible">{{variant.title}}</span>
<img src="{{ variant.featured_image.src | img_url: '250x250' }}" onclick="selectFaceplate(event)"
data-attr-handle="{{variant.handle}}" data-attr-title="{{variant.title}}" data-attr-productId="{{variant.id}}" />
</span>
{% endfor %}
</div>
</div>
<div class='card-footer'>
{% if on_sale %}
<span class="visually-hidden span">{{ 'products.general.sale_price' | t }}</span>
{% else %}
<span class="visually-hidden span">{{ 'products.general.regular_price' | t }}</span>
{% endif %}
{% if product.price_varies %}
{{ product.price_min | money_without_trailing_zeros }}
<span class="icon-fallback-text span">
<span class="icon icon-plus grid-product__price-min" aria-hidden="true"></span>
<span class="fallback-text">+</span>
</span>
{% else %}
<div class='span'>
{{ product.vendor }}
</div>
{% endif %}
<div class='span add_color'>
<img src="{{ 'plus.svg' | asset_url }} " alt='Add Color Plus Sign' /> Color
</div>
<div class='cart'>
<form method="post" action="/cart/add">
<input name="id" value="{{ product.variants.last.id }}" type="hidden" id='selectedProductAndVariantInput' />
<button name="add" value="ORDER NOW" id='AddToCart' type="submit" style="padding: 0; border: 0;">
<img src="{{ 'shopping-bag.svg' | asset_url }} " alt='shopping bag' />
</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function selectFaceplate(event) {
console.log(event.target)
const image = event.target
const imageSrc = image.src
const selectedVariant = {
featuredImage: image.src,
title: image.getAttribute('data-attr-title'),
handle: image.getAttribute('data-attr-handle'),
productId: image.getAttribute('data-attr-productId')
}
const currentCard = event.target.parentElement.parentElement.parentElement.parentElement
const currentCardContent = currentCard.querySelector('.card-content')
const currentFeaturedImage = currentCard.querySelector('.img img')
const cardFooter = currentCardContent.parentElement.querySelector('.card-footer')
const faceplateRow = currentCardContent.querySelector('.card-description .face-plates')
const addColorTag = cardFooter.querySelector('.add_color')
const variantInput = currentCard.querySelector('.card-footer .cart form input')
variantInput.value = selectedVariant.productId
addColorTag.querySelector('img').src = "{{ 'tag.svg' | asset_url }}"
const color = selectedVariant.title.split(' ')[selectedVariant.title.split(' ').length - 1]
const colors = ['Blue', 'Black', 'Red', 'Grey', 'Clear']
colors.forEach(colorOpt => {
if(addColorTag.classList.contains(colorOpt.toLowerCase())) {
addColorTag.classList.remove(colorOpt.toLowerCase())
}
})
if (color === 'Black') {
addColorTag.querySelector('img').src = "{{ 'tag-f.svg' | asset_url }}"
}
addColorTag.classList.add(selectedVariant.title.split(' ')[selectedVariant.title.split(' ').length - 1].toLowerCase())
currentFeaturedImage.src = selectedVariant.featuredImage
currentFeaturedImage.setAttribute('data-srcset', '')
currentFeaturedImage.setAttribute('srcset', '')
currentFeaturedImage.setAttribute('data-srcset', selectedVariant.featuredImage)
currentFeaturedImage.setAttribute('srcset', selectedVariant.featuredImage)
currentCard.setAttribute('data-attr-featured-image', selectedVariant.featuredImage)
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment