File: /var/www/innodrive/src/js/modules/compare.js
import { $, $$, pll, pll_cat } from '@utils';
import axios from 'axios';
import qs from 'qs';
let currentCategoryId = null;
let productsList = [];
let notifyTimer;
const IN_COMPARE_CLASS = 'js-in-compare';
const COMPARE_CLASS = 'js-compare';
const COMPARE_ALL_BUTTON = 'js-compare-all';
const COMPARE_DIFF_BUTTON = 'js-compare-diff';
const initCompare = () => {
$('body').addEventListener('click', function (ev) {
const item = ev.target;
if (item.classList && item.classList.contains(COMPARE_CLASS) && !item.classList.contains(IN_COMPARE_CLASS)) {
ev.preventDefault();
const productId = parseInt(item.dataset.id);
const categoryId = $('[name="category_id"]')
? parseInt($('[name="category_id"]').value)
: parseInt(item.dataset.category_id);
if (addToCompare(productId, categoryId)) {
item.classList.add(IN_COMPARE_CLASS);
updateCompareCounter(productsList.length);
}
}
});
// const compareAllButton = $('.' + COMPARE_ALL_BUTTON);
// const compareDiffButton = $('.' + COMPARE_DIFF_BUTTON);
const compareContainer = $('section.compare');
let compareTable;
class CompareTable {
constructor (container) {
this.container = container;
this.allButton = container.querySelector('.' + COMPARE_ALL_BUTTON) || container.querySelector('.compare__filter .button-link:first-of-type');
this.diffButton = container.querySelector('.' + COMPARE_DIFF_BUTTON) || container.querySelector('.compare__filter .button-link:last-of-type');
this.table = container.querySelector('.compare__table');
this.rows = [...container.querySelectorAll('.compare__table tr:not(:last-of-type):not(.compare__row--buttons-mobile)')];
this.handlerAllButtonClick = this.handlerAllButtonClick.bind(this);
this.handlerDiffButtonClick = this.handlerDiffButtonClick.bind(this);
this.updateEvens = this.updateEvens.bind(this);
this.bind = this.bind.bind(this);
this.removeFromCompare = this.removeFromCompare.bind(this);
}
get sameRows () {
return this.rows.filter((row) => row.classList.contains('js-compare-same'));
}
handlerAllButtonClick (ev) {
ev.stopPropagation();
ev.preventDefault();
if (!this.allButton.classList.contains('compare-filter__button--active')) {
this.sameRows.forEach((row) => {
row.classList.remove('js-hidden');
});
this.diffButton.classList.remove('compare-filter__button--active');
}
this.allButton.classList.add('compare-filter__button--active');
this.updateEvens();
}
handlerDiffButtonClick (ev) {
ev.stopPropagation();
ev.preventDefault();
if (!this.diffButton.classList.contains('compare-filter__button--active')) {
this.sameRows.forEach((row) => {
row.classList.add('js-hidden');
});
this.allButton.classList.remove('compare-filter__button--active');
}
this.diffButton.classList.add('compare-filter__button--active');
this.updateEvens();
}
updateEvens () {
this.rows
.filter((row) => !row.classList.contains('js-hidden'))
.reduce((isEven, nextRow) => {
if (isEven) {
nextRow.classList.remove('js-even');
return false;
} else {
nextRow.classList.add('js-even');
return true;
}
}, true);
const resizeEvent = new Event('resize');
window.dispatchEvent(resizeEvent);
}
bind () {
if (this.allButton) {
this.allButton.addEventListener('click', this.handlerAllButtonClick);
}
if (this.diffButton) {
this.diffButton.addEventListener('click', this.handlerDiffButtonClick);
}
}
init () {
this.updateRows();
this.updateEvens();
this.initProductButtons();
this.bind();
}
updateRows () {
this.rows.slice(3).forEach((row, i) => {
const cells = [...row.querySelectorAll('td')];
if (cells.length <= 1) {
this.diffButton.classList.add('js-disabled');
row.classList.remove('js-hidden');
return;
}
const example = cells[0].textContent.trim();
const isSame = !cells.some((cell) => cell.textContent.trim() !== example);
if (isSame && !example) {
row.remove();
} else if (isSame) {
row.classList.add('js-compare-same');
} else {
row.classList.remove('js-compare-same');
}
});
this.rows = [...this.container.querySelectorAll('.compare__table tr:not(:last-of-type):not(.compare__row--buttons-mobile)')];
this.updateEvens();
}
initProductButtons () {
[...$$('.js-compare-remove')].forEach((button) => {
button.addEventListener('click', (ev) => {
ev.preventDefault();
ev.stopPropagation();
const productId = parseInt(button.dataset.id);
this.removeFromCompare(productId);
});
});
}
removeFromCompare (productId) {
productsList = productsList.filter(function (value) {
return value !== productId;
});
updateState();
[...$$('[data-tdid="' + productId + '"]')].forEach((item) => {
item.remove();
});
updateCompareCounter(productsList.length);
if (productsList.length == 0) {
this.container.classList.add('js-nothing-to-compare');
} else {
this.updateRows();
}
};
}
if (compareContainer) {
compareTable = new CompareTable(compareContainer);
compareTable.init();
}
};
class AlertController {
constructor (container) {
this.box = container;
this.timer = null;
this.cartToggle = document.querySelector('.user-nav__button--cart');
this.compareToggle = document.querySelector('.user-nav__button--compare');
container.addEventListener('click', () => {
clearTimeout(notifyTimer);
container.classList.remove('js-open');
if (this.cartToggle && !this.box.classList.contains('error') && this.box.classList.contains('alerts--cart')) {
this.cartToggle.click();
}
if (this.compareToggle && !this.box.classList.contains('.error') && this.box.classList.contains('alerts--compare')) {
this.compareToggle.click();
}
});
}
clearTimer () {
clearTimeout(this.timer);
this.timer = null;
}
showError (msg) {
this.clearTimer();
this.box.classList.remove('success', 'custom-success', 'custom-error');
if (msg) {
this.box.querySelector('.alerts__error .alerts__custom').textContent = msg;
this.box.classList.add('custom-error');
}
this.box.classList.add('js-open', 'error');
this.timer = setTimeout(() => {
this.box.classList.remove('js-open');
}, 5000);
}
showSuccess (msg, isCart, isCompare) {
this.clearTimer();
this.box.classList.remove('error', 'custom-error', 'custom-success', 'alerts--cart', 'alerts--compare');
if (msg) {
this.box.classList.add('custom-success');
this.box.querySelector('.alerts__success .alerts__custom').textContent = msg;
}
if (isCart) {
this.box.classList.add('alerts--cart');
}
if (isCompare) {
this.box.classList.add('alerts--compare');
}
this.box.classList.add('js-open', 'success');
this.timer = setTimeout(() => {
this.box.classList.remove('js-open');
}, 5000);
}
}
const alertBlock = $('.alerts');
alertBlock.alert = new AlertController(alertBlock);
const addToCompare = (productId, categoryId) => {
if (currentCategoryId === null || !productsList.length) {
currentCategoryId = categoryId;
productsList.push(productId);
updateState();
// compareNotify('Product added to compare list.');
alertBlock.alert.showSuccess(pll('Product added to compare list'), false, true)
return true;
} else if (currentCategoryId === categoryId) {
if (productsList.length < 5) {
productsList.push(productId);
updateState();
// compareNotify('Product added to compare list.');
alertBlock.alert.showSuccess(pll('Product added to compare list'), false, true);
return true;
} else {
// compareErrorNotify('You can compare not much than 5 products');
alertBlock.alert.showError(pll('You can compare not much than 5 products'));
return false;
}
} else {
// compareErrorNotify('You cannot add product to compare. Previously you have added products from category "' + categoryId + '". Clear you compare list and try again.');
alertBlock.alert.showError(pll('You cannot add product to compare. Previously you have added products from category') + ' ' + pll_cat(categoryId) + ' ' + pll('. Clear you compare list and try again.'));
return false;
}
};
const updateState = () => {
const state = {
productsList: productsList,
currentCategoryId: currentCategoryId
};
window.localStorage.setItem('compareState', JSON.stringify(state));
axios
.post(
'/wp-json/compare/save', qs.stringify({
productsList: productsList
})
);
};
const loadState = () => {
const currentState = window.localStorage.getItem('compareState');
if (currentState !== null) {
const obj = JSON.parse(currentState);
productsList = obj.productsList;
currentCategoryId = obj.currentCategoryId;
updateCompareCounter(productsList.length);
updateButtonsState(productsList);
}
};
export const initButtons = () => {
[...$$('.' + COMPARE_CLASS)].forEach((item) => {
const productId = parseInt(item.dataset.id);
if (productsList.indexOf(productId) !== -1) {
item.classList.add(IN_COMPARE_CLASS);
}
});
};
const updateButtonsState = (productsList) => {
[...productsList].forEach((productId) => {
const item = $('.js-compare[data-id="' + productId + '"]');
if (item) {
item.classList.add(IN_COMPARE_CLASS);
}
});
}
const updateCompareCounter = (count) => {
[...$$('.js-compare-count')].forEach((item) => {
item.textContent = count;
});
};
export default () => {
loadState();
initCompare();
updateState();
};