ElixirVault/www/system-brs-core/app/pubBuy/js/pubBuy.js

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;
})();
})();