1941 lines
72 KiB
JavaScript
1941 lines
72 KiB
JavaScript
"use strict";
|
|
|
|
/**
|
|
* @property {string} no
|
|
* @property {string} yes
|
|
*
|
|
* @property {string} baseUrl
|
|
* @property {string} sessionTime
|
|
* @property {string} sessionLoginLink
|
|
*
|
|
* @property {string} show_login_frm
|
|
* @property {string} reqLogin
|
|
* @property {string} pRedirect
|
|
* @property {string} subCfg
|
|
* @property {string} fData
|
|
*
|
|
* @property {string} JsModuleTitle
|
|
* @property {boolean} JsInitPostpone
|
|
*
|
|
* @property {string} msg_subscription_title
|
|
* @property {string} msg_request
|
|
* @property {string} msg_request_download
|
|
* @property {string} msg_continue
|
|
* @property {string} msg_download
|
|
* @property {string} msg_cancel
|
|
*/
|
|
var JsVars, Calc, PBaseUrl, PCheckBoxes;
|
|
var AjaxLoader, AppBase;
|
|
|
|
if(!String.prototype.trim){
|
|
String.prototype.trim = function (){
|
|
return this.replace(/^\s+|\s+$/g, "");
|
|
};
|
|
}
|
|
if(!Date.prototype.addDays){
|
|
Date.prototype.addDays = function(days){
|
|
var d = new Date(this.valueOf());
|
|
d.setDate(d.getDate() + days);
|
|
return d;
|
|
}
|
|
}
|
|
if(!Array.prototype.sum){
|
|
Array.prototype.sum = function(){
|
|
return this.reduce(function(a,b){return a+b;});
|
|
};
|
|
}
|
|
(function(){
|
|
|
|
/**
|
|
* Dynamically loads a JavaScript class from a file path.
|
|
* @param {string} filePath - Path to the .js file (e.g., './models/User.js')
|
|
* @param {string} [className] - Optional: specific export name. Defaults to the default export.
|
|
* @returns {Promise<Function>} - The loaded class constructor
|
|
*/
|
|
async function loadClass(filePath, className = null) {
|
|
try {
|
|
const module = await import(filePath);
|
|
|
|
if (className) {
|
|
if (!module[className]) {
|
|
throw new Error(`Class "${className}" not found in module "${filePath}"`);
|
|
}
|
|
return module[className];
|
|
}
|
|
|
|
// Fall back to default export
|
|
if (module.default) {
|
|
return module.default;
|
|
}
|
|
|
|
throw new Error(`No default export or named class found in "${filePath}"`);
|
|
} catch (err) {
|
|
throw new Error(`Failed to load class from "${filePath}": ${err.message}`);
|
|
}
|
|
}
|
|
|
|
/********************************************************************
|
|
* GLOBAL FUNCTIONS
|
|
********************************************************************/
|
|
window.pr = function(obj){
|
|
if("console" in window){
|
|
var vArgs = Array.from(arguments);
|
|
for(var i = 0; i < vArgs.length; i++){
|
|
console.log(vArgs[i]);
|
|
}
|
|
}
|
|
};
|
|
window.mprint = function(obj){
|
|
if("console" in window){
|
|
var vArgs = Array.from(arguments);
|
|
for(var i = 0; i < vArgs.length; i++){
|
|
console.log(vArgs[i]);
|
|
}
|
|
}
|
|
};
|
|
window.toBinaryStr = function(str) {
|
|
const encoder = new TextEncoder();
|
|
// 1: split the UTF-16 string into an array of bytes
|
|
const charCodes = encoder.encode(str);
|
|
// 2: concatenate byte data to create a binary string
|
|
return String.fromCharCode(...charCodes);
|
|
}
|
|
window.toBase64encode = function(str) {
|
|
return btoa(toBinaryStr(str));
|
|
}
|
|
// Sets default variable
|
|
window.defaultVal = function(arg, val){
|
|
return typeof arg !== 'undefined' && arg !== null ? arg : val;
|
|
};
|
|
// Sets default variable even if var exists and is false
|
|
window.defaultValNotFalse = function(arg, val){
|
|
var rVal = defaultVal(arg, val);
|
|
if(rVal === false)
|
|
return val;
|
|
return rVal;
|
|
};
|
|
window.roundNumber = function (num, dec) {
|
|
return Number(Math.round(parseFloat(num+'e'+dec))+'e-'+dec).toFixed(dec);
|
|
};
|
|
// Format date
|
|
window.formatDateToString = function(date){
|
|
// 01, 02, 03, ... 29, 30, 31
|
|
var dd = (date.getDate() < 10 ? '0' : '') + date.getDate();
|
|
// 01, 02, 03, ... 10, 11, 12
|
|
var MM = ((date.getMonth() + 1) < 10 ? '0' : '') + (date.getMonth() + 1);
|
|
// 1970, 1971, ... 2015, 2016, ...
|
|
var yyyy = date.getFullYear();
|
|
|
|
// create the format you want
|
|
return (dd + "." + MM + "." + yyyy);
|
|
};
|
|
// Add jQuery object check function
|
|
$.isObject = function(e){ return !(typeof e !== "object"); };
|
|
$.isDefined = function(e){ return (typeof e !== "undefined"); };
|
|
|
|
/********************************************************************
|
|
* BASE jQuery plugin extensions
|
|
********************************************************************/
|
|
// Create Jquery Pseudo for case insensitive text lookup
|
|
jQuery.expr[":"].icontains = jQuery.expr.createPseudo(function (arg) {
|
|
return function (elem) {
|
|
return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
|
|
};
|
|
});
|
|
jQuery.fn.hasAttr = function(name) {
|
|
return this.attr(name) !== undefined;
|
|
};
|
|
|
|
/********************************************************************
|
|
* GLOBAL FUNCTIONS
|
|
********************************************************************/
|
|
Calc = (function() {
|
|
|
|
function Calc(num) {
|
|
if (typeof (Big) !== "undefined") {
|
|
this.oBig = new Big(defaultVal(num, 0));
|
|
} else pr("Calculation plugin 'Big.js' must be preloaded!");
|
|
}
|
|
|
|
Calc.prototype = {
|
|
oBig : {},
|
|
plus : function(num){
|
|
this.oBig = this.oBig.plus(num);
|
|
return this;
|
|
},
|
|
minus : function(num){
|
|
this.oBig = this.oBig.minus(num);
|
|
return this;
|
|
},
|
|
times : function(num){
|
|
this.oBig = this.oBig.times(num);
|
|
return this;
|
|
},
|
|
div : function(num){
|
|
this.oBig = this.oBig.div(num);
|
|
return this;
|
|
},
|
|
round : function(num, mode){
|
|
this.oBig = this.oBig.round(num, mode);
|
|
return this;
|
|
},
|
|
toNumber : function(){
|
|
return this.oBig.toNumber();
|
|
},
|
|
toFixedStr : function(dec, mode){
|
|
return this.oBig.toFixed(dec, mode);
|
|
},
|
|
formatNumber : function(num, dec, decP, sep){
|
|
dec = defaultVal(dec, 2);
|
|
sep = defaultVal(sep, " ");
|
|
decP = defaultVal(decP, ".");
|
|
|
|
return this.formatNumTh((new Big(num)).toFixed(dec), decP, sep);
|
|
},
|
|
formatNumTh : function(v, decP, sep){
|
|
sep = defaultVal(sep, " ");
|
|
decP = defaultVal(decP, ".");
|
|
|
|
if(!isNaN(v)){
|
|
if (v >= 1000) {
|
|
v += '';
|
|
var _ = v.split(/\D/);
|
|
var i = _[0].length % 3 || 3;
|
|
|
|
_[0] = v.slice(0,i + (v < 0)) +
|
|
_[0].slice(i).replace(/(\d{3})/g, sep+'$1');
|
|
v = _.join(decP);
|
|
}
|
|
}
|
|
return v;
|
|
}
|
|
};
|
|
|
|
return Calc;
|
|
})();
|
|
|
|
/********************************************************************
|
|
* BASE URL CLASS
|
|
********************************************************************/
|
|
PBaseUrl = (function() {
|
|
|
|
function PBaseUrl(PBaseUrl){
|
|
// Add url
|
|
var url, len, _this = this;
|
|
|
|
if(PBaseUrl && PBaseUrl.url) {
|
|
_this.lang = PBaseUrl.lang;
|
|
url = PBaseUrl.url;
|
|
}else{
|
|
_this.lang = "none";
|
|
url = window.location.pathname;
|
|
}
|
|
|
|
_this.path = url;
|
|
len = url.length;
|
|
|
|
_this.endSlash = url.substring(len - 1) === "/";
|
|
if(url.substring(len - (_this.lang.length + (_this.endSlash ? 1 : 0))) === _this.lang + (_this.endSlash ? "/" : "")){
|
|
url = url.substring(0, len - (_this.lang.length + (_this.endSlash ? 1 : 0)));
|
|
_this.pathAndParam = url + "p:var/" + _this.lang + (_this.endSlash ? "/" : "");
|
|
}else{
|
|
_this.pathAndParam = url + (_this.endSlash ? "" : "/") + "p:var" + (_this.endSlash ? "/" : "");
|
|
}
|
|
}
|
|
|
|
PBaseUrl.prototype.path = "";
|
|
PBaseUrl.prototype.pathAndParam = "";
|
|
PBaseUrl.prototype.lang = "";
|
|
PBaseUrl.prototype.endSlash = false;
|
|
PBaseUrl.prototype.insertSmartsChunk = function(url, chunk, lang){
|
|
|
|
if(url.length && chunk.length){
|
|
|
|
// Replace starting and ending slashes
|
|
var chunks = url.replace("/^\/|\/+$/", '').split('/');
|
|
|
|
// Handle language
|
|
if($.isDefined(lang) && lang.length){
|
|
/*$lang = array_pop($chunks);
|
|
$chunks[] = $chunk;
|
|
$chunks[] = $lang;*/
|
|
}else{
|
|
chunks.push(chunk);
|
|
}
|
|
|
|
if(chunks[0] === 'index')
|
|
delete(chunks[0]);
|
|
|
|
return chunks.join('/');
|
|
}
|
|
};
|
|
return PBaseUrl;
|
|
})();
|
|
|
|
|
|
/*******************************************************************
|
|
* CHECKBOXES
|
|
*******************************************************************/
|
|
PCheckBoxes = (function() {
|
|
|
|
function PCheckBoxes(){ }
|
|
|
|
PCheckBoxes.prototype.NO = "No";
|
|
PCheckBoxes.prototype.YES = "Yes";
|
|
|
|
PCheckBoxes.prototype.bindSliderCheckboxes = function(obj){
|
|
|
|
if($.isDefined(obj)){
|
|
obj = $(".content > .cnt");
|
|
}
|
|
|
|
var no = defaultVal(JsBase.gM.no, this.NO);
|
|
var yes = defaultVal(JsBase.gM.yes, this.YES);
|
|
|
|
|
|
obj.find(".chk-value").each(function(){
|
|
|
|
var parent = $(this).parent();
|
|
var y = (parent.find(".on").length ? parent.find(".on").text() : yes);
|
|
var n = (parent.find(".off").length ? parent.find(".off").text() : no);
|
|
|
|
var elem = $(this).wrap("<div class='chk'></div>");
|
|
elem = elem.parent().append(
|
|
"<div class='slider'>" +
|
|
"<div class='on'>" + y + "</div><div class='off'>" + n + "</div><div class='switch'></div><div class='clear' style='display: none;'></div>" +
|
|
"</div>");
|
|
|
|
if(elem.find("input").val()){
|
|
elem.find(".slider").css({"margin-left" : 0}).find(".off");
|
|
}else{
|
|
elem.find(".slider").css({"margin-left" : "-41px"}).find(".on").css({opacity : 0});
|
|
}
|
|
elem.click(function(){
|
|
var val = $(this).find("input");
|
|
if(val.val()){
|
|
val.val("");
|
|
$(this).find(".slider").animate({"margin-left" : "-41px"}, 100, function(){
|
|
$(this).find(".on").css({opacity : 0});
|
|
val.change();
|
|
});
|
|
}else{
|
|
val.val(1);
|
|
$(this).find(".on").css({opacity : 1});
|
|
$(this).find(".slider").animate({"margin-left" : 0}, 100, function(){
|
|
val.change();
|
|
});
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
PCheckBoxes.prototype.bindBaseCheckboxes = function(obj){
|
|
|
|
if(!$.isDefined(obj)){
|
|
obj = $(".content > .cnt");
|
|
}
|
|
|
|
// New style checkboxes
|
|
obj.find(".hasChk:not(.disabled) .chk:not(.disabled)").each(function(){
|
|
let i = $(this);
|
|
let p = $(this).parent();
|
|
|
|
$(i).add(p).click(function(e){
|
|
e.stopPropagation();
|
|
if(!i.hasClass("dis")){
|
|
if(i.hasClass("chked")){
|
|
i.removeClass("chked");
|
|
}else{
|
|
i.addClass("chked");
|
|
}
|
|
i.change();
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
return PCheckBoxes;
|
|
})();
|
|
|
|
|
|
/********************************************************************
|
|
* AJAX LOADER CLASS
|
|
********************************************************************/
|
|
AjaxLoader = (function() {
|
|
|
|
function AjaxLoader(){
|
|
|
|
var _this = this;
|
|
|
|
// Use existing ajax loader
|
|
_this.jqObj = $("#ju-loading-screen");
|
|
_this.jqLineObj = $("#loader-l");
|
|
|
|
// Create ajax container & loader
|
|
if(!_this.jqObj.length){
|
|
_this.jqObj = $("<div id='ju-loading-screen'></div>").hide();
|
|
$("body").append(_this.jqObj);
|
|
}
|
|
|
|
_this.sRoundAjaxLoader = '<div id="ju-loading-screen" class="style-fix custom-embed-loader"><div class="sk-double-bounce"><div class="sk-child sk-double-bounce1"></div><div class="sk-child sk-double-bounce2"></div></div></div>';
|
|
|
|
$(document).ajaxStart(function(){
|
|
_this.showLoader();
|
|
}).ajaxStop(function(){
|
|
_this.hideLoader();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @property {jQuery} jqObj
|
|
* @property {jQuery} jqLineObj
|
|
* @property {string} sRoundAjaxLoader
|
|
*
|
|
* @property {int} iTimer
|
|
*
|
|
* @property {boolean} disabled
|
|
* @property {boolean} disabledFadeOut
|
|
* @property {boolean} bAjaxLine
|
|
*
|
|
* @property {jQuery|boolean} jqAjaxCaller
|
|
* @property {jQuery|boolean} jqAjaxSaveCaller
|
|
**/
|
|
AjaxLoader.prototype = {
|
|
jqObj : {},
|
|
jqLineObj : {},
|
|
sRoundAjaxLoader : {},
|
|
|
|
iTimer : 0,
|
|
|
|
disabled : false,
|
|
disabledFadeOut : false,
|
|
bAjaxLine : false,
|
|
|
|
jqAjaxCaller : false,
|
|
jqAjaxSaveCaller : false
|
|
};
|
|
AjaxLoader.prototype.showLoader = function(fnCallback){
|
|
var _this = this;
|
|
if(!_this.disabled){
|
|
if(_this.bAjaxLine)
|
|
_this.jqLineObj.addClass("ajax");
|
|
|
|
_this.showLoaderPro();
|
|
_this.jqObj.addClass("style-fix ajax-act").show().removeClass("ju-hide--loading-screen--");
|
|
|
|
if($.isFunction(fnCallback))
|
|
fnCallback();
|
|
}
|
|
};
|
|
AjaxLoader.prototype.hideLoader = function(force){
|
|
var _this = this;
|
|
if(!_this.disabled){
|
|
if(!_this.disabledFadeOut || $.isDefined(force) && force){
|
|
_this.disabledFadeOut = false;
|
|
|
|
if(_this.bAjaxLine){
|
|
_this.jqLineObj.addClass("fin");
|
|
setTimeout(function(){ _this.jqLineObj.removeClass("run ajax fin"); }, 600);
|
|
}
|
|
_this.hideLoaderPro();
|
|
_this.jqObj.addClass("ju-hide--loading-screen--").removeClass("ajax-act").hide();
|
|
}
|
|
}
|
|
};
|
|
AjaxLoader.prototype.resetAjaxObjects = function(){
|
|
var _this = this;
|
|
_this.jqObj.hide();
|
|
if(_this.jqAjaxCaller.length)
|
|
_this.jqAjaxCaller.removeClass("act");
|
|
_this.jqAjaxCaller = $();
|
|
_this.disabled = false;
|
|
_this.jqObj = $("#ju-loading-screen").hide().addClass("ju-hide--loading-screen--").removeClass("ajax-act");
|
|
};
|
|
AjaxLoader.prototype.showLoaderPro = function(){
|
|
var _this = this;
|
|
_this.jqAjaxCaller = defaultValNotFalse(_this.jqAjaxCaller, _this.jqAjaxSaveCaller);
|
|
if(_this.jqAjaxCaller.length)
|
|
_this.jqAjaxCaller.addClass("act");
|
|
};
|
|
AjaxLoader.prototype.hideLoaderPro = function(){
|
|
var _this = this;
|
|
_this.jqAjaxCaller = defaultValNotFalse(_this.jqAjaxCaller, _this.jqAjaxSaveCaller);
|
|
if(_this.jqAjaxCaller.length)
|
|
_this.jqAjaxCaller.removeClass("act");
|
|
_this.jqAjaxCaller = false;
|
|
};
|
|
return AjaxLoader;
|
|
|
|
})();
|
|
|
|
|
|
/*******************************************************************
|
|
* SESSION CLASS
|
|
*******************************************************************/
|
|
class BaseSession {
|
|
|
|
iTime = 0;
|
|
iTimeout = 0;
|
|
|
|
sBody = $();
|
|
sUrlSrc = "";
|
|
|
|
jqIframe = $();
|
|
jqObject = $();
|
|
|
|
bExternalForm = false;
|
|
bSessionEnabled = false;
|
|
|
|
/** @type {SessionTicker} */
|
|
timer;
|
|
|
|
/**
|
|
* BaseSession class for starting session timer
|
|
*
|
|
* @category PUB
|
|
* @dependencies PHP ajax.php
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
*
|
|
* @constructor
|
|
* @this {BaseSession}
|
|
* @param {int} sessionTime - session time
|
|
* @param {string} sLoginLink - user redirect login link
|
|
**/
|
|
constructor(sessionTime, sLoginLink) {
|
|
let _this = this;
|
|
|
|
_this.bSessionEnabled = !!$(".wrapper.session").length;
|
|
_this.bExternalForm = $("html").hasClass("ext-load");
|
|
|
|
if (
|
|
sessionTime
|
|
&& sLoginLink.length
|
|
&& _this.bSessionEnabled
|
|
&& !_this.bExternalForm
|
|
) {
|
|
_this.sUrlSrc = sLoginLink;
|
|
_this.sBody = $("#sessionTime");
|
|
_this.iTime = _this.iTimeout = (parseInt(sessionTime) - 1);
|
|
|
|
if (!_this.sBody.length) {
|
|
$("footer").append(_this.sBody = $(
|
|
"<a id='sessionTime'>" +
|
|
"<div class='left'>" +
|
|
"<p>Session will expire in:</p>" +
|
|
"<p class='ed'>Session has expired! Time left:</p>" +
|
|
"</div>" +
|
|
"<div class='right'><span>00:00</span></div>" +
|
|
"</a>").css({opacity: 0.5}));
|
|
}
|
|
_this.appendSessionTime();
|
|
_this.sBody.find(".ed").hide();
|
|
|
|
_this.init();
|
|
} else {
|
|
_this.bSessionEnabled = false;
|
|
}
|
|
}
|
|
|
|
async init() {
|
|
let _this = this;
|
|
// Load required classes
|
|
const SessionTicker = await loadClass('./class/SessionTicker.js');
|
|
|
|
_this.timer = new SessionTicker({
|
|
duration: _this.iTime,
|
|
tickInterval: 1,
|
|
onTick: (remaining) => {
|
|
_this.iTime = remaining;
|
|
_this.appendSessionTime();
|
|
},
|
|
onExpire: () => {
|
|
_this.callLoginForm();
|
|
},
|
|
});
|
|
_this.timer.start();
|
|
}
|
|
|
|
updateTimer(login, timeOut){
|
|
let _this = this;
|
|
|
|
if (_this.bSessionEnabled) {
|
|
login = $.isDefined(login) ? login : false;
|
|
timeOut = $.isDefined(timeOut) ? timeOut : false;
|
|
|
|
if (_this.iTime > 0 || login || timeOut) {
|
|
_this.iTime = (timeOut ? timeOut : _this.iTimeout);
|
|
_this.timer.reset(_this.iTime);
|
|
}
|
|
|
|
// Restart counter timer
|
|
if (login || timeOut) {
|
|
setTimeout(function () {
|
|
_this.sBody.find("span").removeClass("ajax");
|
|
}, 1000);
|
|
}
|
|
}
|
|
}
|
|
|
|
appendSessionTime(){
|
|
let _this = this;
|
|
_this.sBody.find("span").html(_this.secondsToTime(_this.iTime));
|
|
}
|
|
|
|
callLoginForm(){
|
|
let _this = this;
|
|
|
|
if (_this.bSessionEnabled) {
|
|
// Format status timer
|
|
_this.sBody.find("span").addClass("ajax");
|
|
|
|
JsBase.ajaxLoader.disabled = true;
|
|
JsBase.ajax({ac: "tcheck", app: 1}, "/ajax/g", function (d) {
|
|
if (d && d.jsonok && d.t) {
|
|
// Check if session still active - then update timer
|
|
let t = parseInt(d.t);
|
|
if (t > 5) {
|
|
_this.updateTimer(false, t);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
_this.sBody.addClass("hover");
|
|
_this.sBody.find("span").html("00:00").removeClass("ajax");
|
|
|
|
JsBase.ajaxLoader.disabled = false;
|
|
_this.showLoginForm();
|
|
});
|
|
}
|
|
}
|
|
|
|
showLoginForm(bApiReq, sUrlSrc){
|
|
let _this = this;
|
|
|
|
bApiReq = defaultVal(bApiReq, false);
|
|
sUrlSrc = defaultVal(sUrlSrc, _this.sUrlSrc);
|
|
|
|
if (_this.bSessionEnabled || bApiReq && sUrlSrc) {
|
|
// Create form only if already not exists
|
|
if (!_this.jqIframe.length) {
|
|
_this.jqIframe = $("<iframe class='loginf' id='loginf' src='" + sUrlSrc + "'></iframe>").hide();
|
|
_this.jqObject = $("<div class='iframe-overlay act'></div>").hide().add(_this.jqIframe);
|
|
|
|
$("body").append(_this.jqObject);
|
|
_this.jqObject.first().append(JsBase.ajaxLoader.sRoundAjaxLoader).fadeIn("fast");
|
|
}
|
|
|
|
if (!$("#fancybox-style-noscroll-fix").length) {
|
|
$("head").append(
|
|
'<style id="fancybox-style-noscroll-fix" type="text/css">' +
|
|
' .compensate-for-scrollbar{' +
|
|
' margin:0!important; padding-right:' + JsBase.getScrollBarWidth() + 'px;' +
|
|
' }' +
|
|
' .fancybox-active.compensate-for-scrollbar #fh5co-header{ ' +
|
|
' width: calc(100% - ' + JsBase.getScrollBarWidth() + 'px);' +
|
|
' }' +
|
|
'</style>'
|
|
);
|
|
}
|
|
|
|
_this.jqIframe.on("load", function () {
|
|
_this.jqObject.first().removeClass("act");
|
|
_this.jqIframe.contents().find("html").addClass("session_exp_login");
|
|
|
|
$("body")
|
|
.addClass("compensate-for-scrollbar oh")
|
|
.find("> .wrapper, #confirmDialog, footer > div, #dialogSlider")
|
|
.addClass("fmoreblur");
|
|
|
|
setTimeout(function () {
|
|
_this.jqIframe.fadeIn("fast");
|
|
}, 100);
|
|
});
|
|
}
|
|
}
|
|
|
|
hideIframe(){
|
|
this.jqObject.first().addClass("act");
|
|
this.jqIframe.hide();
|
|
}
|
|
|
|
removeIframeForm(bApiReq){
|
|
let _this = this;
|
|
|
|
bApiReq = defaultVal(bApiReq, false);
|
|
|
|
if (_this.bSessionEnabled || bApiReq) {
|
|
_this.updateTimer(true);
|
|
_this.jqObject.fadeOut("fast", function () {
|
|
$(this).remove();
|
|
_this.jqObject = $();
|
|
_this.jqIframe = $();
|
|
});
|
|
$("body")
|
|
.removeClass("compensate-for-scrollbar oh")
|
|
.find("> .wrapper, #confirmDialog, footer > div, #dialogSlider")
|
|
.removeClass("fmoreblur");
|
|
}
|
|
}
|
|
|
|
secondsToTime(seconds) {
|
|
const mins = Math.floor(seconds / 60);
|
|
const secs = Math.floor(seconds % 60);
|
|
return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
|
|
}
|
|
}
|
|
|
|
AppBase = (function() {
|
|
|
|
/**
|
|
* AppBase base class object
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @this {AppBase}
|
|
*/
|
|
function AppBase(){
|
|
var _this = this;
|
|
|
|
// Load base js params
|
|
if(JsVars && JsVars.data){
|
|
_this.dt = {};
|
|
for(var i in JsVars.data){
|
|
if(JsVars.data.hasOwnProperty(i)){
|
|
if(i === 'gM'){
|
|
_this.gM = $.parseJSON(JsVars.data[i]);
|
|
}else{
|
|
_this.dt[i] = $.parseJSON(JsVars.data[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set starting win width
|
|
_this.winWidth = $(window).width();
|
|
|
|
// Init subclasses
|
|
_this.url = new PBaseUrl($.isDefined(_this.dt.baseUrl) ? _this.dt.baseUrl : false);
|
|
|
|
// Load required classes
|
|
_this.oSession = new BaseSession(
|
|
("sessionTime" in _this.dt ? _this.dt.sessionTime : 3600),
|
|
("sessionLoginLink" in _this.dt ? _this.dt.sessionLoginLink : "")
|
|
);
|
|
|
|
_this.ajaxLoader = new AjaxLoader();
|
|
_this.checkboxes = new PCheckBoxes();
|
|
|
|
if(!_this.isMobile && typeof BrsConsole === 'function'){
|
|
_this.bDebug = true;
|
|
_this.oConsole = new BrsConsole(_this);
|
|
}
|
|
|
|
// Add function to resize event
|
|
// _this.onResize['top_menu'] = _this.recalculateMenu;
|
|
|
|
// Additional actions
|
|
_this.getDevice();
|
|
_this.resizeForm();
|
|
_this.bindBaseActions();
|
|
}
|
|
|
|
/**
|
|
* @property {object} dt
|
|
* @property {object} gM
|
|
* @property {object} os
|
|
* @property {boolean} isMobile
|
|
*
|
|
* @property {PBaseUrl} url
|
|
* @property {object} browser
|
|
* @property {PCheckBoxes} checkboxes
|
|
*
|
|
* @property {int} winWidth
|
|
* @property {PTables|boolean} oTables
|
|
*
|
|
* @property {boolean} bDebug
|
|
* @property {BrsConsole|boolean} oConsole
|
|
*
|
|
* @property {object} jsModule
|
|
* @enum {int} iKeys
|
|
*
|
|
* @property {Validator} validatorSubscribe
|
|
* @property {object} onResize
|
|
**/
|
|
AppBase.prototype = {
|
|
dt : {},
|
|
gM : {},
|
|
os : {},
|
|
isMobile : false,
|
|
|
|
url : {},
|
|
browser : {},
|
|
settings : {},
|
|
checkboxes : {},
|
|
|
|
winWidth : 0,
|
|
oTables : false,
|
|
oAllSliders : {},
|
|
oNewObjectSlider : false,
|
|
|
|
bDebug : false,
|
|
oConsole : false,
|
|
|
|
jsModule : {},
|
|
iKeys : {
|
|
BACKSPACE : 8,
|
|
TAB : 9,
|
|
ENTER : 13,
|
|
SHIFT : 16,
|
|
ESC : 27,
|
|
SPACE : 32,
|
|
ARROW_UP : 38,
|
|
ARROW_DOWN : 40,
|
|
DEL : 46,
|
|
KEY_F : 70,
|
|
KEY_N : 78,
|
|
KEY_S : 83,
|
|
KEY_V : 86
|
|
},
|
|
|
|
validatorSubscribe : {},
|
|
onResize : {}
|
|
};
|
|
|
|
// Call additional resize functions from array
|
|
AppBase.prototype.resizeForm = function(){
|
|
var _this = this;
|
|
//_this.recalculateMenu();
|
|
if($.isDefined(_this.onResize)){
|
|
for(var i in _this.onResize){
|
|
if(_this.onResize.hasOwnProperty(i))
|
|
if($.isFunction(_this.onResize[i]))
|
|
_this.onResize[i]();
|
|
}
|
|
}
|
|
};
|
|
|
|
// Get Class name
|
|
AppBase.prototype.getObjectClass = function(obj){
|
|
var sName = "";
|
|
var _this = this;
|
|
if(_this.dt && _this.dt.JsModuleTitle && _this.dt.JsModuleTitle.length){
|
|
sName = _this.dt.JsModuleTitle;
|
|
}else{
|
|
if(!$.isDefined(obj)){
|
|
sName = this.getObjectClass(this.jsModule);
|
|
}else{
|
|
if($.isFunction(obj)){
|
|
sName = obj.name;
|
|
}else if($.isObject(obj)){
|
|
sName = /(\w+)\(/.exec(obj.constructor.toString())[1];
|
|
}
|
|
}
|
|
}
|
|
if(!!sName)
|
|
sName = sName.charAt(0).toLocaleLowerCase() + sName.slice(1);
|
|
return sName;
|
|
};
|
|
|
|
// Analyse browser agent to get properties
|
|
AppBase.prototype.getDevice = function(){
|
|
var _this = this;
|
|
var ua = navigator.userAgent.toLowerCase();
|
|
_this.browser = {
|
|
idevice: /(iphone|ipod|ipad)/.test(ua),
|
|
blackberry: /blackberry/.test(ua),
|
|
android: /android/.test(ua),
|
|
firefox: /firefox/.test(ua)
|
|
};
|
|
_this.os = {
|
|
mac: /(mac)/.test(ua),
|
|
win: /(win)/.test(ua),
|
|
linux: /(linux)/.test(ua)
|
|
};
|
|
try{ document.createEvent("TouchEvent"); _this.isMobile = true; }
|
|
catch(e){ _this.isMobile = false; }
|
|
|
|
if(_this.isMobile) $("body").addClass("mob");
|
|
};
|
|
|
|
// Gather base fields
|
|
AppBase.prototype.getFields = function(obj, exclude, sKeyAttr){
|
|
|
|
var key;
|
|
obj = defaultVal(obj, $(".cnt"));
|
|
sKeyAttr = defaultValNotFalse(sKeyAttr, "id");
|
|
exclude = defaultValNotFalse(exclude, ".skip");
|
|
|
|
var oData = {};
|
|
$(obj).find("input:text, input:hidden, textarea, input:password").not(exclude).each(function(){
|
|
if(key = $(this).attr(sKeyAttr))
|
|
oData[key] = ($(this).val()?$(this).val():"");
|
|
});
|
|
$(obj).find("input:checkbox,.chk").not(exclude).each(function(){
|
|
if(key = $(this).attr(sKeyAttr))
|
|
oData[key] = ($(this).hasClass("chked") || $(this).is(":checked")? 1: 0);
|
|
});
|
|
$(obj).find("select").not(exclude).each(function(){
|
|
if(key = $(this).attr(sKeyAttr)){
|
|
if($(this).hasClass("getall")){
|
|
var sel = $(this).find("option:selected");
|
|
$(this).find("option").not(exclude).prop("selected", true);
|
|
oData[key] = $(this).val();
|
|
$(this).find("option").not(sel).prop("selected", false);
|
|
}else{
|
|
oData[key] = ($(this).val()?$(this).val():"");
|
|
}
|
|
}
|
|
});
|
|
$(obj).find("input:radio:checked").not(exclude).each(function(){
|
|
if(key = $(this).attr(sKeyAttr))
|
|
oData[key] = ($(this).val()?$(this).val():"");
|
|
});
|
|
|
|
return oData;
|
|
};
|
|
|
|
// Send ajax data
|
|
AppBase.prototype.ajax = function(data, url, onSuccess, type, onError, dataType){
|
|
var _this = this;
|
|
var ajax = $("#ajaxCode");
|
|
|
|
if(ajax.length){
|
|
$.extend((data?data:{}), {ajaxCode : ajax.val()})
|
|
}
|
|
if(!url || url && !url){
|
|
url = window.location;
|
|
}
|
|
|
|
if(!$.isDefined(type))
|
|
type = "POST";
|
|
if(!$.isDefined(dataType))
|
|
dataType = "json";
|
|
|
|
return $.ajax({
|
|
url: url,
|
|
type: type,
|
|
data: data,
|
|
dataType: dataType,
|
|
success: function(d) {
|
|
if(d){
|
|
// Update session timer
|
|
_this.oSession.updateTimer();
|
|
// Update gM messages
|
|
if(d.gM) $.extend(_this.gM, d.gM);
|
|
|
|
// Check if redirect request sent
|
|
if(d.error){
|
|
if(d.show_login_frm) _this.oSession.callLoginForm();
|
|
if((d.reqLogin || d.pRedirect) && d.url){
|
|
window.location = d.url;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
// Success function
|
|
if($.isFunction(onSuccess)){
|
|
onSuccess(d);
|
|
}
|
|
},
|
|
error: function() {
|
|
// Error function
|
|
if ($.isFunction(onError)) {
|
|
onError();
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Load basic bar chart
|
|
*
|
|
* @namespace
|
|
* @author Aivars Žukovskis <info@brsystems.lv>
|
|
* @property {int} number
|
|
* @property {int} [decimals = 2]
|
|
* @property {string} [dec_point = '.']
|
|
* @property {string} [thousands_sep = '']
|
|
*/
|
|
AppBase.prototype.formatNumber = function(number, decimals, dec_point, thousands_sep){
|
|
var n = number, prec = decimals;
|
|
|
|
var toFixedFix = function (n,prec) {
|
|
var k = Math.pow(10,prec);
|
|
return (Math.round(n*k)/k).toString();
|
|
};
|
|
|
|
n = !isFinite(+n) ? 0 : +n;
|
|
prec = !isFinite(+prec) ? 0 : Math.abs(prec);
|
|
var sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep;
|
|
var dec = (typeof dec_point === 'undefined') ? '.' : dec_point;
|
|
|
|
var s = (prec > 0) ? toFixedFix(n, prec) : toFixedFix(Math.round(n), prec); //fix for IE parseFloat(0.55).toFixed(0) = 0;
|
|
|
|
var abs = toFixedFix(Math.abs(n), prec);
|
|
var _, i;
|
|
|
|
if (abs >= 1000) {
|
|
_ = abs.split(/\D/);
|
|
i = _[0].length % 3 || 3;
|
|
|
|
_[0] = s.slice(0,i + (n < 0)) +
|
|
_[0].slice(i).replace(/(\d{3})/g, sep+'$1');
|
|
s = _.join(dec);
|
|
} else {
|
|
s = s.replace('.', dec);
|
|
}
|
|
|
|
var decPos = s.indexOf(dec);
|
|
if (prec >= 1 && decPos !== -1 && (s.length-decPos-1) < prec){
|
|
s += new Array(prec-(s.length-decPos-1)).join('0')+'0';
|
|
}
|
|
else if (prec >= 1 && decPos === -1) {
|
|
s += dec+new Array(prec).join('0')+'0';
|
|
}
|
|
return s;
|
|
};
|
|
|
|
// Binds base actions for html
|
|
AppBase.prototype.bindBaseActions = function(){
|
|
let _this = this;
|
|
// Bind cookies
|
|
let jqCookieCnt = $(".accept_cookies");
|
|
if (jqCookieCnt.length) {
|
|
$(document).ready(function () {
|
|
jqCookieCnt.find("a#accept-cookies,a#accept-all-cookies").click(function(){
|
|
let vData = ($(this).attr("id")==="accept-all-cookies" ? {all:1} : {
|
|
statistics:jqCookieCnt.find("#checkbox_stat").hasClass("chked")?1:0,
|
|
preferences:jqCookieCnt.find("#checkbox_pref").hasClass("chked")?1:0
|
|
});
|
|
_this.ajax(vData, $(this).attr("data-href"), function(d){
|
|
jqCookieCnt.fadeOut(400, function(){
|
|
$(this).remove();
|
|
});
|
|
if(d && d.html){
|
|
$("body").append(d.html);
|
|
}
|
|
});
|
|
});
|
|
|
|
_this.checkboxes.bindBaseCheckboxes(jqCookieCnt);
|
|
});
|
|
}
|
|
|
|
_this.bindFormValidations();
|
|
_this.bindFormSubmits();
|
|
_this.bindMobileMenuActions();
|
|
_this.bindCartActions();
|
|
_this.bindSearchAjax();
|
|
_this.bindCartErrorModal();
|
|
_this.bindTermsModalLinks();
|
|
_this.bindWishlistActions();
|
|
|
|
// Theme scripts (e.g. Swiper) may clone/render product cards after base init.
|
|
// Apply wishlist state once UI components are fully initialized.
|
|
setTimeout(function() {
|
|
_this.initWishlistState();
|
|
}, 1200);
|
|
$(window).off("load.wishlistInit").on("load.wishlistInit", function() {
|
|
_this.initWishlistState();
|
|
});
|
|
};
|
|
|
|
AppBase.prototype.encodeSearchToBase64Url = function(text) {
|
|
var base64 = btoa(encodeURIComponent(text));
|
|
return base64
|
|
.replace(/\+/g, '-')
|
|
.replace(/\//g, '_')
|
|
.replace(/=/g, '');
|
|
};
|
|
|
|
AppBase.prototype.bindSearchAjax = function() {
|
|
var _this = this;
|
|
var searchTimer = null;
|
|
|
|
$(document).on("keyup", ".search-form .search-input", function() {
|
|
var $searchInput = $(this);
|
|
var $searchQuery = $searchInput.val().trim();
|
|
if ($searchQuery.length < 3) return;
|
|
|
|
var $searchForm = $searchInput.closest(".search-form");
|
|
var $searchResult = $searchForm.find(".search-results");
|
|
var $searchUl = $searchResult.find("ul.search-ul");
|
|
var $searchMore = $searchResult.find(".search-more");
|
|
var $searchFail = $searchResult.find(".search-fail");
|
|
var $searchText = $searchResult.find(".search-text");
|
|
|
|
$searchResult.removeClass("d-none");
|
|
$searchText.text($searchQuery);
|
|
|
|
clearTimeout(searchTimer);
|
|
searchTimer = setTimeout(function() {
|
|
var encodedSearch = _this.encodeSearchToBase64Url($searchQuery);
|
|
_this.ajax(
|
|
{ajax : 1, f : encodedSearch, global_search : 1},
|
|
"/meklet/",
|
|
function(data) {
|
|
var html = data && data.html ? data.html : '';
|
|
$searchUl.empty();
|
|
if (html && html.length) {
|
|
$searchUl.html(html);
|
|
// Update "See all results" link with search phrase
|
|
$searchMore.find("a").attr("href", "/meklet/?f=" + encodedSearch);
|
|
$searchMore.show();
|
|
$searchFail.hide();
|
|
} else {
|
|
$searchMore.hide();
|
|
$searchFail.show();
|
|
}
|
|
},
|
|
'POST',
|
|
function() {
|
|
$searchUl.empty();
|
|
$searchMore.hide();
|
|
$searchFail.show();
|
|
}
|
|
)
|
|
}, 300);
|
|
});
|
|
};
|
|
|
|
AppBase.prototype.bindCartErrorModal = function() {
|
|
// When the cart error modal is shown, close the cart drawer
|
|
// (theme2.js may open it after 1s regardless of error)
|
|
$(document).on("shown.bs.modal", "#cart-error-modal", function() {
|
|
$("#cart-drawer").addClass("invisible").removeClass("active visible");
|
|
$(".bg-shop").addClass("opacity-0 invisible").removeClass("opacity-50 visible");
|
|
});
|
|
};
|
|
|
|
AppBase.prototype.showErrorModal = function(msg) {
|
|
// Show guest login modal
|
|
let $errModal = $("#cart-error-modal");
|
|
if ($errModal.length) {
|
|
$errModal.find(".cart-error-body").text(msg);
|
|
let bsErrModal = new bootstrap.Modal($errModal[0]);
|
|
bsErrModal.show();
|
|
}
|
|
};
|
|
|
|
AppBase.prototype.bindTermsModalLinks = function() {
|
|
let _this = this;
|
|
|
|
$(document)
|
|
.off("click.termsModal")
|
|
.on("click.termsModal", ".js-popup-link, .js-terms-modal", function(e) {
|
|
let $link = $(this);
|
|
let href = $link.attr("href");
|
|
let $modal = $("#terms-modal");
|
|
|
|
if (!href) {
|
|
return true;
|
|
}
|
|
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
if (!$modal.length || typeof bootstrap === "undefined") {
|
|
window.location.href = href;
|
|
return false;
|
|
}
|
|
|
|
$modal.find(".terms-modal-title").text($link.data("modal-title") || $.trim($link.text()) || "Terms & Conditions");
|
|
$modal.find(".terms-modal-content").html(
|
|
'<div class="terms-modal-loading text-center py-4"><i class="ri-loader-4-line icon-24 d-block lh-1 mx-auto"></i></div>'
|
|
);
|
|
|
|
bootstrap.Modal.getOrCreateInstance($modal[0]).show();
|
|
|
|
_this.ajax(false, href, function(html) {
|
|
$modal.find(".terms-modal-content").html(html);
|
|
}, "GET", function() {
|
|
$modal.find(".terms-modal-content").html(
|
|
"<div class='alert alert-danger meb-0'>" +
|
|
(_this.gM.ajaxGenErr || "Failed to load content.") +
|
|
"</div>"
|
|
);
|
|
}, "html");
|
|
|
|
return false;
|
|
});
|
|
};
|
|
|
|
AppBase.prototype.getProductId = function (jqObj) {
|
|
return jqObj.closest(".product-image").find("[data-product-id]").data("product-id");
|
|
}
|
|
|
|
AppBase.prototype.getWishlistProductId = function (jqObj) {
|
|
return String(
|
|
jqObj.attr("data-product-id") ||
|
|
jqObj.data("product-id") ||
|
|
this.getProductId(jqObj) ||
|
|
""
|
|
).trim();
|
|
}
|
|
|
|
AppBase.prototype.setWishlistButtonState = function(jqButton, productId, isActive) {
|
|
let _this = this;
|
|
let jqTargets = jqButton.closest(".single-product, .product-detail, .quickview-modal, .wish-table-info").find(".add-to-wishlist");
|
|
|
|
if (productId.length) {
|
|
jqTargets = jqTargets.add($(".add-to-wishlist[data-product-id='" + productId + "']"));
|
|
}
|
|
|
|
jqTargets.each(function() {
|
|
let $target = $(this);
|
|
let $icon = $target.find("i.ri-heart-line, i.ri-heart-fill").first();
|
|
let $tooltip = $target.find(".tooltip-text").first();
|
|
|
|
$target.toggleClass("active", isActive).attr("data-wl-action", (isActive ? "remove" : "add"));
|
|
|
|
if ($icon.length) {
|
|
$icon.removeClass("ri-heart-line ri-heart-fill").addClass(isActive ? "ri-heart-fill" : "ri-heart-line");
|
|
}
|
|
|
|
if ($tooltip.length) {
|
|
$tooltip.text(isActive
|
|
? defaultVal(_this.gM["remove from wishlist"], "remove from wishlist")
|
|
: defaultVal(_this.gM["wishlist"], "wishlist"));
|
|
}
|
|
});
|
|
}
|
|
|
|
AppBase.prototype.bindWishlistActions = function() {
|
|
var _this = this;
|
|
|
|
// Heart icon click - add to wishlist (global, on all pages)
|
|
$(document).on("click", ".add-to-wishlist", function(e) {
|
|
e.stopImmediatePropagation();
|
|
e.preventDefault();
|
|
var $btn = $(this);
|
|
var productId = _this.getWishlistProductId($btn);
|
|
if (!productId) {
|
|
console.warn("No product ID for wishlist");
|
|
return;
|
|
}
|
|
|
|
var action = ($btn.hasClass("active") || $btn.attr("data-wl-action") === "remove" ? "remove" : "add");
|
|
|
|
_this.ajax(
|
|
{action: "runWishlist", wl_action: action, product_id: productId},
|
|
defaultVal(_this.dt.profileLink, false),
|
|
function(data) {
|
|
if (data && data.jsonok) {
|
|
_this.setWishlistButtonState($btn, productId, action === "add");
|
|
_this.updateWishlistCount(defaultVal(data.count, 0));
|
|
} else if (data && data.error) {
|
|
_this.showErrorModal(data.msg ? data.msg : 'You must be logged in to use wishlist');
|
|
}
|
|
},
|
|
'POST',
|
|
function() {
|
|
console.log("Wishlist add failed");
|
|
}
|
|
);
|
|
});
|
|
};
|
|
|
|
AppBase.prototype.initWishlistState = function() {
|
|
var _this = this;
|
|
var wishlistUrl = defaultVal(_this.dt.profileLink, false);
|
|
|
|
if (!wishlistUrl || !$(".add-to-wishlist, .wishlist-counter").length) {
|
|
return;
|
|
}
|
|
|
|
_this.ajax(
|
|
{action: "runWishlist", wl_action: "getIds"},
|
|
wishlistUrl,
|
|
function(data) {
|
|
if (!data || data.error || !data.jsonok) {
|
|
return;
|
|
}
|
|
|
|
var wishlistIds = Array.isArray(data.ids) ? data.ids.map(String) : [];
|
|
_this.updateWishlistCount(defaultVal(data.count, wishlistIds.length));
|
|
|
|
$(".add-to-wishlist").each(function() {
|
|
var $btn = $(this);
|
|
var productId = _this.getWishlistProductId($btn);
|
|
if (!productId.length) {
|
|
return;
|
|
}
|
|
_this.setWishlistButtonState($btn, productId, wishlistIds.indexOf(productId) !== -1);
|
|
});
|
|
},
|
|
"POST"
|
|
);
|
|
};
|
|
|
|
AppBase.prototype.updateWishlistCount = function(count) {
|
|
$(".wishlist-count, .wish-counter, .wishlist-counter").text(count);
|
|
};
|
|
|
|
AppBase.prototype.getCartOptionValue = function(jqScope, suffix){
|
|
let jqValue = jqScope.find("input[type='radio'][name$='" + suffix + "']:checked").first();
|
|
if (!jqValue.length) {
|
|
jqValue = jqScope.find("input[type='radio'][name*='" + suffix.replace('-', '') + "']:checked").first();
|
|
}
|
|
return String(jqValue.val() || "").trim();
|
|
};
|
|
|
|
AppBase.prototype.getCartAddPayload = function(jqButton){
|
|
let productId = String(jqButton.attr("data-product-id") || jqButton.data("product-id") || "").trim();
|
|
if (!productId.length) {
|
|
return false;
|
|
}
|
|
|
|
let selectors = ".product-detail, .single-product, .product-info, .product-action-wrap, .product-image-col, .product-review, .drawer-recommended-product, .cart-area";
|
|
let jqScope = jqButton.closest(selectors);
|
|
// If scoped to a sub-section (not a top-level wrapper), expand to the full product detail container
|
|
// so variant radio inputs in sibling sections are also reachable via find()
|
|
if (jqScope.length && !jqScope.is(".product-detail, .single-product, .cart-area")) {
|
|
let jqWider = jqScope.closest(".product-detail-info, .product-detail, .single-product");
|
|
if (jqWider.length) jqScope = jqWider;
|
|
}
|
|
let d1 = String(jqButton.attr("data-d1") || jqButton.data("d1") || "").trim();
|
|
let d2 = String(jqButton.attr("data-d2") || jqButton.data("d2") || "").trim();
|
|
if (!d1.length) {
|
|
d1 = this.getCartOptionValue(jqScope, "-size") || String(jqScope.find("[data-d1]").first().data("d1") || "").trim();
|
|
}
|
|
if (!d2.length) {
|
|
d2 = this.getCartOptionValue(jqScope, "-color") || String(jqScope.find("[data-d2]").first().data("d2") || "").trim();
|
|
}
|
|
let jqQty = jqScope.find(".js-qty-num").first();
|
|
let count = parseInt(jqQty.val(), 10);
|
|
if (isNaN(count) || count < 1) {
|
|
count = 1;
|
|
}
|
|
|
|
return {
|
|
action: "addToCart",
|
|
p: productId,
|
|
d1: d1 || 0,
|
|
d2: d2 || 0,
|
|
count: count
|
|
};
|
|
};
|
|
|
|
AppBase.prototype.getCartItemId = function(jqButton){
|
|
// First try to get from parent .cart-drawer-info
|
|
let jqCartItem = jqButton.closest("[data-item]");
|
|
console.log(jqCartItem);
|
|
if (jqCartItem.length) {
|
|
return String(jqCartItem.attr("data-item") || "").trim();
|
|
}
|
|
|
|
return '';
|
|
// Fallback: try to get from nearby elements (for backward compatibility)
|
|
//let jqWrap = jqButton.closest(".js-qty-wrap, .cart-drawer-qty-remove, .cart-qty-remove");
|
|
//let jqInput = jqWrap.find(".js-qty-num").first();
|
|
//return String(jqButton.attr("data-item") || jqInput.attr("name") || jqInput.attr("data-item") || "").trim();
|
|
};
|
|
|
|
AppBase.prototype.requestCartAction = function(data, onSuccess){
|
|
if (!this.dt || !this.dt.cartLink) {
|
|
return false;
|
|
}
|
|
|
|
return this.ajax(data, this.dt.cartLink, function(resp) {
|
|
if ($.isFunction(onSuccess)) {
|
|
onSuccess(resp);
|
|
}
|
|
return resp;
|
|
});
|
|
};
|
|
|
|
AppBase.prototype.openCartDrawer = function($force){
|
|
// Remove invisible, then trigger CSS transition
|
|
var $drawer = $("#cart-drawer");
|
|
var $bgShop = $(".bg-screen .bg-shop");
|
|
|
|
$drawer.removeClass("invisible");
|
|
$bgShop.removeClass("opacity-0 invisible");
|
|
|
|
if (defaultVal($force, true)) {
|
|
// Force reflow, and trigger animation
|
|
void $drawer[0].offsetWidth;
|
|
}
|
|
|
|
$drawer.addClass("active visible");
|
|
$bgShop.addClass("opacity-50 visible");
|
|
$("body").addClass("oh");
|
|
};
|
|
|
|
AppBase.prototype.openMobileMenu = function(){
|
|
var $menu = $("#mobile-menu");
|
|
var $bgBack = $(".bg-screen .bg-back");
|
|
if (!$menu.length) {
|
|
return false;
|
|
}
|
|
|
|
$menu.removeClass("invisible").addClass("active visible").attr("aria-hidden", "false");
|
|
$bgBack.removeClass("opacity-0 invisible").addClass("opacity-50 visible").attr("aria-hidden", "false");
|
|
$("body").addClass("mobile-menu-open");
|
|
$("a.toggler-btn").attr("aria-expanded", "true");
|
|
|
|
return true;
|
|
};
|
|
|
|
AppBase.prototype.closeMobileMenu = function(resetAccordions){
|
|
var $menu = $("#mobile-menu");
|
|
var $bgBack = $(".bg-screen .bg-back");
|
|
|
|
$menu.addClass("invisible").removeClass("active visible").attr("aria-hidden", "true");
|
|
$bgBack.addClass("opacity-0 invisible").removeClass("opacity-50 visible").attr("aria-hidden", "true");
|
|
$("body").removeClass("mobile-menu-open");
|
|
$("a.toggler-btn").attr("aria-expanded", "false");
|
|
|
|
if (resetAccordions && $.fn.collapse) {
|
|
$menu.find(".collapse.show").collapse("hide");
|
|
}
|
|
};
|
|
|
|
AppBase.prototype.bindMobileMenuActions = function(){
|
|
var _this = this;
|
|
|
|
$(document).off("click", "a.toggler-btn");
|
|
$(document).off("click", ".menu-close button.menu-close-btn, .bg-screen .bg-back");
|
|
|
|
$(document).on("click.baseMobileMenu", "a.toggler-btn", function(e) {
|
|
e.stopImmediatePropagation();
|
|
e.preventDefault();
|
|
|
|
if ($("#mobile-menu").hasClass("active")) {
|
|
_this.closeMobileMenu(true);
|
|
return false;
|
|
}
|
|
|
|
_this.openMobileMenu();
|
|
return false;
|
|
});
|
|
|
|
$(document).on("click.baseMobileMenu", ".menu-close button.menu-close-btn, .bg-screen .bg-back", function(e) {
|
|
e.stopImmediatePropagation();
|
|
e.preventDefault();
|
|
_this.closeMobileMenu(true);
|
|
return false;
|
|
});
|
|
|
|
$(document).on("click.baseMobileMenu", "#mobile-menu a.js-mobile-menu-link", function() {
|
|
var href = String($(this).attr("href") || "").trim().toLowerCase();
|
|
if (href && href !== "#" && href !== "javascript:void(0)") {
|
|
_this.closeMobileMenu(true);
|
|
}
|
|
});
|
|
|
|
$(document).off("keyup.baseMobileMenu").on("keyup.baseMobileMenu", function(e) {
|
|
if (e.key === "Escape" && $("#mobile-menu").hasClass("active")) {
|
|
_this.closeMobileMenu(true);
|
|
}
|
|
});
|
|
|
|
$(window).off("resize.baseMobileMenu").on("resize.baseMobileMenu", function() {
|
|
if ($(window).width() >= 1200 && $("#mobile-menu").hasClass("active")) {
|
|
_this.closeMobileMenu(true);
|
|
}
|
|
});
|
|
};
|
|
|
|
AppBase.prototype.closeCartDrawer = function(){
|
|
$("#cart-drawer").addClass("invisible").removeClass("active visible");
|
|
$(".bg-screen .bg-shop").addClass("opacity-0 invisible").removeClass("opacity-50 visible");
|
|
$("body").removeClass("oh");
|
|
};
|
|
|
|
AppBase.prototype.applyCartResponse = function(resp, options){
|
|
let _this = this;
|
|
options = defaultVal(options, {});
|
|
|
|
if (!resp) {
|
|
return false;
|
|
}
|
|
|
|
if (resp.counter !== undefined) {
|
|
$(".cart-counter").text(resp.counter);
|
|
} else if (resp.total !== undefined) {
|
|
$(".cart-counter").text(resp.total);
|
|
}
|
|
|
|
if (resp.subtotal !== undefined) {
|
|
$(".js-cart-subtotal").text("€ " + resp.subtotal);
|
|
}
|
|
|
|
// Full drawer refresh (add-to-cart, open drawer)
|
|
if (resp.html) {
|
|
let wasOpen = $("#cart-drawer").hasClass("visible");
|
|
$("#cart-drawer").replaceWith(resp.html);
|
|
if (wasOpen) {
|
|
_this.openCartDrawer(false);
|
|
}
|
|
_this.updateCheckoutButtonState();
|
|
}
|
|
// Optimized items-only refresh (qty adjust, remove from drawer)
|
|
if (resp.cart_view_items_html) {
|
|
$(".cart-table-detail").replaceWith(resp.cart_view_items_html);
|
|
}
|
|
// Optimized items-only refresh (qty adjust, remove from drawer)
|
|
if (resp.cart_items_html) {
|
|
let $cart = $(".cart-table");
|
|
let cartTable = $cart.length ? $cart : $(".cart-drawer-table");
|
|
cartTable.replaceWith(resp.cart_items_html);
|
|
}
|
|
|
|
if (resp.reload && options.reloadOnEmpty) {
|
|
window.location.reload();
|
|
}
|
|
|
|
$(document).trigger("cart:updated", [resp, options]);
|
|
|
|
return true;
|
|
};
|
|
|
|
AppBase.prototype.bindCartActions = function(){
|
|
let _this = this;
|
|
|
|
if (!this.dt || !this.dt.cartLink) {
|
|
return;
|
|
}
|
|
|
|
// Global Open cart drawer
|
|
$(document).on("click", ".js-cart-drawer", function(e) {
|
|
e.stopImmediatePropagation();
|
|
e.preventDefault();
|
|
_this.openCartDrawer();
|
|
});
|
|
// Global Close cart drawer
|
|
$(document).on("click", ".drawer-close-btn, .bg-screen .bg-shop", function(e) {
|
|
e.stopImmediatePropagation();
|
|
e.preventDefault();
|
|
_this.closeCartDrawer();
|
|
});
|
|
// Global add to cart
|
|
$(document).on("click", ".add-to-cart", function(e) {
|
|
e.stopImmediatePropagation();
|
|
e.preventDefault();
|
|
|
|
let $btn = $(this);
|
|
if ($btn.hasClass("disabled") || $btn.is("[disabled]")) {
|
|
return false;
|
|
}
|
|
|
|
let payload = _this.getCartAddPayload($btn);
|
|
if (!payload) {
|
|
return true;
|
|
}
|
|
|
|
_this.ajaxLoader.jqAjaxSaveCaller = $btn;
|
|
_this.requestCartAction(payload, function(resp) {
|
|
_this.applyCartResponse(resp, {action: payload.action});
|
|
if (resp && resp.error) {
|
|
_this.showErrorModal(resp.data || resp.message || '');
|
|
} else if (resp && !resp.error) {
|
|
_this.openCartDrawer();
|
|
}
|
|
});
|
|
return false;
|
|
});
|
|
// Global buy now
|
|
$(document).on("click", ".js-buy-now", function(e) {
|
|
e.stopImmediatePropagation();
|
|
e.preventDefault();
|
|
|
|
let $btn = $(this);
|
|
if ($btn.hasClass("disabled") || $btn.is("[disabled]")) {
|
|
return false;
|
|
}
|
|
|
|
let payload = _this.getCartAddPayload($btn);
|
|
if (!payload) {
|
|
return true;
|
|
}
|
|
|
|
payload.buyNow = 1;
|
|
_this.ajaxLoader.jqAjaxSaveCaller = $btn;
|
|
_this.requestCartAction(payload, function(resp) {
|
|
_this.applyCartResponse(resp, {action: payload.action});
|
|
if (resp) {
|
|
if (resp.error) {
|
|
_this.showErrorModal(resp.data || resp.message || '');
|
|
} else if (resp.checkoutUrl) {
|
|
window.location.href = resp.checkoutUrl;
|
|
} else {
|
|
window.location.href = $btn.attr("href");
|
|
}
|
|
}
|
|
});
|
|
return false;
|
|
});
|
|
// Cart drawer qty adjust
|
|
$(document).on("click", ".cart-drawer .js-qty-adjust, .cart-area .js-qty-adjust", function(e) {
|
|
e.stopImmediatePropagation();
|
|
e.preventDefault();
|
|
|
|
let $btn = $(this);
|
|
let itemId = _this.getCartItemId($btn);
|
|
if (!itemId.length) {
|
|
return false;
|
|
}
|
|
|
|
let $input = $btn.closest(".js-qty-wrap").find(".js-qty-num").first();
|
|
let count = parseInt($input.val(), 10);
|
|
if (isNaN(count) || count < 1) {
|
|
count = 1;
|
|
}
|
|
|
|
if ($btn.hasClass("js-qty-adjust-minus")) {
|
|
count -= 1;
|
|
} else {
|
|
count += 1;
|
|
}
|
|
|
|
_this.ajaxLoader.jqAjaxSaveCaller = $btn;
|
|
if (count < 1) {
|
|
_this.requestCartAction({action: "remItem", item: itemId}, function(resp) {
|
|
_this.applyCartResponse(resp, {action: "remItem"});
|
|
});
|
|
return false;
|
|
}
|
|
|
|
$input.val(count);
|
|
_this.requestCartAction({action: "incDec", item: itemId, count: count}, function(resp) {
|
|
_this.applyCartResponse(resp, {action: "incDec"});
|
|
});
|
|
return false;
|
|
});
|
|
// Cart drawer remove
|
|
$(document).on("click", ".cart-drawer .cart-drawer-remove, .cart-area .cart-remove", function(e) {
|
|
e.stopImmediatePropagation();
|
|
e.preventDefault();
|
|
|
|
let $btn = $(this);
|
|
let itemId = _this.getCartItemId($btn);
|
|
if (!itemId.length) {
|
|
return false;
|
|
}
|
|
|
|
_this.ajaxLoader.jqAjaxSaveCaller = $btn;
|
|
_this.requestCartAction({action: "remItem", item: itemId}, function(resp) {
|
|
_this.applyCartResponse(resp, {action: "remItem"});
|
|
});
|
|
return false;
|
|
});
|
|
// Cart drawer agree to terms
|
|
$(document).on("click", ".cart-drawer #agree_to_terms", function() {
|
|
$(this).toggleClass("chked");
|
|
_this.updateCheckoutButtonState();
|
|
});
|
|
// Cart drawer agree to terms checkbox label
|
|
$(document).on("click", ".cart-drawer .agree_to label", function () {
|
|
$(this).parent().find("#agree_to_terms").toggleClass("chked");
|
|
_this.updateCheckoutButtonState();
|
|
});
|
|
};
|
|
|
|
AppBase.prototype.updateCheckoutButtonState = function(){
|
|
let $termsCheckbox = $("#agree_to_terms");
|
|
let $checkoutBtn = $("#cart-drawer a.secondary-btn[href*='STEP_2_CHECKOUT'], #cart-drawer .drawer-cart-checkout a.secondary-btn");
|
|
|
|
if (!$checkoutBtn.length) {
|
|
return;
|
|
}
|
|
|
|
if ($termsCheckbox.length && $termsCheckbox.hasClass("chked")) {
|
|
$checkoutBtn.removeClass("disabled opacity-50 pe-none").addClass("enabled");
|
|
} else {
|
|
$checkoutBtn.addClass("disabled opacity-50 pe-none").removeClass("enabled");
|
|
}
|
|
};
|
|
|
|
AppBase.prototype.bindFormSubmits = function(){
|
|
let _this = this;
|
|
let jqForms = $("#popup_subscribe, #footer_subscribe");
|
|
|
|
jqForms.each(function() {
|
|
let $form = $(this);
|
|
|
|
// Form input handling
|
|
$form.find("input").on({
|
|
focus: function() {
|
|
$(this).parent().addClass("active");
|
|
},
|
|
blur: function() {
|
|
$(this).parent().removeClass("active");
|
|
},
|
|
keydown: function(e) {
|
|
if (e.which === _this.iKeys.ENTER) {
|
|
_this.ajaxLoader.jqAjaxSaveCaller = $(this);
|
|
_this.submitSubscribeForm($form);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Submit button
|
|
$form.find("button[type='submit']").click(function(e) {
|
|
e.preventDefault();
|
|
_this.ajaxLoader.jqAjaxSaveCaller = $(this);
|
|
_this.submitSubscribeForm($form);
|
|
return true;
|
|
});
|
|
});
|
|
|
|
// Search form submit handler
|
|
$(document).on("submit", ".search-form", function(e) {
|
|
var $form = $(this);
|
|
var $searchInput = $form.find(".search-input");
|
|
var searchVal = $searchInput.val().trim();
|
|
if (!searchVal.length) {
|
|
e.preventDefault();
|
|
return false;
|
|
}
|
|
// PHP side handles base64 encoding, just let form submit naturally
|
|
});
|
|
};
|
|
|
|
AppBase.prototype.submitSubscribeForm = function(jqParent){
|
|
let _this = this;
|
|
let jqField = jqParent.find('input[type="email"]');
|
|
if (!_this.validatorSubscribe.isFormValid(jqField)) return false;
|
|
|
|
let oData = {action: 'subscribe', data: {sub_email: jqField.val()}};
|
|
_this.ajax(oData, _this.dt['subLink'], (data) => {
|
|
_this.handleFormResponse(jqParent, data);
|
|
_this.closePopup(jqParent);
|
|
});
|
|
|
|
return true;
|
|
};
|
|
|
|
AppBase.prototype.closePopup = function(jqParent){
|
|
jqParent.closest("div.modal-body").find("button > i.ri-close-large-line").click();
|
|
};
|
|
|
|
AppBase.prototype.bindFormValidations = function(){
|
|
let _this = this;
|
|
|
|
if (typeof Validator === "undefined") {
|
|
console.log("Validator is not defined, form validation will not work.");
|
|
return;
|
|
}
|
|
|
|
Validator.prototype.showError = function(caller, msg) {
|
|
if (caller) _this.showFieldError(caller, msg);
|
|
};
|
|
|
|
Validator.prototype.hideError = function(caller) {
|
|
if (caller) _this.hideFieldError(caller);
|
|
};
|
|
|
|
if ($.isDefined(_this.dt.subCfg)) {
|
|
_this.validatorSubscribe = new Validator(_this.dt.subCfg, "body", _this.gM);
|
|
if ($.isDefined(_this.dt.fData)) {
|
|
_this.validatorSubscribe.showErrorsByObject(_this.dt.fData.err);
|
|
}
|
|
}
|
|
};
|
|
|
|
AppBase.prototype.getValidationWrapper = function(caller) {
|
|
let $caller = $(caller);
|
|
let $validate = $caller.closest(".validate");
|
|
return ($validate.length ? $validate : $caller.parent());
|
|
};
|
|
|
|
AppBase.prototype.showFieldError = function(caller, msg) {
|
|
let $wrapper = this.getValidationWrapper(caller);
|
|
let $errMsg = $wrapper.addClass("v-error").removeClass("v-ok").find(".errMsg");
|
|
$errMsg.length ? $errMsg.show().html(msg) : $wrapper.append("<div class='errMsg'>" + msg + "</div>");
|
|
};
|
|
|
|
AppBase.prototype.hideFieldError = function(caller) {
|
|
this.getValidationWrapper(caller).addClass("v-ok").removeClass("v-error").find(".errMsg").hide().html("");
|
|
};
|
|
|
|
AppBase.prototype.shakeInvalidCheckboxes = function(jqScope) {
|
|
let $scope = $(jqScope || document.body);
|
|
let $invalidGroups = $scope.find(".validate.v-error").has("input[type='checkbox']");
|
|
|
|
if (!$invalidGroups.length || !$.isFunction($.fn.effect)) {
|
|
return;
|
|
}
|
|
|
|
$invalidGroups.each(function() {
|
|
$(this).stop(true, true).effect("shake", {}, 500);
|
|
});
|
|
};
|
|
|
|
AppBase.prototype.handleFormResponse = function(jqParent, data) {
|
|
let _this = this;
|
|
let isSuccess = data && data.jsonok;
|
|
if (!isSuccess && data.error && data.err) {
|
|
for(let i in data.err) {
|
|
if (data.err.hasOwnProperty(i)) {
|
|
let $field = jqParent.find("#" + i);
|
|
if ($field.length) {
|
|
_this.validatorContactUs.showError($field, data.err[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
setTimeout(() => {
|
|
jqParent.find("h3.tt, .v-ok").removeClass("ok err v-ok");
|
|
if (isSuccess) {
|
|
jqParent.find("input:not(.btn), textarea").val('');
|
|
}
|
|
}, 1400);
|
|
};
|
|
|
|
AppBase.prototype.genRandomUniqueDocID = function(){
|
|
var sID = "ID" + Math.floor((Math.random() * 100000) + 1);
|
|
while($("#"+sID).length) sID = "ID" + Math.floor((Math.random() * 100000) + 1);
|
|
return sID;
|
|
};
|
|
|
|
AppBase.prototype.genRandomID = function(length){
|
|
var result = [];
|
|
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
var charactersLength = characters.length;
|
|
for ( var i = 0; i < length; i++ ) {
|
|
result.push(characters.charAt(Math.floor(Math.random() *
|
|
charactersLength)));
|
|
}
|
|
return result.join('');
|
|
};
|
|
|
|
AppBase.prototype.scrollToSeeElement = function(jqElement, fnCallback){
|
|
var iScrollTo = false;
|
|
var winH = window.innerHeight;
|
|
var jqHtml = $("html"), winS2Top = jqHtml.scrollTop();
|
|
|
|
var iElemTop = jqElement.offset().top;
|
|
|
|
if(iElemTop < winS2Top){
|
|
iScrollTo = iElemTop - 30;
|
|
}else if((iElemTop + jqElement.outerHeight()) > (winH + winS2Top)){
|
|
iScrollTo = winS2Top + (iElemTop + jqElement.outerHeight()) - (winH + winS2Top) + 20;
|
|
}
|
|
if(iScrollTo){
|
|
jqHtml.stop(true, true).animate({scrollTop: iScrollTo}, 400, function(){
|
|
if ($.isFunction(fnCallback))
|
|
fnCallback();
|
|
});
|
|
}
|
|
};
|
|
|
|
// Copies a string to the clipboard. Must be called from within an event handler such as click.
|
|
// May return false if it failed, but this is not always
|
|
// possible. Browser support for Chrome 43+, Firefox 42+, Edge and IE 10+.
|
|
// No Safari support, as of (Nov. 2015). Returns false.
|
|
// IE: The clipboard feature may be disabled by an adminstrator. By default a prompt is
|
|
// shown the first time the clipboard is used (per session).
|
|
AppBase.prototype.copyToClipboard = function(text) {
|
|
if (window.clipboardData && window.clipboardData.setData) {
|
|
// IE specific code path to prevent textarea being shown while dialog is visible.
|
|
return clipboardData.setData("Text", text);
|
|
|
|
} else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
|
|
var textarea = document.createElement("textarea");
|
|
textarea.textContent = text;
|
|
textarea.style.position = "fixed"; // Prevent scrolling to bottom of page in MS Edge.
|
|
document.body.appendChild(textarea);
|
|
textarea.select();
|
|
try {
|
|
return document.execCommand("copy"); // Security exception may be thrown by some browsers.
|
|
} catch (ex) {
|
|
console.warn("Copy to clipboard failed.", ex);
|
|
return false;
|
|
} finally {
|
|
document.body.removeChild(textarea);
|
|
}
|
|
}
|
|
};
|
|
|
|
AppBase.prototype.xPos = 0;
|
|
AppBase.prototype.yPos = 0;
|
|
// Function that logs user mouse position at all time
|
|
AppBase.prototype.findDocumentXY = function(e){
|
|
var _this = this;
|
|
|
|
// FireFox Chrome Safari
|
|
if(e){
|
|
_this.xPos = e.pageX;
|
|
_this.yPos = e.pageY;
|
|
//IE
|
|
}else{
|
|
_this.xPos = window.event.x + document.body.scrollLeft - 2;
|
|
_this.yPos = window.event.y + document.body.scrollTop - 2;
|
|
}
|
|
//console.log(_this.xPos, _this.yPos);
|
|
};
|
|
|
|
/**
|
|
* Function to get scrollbar width
|
|
*
|
|
* @this {AppBase}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @return int
|
|
*/
|
|
AppBase.prototype.getScrollBarWidth = function(){
|
|
|
|
// Creating invisible container
|
|
const outer = document.createElement('div');
|
|
outer.style.visibility = 'hidden';
|
|
outer.style.overflow = 'scroll'; // forcing scrollbar to appear
|
|
outer.style.msOverflowStyle = 'scrollbar'; // needed for WinJS apps
|
|
document.body.appendChild(outer);
|
|
document.body.appendChild(outer);
|
|
|
|
// Creating inner element and placing it in the container
|
|
const inner = document.createElement('div');
|
|
outer.appendChild(inner);
|
|
|
|
// Calculating difference between container's full width and the child width
|
|
const scrollbarWidth = (outer.offsetWidth - inner.offsetWidth);
|
|
|
|
// Removing temporary elements from the DOM
|
|
outer.parentNode.removeChild(outer);
|
|
|
|
return scrollbarWidth;
|
|
};
|
|
|
|
/**
|
|
* Function to check if scrollbar is activated
|
|
*
|
|
* @this {AppBase}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @param {jQuery} [jqContainer = $(#cms-table-drop-marker > .table-rows:first-child)] - container object
|
|
* @param {int} [eType = 1] - Scroll to check 1 - Horizontal, 2 - vertical
|
|
* @return boolean
|
|
*/
|
|
AppBase.prototype.chkScrollActive = function(jqContainer, eType){
|
|
eType = defaultVal(eType, 1);
|
|
jqContainer = defaultVal(jqContainer, $("#cms-table-drop-marker > .table-rows:first-child"));
|
|
if(jqContainer.length && jqContainer.is(":visible")){
|
|
if(eType === 1)
|
|
return jqContainer[0].scrollWidth > jqContainer[0].clientWidth;
|
|
else
|
|
return jqContainer[0].scrollHeight > jqContainer[0].clientHeight;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Function to initialize & load JS module
|
|
*
|
|
* @this {AppBase}
|
|
* @author Mareks Keiss <mareks.keiss@brsystems.lv>
|
|
* @return void
|
|
*/
|
|
AppBase.prototype.initJsModule = function() {
|
|
var _this = this;
|
|
|
|
// Init module if set
|
|
if(_this.dt && _this.dt.JsModuleTitle && !defaultVal(_this.dt.JsInitPostpone, false))
|
|
_this.jsModule = new window[_this.dt.JsModuleTitle]();
|
|
|
|
_this.dt.JsInitPostpone = false;
|
|
};
|
|
|
|
return AppBase;
|
|
})();
|
|
})();
|