564 lines
185 KiB
JavaScript
564 lines
185 KiB
JavaScript
|
|
/**
|
||
|
|
* Swiper 10.2.0
|
||
|
|
* Most modern mobile touch slider and framework with hardware accelerated transitions
|
||
|
|
* https://swiperjs.com
|
||
|
|
*
|
||
|
|
* Copyright 2014-2023 Vladimir Kharlampidi
|
||
|
|
*
|
||
|
|
* Released under the MIT License
|
||
|
|
*
|
||
|
|
* Released on: August 17, 2023
|
||
|
|
*/
|
||
|
|
|
||
|
|
var Swiper = function () { "use strict"; function e(e) { return null !== e && "object" == typeof e && "constructor" in e && e.constructor === Object } function t(s, a) { void 0 === s && (s = {}), void 0 === a && (a = {}), Object.keys(a).forEach((i => { void 0 === s[i] ? s[i] = a[i] : e(a[i]) && e(s[i]) && Object.keys(a[i]).length > 0 && t(s[i], a[i]) })) } const s = { body: {}, addEventListener() { }, removeEventListener() { }, activeElement: { blur() { }, nodeName: "" }, querySelector: () => null, querySelectorAll: () => [], getElementById: () => null, createEvent: () => ({ initEvent() { } }), createElement: () => ({ children: [], childNodes: [], style: {}, setAttribute() { }, getElementsByTagName: () => [] }), createElementNS: () => ({}), importNode: () => null, location: { hash: "", host: "", hostname: "", href: "", origin: "", pathname: "", protocol: "", search: "" } }; function a() { const e = "undefined" != typeof document ? document : {}; return t(e, s), e } const i = { document: s, navigator: { userAgent: "" }, location: { hash: "", host: "", hostname: "", href: "", origin: "", pathname: "", protocol: "", search: "" }, history: { replaceState() { }, pushState() { }, go() { }, back() { } }, CustomEvent: function () { return this }, addEventListener() { }, removeEventListener() { }, getComputedStyle: () => ({ getPropertyValue: () => "" }), Image() { }, Date() { }, screen: {}, setTimeout() { }, clearTimeout() { }, matchMedia: () => ({}), requestAnimationFrame: e => "undefined" == typeof setTimeout ? (e(), null) : setTimeout(e, 0), cancelAnimationFrame(e) { "undefined" != typeof setTimeout && clearTimeout(e) } }; function r() { const e = "undefined" != typeof window ? window : {}; return t(e, i), e } function n(e, t) { return void 0 === t && (t = 0), setTimeout(e, t) } function l() { return Date.now() } function o(e, t) { void 0 === t && (t = "x"); const s = r(); let a, i, n; const l = function (e) { const t = r(); let s; return t.getComputedStyle && (s = t.getComputedStyle(e, null)), !s && e.currentStyle && (s = e.currentStyle), s || (s = e.style), s }(e); return s.WebKitCSSMatrix ? (i = l.transform || l.webkitTransform, i.split(",").length > 6 && (i = i.split(", ").map((e => e.replace(",", "."))).join(", ")), n = new s.WebKitCSSMatrix("none" === i ? "" : i)) : (n = l.MozTransform || l.OTransform || l.MsTransform || l.msTransform || l.transform || l.getPropertyValue("transform").replace("translate(", "matrix(1, 0, 0, 1,"), a = n.toString().split(",")), "x" === t && (i = s.WebKitCSSMatrix ? n.m41 : 16 === a.length ? parseFloat(a[12]) : parseFloat(a[4])), "y" === t && (i = s.WebKitCSSMatrix ? n.m42 : 16 === a.length ? parseFloat(a[13]) : parseFloat(a[5])), i || 0 } function d(e) { return "object" == typeof e && null !== e && e.constructor && "Object" === Object.prototype.toString.call(e).slice(8, -1) } function c() { const e = Object(arguments.length <= 0 ? void 0 : arguments[0]), t = ["__proto__", "constructor", "prototype"]; for (let a = 1; a < arguments.length; a += 1) { const i = a < 0 || arguments.length <= a ? void 0 : arguments[a]; if (null != i && (s = i, !("undefined" != typeof window && void 0 !== window.HTMLElement ? s instanceof HTMLElement : s && (1 === s.nodeType || 11 === s.nodeType)))) { const s = Object.keys(Object(i)).filter((e => t.indexOf(e) < 0)); for (let t = 0, a = s.length; t < a; t += 1) { const a = s[t], r = Object.getOwnPropertyDescriptor(i, a); void 0 !== r && r.enumerable && (d(e[a]) && d(i[a]) ? i[a].__swiper__ ? e[a] = i[a] : c(e[a], i[a]) : !d(e[a]) && d(i[a]) ? (e[a] = {}, i[a].__swiper__ ? e[a] = i[a] : c(e[a], i[a])) : e[a] = i[a]) } } } var s; return e } function p(e, t, s) { e.style.setProperty(t, s) } function u(e) { let { swiper: t, targetPosition: s, side: a } = e; const i = r(), n = -t.translate; let l, o = null; const d = t.params.speed; t.wrapperEl.style.scrollSnapType = "none", i.cancelAnimationFrame(t.cssModeFrameID); const c = s > n ? "next" : "prev", p = (e, t) => "next" === c && e >= t || "prev" === c && e <= t, u = () => { l = (new Date).getTime(), null === o && (o = l
|
||
|
|
//# sourceMappingURL=swiper-bundle.min.js.map
|
||
|
|
|
||
|
|
/**
|
||
|
|
* LAZY LOADING
|
||
|
|
*/
|
||
|
|
|
||
|
|
function _extends() { return (_extends = Object.assign || function (t) { for (var e = 1; e < arguments.length; e++) { var n = arguments[e]; for (var o in n) Object.prototype.hasOwnProperty.call(n, o) && (t[o] = n[o]) } return t }).apply(this, arguments) } function _typeof(t) { return (_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (t) { return typeof t } : function (t) { return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t })(t) } !function (t, e) { "object" === ("undefined" == typeof exports ? "undefined" : _typeof(exports)) && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : t.LazyLoad = e() }(this, function () { "use strict"; var t = "undefined" != typeof window, e = t && !("onscroll" in window) || "undefined" != typeof navigator && /(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent), n = t && "IntersectionObserver" in window, o = t && "classList" in document.createElement("p"), r = { elements_selector: "img", container: e || t ? document : null, threshold: 300, thresholds: null, data_src: "src", data_srcset: "srcset", data_sizes: "sizes", data_bg: "bg", class_loading: "loading", class_loaded: "loaded", class_error: "error", load_delay: 0, auto_unobserve: !0, callback_enter: null, callback_exit: null, callback_reveal: null, callback_loaded: null, callback_error: null, callback_finish: null }, a = function (t, e) { return t.getAttribute("data-" + e) }, s = function (t, e, n) { var o = "data-" + e; null !== n ? t.setAttribute(o, n) : t.removeAttribute(o) }, i = function (t) { return "true" === a(t, "was-processed") }, c = function (t, e) { return s(t, "ll-timeout", e) }, l = function (t) { return a(t, "ll-timeout") }, u = function (t, e) { var n, o = new t(e); try { n = new CustomEvent("LazyLoad::Initialized", { detail: { instance: o } }) } catch (t) { (n = document.createEvent("CustomEvent")).initCustomEvent("LazyLoad::Initialized", !1, !1, { instance: o }) } window.dispatchEvent(n) }; var d = function (t, e) { t && t(e) }, f = function (t, e) { t._loadingCount += e, 0 === t._elements.length && 0 === t._loadingCount && d(t._settings.callback_finish) }, _ = function (t) { for (var e, n = [], o = 0; e = t.children[o]; o += 1)"SOURCE" === e.tagName && n.push(e); return n }, v = function (t, e, n) { n && t.setAttribute(e, n) }, b = function (t, e) { v(t, "sizes", a(t, e.data_sizes)), v(t, "srcset", a(t, e.data_srcset)), v(t, "src", a(t, e.data_src)) }, g = { IMG: function (t, e) { var n = t.parentNode; n && "PICTURE" === n.tagName && _(n).forEach(function (t) { b(t, e) }); b(t, e) }, IFRAME: function (t, e) { v(t, "src", a(t, e.data_src)) }, VIDEO: function (t, e) { _(t).forEach(function (t) { v(t, "src", a(t, e.data_src)) }), v(t, "src", a(t, e.data_src)), t.load() } }, m = function (t, e) { var n, o, r = e._settings, s = t.tagName, i = g[s]; if (i) return i(t, r), f(e, 1), void (e._elements = (n = e._elements, o = t, n.filter(function (t) { return t !== o }))); !function (t, e) { var n = a(t, e.data_src), o = a(t, e.data_bg); n && (t.style.backgroundImage = 'url("'.concat(n, '")')), o && (t.style.backgroundImage = o) }(t, r) }, h = function (t, e) { o ? t.classList.add(e) : t.className += (t.className ? " " : "") + e }, p = function (t, e, n) { t.addEventListener(e, n) }, y = function (t, e, n) { t.removeEventListener(e, n) }, E = function (t, e, n) { y(t, "load", e), y(t, "loadeddata", e), y(t, "error", n) }, w = function (t, e, n) { var r = n._settings, a = e ? r.class_loaded : r.class_error, s = e ? r.callback_loaded : r.callback_error, i = t.target; !function (t, e) { o ? t.classList.remove(e) : t.className = t.className.replace(new RegExp("(^|\\s+)" + e + "(\\s+|$)"), " ").replace(/^\s+/, "").replace(/\s+$/, "") }(i, r.class_loading), h(i, a), d(s, i), f(n, -1) }, k = function (t, e) { var n = function n(r) { w(r, !0, e), E(t, n, o) }, o = function o(r) { w(r, !1, e), E(t, n, o) }; !function (t, e, n) { p(t, "load", e), p(t, "loadeddata", e), p(t,
|
||
|
|
//# sourceMappingURL=lazyload.min.js.map
|
||
|
|
|
||
|
|
function formatCurrency(c) {
|
||
|
|
var a = parseFloat(c)
|
||
|
|
.toFixed(2)
|
||
|
|
.replace(/(\d)(?=(\d{3})+\.)/g, "$1.")
|
||
|
|
.toString(),
|
||
|
|
d = a.length;
|
||
|
|
return (a = a.substring(0, d - 3)), a;
|
||
|
|
}
|
||
|
|
|
||
|
|
function strToNumber(a) {
|
||
|
|
for (a += ""; 0 < a.indexOf(".");) a = a.replace(".", "");
|
||
|
|
var b = parseFloat(a);
|
||
|
|
return isNaN(b) ? 0 : b;
|
||
|
|
}
|
||
|
|
|
||
|
|
function formatDate(b) {
|
||
|
|
var b = new Date(1e3 * parseInt(b)),
|
||
|
|
c = b.getFullYear(),
|
||
|
|
d = b.getMonth() + 1,
|
||
|
|
e = b.getDate(),
|
||
|
|
f = b.getHours(),
|
||
|
|
g = b.getMinutes(),
|
||
|
|
h = b.getSeconds();
|
||
|
|
return e + "/" + d + "/" + c;
|
||
|
|
}
|
||
|
|
|
||
|
|
function convertToSlug(e) {
|
||
|
|
let r = e;
|
||
|
|
return r
|
||
|
|
.toLowerCase()
|
||
|
|
.replace(/à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ/g, "a")
|
||
|
|
.replace(/è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ/g, "e")
|
||
|
|
.replace(/ì|í|ị|ỉ|ĩ/g, "i")
|
||
|
|
.replace(/ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ/g, "o")
|
||
|
|
.replace(/ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ/g, "u")
|
||
|
|
.replace(/ỳ|ý|ỵ|ỷ|ỹ/g, "y")
|
||
|
|
.replace(/đ/g, "d")
|
||
|
|
.replace(/\u0300|\u0301|\u0303|\u0309|\u0323/g, "")
|
||
|
|
.replace(/\u02C6|\u0306|\u031B/g, "")
|
||
|
|
.replace(/[^\w ]+/g, "")
|
||
|
|
.replace(/ +/g, "-");
|
||
|
|
}
|
||
|
|
|
||
|
|
function validateEmail(a) {
|
||
|
|
return /^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/.test(
|
||
|
|
a
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
function validateTel(a) {
|
||
|
|
return (
|
||
|
|
(vnf_regex_tel = /((09|03|07|08|05|02)+([0-9]{8})\b)/g),
|
||
|
|
vnf_regex_tel.test(a)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
function debounce(a, b, c) {
|
||
|
|
var d;
|
||
|
|
return function () {
|
||
|
|
var e = this,
|
||
|
|
f = arguments,
|
||
|
|
g = c && !d;
|
||
|
|
clearTimeout(d),
|
||
|
|
(d = setTimeout(function () {
|
||
|
|
(d = null), c || a.apply(e, f);
|
||
|
|
}, b)),
|
||
|
|
g && a.apply(e, f);
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
// IS ON SCREEN CHECK
|
||
|
|
function isOnScreen(a) {
|
||
|
|
if (0 != a.length) {
|
||
|
|
var b = jQuery(window),
|
||
|
|
c = b.scrollTop(),
|
||
|
|
d = b.height(),
|
||
|
|
e = c + d,
|
||
|
|
f = jQuery(a),
|
||
|
|
g = f.offset().top,
|
||
|
|
h = f.height(),
|
||
|
|
i = g + h;
|
||
|
|
return (
|
||
|
|
(g >= c && g < e) || (i > c && i <= e) || (h > d && g <= c && i >= e)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// IS ON SCREEN HANDLER ( isOnScreenHandler({id: "#id",loadFn: function () {function(params);},}); )
|
||
|
|
function isOnScreenHandler(a) {
|
||
|
|
isOnScreen(a.id) && !$(a.id).hasClass("loaded")
|
||
|
|
? (a.loadFn(), $(a.id).addClass("loaded"))
|
||
|
|
: lazy_load_group.push({
|
||
|
|
id: a.id.slice(1, a.length),
|
||
|
|
target: a.id,
|
||
|
|
loadFn: function () {
|
||
|
|
a.loadFn();
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// LAZY LOADING BLOCK
|
||
|
|
var lazy_load_group = [];
|
||
|
|
|
||
|
|
// LAZY LOADING IMAGE
|
||
|
|
function runLazyImageLoad() {
|
||
|
|
var lazyLoadInstance = new LazyLoad({
|
||
|
|
elements_selector: ".lazy"
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// FADE TOGGLE
|
||
|
|
function fadeToggle(target) {
|
||
|
|
$(target).fadeToggle();
|
||
|
|
}
|
||
|
|
|
||
|
|
// SCROLL TO ELEMENT
|
||
|
|
function scrollElement(target) {
|
||
|
|
document.querySelector(target).scrollIntoView({ behavior: 'smooth' });
|
||
|
|
}
|
||
|
|
|
||
|
|
// CALL MODAL SUCCESS
|
||
|
|
function modalSuccess() {
|
||
|
|
const successForm = document.querySelector(".success-form");
|
||
|
|
successForm.classList.toggle("hide");
|
||
|
|
setTimeout(function () {
|
||
|
|
successForm.classList.toggle("hide");
|
||
|
|
}, 1200);
|
||
|
|
}
|
||
|
|
|
||
|
|
// VIEW MORE CONTENT HANDLER
|
||
|
|
function viewMoreHandler(target) {
|
||
|
|
if ($(target)) $(target).each(function () {
|
||
|
|
const type = $(this).attr('vm-type') ? $(this).attr('vm-type') : 'html';
|
||
|
|
const check = type === 'html' ? $(this).find('.vm-content').get(0).scrollHeight : $(this).find('.vm-list .vm-list-item').length;
|
||
|
|
const text = $(this).attr('vm-text') ? $(this).attr('vm-text') : 'Xem thêm';
|
||
|
|
const text_reverse = $(this).attr('vm-text-reverse') ? $(this).attr('vm-text-reverse') : 'Thu gọn';
|
||
|
|
const limited = parseInt($(this).attr('vm-limited')) ? parseInt($(this).attr('vm-limited')) : 500;
|
||
|
|
|
||
|
|
if (check <= limited) {
|
||
|
|
if (type === 'html') $(this).find('.vm-content').removeClass('blur')
|
||
|
|
$(this).find('.vm-btn').remove();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (type === 'list') $(this).find(`.vm-list .vm-list-item:nth-child(n + ${limited + 1})`).hide();
|
||
|
|
|
||
|
|
$(this).on('click', function () {
|
||
|
|
viewMoreAction(this, type, text, text_reverse, limited);
|
||
|
|
})
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
function viewMoreAction(_this, type, text, text_reverse, limited) {
|
||
|
|
const $btn = $(_this).find('.vm-btn');
|
||
|
|
const $icon = $btn.find('.vm-btn-icon').length ? $btn.find('.vm-btn-icon')[0].outerHTML : '';
|
||
|
|
const btn_text = $btn.text().replace(/\s/g, '').toLocaleLowerCase();
|
||
|
|
const text_check = text.replace(/\s/g, '').toLocaleLowerCase();
|
||
|
|
|
||
|
|
switch (type) {
|
||
|
|
case 'html':
|
||
|
|
const $content = $(_this).find(".vm-content");
|
||
|
|
$content.toggleClass("max-height-none").toggleClass("blur");
|
||
|
|
if (!$($content).hasClass("max-height-none")) $(_this).get(0).scrollIntoView({ behavior: 'smooth' });
|
||
|
|
break;
|
||
|
|
case 'list':
|
||
|
|
$(_this).find(`.vm-list .vm-list-item:nth-child(n + ${limited + 1})`).fadeToggle();
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
btn_text.indexOf(text_check) !== -1 ? $btn.html(`${text_reverse} ${$icon}`).addClass('show-less') : $btn.html(`${text} ${$icon}`).removeClass('show-less');
|
||
|
|
}
|
||
|
|
|
||
|
|
// SEARCH HANDLER (type = "search/search-article")
|
||
|
|
function searchHandler(target, type) {
|
||
|
|
const $search_input = $(target).find(".search-bar-input");
|
||
|
|
const $search_result = $(target).find(".search-results");
|
||
|
|
const $search_result_list = $(target).find(".search-results-list");
|
||
|
|
|
||
|
|
$search_input.on("click", function () {
|
||
|
|
if ($search_result_list.children().length > 0) $search_result.show();
|
||
|
|
});
|
||
|
|
|
||
|
|
$search_input.on("keyup", debounce(function (e) {
|
||
|
|
let search_value = e.target.value;
|
||
|
|
|
||
|
|
if (search_value) searchPopup(search_value, type, target);
|
||
|
|
else {
|
||
|
|
$search_result.hide();
|
||
|
|
$search_result_list.children().remove();
|
||
|
|
}
|
||
|
|
}, 500));
|
||
|
|
}
|
||
|
|
|
||
|
|
function searchPopup(value, type, target) {
|
||
|
|
const params = {
|
||
|
|
action: "search",
|
||
|
|
action_type: type,
|
||
|
|
sort: "order",
|
||
|
|
q: value,
|
||
|
|
};
|
||
|
|
|
||
|
|
Hura.Ajax.get("search", params).then(function (data) {
|
||
|
|
//console.log(data.list);
|
||
|
|
|
||
|
|
const $search_result = $(target).find(".search-results");
|
||
|
|
const $search_result_list = $(target).find(".search-results-list");
|
||
|
|
const $search_result_total = $(target).find(".search-results-total");
|
||
|
|
const search_href = type === "search" ? `tim?q=${value}` : `/tim-bai?q=${value}`;
|
||
|
|
|
||
|
|
if (data.list.length > 0) {
|
||
|
|
let html = Hura.Template.parse(search_results_tpl, data.list);
|
||
|
|
Hura.Template.render($search_result_list, html);
|
||
|
|
$search_result_total.html(`Xem tất cả <b>${data.total}</b> kết quả tìm được`).attr('href', search_href);
|
||
|
|
} else {
|
||
|
|
$search_result_list.html(`
|
||
|
|
<div class="search-alert text-center color-red py-4 px-3">
|
||
|
|
<p>Không thể tìm thấy kết quả phù hợp.</p>
|
||
|
|
<p>Vui lòng thử với từ khóa khác...</p>
|
||
|
|
</div>
|
||
|
|
`);
|
||
|
|
$search_result_total.html('Không có kết quả').attr('href', 'javascript:;');
|
||
|
|
}
|
||
|
|
|
||
|
|
$search_result.show();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// CLICK OUTSIDE CLOSE SEARCH
|
||
|
|
function closeWhenClickOutside() {
|
||
|
|
$(document).on("click", function (e) {
|
||
|
|
const $search_block = $(".search-bar");
|
||
|
|
const $search_result = $(".search-results")
|
||
|
|
|
||
|
|
if (!$search_block.is(e.target) && $search_block.has(e.target).length === 0) $search_result.fadeOut();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// ADD ITEM TO CART SUCCESS FORM
|
||
|
|
function addCart(id) {
|
||
|
|
Hura.Cart.Product.add(id, 0, { quantity: 1 }).then(function (add_status) {
|
||
|
|
//console.log('addcart:', add_status);
|
||
|
|
if (add_status.status === "error") callModal("error", "Sản phẩm đã có sẵn trong giỏ hàng");
|
||
|
|
else {
|
||
|
|
modalSuccess();
|
||
|
|
getHeaderCartListProductNew(add_status);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// CART HEADER HANDLER
|
||
|
|
function headerCartHandler() {
|
||
|
|
headerCartPopup();
|
||
|
|
headerCartChange();
|
||
|
|
}
|
||
|
|
|
||
|
|
// CART HEADER POPUP
|
||
|
|
function headerCartPopup() {
|
||
|
|
$(".header-cart").on("mouseenter", function () {
|
||
|
|
const $target = $('#js-cart-ttip-container');
|
||
|
|
|
||
|
|
if (!$target.hasClass('loaded')) {
|
||
|
|
Hura.Cart.getCart().then(function (data) {
|
||
|
|
//console.log(data);
|
||
|
|
getHeaderCartListProductNew(data);
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
$target.addClass('loaded');
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// CART HEADER CHANGE
|
||
|
|
function headerCartChange() {
|
||
|
|
Hura.Cart.getSummary().then(function (data) {
|
||
|
|
//console.log(data);
|
||
|
|
const $target = $("#js-header-cart-amount");
|
||
|
|
if (data.total_item > 0) $target.show().html(data.total_item);
|
||
|
|
else $target.hide();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// CART HEADER LIST
|
||
|
|
function getHeaderCartListProductNew(data) {
|
||
|
|
//console.log(data);
|
||
|
|
const target = "#js-cart-ttip-container";
|
||
|
|
|
||
|
|
if (data.length > 0) {
|
||
|
|
let header_cart_tpl = "";
|
||
|
|
let header_cart_total = 0;
|
||
|
|
let header_cart_quantity = 0;
|
||
|
|
data.forEach(function (item) {
|
||
|
|
header_cart_total += item.in_cart.total_price;
|
||
|
|
header_cart_quantity += item.in_cart.quantity;
|
||
|
|
|
||
|
|
header_cart_tpl += `
|
||
|
|
<div class="compare-item js-compare-item">
|
||
|
|
<div class="compare-item-img">
|
||
|
|
<a href="${item.item_info.productUrl}" class="style-img-block">
|
||
|
|
<img src="${item.item_info.productImage.large}" alt="${item.item_info.productName}" class="style-img-content" />
|
||
|
|
</a>
|
||
|
|
</div>
|
||
|
|
<div class="compare-item-info">
|
||
|
|
<a href="${item.item_info.productUrl}" class="compare-item-name line-clamp-2">${item.item_info.productName} ${item.item_info.variant_info == null ? "" : `| <span class="color-primary">${item.item_info.variant_info.name}</span>`}</a>
|
||
|
|
<div class="compare-item-price">
|
||
|
|
<b style="display:inline;color:#000">x ${item.in_cart.quantity}</b>
|
||
|
|
<b style="width:auto;color:#000">
|
||
|
|
${item.in_cart.total_price > 0 ? item.in_cart.total_price.toLocaleString() + ' VNĐ' : 'Liên hệ'}
|
||
|
|
</b>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
`;
|
||
|
|
})
|
||
|
|
$(target).html(header_cart_tpl);
|
||
|
|
|
||
|
|
$("#js-cart-ttip-price-block").show();
|
||
|
|
$("#js-header-cart-quantity").html(`<i>(Số lượng: ${header_cart_quantity} sản phẩm)</i>`);
|
||
|
|
$("#js-header-cart-total-price").html(header_cart_total.toLocaleString() + " VNĐ");
|
||
|
|
$("#js-header-cart-amount").show().html(data.length);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// REVIEW
|
||
|
|
function convertAvatarUser() {
|
||
|
|
$(".js-avatar-name").each(function () {
|
||
|
|
var name = $(this).text().split("", 1);
|
||
|
|
$(this).html(name);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// GET REVIEW COMMENT LIST
|
||
|
|
function getReviewCommentList(product_id, item_type, search_text, search_field, sort, action_type, type) {
|
||
|
|
const params = {
|
||
|
|
action_type: action_type,
|
||
|
|
item_type: item_type,
|
||
|
|
item_id: product_id,
|
||
|
|
search: search_text,
|
||
|
|
search_field: search_field,
|
||
|
|
order_by: sort,
|
||
|
|
};
|
||
|
|
|
||
|
|
Hura.Ajax.get(type, params).then(function (data) {
|
||
|
|
//console.log(data);
|
||
|
|
if (data.length === 0) return;
|
||
|
|
const newData = data.filter(obj => { return (obj.approved == "1" || obj.is_user_admin == "1") });
|
||
|
|
|
||
|
|
if (newData.length > 0) {
|
||
|
|
let html = type === 'review' ? Hura.Template.parse(review_tpl, newData) : Hura.Template.parse(comment_tpl, newData);
|
||
|
|
Hura.Template.render(`#js-${type}-list`, html);
|
||
|
|
convertAvatarUser();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// POST REVIEW COMMENT
|
||
|
|
function postComment(id, reply, type) {
|
||
|
|
const checkForm = checkFormGlobal(`#js-${type}-form-${id}`, '#d9d9d9');
|
||
|
|
if (!checkForm.result) return false;
|
||
|
|
|
||
|
|
var item_type = $("[name='user_post[item_type]']").val();
|
||
|
|
var item_id = $("[name='user_post[item_id]']").val();
|
||
|
|
var item_title = $("[name='user_post[item_title]']").val();
|
||
|
|
var title = $("[name='user_post[title]']").val();
|
||
|
|
// var avatar = $("[name='user_post[user_avatar]']").val();
|
||
|
|
|
||
|
|
var rate = type === "comment" ? 5 : $(".rating-comment input:checked").val();
|
||
|
|
var alert_title = type === "comment" ? "bình luận" : "đánh giá";
|
||
|
|
var alert_text = reply === "" ? "" : "phản hồi ";
|
||
|
|
|
||
|
|
var email = checkForm.values.email;
|
||
|
|
var name = checkForm.values.name;
|
||
|
|
var content = checkForm.values.content;
|
||
|
|
|
||
|
|
var params;
|
||
|
|
var info = {
|
||
|
|
item_type: item_type,
|
||
|
|
item_id: item_id,
|
||
|
|
item_title: item_title,
|
||
|
|
user_email: email,
|
||
|
|
user_name: name,
|
||
|
|
user_tel: "",
|
||
|
|
user_avatar: "",
|
||
|
|
user_note: "",
|
||
|
|
rate: rate,
|
||
|
|
title: title,
|
||
|
|
content: content,
|
||
|
|
files: "",
|
||
|
|
}
|
||
|
|
|
||
|
|
if (reply == "") params = { action_type: type, info: info };
|
||
|
|
else params = { action_type: `${type}-reply`, info: { ...info, reply_to: id } };
|
||
|
|
|
||
|
|
Hura.Ajax.post("customer", params).then(function (data) {
|
||
|
|
callModal("success", `Bạn đã gửi ${alert_text}${alert_title} thành công!`, "hideModalReLoad()");
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// CHECK FORM WITH INPUT HAS ATTRIBUTE "check-type"
|
||
|
|
function checkFormGlobal(targetForm, borderColorDefault) {
|
||
|
|
const listTotalInputs = $(`${targetForm} [check-type]`);
|
||
|
|
const listcheckAlerts = $(`${targetForm} [check-alert]`);
|
||
|
|
let error = "";
|
||
|
|
let inputsCheckData = [];
|
||
|
|
let listErrorInputs = [];
|
||
|
|
let inputValueData = {};
|
||
|
|
|
||
|
|
// CREATE ARRAY DATA INPUT
|
||
|
|
listTotalInputs.each(function () {
|
||
|
|
let id = $(this).attr('id');
|
||
|
|
let type = $(this).attr('check-type');
|
||
|
|
inputsCheckData = [...inputsCheckData, { id: id, type: type }];
|
||
|
|
})
|
||
|
|
|
||
|
|
// RESET DEFAULT
|
||
|
|
listTotalInputs.css('border-color', borderColorDefault);
|
||
|
|
if (listcheckAlerts.length) listcheckAlerts.remove();
|
||
|
|
|
||
|
|
// CHECK INPUT AND CREATE ERROR
|
||
|
|
inputsCheckData.forEach(function (input) {
|
||
|
|
let inputEl = document.getElementById(input.id);
|
||
|
|
let inputValue = inputEl.value;
|
||
|
|
let inputType = input.type;
|
||
|
|
|
||
|
|
inputValueData = { ...inputValueData, [inputType]: inputValue };
|
||
|
|
|
||
|
|
switch (inputType) {
|
||
|
|
case 'email':
|
||
|
|
if (validateEmail(inputValue) == false) errorInputHandler(inputEl, 'Email không hợp lệ');
|
||
|
|
break;
|
||
|
|
case 'name':
|
||
|
|
if (inputValue.length < 2 && 1 < 2) errorInputHandler(inputEl, 'Tên quá ngắn (tối thiểu 2 ký tự)');
|
||
|
|
break;
|
||
|
|
case 'tel':
|
||
|
|
if (!validateTel(inputValue)) errorInputHandler(inputEl, 'Số điện thoại không hợp lệ');
|
||
|
|
break;
|
||
|
|
case 'address':
|
||
|
|
if (inputValue.length < 6 && 1 < 2) errorInputHandler(inputEl, 'Bạn chưa nhập địa chỉ (tối thiểu 6 ký tự)');
|
||
|
|
break;
|
||
|
|
case 'province':
|
||
|
|
if (inputValue === '') errorInputHandler(inputEl, 'Bạn chưa chọn Tỉnh/Thành phố');
|
||
|
|
break;
|
||
|
|
case 'district':
|
||
|
|
if (inputValue === '') errorInputHandler(inputEl, 'Bạn chưa chọn Quận/Huyện');
|
||
|
|
break;
|
||
|
|
case 'ward':
|
||
|
|
if (inputValue === '') errorInputHandler(inputEl, 'Bạn chưa chọn Phường/Xã');
|
||
|
|
break;
|
||
|
|
case 'content':
|
||
|
|
if (inputValue.length < 8 && 1 < 2) errorInputHandler(inputEl, 'Bạn chưa nhập nội dung (tối thiểu 8 ký tự)');
|
||
|
|
break;
|
||
|
|
case 'password':
|
||
|
|
if (inputValue.length < 6 && 1 < 2) errorInputHandler(inputEl, 'Bạn chưa nhập mật khẩu/ Mật khẩu quá yếu (tối thiểu 6 ký tự)');
|
||
|
|
break;
|
||
|
|
case 'password-repeat':
|
||
|
|
let passwordValue = document.querySelector('[check-type="password"]').value;
|
||
|
|
if (inputValue !== passwordValue) errorInputHandler(inputEl, 'Mật khẩu nhập lại chưa trùng khớp');
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
// ERROR INPUT HANDLER
|
||
|
|
function errorInputHandler(inputEl, errorTitle) {
|
||
|
|
listErrorInputs = [...listErrorInputs, inputEl];
|
||
|
|
$(inputEl).after(`<p class="alert-text" check-alert>${errorTitle}</p>`);
|
||
|
|
error += `<li>${errorTitle}</li>`;
|
||
|
|
}
|
||
|
|
|
||
|
|
// SHOW ERROR
|
||
|
|
if (error !== '') {
|
||
|
|
$(listErrorInputs).css('border-color', '#e80000');
|
||
|
|
callModal("error", `<ul>${error}</ul>`);
|
||
|
|
return { result: false };
|
||
|
|
} else return { result: true, values: inputValueData };
|
||
|
|
}
|
||
|
|
|
||
|
|
// CALL GLOBAL ALERT MODAL
|
||
|
|
function callModal(type, content, callback) {
|
||
|
|
let modal_type, modal_title, modal_icon;
|
||
|
|
let modal_callback = callback ? callback : 'hideModal()';
|
||
|
|
let modal_btn = `<div class="global-popup-modal__button submit" onclick="${modal_callback}">Đóng</div>`;
|
||
|
|
|
||
|
|
switch (type) {
|
||
|
|
case 'success':
|
||
|
|
modal_type = 'success';
|
||
|
|
modal_title = 'Thành công!';
|
||
|
|
modal_icon = 'M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z';
|
||
|
|
break;
|
||
|
|
case 'error':
|
||
|
|
modal_type = 'error';
|
||
|
|
modal_title = 'Có lỗi xảy ra!';
|
||
|
|
modal_icon = 'M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24V264c0 13.3-10.7 24-24 24s-24-10.7-24-24V152c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z';
|
||
|
|
break;
|
||
|
|
case 'warning':
|
||
|
|
modal_type = 'warning';
|
||
|
|
modal_title = 'Cảnh báo!';
|
||
|
|
modal_icon = 'M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480H40c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24V296c0 13.3 10.7 24 24 24s24-10.7 24-24V184c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z';
|
||
|
|
modal_btn = `
|
||
|
|
<div class="global-popup-modal__button-box">
|
||
|
|
<div class="global-popup-modal__button cancel" onclick="hideModal()">Hủy bỏ</div>
|
||
|
|
<div class="global-popup-modal__button submit" onclick="${modal_callback}">Xác nhận</div>
|
||
|
|
</div>
|
||
|
|
`;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
const modal_html = `
|
||
|
|
<div class="global-popup-modal__container ${modal_type}">
|
||
|
|
<svg class="global-popup-modal__icon" xmlns="http://www.w3.org/2000/svg" height="2em" viewBox="0 0 512 512">
|
||
|
|
<path d="${modal_icon}" />
|
||
|
|
</svg>
|
||
|
|
<span class="global-popup-modal__title">${modal_title}</span>
|
||
|
|
<div class="global-popup-modal__noffy">${content}</div>
|
||
|
|
${modal_btn}
|
||
|
|
</div>
|
||
|
|
`;
|
||
|
|
|
||
|
|
$('.global-popup-modal').html(modal_html).removeClass('hide-modal');
|
||
|
|
$('.global-popup-frame').removeClass('hide-modal').fadeIn();
|
||
|
|
$('body').css('overflow', 'hidden');
|
||
|
|
}
|
||
|
|
|
||
|
|
// CLOSE GLOBAL ALERT MODAL
|
||
|
|
function hideModal() {
|
||
|
|
$('.global-popup-frame').addClass('hide-modal');
|
||
|
|
$('.global-popup-modal').addClass('hide-modal');
|
||
|
|
$('body').css('overflow', 'auto');
|
||
|
|
}
|
||
|
|
|
||
|
|
// CLOSE GLOBAL ALERT MODAL WITH PAGE RELOAD
|
||
|
|
function hideModalReLoad(href) {
|
||
|
|
hideModal();
|
||
|
|
setTimeout(function () {
|
||
|
|
if (href) window.location.href = href
|
||
|
|
else location.reload();
|
||
|
|
}, 1200);
|
||
|
|
}
|