593 lines
23 KiB
JavaScript
593 lines
23 KiB
JavaScript
"use strict";
|
|
|
|
var PubBuy;
|
|
|
|
(function() {
|
|
|
|
PubBuy = (function() {
|
|
|
|
function PubBuy() {
|
|
JsBase.jsModule = this;
|
|
this.jqCartArea = $(".cart-area");
|
|
this.jqCheckoutForm = $("#checkoutForm");
|
|
this.checkoutValidator = false;
|
|
this.init();
|
|
}
|
|
|
|
PubBuy.prototype = {
|
|
jqCartArea: false,
|
|
jqCheckoutForm: false,
|
|
checkoutValidator: false,
|
|
|
|
init: function() {
|
|
this.cacheCheckoutSectionState();
|
|
this.bindActions();
|
|
this.bindCheckoutValidation();
|
|
},
|
|
|
|
bindActions: function() {
|
|
var _this = this;
|
|
|
|
$(document).on("cart:updated", function(e, resp, options) {
|
|
e.stopImmediatePropagation();
|
|
e.preventDefault();
|
|
_this.updateCartPage(resp, options);
|
|
});
|
|
|
|
$(document).on("click", ".clear-cart-btn", function(e) {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
_this.clearCartAjax();
|
|
});
|
|
|
|
if (!this.jqCheckoutForm.length) {
|
|
return;
|
|
}
|
|
|
|
this.jqCheckoutForm.on("click", "button.acc-edit", function(e) {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
_this.expandCheckoutSection($(this).closest(".acc-info"));
|
|
});
|
|
|
|
this.jqCheckoutForm.on("click", "button.acc-save", function(e) {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
_this.saveCheckoutSection($(this).closest(".acc-info"));
|
|
});
|
|
|
|
this.jqCheckoutForm.on("click", "button.acc-cancel", function(e) {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
_this.resetCheckoutSectionAjax($(this).closest(".acc-info"));
|
|
});
|
|
},
|
|
|
|
updateCartPage: function(resp, options) {
|
|
if (!resp) {
|
|
return;
|
|
}
|
|
|
|
var action = options && options.action ? options.action : "";
|
|
var subtotal = String(resp.subtotal || "").trim();
|
|
var subtotalText = subtotal.length ? "€ " + subtotal : "";
|
|
|
|
if (resp.counter !== undefined) {
|
|
this.jqCartArea.find(".cart-counter").text(resp.counter);
|
|
}
|
|
|
|
if (subtotalText.length) {
|
|
this.jqCartArea.find(".js-cart-subtotal, .js-cart-total").text(subtotalText);
|
|
}
|
|
|
|
if (action === "remItem" && (!resp.counter || resp.counter < 1)) {
|
|
window.location.reload();
|
|
return;
|
|
}
|
|
|
|
if (!resp.item) {
|
|
return;
|
|
}
|
|
|
|
// Full view cart table refresh (from view cart page)
|
|
if (resp.cart_view_items_html) {
|
|
// cart-table-detail
|
|
var $cartTableDetail = $(".cart-table-detail");
|
|
if ($cartTableDetail.length) {
|
|
$cartTableDetail.replaceWith(resp.cart_view_items_html);
|
|
}
|
|
}
|
|
|
|
if (resp.cart_items_html) {
|
|
// Full drawer table refresh (from drawer)
|
|
var $cartDrawerTable = $(".cart-drawer-table");
|
|
if ($cartDrawerTable.length) {
|
|
$cartDrawerTable.replaceWith(resp.cart_items_html);
|
|
}
|
|
}
|
|
|
|
var $row = this.jqCartArea.find("[data-item='" + resp.item + "']");
|
|
if (!$row.length) {
|
|
return;
|
|
}
|
|
|
|
if (action === "remItem") {
|
|
$row.remove();
|
|
return;
|
|
}
|
|
|
|
if (resp.c !== undefined) {
|
|
$row.find(".js-qty-num").val(resp.c);
|
|
}
|
|
},
|
|
|
|
bindCheckoutValidation: function() {
|
|
var _this = this;
|
|
var requiredMsg = JsBase.gM && JsBase.gM.chkComp ? JsBase.gM.chkComp : "Please fill in the field!";
|
|
|
|
if (!this.jqCheckoutForm.length || typeof Validator === "undefined" || !$.isDefined(JsBase.dt.cCfg)) {
|
|
return;
|
|
}
|
|
|
|
this.checkoutValidator = new Validator(JsBase.dt.cCfg, "body", JsBase.gM);
|
|
|
|
if ($.isDefined(JsBase.dt.fData) && $.isDefined(JsBase.dt.fData.err)) {
|
|
this.checkoutValidator.showErrorsByObject(JsBase.dt.fData.err);
|
|
}
|
|
|
|
this.jqCheckoutForm.on("change", "input[name='sh_and_py[shipping_method]']", function() {
|
|
_this.toggleGroupError(".js-shipping-validate", this, requiredMsg, true);
|
|
});
|
|
|
|
this.jqCheckoutForm.on("change", "input[name='sh_and_py[payment_method]']", function() {
|
|
_this.toggleGroupError(".js-payment-validate", this, requiredMsg, true);
|
|
});
|
|
|
|
this.jqCheckoutForm.on("change", "input[name='confirmation[agree_to_terms]']", function() {
|
|
_this.toggleGroupError(".js-terms-validate", this, requiredMsg, $(this).is(":checked"));
|
|
});
|
|
|
|
this.jqCheckoutForm.on("submit", function(e) {
|
|
e.preventDefault();
|
|
|
|
if (!_this.isCheckoutFormValid(requiredMsg)) {
|
|
return;
|
|
}
|
|
|
|
_this.placeOrder();
|
|
});
|
|
|
|
},
|
|
|
|
isCheckoutFormValid: function(requiredMsg) {
|
|
var isValid = true;
|
|
|
|
this.syncBillingAddressFromShipping();
|
|
|
|
if (!this.checkoutValidator || !this.checkoutValidator.isFormValid()) {
|
|
isValid = false;
|
|
}
|
|
|
|
if (!this.jqCheckoutForm.find("input[name='sh_and_py[shipping_method]']:checked").length) {
|
|
this.toggleGroupError(".js-shipping-validate", this.jqCheckoutForm.find("input[name='sh_and_py[shipping_method]']").first(), requiredMsg, false);
|
|
isValid = false;
|
|
}
|
|
|
|
if (!this.jqCheckoutForm.find("input[name='sh_and_py[payment_method]']:checked").length) {
|
|
this.toggleGroupError(".js-payment-validate", this.jqCheckoutForm.find("input[name='sh_and_py[payment_method]']").first(), requiredMsg, false);
|
|
isValid = false;
|
|
}
|
|
|
|
if (!this.jqCheckoutForm.find("input[name='confirmation[agree_to_terms]']").is(":checked")) {
|
|
this.toggleGroupError(".js-terms-validate", this.jqCheckoutForm.find("input[name='confirmation[agree_to_terms]']"), requiredMsg, false);
|
|
isValid = false;
|
|
}
|
|
|
|
if (!isValid && this.checkoutValidator && typeof this.checkoutValidator.scrollToFirstError === "function") {
|
|
if (window.JsBase && typeof JsBase.shakeInvalidCheckboxes === "function") {
|
|
JsBase.shakeInvalidCheckboxes(this.jqCheckoutForm);
|
|
}
|
|
this.checkoutValidator.scrollToFirstError(this.jqCheckoutForm);
|
|
}
|
|
|
|
return isValid;
|
|
},
|
|
|
|
toggleGroupError: function(groupSelector, field, message, isValid) {
|
|
var $group = this.jqCheckoutForm.find(groupSelector).first();
|
|
|
|
if (!$group.length || !this.checkoutValidator) {
|
|
return;
|
|
}
|
|
|
|
if (isValid) {
|
|
this.checkoutValidator.hideError(field);
|
|
return;
|
|
}
|
|
|
|
this.checkoutValidator.showError(field, message);
|
|
},
|
|
|
|
placeOrder: function() {
|
|
if (!this.jqCheckoutForm.length) {
|
|
return;
|
|
}
|
|
this.clearCheckoutErrors();
|
|
if (this.jqCheckoutForm.data("submitting")) {
|
|
return;
|
|
}
|
|
|
|
var _this = this;
|
|
this.syncBillingAddressFromShipping();
|
|
var data = JsBase.getFields(this.jqCheckoutForm, false, "name");
|
|
data.checkout_action = "place-order";
|
|
this.jqCheckoutForm.data("submitting", true);
|
|
|
|
JsBase.ajaxLoader.jqAjaxCaller = this.jqCheckoutForm;
|
|
JsBase.ajaxLoader.jqAjaxSaveCaller = this.jqCheckoutForm.find("button[type='submit']").first();
|
|
JsBase.ajax(data, false, function(resp) {
|
|
_this.jqCheckoutForm.data("submitting", false);
|
|
|
|
if (resp && resp.error) {
|
|
if (resp.data && _this.checkoutValidator && typeof _this.checkoutValidator.showErrorsByObject === "function") {
|
|
_this.checkoutValidator.showErrorsByObject(resp.data);
|
|
}
|
|
|
|
if (resp.data && typeof resp.data === "object") {
|
|
if (resp.data.checkout) {
|
|
_this.showCheckoutNotice(resp.data.checkout);
|
|
} else if (resp.data.msg) {
|
|
_this.showCheckoutNotice(resp.data.msg);
|
|
}
|
|
} else if (resp.data) {
|
|
_this.showCheckoutNotice(resp.data);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (resp && resp.jsonok && resp.order_complete_url) {
|
|
window.location.href = resp.order_complete_url;
|
|
}
|
|
});
|
|
},
|
|
|
|
clearCheckoutErrors: function() {
|
|
if (this.checkoutValidator && typeof this.checkoutValidator.hideAllErrors === "function") {
|
|
this.checkoutValidator.hideAllErrors();
|
|
}
|
|
|
|
if (!this.jqCheckoutForm.length) {
|
|
return;
|
|
}
|
|
|
|
this.jqCheckoutForm.find(".checkout-form-notice").remove();
|
|
},
|
|
|
|
showCheckoutNotice: function(message) {
|
|
if (!this.jqCheckoutForm.length || !message) {
|
|
return;
|
|
}
|
|
|
|
var $notice = this.jqCheckoutForm.find(".checkout-form-notice").first();
|
|
if (!$notice.length) {
|
|
$notice = $("<div class='alert alert-danger meb-20 checkout-form-notice'></div>");
|
|
this.jqCheckoutForm.prepend($notice);
|
|
}
|
|
|
|
$notice.text(message);
|
|
},
|
|
|
|
cacheCheckoutSectionState: function() {
|
|
if (!this.jqCheckoutForm.length) {
|
|
return;
|
|
}
|
|
|
|
var _this = this;
|
|
this.jqCheckoutForm.find(".acc-info").each(function() {
|
|
var $section = $(this);
|
|
_this.updateCheckoutSectionSnapshot($section);
|
|
_this.syncCheckoutSectionVisibility($section);
|
|
});
|
|
},
|
|
|
|
expandCheckoutSection: function($section) {
|
|
if (!$section || !$section.length) {
|
|
return;
|
|
}
|
|
|
|
$section.find(".acc-detail-form").removeClass("d-none");
|
|
$section.find(".acc-edit").addClass("d-none");
|
|
this.syncCheckoutSectionVisibility($section);
|
|
},
|
|
|
|
collapseCheckoutSection: function($section) {
|
|
if (!$section || !$section.length) {
|
|
return;
|
|
}
|
|
|
|
$section.find(".acc-detail-form").addClass("d-none");
|
|
$section.find(".acc-edit").removeClass("d-none");
|
|
},
|
|
|
|
resetCheckoutSection: function($section) {
|
|
if (!$section || !$section.length) {
|
|
return;
|
|
}
|
|
|
|
$section.find(".acc-detail-form").find("input, textarea, select").each(function() {
|
|
var $field = $(this);
|
|
if ($field.is(":checkbox") || $field.is(":radio")) {
|
|
$field.prop("checked", false);
|
|
} else {
|
|
$field.val("");
|
|
}
|
|
});
|
|
|
|
this.syncCheckoutSectionVisibility($section);
|
|
this.updateCheckoutSectionSnapshot($section);
|
|
},
|
|
|
|
saveCheckoutSection: function($section) {
|
|
if (!$section || !$section.length) {
|
|
return;
|
|
}
|
|
|
|
var _this = this;
|
|
var requiredMsg = JsBase.gM && JsBase.gM.chkComp ? JsBase.gM.chkComp : "Please fill in the field!";
|
|
this.clearCheckoutErrors();
|
|
if (!this.isCheckoutSectionValid($section, requiredMsg)) {
|
|
return;
|
|
}
|
|
|
|
if (!this.isCheckoutSectionDirty($section)) {
|
|
this.collapseCheckoutSection($section);
|
|
return;
|
|
}
|
|
|
|
var section = String($section.data("checkout-section") || "");
|
|
var data = this.getCheckoutSectionData($section);
|
|
data.checkout_action = "section-save";
|
|
data.checkout_section = section;
|
|
|
|
JsBase.ajax(data, false, function(resp) {
|
|
if (resp && resp.error) {
|
|
if (resp.data && _this.checkoutValidator && typeof _this.checkoutValidator.showErrorsByObject === "function") {
|
|
_this.checkoutValidator.showErrorsByObject(resp.data);
|
|
} else if (_this.checkoutValidator && typeof _this.checkoutValidator.showErrorsByObject === "function") {
|
|
var errors = $.extend({}, resp);
|
|
delete errors.error;
|
|
delete errors.jsonok;
|
|
delete errors.data;
|
|
_this.checkoutValidator.showErrorsByObject(errors);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (resp && resp.jsonok) {
|
|
_this.updateCheckoutSectionSnapshot($section);
|
|
$section.find(".acc-detail-form").addClass("d-none");
|
|
$section.find(".acc-edit").removeClass("d-none");
|
|
return;
|
|
}
|
|
|
|
if (resp && resp.data && _this.checkoutValidator && typeof _this.checkoutValidator.showErrorsByObject === "function") {
|
|
_this.checkoutValidator.showErrorsByObject(resp.data.errors || resp.data);
|
|
}
|
|
});
|
|
},
|
|
|
|
resetCheckoutSectionAjax: function($section) {
|
|
if (!$section || !$section.length) {
|
|
return;
|
|
}
|
|
|
|
var _this = this;
|
|
var section = String($section.data("checkout-section") || "");
|
|
var data = {
|
|
checkout_action: "section-reset",
|
|
checkout_section: section
|
|
};
|
|
|
|
JsBase.ajax(data, false, function(resp) {
|
|
if (resp && resp.error) {
|
|
return;
|
|
}
|
|
|
|
if (resp && resp.jsonok) {
|
|
_this.clearCheckoutErrors();
|
|
_this.resetCheckoutSection($section);
|
|
if (resp.prefill && String($section.data("checkout-section") || "") === "address") {
|
|
_this.applyCheckoutAddressPrefill($section, resp.prefill);
|
|
}
|
|
_this.collapseCheckoutSection($section);
|
|
}
|
|
});
|
|
},
|
|
|
|
applyCheckoutAddressPrefill: function($section, prefill) {
|
|
if (!$section || !$section.length || !prefill) {
|
|
return;
|
|
}
|
|
|
|
var shipping = prefill.shipping_address || {};
|
|
var delivery = prefill.delivery_info || {};
|
|
var sameAsBill = prefill.delivery_same_as_bill === undefined ? true : !!Number(prefill.delivery_same_as_bill);
|
|
|
|
$.each(shipping, function(key, value) {
|
|
$section.find("[name='shipping_address[" + key + "]']").val(value || "");
|
|
});
|
|
$.each(delivery, function(key, value) {
|
|
$section.find("[name='delivery_info[" + key.replace("checkout_", "checkout_bill_") + "]']").val(value || "");
|
|
});
|
|
|
|
var $sameAsBill = $section.find("input[name='delivery_info[billing_address]']");
|
|
if ($sameAsBill.length) {
|
|
$sameAsBill.prop("checked", sameAsBill);
|
|
}
|
|
this.syncCheckoutSectionVisibility($section);
|
|
this.updateCheckoutSectionSnapshot($section);
|
|
},
|
|
|
|
getCheckoutSectionData: function($section) {
|
|
var data = JsBase.getFields($section, false, "name");
|
|
|
|
if (String($section.data("checkout-section") || "") === "address") {
|
|
data["delivery_info[billing_address]"] = data["delivery_info[billing_address]"] ? "same_as_bill" : "";
|
|
}
|
|
|
|
return data;
|
|
},
|
|
|
|
updateCheckoutSectionSnapshot: function($section) {
|
|
if (!$section || !$section.length) {
|
|
return "";
|
|
}
|
|
|
|
var snapshot = JSON.stringify(this.getCheckoutSectionData($section));
|
|
$section.data("checkoutSnapshot", snapshot);
|
|
return snapshot;
|
|
},
|
|
|
|
getCheckoutSectionSnapshot: function($section) {
|
|
if (!$section || !$section.length) {
|
|
return "";
|
|
}
|
|
|
|
return String($section.data("checkoutSnapshot") || "");
|
|
},
|
|
|
|
isCheckoutSectionDirty: function($section) {
|
|
return this.getCheckoutSectionSnapshot($section) !== JSON.stringify(this.getCheckoutSectionData($section));
|
|
},
|
|
|
|
syncCheckoutSectionVisibility: function($section) {
|
|
if (!$section || !$section.length) {
|
|
return;
|
|
}
|
|
|
|
var $sameAsBill = $section.find("input[name='delivery_info[billing_address]']");
|
|
var $billingBlock = $section.find(".acc-detail-hide").last();
|
|
|
|
if ($sameAsBill.length && $billingBlock.length) {
|
|
$billingBlock.toggleClass("d-none", $sameAsBill.is(":checked"));
|
|
}
|
|
},
|
|
|
|
getCheckoutSectionFields: function($section) {
|
|
var section = String($section.data("checkout-section") || "");
|
|
var $fields = $();
|
|
|
|
if (section === "address") {
|
|
$fields = $fields.add($section.find("input[name^='shipping_address[']"));
|
|
$fields = $fields.add($section.find("select[name^='shipping_address[']"));
|
|
$fields = $fields.add($section.find(".acc-detail-hide").not(".d-none").find("input[name^='delivery_info[']"));
|
|
$fields = $fields.add($section.find(".acc-detail-hide").not(".d-none").find("select[name^='delivery_info[']"));
|
|
$fields = $fields.add($section.find("input[name='delivery_info[billing_address]']"));
|
|
}
|
|
|
|
if (section === "shipping") {
|
|
$fields = $fields.add($section.find("input[name='sh_and_py[shipping_method]']"));
|
|
}
|
|
|
|
if (section === "payment") {
|
|
$fields = $fields.add($section.find("input[name='sh_and_py[payment_method]']"));
|
|
}
|
|
|
|
if (section === "notes") {
|
|
$fields = $fields.add($section.find("textarea[name='check-note']"));
|
|
}
|
|
|
|
return $fields;
|
|
},
|
|
|
|
isCheckoutSectionValid: function($section, requiredMsg) {
|
|
var section = String($section.data("checkout-section") || "");
|
|
var isValid = true;
|
|
|
|
this.syncCheckoutSectionVisibility($section);
|
|
|
|
if (!this.checkoutValidator) {
|
|
return true;
|
|
}
|
|
|
|
if (section === "shipping" || section === "payment") {
|
|
var $fields = this.getCheckoutSectionFields($section);
|
|
var $selected = $fields.filter(":checked");
|
|
|
|
if (!$selected.length) {
|
|
this.toggleGroupError(
|
|
section === "shipping" ? ".js-shipping-validate" : ".js-payment-validate",
|
|
$fields.first(),
|
|
requiredMsg,
|
|
false
|
|
);
|
|
isValid = false;
|
|
} else {
|
|
this.toggleGroupError(
|
|
section === "shipping" ? ".js-shipping-validate" : ".js-payment-validate",
|
|
$selected.first(),
|
|
requiredMsg,
|
|
true
|
|
);
|
|
}
|
|
} else {
|
|
isValid = this.checkoutValidator.isFormValid(this.getCheckoutSectionFields($section));
|
|
}
|
|
|
|
if (!isValid && this.checkoutValidator && typeof this.checkoutValidator.scrollToFirstError === "function") {
|
|
this.checkoutValidator.scrollToFirstError(this.jqCheckoutForm);
|
|
}
|
|
|
|
return isValid;
|
|
},
|
|
|
|
syncBillingAddressFromShipping: function() {
|
|
if (!this.jqCheckoutForm.length) {
|
|
return;
|
|
}
|
|
|
|
var $section = this.jqCheckoutForm.find(".acc-info[data-checkout-section='address']").first();
|
|
if (!$section.length) {
|
|
return;
|
|
}
|
|
|
|
var $sameAsBill = $section.find("input[name='delivery_info[billing_address]']");
|
|
if (!$sameAsBill.length || !$sameAsBill.is(":checked")) {
|
|
return;
|
|
}
|
|
|
|
var fields = [
|
|
"checkout_first_name",
|
|
"checkout_last_name",
|
|
"checkout_email",
|
|
"checkout_phone",
|
|
"checkout_address1",
|
|
"checkout_address2",
|
|
"checkout_country",
|
|
"checkout_city",
|
|
"checkout_zip"
|
|
];
|
|
|
|
for (var i = 0; i < fields.length; i++) {
|
|
var field = fields[i];
|
|
var $shipping = $section.find("input[name='shipping_address[" + field + "]']");
|
|
var $billing = $section.find("input[name='delivery_info[" + field.replace("checkout_", "checkout_bill_") + "]']");
|
|
|
|
if ($shipping.length && $billing.length) {
|
|
$billing.val($shipping.val());
|
|
}
|
|
}
|
|
},
|
|
|
|
clearCartAjax: function() {
|
|
JsBase.ajax({action: "clear", delAll: 1}, false, function(resp) {
|
|
if (resp && resp.jsonok) {
|
|
window.location.reload();
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
return PubBuy;
|
|
})();
|
|
})(); |