Files
kupshop/web/common/static/wpj/wpj.cart.js
2025-08-02 16:30:27 +02:00

371 lines
12 KiB
JavaScript

$.widget('wpj.cart', {
options: {
$form: null,
delivery_types: null,
select_first: true,
reload_containers: null,
custom_delivery_error_callback: null,
js_shop_reload_event: false // call wpj.jsShop.refresh('cart-detail'); after change, should only be called in first step
},
reloadXMLHttpRequest: null,
doReloadCart: function(url) {
var data = this.options.$form.serializeArray(),
me = this;
var $parts = this.options.$form.find('[data-reload]');
if (this.options.reload_containers) {
$.merge($parts, this.options.reload_containers);
} else {
$.merge($parts, $('[data-reload=cart-info]'));
}
url = url || '?act=recount';
if (this.reloadXMLHttpRequest) {
this.reloadXMLHttpRequest.abort();
}
if (this.options.js_shop_reload_event && wpj.jsShop && 'clearCache' in wpj.jsShop) {
wpj.jsShop.clearCache();
}
this.reloadXMLHttpRequest = $.post(
url,
data,
function(data) {
var $newHtml = wpj.domUtils.parseHtml(data);
$newHtml.find('input[name=payment_id]').each(function() {
$(this).attr('name', 'payment_id_new');
});
var newParts = wpj.domUtils.crossFadeParts($parts, $newHtml, function($old, $new) {
$old.remove();
$new.find('input[name=payment_id_new]').each(function() {
var $this = $(this);
$this.attr('name', 'payment_id');
});
});
me.element.trigger('loaded', [$(newParts)]);
if (me.options.js_shop_reload_event && 'refresh' in wpj.jsShop) {
try {
wpj.jsShop.refresh('cart-detail'); // jsshop will refresh only if config.ts cartDetailRefresh is true
} catch (e) {
console.log('wpj.cart.js: ', e);
}
}
},
'html'
);
},
reloadCart: function() {
var me = this;
wpj.domUtils.resetTimer('cart', 500, function() {
me.doReloadCart();
});
},
getItem: function($this) {
return $this.closest('[data-cart=row]').find('input[name*=pieces]');
},
onSpinButton: function(e) {
// $item = input, $this = button
var $this = $(e.currentTarget);
var $item = this.getItem($this);
var diff = 0;
var step = $item.attr('step') ? parseFloat($item.attr('step')) : 1;
var precision = $item.data('precision') ? parseFloat($item.data('precision')) : 0;
var min = $item.attr('min') ? parseFloat($item.attr('min')) : 1;
// skryje button pokud BUTTON ma data-max="..."
// Bacha, musi se oifovat i v template, jinak se tlacitko po reloadu kosiku zase objevi
if ($this.data('max') === Number($item.val()) + step) {
$this.hide();
}
if ($this.data('cart') === 'plus' && parseFloat($item.attr('max')) === Number($item.val()) + step) {
$this.addClass('disabled');
}
if (
($this.data('cart') === 'plus' && parseFloat($item.attr('max')) === Number($item.val())) ||
($this.data('cart') === 'minus' && parseFloat($item.attr('min')) === Number($item.val()))
) {
return false;
}
if ($this.data('cart') === 'plus') {
diff = +step;
} else {
diff = -step;
}
if (Number($item.val()) + diff < min) {
diff = 0;
}
$item.val(Math.max(Number($item.val()) + diff, step).toFixed(precision));
this.reloadCart();
},
onRowDelete: function(e) {
var url = $(e.currentTarget).attr('href');
this._trigger('rowdelete', e, {
id: $(e.currentTarget)
.closest('[data-product-id]')
.data('product-id') // todo pridat data-atribut do ordering.cart s id, posilat v data id smazaneho produktu
});
this.doReloadCart(url);
e.preventDefault();
},
onPiecesKeydown: function(e) {
if (e.keyCode === 13) {
e.preventDefault();
$(e.target).blur();
}
},
onChange: function(e) {
var $this = $(e.target);
if ($this.data('cart') === 'pieces' && $this.val() === '') {
return;
}
if ($this.data('cart') === 'noreload' || $this.closest('[data-cart-noreload]').length) {
return;
}
this.reloadCart();
},
onPaymentChange: function(e) {
if (e) {
var id = $(e.target).val();
var $element = $('#payment_description_' + id);
$element.not(':visible').slideDown('slow');
$('.payment_description')
.not($element)
.filter(':visible')
.slideUp('slow');
const $selectedInput = $(e.currentTarget);
$selectedInput.closest('[data-box="payments"]').find('.payment-item.selected').removeClass('selected');
if($selectedInput.val() === '-1') {
$selectedInput.closest('.deliveries').removeClass('payment-selected');
} else {
$selectedInput.closest('.deliveries').addClass('payment-selected');
$selectedInput.closest('.payment-item').addClass('selected');
}
}
this._trigger('paymentchange', e);
document.querySelector('#cart').dispatchEvent(new CustomEvent('$cartpaymentchange', {
detail: {
originalEvent: e,
}
}));
},
onDeliveryChange: function(e) {
var me = this,
delivery_id = e ? $(e.target).val() : 0,
allowed_payments = this.options.delivery_types[delivery_id],
$payments = this.getPayments();
var $this,
enabled,
enabledCount = 0,
index;
$payments.each(function() {
$this = $(this);
index = $this.val().split('-')[0];
enabled = allowed_payments && allowed_payments[index] != undefined && !$this.data('exception');
if (enabled) {
enabledCount++;
}
if (!enabled && $this.prop('checked')) {
$this.prop('checked', false);
me.onPaymentChange();
}
me.disableDeliveryItem($this, !enabled);
});
if (
this.options.select_first &&
this.options.$form.find('input[name=payment_id]:checked').not(':disabled').length === 0
) {
enabledCount = 1;
}
if (enabledCount === 1) {
this.options.$form
.find('input[name=payment_id]')
.not(':disabled')
.eq(0)
.prop('checked', true).click();
}
if (e) {
$this = $(e.target);
var id = $this.val(),
$element = $('#delivery_description_' + id);
$element.not(':visible').slideDown('slow');
$('.delivery_description')
.not($element)
.filter(':visible')
.slideUp('slow');
} else {
$('.delivery_description')
.filter(':visible')
.slideUp('slow');
}
const $selectedInput = $(e.currentTarget);
$selectedInput.closest('[data-box="deliveries"]').find('[data-cart="item"].selected').removeClass('selected');
//pokud je mozne vybrat pouze jednu platbu a ta se predvybere (radek 191-197) tak te predvybrane neodebrat classu selected, pak je sice vybrana ale neni videt v collapsible deliveries (oprava tiket 9511)
if (enabledCount !== 1) {
$selectedInput.closest('.deliveries').find('.payment-item.selected').removeClass('selected');
}
if($selectedInput.val() === '-1') {
$selectedInput.closest('.deliveries').removeClass('delivery-selected payment-selected');
} else {
$selectedInput.closest('.deliveries').addClass('delivery-selected');
$selectedInput.closest('[data-cart="item"]').addClass('selected');
}
this._trigger('deliverychange', e, { delivery_id: delivery_id });
document.querySelector('#cart').dispatchEvent(new CustomEvent('$cartdeliverychange', {
detail: {
originalEvent: e,
delivery_id: delivery_id,
}
}));
},
disableDeliveryItem: function($item, disable) {
$item.prop('disabled', disable);
$item.closest('[data-cart=item]').toggleClass('disabled', disable);
},
initializeDeliveryTypes: function() {
// Convert deliveryTypes list to better format
var deliveries = {},
delivery;
for (var index in this.options.delivery_types) {
delivery = this.options.delivery_types[index];
if (deliveries[delivery[0]] === undefined) {
deliveries[delivery[0]] = {};
}
deliveries[delivery[0]][delivery[1]] = true;
}
this.options.delivery_types = deliveries;
// Disable unavailable fields
var $payments = this.getPayments();
// Disable all payments. Will get enabled again if delivery is selected
this.disableDeliveryItem($payments, true);
// Simulate click on pre-selected options
$('input[name=delivery_id][checked]', this.options.$form).click();
$('input[name=payment_id][checked]', this.options.$form).click();
},
getPayments: function () {
return this.options.$form.find('input[name=payment_id]').not('[data-payment-reset]');
},
getDeliveries: function () {
return this.options.$form.find('input[name=delivery_id]').not('[data-delivery-reset]');
},
onFormSubmit: function(hasError) {
$('[name="OrderNext"]').addClass('is-submitting');
wpj.domUtils.resetTimer('cart', 500, function() {
// Nic nedělám - zabráním tím reloadnutí košíku po tom, co jsem zmáčknul odeslání košíku
});
var deliveryPick = this.getDeliveries(),
paymentPick = this.getPayments();
hasError = hasError || {};
if (deliveryPick.length && !deliveryPick.is(':checked')) {
if (this.options.custom_delivery_error_callback) {
this._trigger('deliveryerror');
} else {
const delivery_alert = $('[data-alert-choose-delivery]').data('alert-choose-delivery');
window.alert(delivery_alert ? delivery_alert : 'Vyberte prosím způsob dopravy');
}
$('[name="OrderNext"]').removeClass('is-submitting');
hasError.error = true;
return false;
}
if (paymentPick.length && !paymentPick.is(':checked')) {
if (this.options.custom_delivery_error_callback) {
this._trigger('paymenterror');
} else {
const payment_alert = $('[data-alert-choose-payment]').data('alert-choose-payment');
window.alert(payment_alert ? payment_alert : 'Vyberte prosím typ platby');
}
$('[name="OrderNext"]').removeClass('is-submitting');
hasError.error = true;
return false;
}
},
onStepSubmit: function(e) {
$(e.currentTarget).addClass('is-submitting');
},
_create: function() {
var me = this;
this.options.$form = this.element.closest('form');
this._on(this.options.$form, {
'click [data-cart=plus], [data-cart=minus]': this.onSpinButton,
'click [data-cart=delete]': this.onRowDelete,
change: this.onChange,
ifChanged: this.onChange,
'keydown input[data-cart="pieces"]': this.onPiecesKeydown,
'click [name="OrderNext"]': this.onStepSubmit
});
if (this.options.delivery_types) {
this._on(this.options.$form, {
'click input[name=delivery_id]': this.onDeliveryChange,
'click input[name=payment_id]': this.onPaymentChange
});
this.initializeDeliveryTypes(this.options.delivery_types);
// Preselect if only one delivery
var $deliveries = $('input[name=delivery_id]');
if ($deliveries.length === 1 && !$deliveries.prop('checked')) {
$deliveries.eq(0).click();
}
if (this.options.select_first && $deliveries.filter(':checked').length === 0) {
$deliveries
.filter(':enabled')
.eq(0)
.click();
}
if (this.options.select_first) {
var $payments = $('input[name=payment_id]');
$payments.filter(':checked').eq(0).click();
}
this.options.$form.on('success.form.bv', function(w, hasError) {
return me.onFormSubmit(hasError);
});
}
}
});