Skip to content

Instantly share code, notes, and snippets.

@marioloncarek
Created October 12, 2018 14:34
Show Gist options
  • Save marioloncarek/c8db10c580fb8f90dd844efe4e0c11fa to your computer and use it in GitHub Desktop.
Save marioloncarek/c8db10c580fb8f90dd844efe4e0c11fa to your computer and use it in GitHub Desktop.
/**
* Product Template Script
* ------------------------------------------------------------------------------
* A file that contains scripts highly couple code to the Product template.
*
* @namespace product
*/
import $ from 'jquery';
import Variants from '@shopify/theme-variants';
import {formatMoney} from '@shopify/theme-currency';
import {register} from '@shopify/theme-sections';
const selectors = {
addToCart: '[data-add-to-cart]',
addToCartText: '[data-add-to-cart-text]',
comparePrice: '[data-compare-price]',
comparePriceText: '[data-compare-text]',
originalSelectorId: '[data-product-select]',
priceWrapper: '[data-price-wrapper]',
productImageWrapper: '[data-product-image-wrapper]',
productFeaturedImage: '[data-product-featured-image]',
productJson: '[data-product-json]',
productPrice: '[data-product-price]',
productThumbs: '[data-product-single-thumbnail]',
singleOptionSelector: '[data-single-option-selector]',
bundleTemplate: '.template-pack-single',
oosForm: '.js-OOS-form',
};
// JAKI
const $bundleTemplate = $(selectors.bundleTemplate);
const $oosForm = $(selectors.oosForm);
if ($bundleTemplate.length > 0) {
console.log($bundleTemplate);
} else {
console.log('ne postoji');
}
function isAnySizeOptionSelected() {
return $('.p-single-product--bundle-single-active .c-size-picker__sizes input[type=radio]:checked').length > 0;
}
console.log(isAnySizeOptionSelected());
// JAKI
const cssClasses = {
activeThumbnail: 'active-thumbnail',
hide: 'hide',
};
const keyboardKeys = {
ENTER: 13,
};
/**
* Product section constructor. Runs on page load as well as Theme Editor
* `section:load` events.
* @param {string} container - selector for the section container DOM element
*/
register('product', {
onLoad() {
this.$container = $(this.container);
this.namespace = `.${this.id}`;
// Stop parsing if we don't have the product json script tag when loading
// section in the Theme Editor
if (!$(selectors.productJson, this.$container)
.html()) {
return;
}
this.productSingleObject = JSON.parse(
$(selectors.productJson, this.$container)
.html(),
);
const options = {
$container: this.$container,
enableHistoryState: this.$container.data('enable-history-state') || false,
singleOptionSelector: selectors.singleOptionSelector,
originalSelectorId: selectors.originalSelectorId,
product: this.productSingleObject,
};
this.settings = {};
this.variants = new Variants(options);
this.$featuredImage = $(selectors.productFeaturedImage, this.$container);
this.$container.on(
`variantChange${this.namespace}`,
this.updateAddToCartState.bind(this),
);
this.$container.on(
`variantPriceChange${this.namespace}`,
this.updateProductPrices.bind(this),
);
if (this.$featuredImage.length > 0) {
this.$container.on(
`variantImageChange${this.namespace}`,
this.updateImages.bind(this),
);
}
this.initImageSwitch();
},
initImageSwitch() {
const $productThumbs = $(selectors.productThumbs, this.$container);
if (!$productThumbs.length) {
return;
}
$productThumbs
.on('click', (evt) => {
evt.preventDefault();
const imageId = $(evt.currentTarget)
.data('thumbnail-id');
this.switchImage(imageId);
this.setActiveThumbnail(imageId);
})
.on('keyup', this.handleImageFocus.bind(this));
},
handleImageFocus(evt) {
if (evt.keyCode !== keyboardKeys.ENTER) {
return;
}
this.$featuredImage.filter(':visible')
.focus();
},
setActiveThumbnail(imageId) {
let newImageId = imageId;
// If "imageId" is not defined in the function parameter, find it by the current product image
if (typeof newImageId === 'undefined') {
newImageId = $(
`${selectors.productImageWrapper}:not('.${cssClasses.hide}')`,
)
.data('image-id');
}
const $thumbnail = $(
`${selectors.productThumbs}[data-thumbnail-id='${newImageId}']`,
);
$(selectors.productThumbs)
.removeClass(cssClasses.activeThumbnail)
.removeAttr('aria-current');
$thumbnail.addClass(cssClasses.activeThumbnail);
$thumbnail.attr('aria-current', true);
},
switchImage(imageId) {
const $newImage = $(
`${selectors.productImageWrapper}[data-image-id='${imageId}']`,
this.$container,
);
const $otherImages = $(
`${selectors.productImageWrapper}:not([data-image-id='${imageId}'])`,
this.$container,
);
$newImage.removeClass(cssClasses.hide);
$otherImages.addClass(cssClasses.hide);
},
/**
* Updates the DOM state of the add to cart button
*
* @param {boolean} enabled - Decides whether cart is enabled or disabled
* @param {string} text - Updates the text notification content of the cart
*/
updateAddToCartState(evt) {
const variant = evt.variant;
console.log(isAnySizeOptionSelected());
if ($bundleTemplate.length > 0) {
if (variant) {
$(selectors.priceWrapper, this.$container)
.removeClass(cssClasses.hide);
} else {
$(selectors.addToCart, this.$container)
.prop('disabled', true);
$(selectors.addToCartText, this.$container)
.html(
theme.strings.unavailable,
);
$(selectors.priceWrapper, this.$container)
.addClass(cssClasses.hide);
return;
}
if (isAnySizeOptionSelected()) {
if (variant.available) {
$(selectors.addToCart, this.$container)
.prop('disabled', false);
if ($(this.$container)
.hasClass('p-single-product--bundle-single-last-step') && isAnySizeOptionSelected()) {
$(selectors.addToCartText, this.$container)
.html('Finish and add to cart');
} else {
$(selectors.addToCartText, this.$container)
.html('Proceed to next step');
}
$(this.container)
.find('.js-button')
.on('click', () => {
$(this.$container)
.next()
.next()
.addClass('p-single-product--bundle-single-active')
.removeClass('p-single-product--bundle-single-disabled')
.find($(selectors.addToCartText))
.html('Select your size');
});
} else {
$(selectors.addToCart, this.$container)
.prop('disabled', true);
$(selectors.addToCartText, this.$container)
.html(theme.strings.soldOut);
}
} else if (variant.available) {
$(selectors.addToCart, this.$container)
.prop('disabled', true);
$(selectors.addToCartText, this.$container)
.html('Select your size');
} else {
$(selectors.addToCart, this.$container)
.prop('disabled', true);
$(selectors.addToCartText, this.$container)
.html('Select your size');
}
} else {
if (variant) {
$(selectors.priceWrapper, this.$container)
.removeClass(cssClasses.hide);
} else {
$(selectors.addToCart, this.$container)
.prop('disabled', true);
$(selectors.addToCartText, this.$container)
.html(
theme.strings.unavailable,
);
$(selectors.priceWrapper, this.$container)
.addClass(cssClasses.hide);
return;
}
if (variant.available) {
$(selectors.addToCart, this.$container)
.prop('disabled', false);
$(selectors.addToCartText, this.$container)
.html(theme.strings.addToCart);
$($oosForm)
.removeClass('is-visible');
} else {
$(selectors.addToCart, this.$container)
.prop('disabled', true);
$(selectors.addToCartText, this.$container)
.html(theme.strings.soldOut);
$($oosForm)
.addClass('is-visible');
}
}
},
updateImages(evt) {
const variant = evt.variant;
const imageId = variant.featured_image.id;
this.switchImage(imageId);
this.setActiveThumbnail(imageId);
},
/**
* Updates the DOM with specified prices
*
* @param {string} productPrice - The current price of the product
* @param {string} comparePrice - The original price of the product
*/
updateProductPrices(evt) {
const variant = evt.variant;
const $comparePrice = $(selectors.comparePrice, this.$container);
const $compareEls = $comparePrice.add(
selectors.comparePriceText,
this.$container,
);
$(selectors.productPrice, this.$container)
.html(
formatMoney(variant.price, theme.moneyFormat),
);
if (variant.compare_at_price > variant.price) {
$comparePrice.html(
formatMoney(variant.compare_at_price, theme.moneyFormat),
);
$compareEls.removeClass(cssClasses.hide);
} else {
$comparePrice.html('');
$compareEls.addClass(cssClasses.hide);
}
},
/**
* Event callback for Theme Editor `section:unload` event
*/
onUnload() {
this.$container.off(this.namespace);
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment