642 lines
188 KiB
JavaScript
642 lines
188 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);
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
// LAZY LOADING BLOCK
|
||
|
|
var lazy_load_group = [];
|
||
|
|
|
||
|
|
// LAZY LOADING IMAGE
|
||
|
|
function runLazyImageLoad() {
|
||
|
|
var lazyLoadInstance = new LazyLoad({
|
||
|
|
elements_selector: ".lazy"
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// 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();
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// 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);
|
||
|
|
}
|
||
|
|
|
||
|
|
// ARCCODION HANDLER
|
||
|
|
function arccodionHandler(target, responsive) {
|
||
|
|
if (responsive && window.screen.availWidth > responsive) return;
|
||
|
|
|
||
|
|
$(target).on("click", function () {
|
||
|
|
const $arc_container = $(this).closest(".arc-container");
|
||
|
|
const $arc_item = $(this).closest(".arc-item");
|
||
|
|
const $arc_content = $arc_item.find(".arc-content");
|
||
|
|
const $arc_icon = $arc_item.find(".arc-icon");
|
||
|
|
|
||
|
|
if (!$arc_content.hasClass('active')) {
|
||
|
|
$arc_container.find(".arc-content").slideUp().removeClass("active");
|
||
|
|
if ($arc_icon) $arc_container.find(".arc-icon").removeClass("rotate");
|
||
|
|
}
|
||
|
|
|
||
|
|
$arc_content.slideToggle().toggleClass("active");
|
||
|
|
if ($arc_icon) $arc_icon.toggleClass("rotate");
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// VIEW MORE CONTENT HANDLER
|
||
|
|
function viewMoreHandler(target) {
|
||
|
|
if ($(target)) $(target).each(function () {
|
||
|
|
const block = this;
|
||
|
|
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).find('.vm-btn').on('click', function () {
|
||
|
|
viewMoreAction(block, type, text, text_reverse, limited);
|
||
|
|
})
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
function viewMoreAction(block, type, text, text_reverse, limited) {
|
||
|
|
const $btn = $(block).find('.vm-btn');
|
||
|
|
const $icon = $btn.find('.vm-btn-icon').length ? $btn.find('.vm-btn-icon')[0].outerHTML : '';
|
||
|
|
|
||
|
|
switch (type) {
|
||
|
|
case 'html':
|
||
|
|
const $content = $(block).find(".vm-content");
|
||
|
|
$content.toggleClass("max-height-none").toggleClass("blur");
|
||
|
|
if (!$($content).hasClass("max-height-none")) $(block).get(0).scrollIntoView({ behavior: 'smooth' });
|
||
|
|
break;
|
||
|
|
case 'list':
|
||
|
|
$(block).find(`.vm-list .vm-list-item:nth-child(n + ${limited + 1})`).fadeToggle();
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
const btn_text = $btn.text().replace(/\s/g, '').toLocaleLowerCase();
|
||
|
|
const text_check = text.replace(/\s/g, '').toLocaleLowerCase();
|
||
|
|
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") window.location.href="/cart";
|
||
|
|
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";
|
||
|
|
const combo_image = "/media/banner/logo_logo.png";
|
||
|
|
|
||
|
|
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;
|
||
|
|
|
||
|
|
const item_url = item.item_type == "combo" ? "javascript:;" : item.item_info.productUrl;
|
||
|
|
const item_image = item.item_type == "combo" ? combo_image : item.item_info.productImage.large;
|
||
|
|
const item_name = item.item_type == "combo" ? "Combo :" + item.item_info.title : item.item_info.productName;
|
||
|
|
|
||
|
|
header_cart_tpl += `
|
||
|
|
<div class="compare-item js-compare-item">
|
||
|
|
<div class="compare-item-img">
|
||
|
|
<a href="${item_url}" class="style-img-block">
|
||
|
|
<img src="${item_image}" alt="${item_name}" class="style-img-content" />
|
||
|
|
</a>
|
||
|
|
</div>
|
||
|
|
<div class="compare-item-info">
|
||
|
|
<a href="${item_url}" class="compare-item-name line-clamp-2">${item_name}</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 filterData = data.filter(obj => { return (obj.approved == "1" || obj.is_user_admin == "1") });
|
||
|
|
const newData = filterData.map(item => { return { ...item, type: type } });
|
||
|
|
// let html = type === 'review' ? Hura.Template.parse(review_tpl, filterData) : Hura.Template.parse(comment_tpl, filterData);
|
||
|
|
let html = Hura.Template.parse(review_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;
|
||
|
|
|
||
|
|
const item_type = $("[name='user_post[item_type]']").val();
|
||
|
|
const item_id = $("[name='user_post[item_id]']").val();
|
||
|
|
const item_title = $("[name='user_post[item_title]']").val();
|
||
|
|
const title = $("[name='user_post[title]']").val();
|
||
|
|
// const avatar = $("[name='user_post[user_avatar]']").val();
|
||
|
|
|
||
|
|
const rate = type === $(".rating-comment input:checked").val() ? $(".rating-comment input:checked").val() : 5;
|
||
|
|
const alert_title = type === "comment" ? "bình luận" : "đánh giá";
|
||
|
|
const alert_text = reply === "" ? "" : "phản hồi ";
|
||
|
|
const alert_html = `Bạn đã gửi ${alert_text}${alert_title} thành công!`;
|
||
|
|
|
||
|
|
const name = checkForm.values.name ? checkForm.values.name : '';
|
||
|
|
const email = checkForm.values.email ? checkForm.values.email : '';
|
||
|
|
const tel = checkForm.values.tel ? checkForm.values.tel : '';
|
||
|
|
const content = checkForm.values.content ? checkForm.values.content : '';
|
||
|
|
|
||
|
|
let params;
|
||
|
|
const info = {
|
||
|
|
item_type: item_type,
|
||
|
|
item_id: item_id,
|
||
|
|
item_title: item_title,
|
||
|
|
user_email: email,
|
||
|
|
user_name: name,
|
||
|
|
user_tel: 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) {
|
||
|
|
if (data.status == "success") QiuModal.call({ type: "success", content: alert_html, closeButtonUrl: "" });
|
||
|
|
else QiuModal.call({ type: "error", content: "Lỗi không xác định. Vui lòng kiểm tra thông tin và thử lại!" });
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// 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');
|
||
|
|
QiuModal.call({ type: "error", content: `<ul>${error}</ul>` });
|
||
|
|
return { result: false };
|
||
|
|
} else return { result: true, values: inputValueData };
|
||
|
|
}
|
||
|
|
|
||
|
|
// QIU MODAL (params = {type: "success|error|warning|comfirm", title: "", content: "", submitButtonText: "", cancelButtonText: "", closeButtonText: "", submitButtonUrl: "", cancelButtonUrl: "", closeButtonUrl: ""})
|
||
|
|
const QiuModal = {
|
||
|
|
call: async function (params) { return await createQiuModal(params) }
|
||
|
|
};
|
||
|
|
|
||
|
|
// CREATE QIU MODAL
|
||
|
|
function createQiuModal(params) {
|
||
|
|
return new Promise(function (resolve, reject) {
|
||
|
|
createUIQiuModal(params);
|
||
|
|
|
||
|
|
const $btnSubmit = $(".global-popup-modal__button.submit");
|
||
|
|
const $btnCancel = $(".global-popup-modal__button.cancel");
|
||
|
|
const $btnClose = $(".global-popup-modal__button.close");
|
||
|
|
|
||
|
|
$btnSubmit.off("click");
|
||
|
|
$btnCancel.off("click");
|
||
|
|
$btnClose.off("click");
|
||
|
|
|
||
|
|
$btnSubmit.on("click", function () {
|
||
|
|
hideQiuModal(params.submitButtonUrl);
|
||
|
|
resolve({ status: "submit", result: true });
|
||
|
|
});
|
||
|
|
$btnCancel.on("click", function () {
|
||
|
|
hideQiuModal(params.cancelButtonUrl);
|
||
|
|
resolve({ status: "cancel", result: false });
|
||
|
|
});
|
||
|
|
$btnClose.on("click", function () {
|
||
|
|
hideQiuModal(params.closeButtonUrl);
|
||
|
|
resolve({ status: "close", result: null });
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// CREATE UI QIU MODAL
|
||
|
|
function createUIQiuModal(params) {
|
||
|
|
let modal_icon;
|
||
|
|
let modal_title = params.title ? params.title : "";
|
||
|
|
const modal_type = params.type ? params.type : "";
|
||
|
|
const modal_content = params.content ? params.content : "";
|
||
|
|
const btn_submit = params.submitButtonText
|
||
|
|
? `<div class="global-popup-modal__button submit show">${params.submitButtonText}</div>`
|
||
|
|
: '<div class="global-popup-modal__button submit">Xác nhận</div>';
|
||
|
|
const btn_cancel = params.cancelButtonText
|
||
|
|
? `<div class="global-popup-modal__button cancel show">${params.cancelButtonText}</div>`
|
||
|
|
: '<div class="global-popup-modal__button cancel">Hủy bỏ</div>';
|
||
|
|
let btn_close;
|
||
|
|
if (params.submitButtonText || params.cancelButtonText || modal_type === "comfirm")
|
||
|
|
btn_close = params.cancelButtonText
|
||
|
|
? `<div class="global-popup-modal__button close show">${params.closeButtonText}</div>`
|
||
|
|
: '<div class="global-popup-modal__button close">Đóng</div>';
|
||
|
|
else
|
||
|
|
btn_close = params.cancelButtonText
|
||
|
|
? `<div class="global-popup-modal__button close default show">${params.closeButtonText}</div>`
|
||
|
|
: '<div class="global-popup-modal__button close default">Đóng</div>';
|
||
|
|
|
||
|
|
switch (modal_type) {
|
||
|
|
case "success":
|
||
|
|
if (!modal_title) 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":
|
||
|
|
if (!modal_title) 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":
|
||
|
|
if (!modal_title) modal_title = "Cảnh báo";
|
||
|
|
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 "comfirm":
|
||
|
|
if (!modal_title) modal_title = "Xác nhận";
|
||
|
|
modal_icon =
|
||
|
|
"M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM169.8 165.3c7.9-22.3 29.1-37.3 52.8-37.3h58.3c34.9 0 63.1 28.3 63.1 63.1c0 22.6-12.1 43.5-31.7 54.8L280 264.4c-.2 13-10.9 23.6-24 23.6c-13.3 0-24-10.7-24-24V250.5c0-8.6 4.6-16.5 12.1-20.8l44.3-25.4c4.7-2.7 7.6-7.7 7.6-13.1c0-8.4-6.8-15.1-15.1-15.1H222.6c-3.4 0-6.4 2.1-7.5 5.3l-.4 1.2c-4.4 12.5-18.2 19-30.6 14.6s-19-18.2-14.6-30.6l.4-1.2zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z";
|
||
|
|
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">${modal_content}</div>
|
||
|
|
<div class="global-popup-modal__button-box">
|
||
|
|
${btn_close}${btn_cancel}${btn_submit}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
`;
|
||
|
|
|
||
|
|
$(".global-popup-modal").html(modal_html).removeClass("hide-modal");
|
||
|
|
$(".global-popup-frame").removeClass("hide-modal").fadeIn();
|
||
|
|
$("body").css("overflow", "hidden");
|
||
|
|
}
|
||
|
|
|
||
|
|
// CLOSE QIU MODAL
|
||
|
|
function hideQiuModal(href) {
|
||
|
|
$(".global-popup-frame").addClass("hide-modal");
|
||
|
|
$(".global-popup-modal").addClass("hide-modal");
|
||
|
|
$("body").css("overflow", "auto");
|
||
|
|
|
||
|
|
if (href !== undefined) {
|
||
|
|
setTimeout(function () {
|
||
|
|
if (href !== "") window.location.href = href;
|
||
|
|
else location.reload();
|
||
|
|
}, 1200);
|
||
|
|
}
|
||
|
|
}
|