arch-8.x-1.x-dev/modules/cart/assets/js/api-cart.js
modules/cart/assets/js/api-cart.js
/**
* @file
* Mini-cart JS Behavior.
*/
/* global ArchApiCartRequest */
(function (Drupal, $, _, drupalSettings, window) {
'use strict';
var CART = {};
var CART_CONTENT = '';
function initable() {
return (
drupalSettings.arch_api_cart
&& drupalSettings.arch_api_cart.templates
&& drupalSettings.arch_api_cart.templates.cart
&& drupalSettings.arch_api_cart.templates.item
&& $(drupalSettings.arch_api_cart.templates.cart).length
&& $(drupalSettings.arch_api_cart.templates.item).length
);
}
Drupal.behaviors.arch_cart_api_cart = {
requests: [],
attach: function (context) {
// Prevent error when BigPipe is enabled.
if (!initable()) {
return;
}
// Prevent multiple init.
var processedClass = 'api-cart--processed'
, $body = $('body')
;
if ($body.hasClass(processedClass)) {
return;
}
var $mini_cart = $('#mini-cart-wrapper');
var templates = getTemplates();
var _self = this;
$body.attr('data-minicart-status', 'hidden');
$body.attr('cart-has-items', false);
$body
.addClass(processedClass)
.on('arch_cart_api_cart_update arch_cart_api_cart_update_and_show', function (ev) {
updateCart()
.done(function (data, status, jqXHR) {
CART = data.cart;
if (drupalSettings.arch_api_cart.settings.click_event === 'open') {
CART_CONTENT = renderCart(templates);
$mini_cart.empty().append(CART_CONTENT);
}
$('.api-cart--link').attr('data-count', CART.products);
if (drupalSettings.arch_api_cart.settings.show_cart_item_count) {
$('.api-cart--link .item-count').html(templates.count({
count: CART.products
}));
}
if (CART.products > 0) {
$body.attr('cart-has-items', true);
}
else {
$body.attr('cart-has-items', false);
}
if (ev.type === 'arch_cart_api_cart_update_and_show') {
$body.trigger('arch_cart_api_cart_show');
}
});
})
.on('arch_cart_api_cart_show', function () {
if (drupalSettings.arch_api_cart.settings.click_event === 'open') {
toggleCart($mini_cart, 'show');
}
})
.on('click', '.api-cart--link', function (ev) {
if ($(this).attr('data-api-cart-disabled') === 'disabled') {
ev.preventDefault();
}
else if (drupalSettings.arch_api_cart.settings.click_event === 'open') {
ev.preventDefault();
ev.stopPropagation();
toggleCart($mini_cart);
}
})
.on('change', ':input.mini-cart-item-quantity[data-type][data-id]', function (ev) {
var $input = $(this);
var data = {
key: $input.attr('data-key'),
type: $input.attr('data-type'),
id: $input.attr('data-id'),
quantity: parseFloat($input.val())
};
if (_self.requests[data.key]) {
_self.requests[data.key].abort();
delete _self.requests[data.key];
}
_self.requests[data.key] = ArchApiCartRequest(
'quantity',
data.quantity > 0
? drupalSettings.arch_api_cart.api.quantity
: drupalSettings.arch_api_cart.api.remove,
data,
CART
);
})
.on('click', '.mini-cart-item-remove[data-type][data-id]', function (ev) {
var $btn = $(this);
var workingClass = 'api-cart-item-quantity--working';
$btn.addClass(workingClass);
var data = {
key: $btn.attr('data-key'),
type: $btn.attr('data-type'),
id: $btn.attr('data-id')
};
ArchApiCartRequest('remove', drupalSettings.arch_api_cart.api.remove, data, CART)
.always(function () {
setTimeout(function () {
$btn.removeClass(workingClass);
}, 1500);
});
})
.on('arch_cart_api_do', function (ev, params) {
runTasks(
(params.tasks || []),
(params.data || {})
);
})
.trigger('arch_cart_api_cart_update')
;
$(document).on('click', function (e) {
if (
$mini_cart.is(':visible')
&& $mini_cart.has(e.target).length === 0
&& !$mini_cart.is(e.target)
) {
toggleCart($mini_cart, 'hide');
}
});
$(window).on('keyup', function (ev) {
if (ev.keyCode === 27) {
toggleCart($mini_cart, 'hide');
}
});
}
};
function getTemplates() {
var cart_tpl = $(drupalSettings.arch_api_cart.templates.cart).html()
, message_tpl = $(drupalSettings.arch_api_cart.templates.message).html()
, item_tpl = $(drupalSettings.arch_api_cart.templates.item).html()
, quantity_tpl = $(drupalSettings.arch_api_cart.templates.itemQuantity).html()
, remove_tpl = $(drupalSettings.arch_api_cart.templates.itemRemove).html()
, count_tpl = $(drupalSettings.arch_api_cart.templates.count).html()
;
return {
cart: _.template(cart_tpl),
message: _.template(message_tpl),
item: _.template(item_tpl),
quantity: _.template(quantity_tpl),
remove: _.template(remove_tpl),
count: _.template(count_tpl)
};
}
function updateCart() {
var conf = {
url: drupalSettings.arch_api_cart.api.cart,
method: 'get',
dataType: 'json',
data: {
theme: drupalSettings.arch_api_cart.settings.theme
}
};
return $.ajax(conf)
.fail(function (jqXHR, textStatus, errorThrown) {
// @todo alter user about error.
// eslint-disable-next-line no-console
console.warn(textStatus, errorThrown, jqXHR);
});
}
function renderCart(templates) {
var allowModifyQuantity = false
, allowRemove = false
;
if (
drupalSettings
&& drupalSettings.arch_api_cart
&& drupalSettings.arch_api_cart.settings
) {
allowModifyQuantity = drupalSettings.arch_api_cart.settings.allow_modify_quantity || false;
allowRemove = drupalSettings.arch_api_cart.settings.allow_remove || false;
}
var items = '';
for (var ii = 0, li = CART.items.length; ii < li; ii++) {
items += renderItem(CART.items[ii], templates, allowModifyQuantity, allowRemove);
}
var messages = '';
for (var im = 0, lm = CART.messages.length; im < lm; im++) {
messages += templates.message({message: CART.messages[im]});
}
return templates.cart({
messages: messages,
items: items,
grand_total: CART.total
});
}
function renderItem(item, templates, allow_modify, allow_remove) {
item.formatted_quantity = item.quantity;
item.remove = '';
var line_item = item._line_item;
if (allow_modify) {
item.formatted_quantity = templates.quantity({
quantity: line_item.quantity,
input_max: ((typeof line_item.max_quantity === 'undefined') ? false : parseInt(line_item.max_quantity)),
key: item._index,
type: line_item.type,
id: line_item.id
});
}
if (allow_remove) {
item.remove = templates.remove({
key: item._index,
type: line_item.type,
id: line_item.id
});
}
return templates.item(item);
}
function runTasks(tasks, data) {
var $body = $('body');
for (var i = 0, l = tasks.length; i < l; i++) {
if (typeof tasks[i] === 'string') {
if (tasks[i] === 'update_cart') {
$body.trigger('arch_cart_api_cart_update', data);
}
else if (tasks[i] === 'show_cart') {
$body.trigger('arch_cart_api_cart_show', data);
}
}
else if (typeof tasks[i] === 'object') {
if (tasks[i].message) {
// @todo implement this.
}
}
}
}
function toggleCart($mini_cart, action) {
var $body = $('body');
var status = $body.attr('data-minicart-status');
if (
action
&& (
(action === 'show' && status === 'visible')
|| (action === 'hide' && status === 'hidden')
)
) {
return;
}
if (
$body.attr('data-minicart-status') === 'visible'
|| action === 'hide'
) {
$body.attr('data-minicart-status', 'hidden');
}
else if (drupalSettings.arch_api_cart.settings.click_event === 'open') {
$body.attr('data-minicart-status', 'visible');
}
}
})(Drupal, jQuery, _, drupalSettings, window);
