541 lines
19 KiB
JavaScript
541 lines
19 KiB
JavaScript
/**
|
|
* 2007-2017 PrestaShop
|
|
*
|
|
* NOTICE OF LICENSE
|
|
*
|
|
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
|
|
* that is bundled with this package in the file LICENSE.txt.
|
|
* It is also available through the world-wide-web at this URL:
|
|
* https://opensource.org/licenses/AFL-3.0
|
|
* If you did not receive a copy of the license and are unable to
|
|
* obtain it through the world-wide-web, please send an email
|
|
* to license@prestashop.com so we can send you a copy immediately.
|
|
*
|
|
* DISCLAIMER
|
|
*
|
|
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
|
* versions in the future. If you wish to customize PrestaShop for your
|
|
* needs please refer to http://www.prestashop.com for more information.
|
|
*
|
|
* @author PrestaShop SA <contact@prestashop.com>
|
|
* @copyright 2007-2017 PrestaShop SA
|
|
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
|
|
* International Registered Trademark & Property of PrestaShop SA
|
|
*/
|
|
import $ from 'jquery';
|
|
import prestashop from 'prestashop';
|
|
import 'velocity-animate';
|
|
|
|
import ProductMinitature from './components/product-miniature';
|
|
|
|
$(document).ready(() => {
|
|
prestashop.on('clickQuickView', function (elm) {
|
|
let data = {
|
|
'action': 'quickview',
|
|
'id_product': elm.dataset.idProduct,
|
|
'id_product_attribute': elm.dataset.idProductAttribute,
|
|
};
|
|
$.post(prestashop.urls.pages.product, data, null, 'json').then(function (resp) {
|
|
$('body').append(resp.quickview_html);
|
|
let productModal = $(`#quickview-modal-${resp.product.id}-${resp.product.id_product_attribute}`);
|
|
productModal.modal('show');
|
|
productConfig(productModal);
|
|
productModal.on('hidden.bs.modal', function () {
|
|
productModal.remove();
|
|
});
|
|
}).fail((resp) => {
|
|
prestashop.emit('handleError', {eventType: 'clickQuickView', resp: resp});
|
|
});
|
|
});
|
|
|
|
var productConfig = (qv) => {
|
|
const MAX_THUMBS = 4;
|
|
var $arrows = $('.js-arrows');
|
|
var $thumbnails = qv.find('.js-qv-product-images');
|
|
$('.js-thumb').on('click', (event) => {
|
|
if ($('.js-thumb').hasClass('selected')) {
|
|
$('.js-thumb').removeClass('selected');
|
|
}
|
|
$(event.currentTarget).addClass('selected');
|
|
$('.js-qv-product-cover').attr('src', $(event.target).data('image-large-src'));
|
|
});
|
|
if ($thumbnails.find('li').length <= MAX_THUMBS) {
|
|
$arrows.hide();
|
|
} else {
|
|
$arrows.on('click', (event) => {
|
|
if ($(event.target).hasClass('arrow-up') && $('.js-qv-product-images').position().top < 0) {
|
|
move('up');
|
|
$('.arrow-down').css('opacity', '1');
|
|
} else if ($(event.target).hasClass('arrow-down') && $thumbnails.position().top + $thumbnails.height() > $('.js-qv-mask').height()) {
|
|
move('down');
|
|
$('.arrow-up').css('opacity', '1');
|
|
}
|
|
});
|
|
}
|
|
qv.find('#quantity_wanted').TouchSpin({
|
|
verticalbuttons: false,
|
|
verticalupclass: 'material-icons touchspin-up',
|
|
verticaldownclass: 'material-icons touchspin-down',
|
|
buttondown_class: 'btn btn-touchspin js-touchspin',
|
|
buttonup_class: 'btn btn-touchspin js-touchspin',
|
|
min: 1,
|
|
max: 1000000
|
|
});
|
|
setTimeout(function() {
|
|
qv.find('.product-images').flickity({
|
|
draggable:1,
|
|
pageDots: false,
|
|
cellAlign: 'left',
|
|
contain: true,
|
|
arrowShape: {
|
|
x0: 30,
|
|
x1: 60, y1: 50,
|
|
x2: 70, y2: 50,
|
|
x3: 40
|
|
}
|
|
});
|
|
},300);
|
|
};
|
|
var move = (direction) => {
|
|
const THUMB_MARGIN = 20;
|
|
var $thumbnails = $('.js-qv-product-images');
|
|
var thumbHeight = $('.js-qv-product-images li img').height() + THUMB_MARGIN;
|
|
var currentPosition = $thumbnails.position().top;
|
|
$thumbnails.velocity({
|
|
translateY: (direction === 'up') ? currentPosition + thumbHeight : currentPosition - thumbHeight
|
|
}, function () {
|
|
if ($thumbnails.position().top >= 0) {
|
|
$('.arrow-up').css('opacity', '.2');
|
|
} else if ($thumbnails.position().top + $thumbnails.height() <= $('.js-qv-mask').height()) {
|
|
$('.arrow-down').css('opacity', '.2');
|
|
}
|
|
});
|
|
};
|
|
|
|
const parseSearchUrl = function (event) {
|
|
if (event.target.dataset.searchUrl !== undefined) {
|
|
return event.target.dataset.searchUrl;
|
|
}
|
|
|
|
if ($(event.target).parent()[0].dataset.searchUrl === undefined) {
|
|
throw new Error('Can not parse search URL');
|
|
}
|
|
|
|
return $(event.target).parent()[0].dataset.searchUrl;
|
|
};
|
|
|
|
$('body').on('change', '#search_filters input[data-search-url]', function (event) {
|
|
prestashop.emit('updateFacets', parseSearchUrl(event));
|
|
});
|
|
|
|
$('body').on('click', '.js-search-filters-clear-all', function (event) {
|
|
prestashop.emit('updateFacets', parseSearchUrl(event));
|
|
});
|
|
|
|
$('body').on('click', '.js-search-link', function (event) {
|
|
event.preventDefault();
|
|
prestashop.emit('updateFacets', $(event.target).closest('a').get(0).href);
|
|
});
|
|
|
|
$('body').on('change', '#search_filters select', function (event) {
|
|
const form = $(event.target).closest('form');
|
|
prestashop.emit('updateFacets', '?' + form.serialize());
|
|
});
|
|
|
|
prestashop.on('updateProductList', (data) => {
|
|
updateProductListDOM(data);
|
|
updateCounters();
|
|
hideProds();
|
|
showProds();
|
|
|
|
let target = $("#products");
|
|
if (target.length) {
|
|
$('html, body').animate({
|
|
scrollTop: target.offset().top - 100
|
|
}, 240);
|
|
}
|
|
|
|
});
|
|
|
|
// Grid - list
|
|
|
|
$('.show_list').click(function(){
|
|
document.cookie = "show_list=true; expires=Thu, 30 Jan 2100 12:00:00 UTC; path=/";
|
|
$('#main #js-product-list .product-item').addClass('product_show_list');
|
|
$(this).addClass('active');
|
|
$('.show_grid').removeClass('active');
|
|
hideProds();
|
|
showProds();
|
|
});
|
|
|
|
$('.show_grid').click(function(){
|
|
document.cookie = "show_list=; expires=Thu, 30 Jan 1970 12:00:00 UTC; path=/";
|
|
$('#main #js-product-list .product-item').removeClass('product_show_list');
|
|
$(this).addClass('active');
|
|
$('.show_list').removeClass('active');
|
|
hideProds();
|
|
showProds();
|
|
});
|
|
|
|
prestashop.on('updateProductList', function (event) {
|
|
$('.show_list').click(function(){
|
|
$('#main #js-product-list .product-item').addClass('product_show_list');
|
|
$(this).addClass('active');
|
|
$('.show_grid').removeClass('active');
|
|
hideProds();
|
|
showProds();
|
|
});
|
|
|
|
$('.show_grid').click(function(){
|
|
$('#main #js-product-list .product-item').removeClass('product_show_list');
|
|
$(this).addClass('active');
|
|
$('.show_list').removeClass('active');
|
|
hideProds();
|
|
showProds();
|
|
});
|
|
});
|
|
|
|
// roythemes show prods
|
|
|
|
function showProds() {
|
|
$('#products #js-product-list').find('.products > .product-item').each(function(i){
|
|
var row = $(this);
|
|
setTimeout(function(){
|
|
row.addClass('show');
|
|
}, 360 + i * 140);
|
|
});
|
|
}
|
|
showProds();
|
|
|
|
function hideProds() {
|
|
$('#products #js-product-list').find('.products > .product-item').each(function(i){
|
|
$(this).removeClass('show')
|
|
});
|
|
}
|
|
|
|
// modez fastview
|
|
|
|
class Details {
|
|
constructor() {
|
|
this.DOM = {};
|
|
|
|
const detailsTmpl = `
|
|
<div class="details__bg details__bg--up"></div>
|
|
<div class="details__bg details__bg--down"></div>
|
|
<div class="details__close"></div>
|
|
<img class="details__img" src="" alt="img 01"/>
|
|
<h2 class="details__title"></h2>
|
|
<div class="details__price"></div>
|
|
<p class="details__description"></p>
|
|
<button class="details__addtocart">Add to cart</button>
|
|
<button class="details__magnifier"><svg class="icon icon--magnifier"><use xlink:href="#icon-magnifier"></use></svg></button>
|
|
`;
|
|
|
|
this.DOM.details = document.createElement('div');
|
|
this.DOM.details.className = 'details';
|
|
this.DOM.details.innerHTML = detailsTmpl;
|
|
DOM.content.appendChild(this.DOM.details);
|
|
this.init();
|
|
}
|
|
init() {
|
|
this.DOM.bgUp = this.DOM.details.querySelector('.details__bg--up');
|
|
this.DOM.bgDown = this.DOM.details.querySelector('.details__bg--down');
|
|
this.DOM.img = this.DOM.details.querySelector('.details__img');
|
|
this.DOM.title = this.DOM.details.querySelector('.details__title');
|
|
this.DOM.price = this.DOM.details.querySelector('.details__price');
|
|
this.DOM.description = this.DOM.details.querySelector('.details__description');
|
|
this.DOM.cart = this.DOM.details.querySelector('.details__addtocart');
|
|
this.DOM.close = this.DOM.details.querySelector('.details__close');
|
|
this.DOM.magnifier = this.DOM.details.querySelector('.details__magnifier');
|
|
|
|
this.initEvents();
|
|
}
|
|
initEvents() {
|
|
this.DOM.close.addEventListener('click', () => this.isZoomed ? this.zoomOut() : this.close());
|
|
this.DOM.magnifier.addEventListener('click', () => this.zoomIn());
|
|
}
|
|
fill(info) {
|
|
this.DOM.img.src = info.img;
|
|
this.DOM.title.innerHTML = info.title;
|
|
this.DOM.price.innerHTML = info.price;
|
|
this.DOM.description.innerHTML = info.description;
|
|
}
|
|
getProductDetailsRect() {
|
|
return {
|
|
productBgRect: this.DOM.productBg.getBoundingClientRect(),
|
|
detailsBgRect: this.DOM.bgDown.getBoundingClientRect(),
|
|
productImgRect: this.DOM.productImg.getBoundingClientRect(),
|
|
detailsImgRect: this.DOM.img.getBoundingClientRect()
|
|
};
|
|
}
|
|
open(data) {
|
|
if ( this.isAnimating ) return false;
|
|
this.isAnimating = true;
|
|
|
|
this.DOM.details.classList.add('details--open');
|
|
|
|
this.DOM.productBg = data.productBg;
|
|
this.DOM.productImg = data.productImg;
|
|
|
|
this.DOM.productBg.style.opacity = 0;
|
|
this.DOM.productImg.style.opacity = 0;
|
|
|
|
const rect = this.getProductDetailsRect();
|
|
|
|
this.DOM.bgDown.style.transform = `translateX(${rect.productBgRect.left-rect.detailsBgRect.left}px) translateY(${rect.productBgRect.top-rect.detailsBgRect.top}px) scaleX(${rect.productBgRect.width/rect.detailsBgRect.width}) scaleY(${rect.productBgRect.height/rect.detailsBgRect.height})`;
|
|
this.DOM.bgDown.style.opacity = 1;
|
|
|
|
this.DOM.img.style.transform = `translateX(${rect.productImgRect.left-rect.detailsImgRect.left}px) translateY(${rect.productImgRect.top-rect.detailsImgRect.top}px) scaleX(${rect.productImgRect.width/rect.detailsImgRect.width}) scaleY(${rect.productImgRect.height/rect.detailsImgRect.height})`;
|
|
this.DOM.img.style.opacity = 1;
|
|
|
|
anime({
|
|
targets: [this.DOM.bgDown,this.DOM.img],
|
|
duration: (target, index) => index ? 800 : 250,
|
|
easing: (target, index) => index ? 'easeOutElastic' : 'easeOutSine',
|
|
elasticity: 250,
|
|
translateX: 0,
|
|
translateY: 0,
|
|
scaleX: 1,
|
|
scaleY: 1,
|
|
complete: () => this.isAnimating = false
|
|
});
|
|
|
|
anime({
|
|
targets: [this.DOM.title, this.DOM.price, this.DOM.description, this.DOM.cart, this.DOM.magnifier],
|
|
duration: 600,
|
|
easing: 'easeOutExpo',
|
|
delay: (target, index) => {
|
|
return index*60;
|
|
},
|
|
translateY: (target, index, total) => {
|
|
return index !== total - 1 ? [50,0] : 0;
|
|
},
|
|
scale: (target, index, total) => {
|
|
return index === total - 1 ? [0,1] : 1;
|
|
},
|
|
opacity: 1
|
|
});
|
|
|
|
anime({
|
|
targets: this.DOM.bgUp,
|
|
duration: 100,
|
|
easing: 'linear',
|
|
opacity: 0.8
|
|
});
|
|
|
|
anime({
|
|
targets: this.DOM.close,
|
|
duration: 250,
|
|
easing: 'easeOutSine',
|
|
translateY: ['100%',0],
|
|
opacity: 1
|
|
});
|
|
|
|
}
|
|
close() {
|
|
if ( this.isAnimating ) return false;
|
|
this.isAnimating = true;
|
|
|
|
this.DOM.details.classList.remove('details--open');
|
|
|
|
|
|
anime({
|
|
targets: this.DOM.close,
|
|
duration: 250,
|
|
easing: 'easeOutSine',
|
|
translateY: '100%',
|
|
opacity: 0
|
|
});
|
|
|
|
anime({
|
|
targets: this.DOM.bgUp,
|
|
duration: 100,
|
|
easing: 'linear',
|
|
opacity: 0
|
|
});
|
|
|
|
anime({
|
|
targets: [this.DOM.title, this.DOM.price, this.DOM.description, this.DOM.cart, this.DOM.magnifier],
|
|
duration: 20,
|
|
easing: 'linear',
|
|
opacity: 0
|
|
});
|
|
|
|
const rect = this.getProductDetailsRect();
|
|
anime({
|
|
targets: [this.DOM.bgDown,this.DOM.img],
|
|
duration: 250,
|
|
easing: 'easeOutSine',
|
|
translateX: (target, index) => {
|
|
return index ? rect.productImgRect.left-rect.detailsImgRect.left : rect.productBgRect.left-rect.detailsBgRect.left;
|
|
},
|
|
translateY: (target, index) => {
|
|
return index ? rect.productImgRect.top-rect.detailsImgRect.top : rect.productBgRect.top-rect.detailsBgRect.top;
|
|
},
|
|
scaleX: (target, index) => {
|
|
return index ? rect.productImgRect.width/rect.detailsImgRect.width : rect.productBgRect.width/rect.detailsBgRect.width;
|
|
},
|
|
scaleY: (target, index) => {
|
|
return index ? rect.productImgRect.height/rect.detailsImgRect.height : rect.productBgRect.height/rect.detailsBgRect.height;
|
|
},
|
|
complete: () => {
|
|
this.DOM.bgDown.style.opacity = 0;
|
|
this.DOM.img.style.opacity = 0;
|
|
this.DOM.bgDown.style.transform = 'none';
|
|
this.DOM.img.style.transform = 'none';
|
|
this.DOM.productBg.style.opacity = 1;
|
|
this.DOM.productImg.style.opacity = 1;
|
|
this.isAnimating = false;
|
|
}
|
|
});
|
|
}
|
|
zoomIn() {
|
|
this.isZoomed = true;
|
|
|
|
anime({
|
|
targets: [this.DOM.title, this.DOM.price, this.DOM.description, this.DOM.cart, this.DOM.magnifier],
|
|
duration: 100,
|
|
easing: 'easeOutSine',
|
|
translateY: (target, index, total) => {
|
|
return index !== total - 1 ? [0, index === 0 || index === 1 ? -50 : 50] : 0;
|
|
},
|
|
scale: (target, index, total) => {
|
|
return index === total - 1 ? [1,0] : 1;
|
|
},
|
|
opacity: 0
|
|
});
|
|
|
|
const imgrect = this.DOM.img.getBoundingClientRect();
|
|
const win = {w: window.innerWidth, h: window.innerHeight};
|
|
|
|
const imgAnimeOpts = {
|
|
targets: this.DOM.img,
|
|
duration: 250,
|
|
easing: 'easeOutCubic',
|
|
translateX: win.w/2 - (imgrect.left+imgrect.width/2),
|
|
translateY: win.h/2 - (imgrect.top+imgrect.height/2)
|
|
};
|
|
|
|
if ( win.w > 0.8*win.h ) {
|
|
this.DOM.img.style.transformOrigin = '50% 50%';
|
|
Object.assign(imgAnimeOpts, {
|
|
scaleX: 0.95*win.w/parseInt(0.8*win.h),
|
|
scaleY: 0.95*win.w/parseInt(0.8*win.h),
|
|
rotate: 90
|
|
});
|
|
}
|
|
anime(imgAnimeOpts);
|
|
|
|
anime({
|
|
targets: this.DOM.close,
|
|
duration: 250,
|
|
easing: 'easeInOutCubic',
|
|
scale: 1.8,
|
|
rotate: 180
|
|
});
|
|
}
|
|
zoomOut() {
|
|
this.isZoomed = false;
|
|
|
|
anime({
|
|
targets: [this.DOM.title, this.DOM.price, this.DOM.description, this.DOM.cart, this.DOM.magnifier],
|
|
duration: 250,
|
|
easing: 'easeOutCubic',
|
|
translateY: 0,
|
|
scale: 1,
|
|
opacity: 1
|
|
});
|
|
|
|
anime({
|
|
targets: this.DOM.img,
|
|
duration: 250,
|
|
easing: 'easeOutCubic',
|
|
translateX: 0,
|
|
translateY: 0,
|
|
scaleX: 1,
|
|
scaleY: 1,
|
|
rotate: 0,
|
|
complete: () => this.DOM.img.style.transformOrigin = '0 0'
|
|
});
|
|
|
|
anime({
|
|
targets: this.DOM.close,
|
|
duration: 250,
|
|
easing: 'easeInOutCubic',
|
|
scale: 1,
|
|
rotate: 0
|
|
});
|
|
}
|
|
};
|
|
|
|
class Item {
|
|
constructor(el) {
|
|
this.DOM = {};
|
|
this.DOM.el = el;
|
|
this.DOM.product = this.DOM.el.querySelector('.thumbnail-container');
|
|
this.DOM.productBg = this.DOM.product.querySelector('.product-description');
|
|
this.DOM.productImg = this.DOM.product.querySelector('.product-image img');
|
|
this.DOM.fw = this.DOM.product.querySelector('.fast-view');
|
|
|
|
this.info = {
|
|
img: this.DOM.productImg.src,
|
|
title: this.DOM.product.querySelector('.product-title').innerHTML,
|
|
description: this.DOM.product.querySelector('.prod-short-desc').innerHTML,
|
|
price: this.DOM.product.querySelector('.product-price-and-shipping').innerHTML
|
|
};
|
|
|
|
this.initEvents();
|
|
}
|
|
initEvents() {
|
|
console.log(this.DOM.fw);
|
|
this.DOM.fw.addEventListener('click', () => this.open());
|
|
}
|
|
open() {
|
|
DOM.details.fill(this.info);
|
|
DOM.details.open({
|
|
productBg: this.DOM.productBg,
|
|
productImg: this.DOM.productImg
|
|
});
|
|
}
|
|
};
|
|
|
|
if ( $('product-item ').length){
|
|
const DOM = {};
|
|
DOM.grid = document.querySelector('#main .products');
|
|
DOM.content = DOM.grid.parentNode;
|
|
DOM.gridItems = Array.from(DOM.grid.querySelectorAll('.product-item'));
|
|
let items = [];
|
|
DOM.gridItems.forEach(item => items.push(new Item(item)));
|
|
|
|
DOM.details = new Details();
|
|
}
|
|
|
|
});
|
|
|
|
function updateCounters() {
|
|
$(".countcontainer").each(function(e) {
|
|
var $roycountdown = $(this).find(".roycountdown");
|
|
var $roycount = $roycountdown.find(".roycount");
|
|
var $dataspecificpriceto = $roycount.attr('data-specific-price-to');
|
|
if ($roycountdown.length) {
|
|
$roycountdown.county({
|
|
endDateTime: new Date($dataspecificpriceto.replace(/-/g, "/")) , reflection: false, animation: 'none', theme: 'black',
|
|
titleDays:$roycount.data('days'),titleHours:$roycount.data('hours'),titleMinutes:$roycount.data('minutes'),titleSeconds:$roycount.data('seconds')
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateProductListDOM (data) {
|
|
$('#search_filters').replaceWith(data.rendered_facets);
|
|
$('#js-active-search-filters').replaceWith(data.rendered_active_filters);
|
|
$('#js-product-list-top').replaceWith(data.rendered_products_top);
|
|
$('#js-product-list').replaceWith(data.rendered_products);
|
|
$('#js-product-list-bottom').replaceWith(data.rendered_products_bottom);
|
|
$('#js-active-search-filters-mobile').replaceWith(data.rendered_active_filters);
|
|
|
|
let productMinitature = new ProductMinitature();
|
|
productMinitature.init();
|
|
|
|
}
|