/* * Cms Base JavaScript Library v1.1 */ /******************************************************************** * GLOBAL FUNCTIONS ********************************************************************/ window.pr = function (obj) { if ("console" in window) { let vArgs = Array.from(arguments); for (let 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) { let rVal = defaultVal(arg, val); if (rVal === false) return val; return rVal; }; // Add jQuery object check function $.isObject = function(e){ return !(typeof e !== "object"); }; $.isDefined = function(e){ return (typeof e !== "undefined"); }; /** * 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} - 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}`); } } /******************************************************************** * BASE URL CLASS ********************************************************************/ class BaseUrl { path = ""; constructor(baseUrl) { // Add url let url, len; if (!$.isDefined(baseUrl) || $.isDefined(baseUrl) && !baseUrl) { url = window.location.pathname; } else { url = baseUrl; } len = url.length; this.path = (url.substring(len - 1) === "/" ? url.substring(0, len - 1) : url); } } /******************************************************************** * SESSION CLASS ********************************************************************/ class BaseSession { iTime = 0; iTimeout = 0; sBody = $(); sUrlSrc = ""; jqIframe = $(); jqObject = $(); /** @type {SessionTicker} */ timer; constructor(sessionTime, sLoginLink) { let _this = this; if (sessionTime) { _this.sUrlSrc = sLoginLink; _this.sBody = $("#sessionTime"); _this.iTime = _this.iTimeout = (parseInt(sessionTime) - 1); if (!_this.sBody.length) { $("body").append(_this.sBody = $( "" + "
" + "

Session will expire in:

" + "

Session has expired! Time left:

" + "
" + "
00:00
" + "
").css({opacity: 0.5})); } _this.appendSessionTime(); _this.sBody.find(".ed").hide(); _this.init(); } } 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; 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; // Format status timer _this.sBody.find("span").addClass("ajax"); CBase.ajaxLoader.disabled = true; CBase.ajax({ac: "tcheck"}, "/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"); CBase.ajaxLoader.disabled = false; _this.showLoginForm(); }); } showLoginForm(){ let _this = this, bAppended = false; // Create form only if already not exists if (!_this.jqIframe.length) { bAppended = true; _this.jqIframe = $("") .css({visibility: "hidden"}); $("body").append(_this.jqIframe); } _this.jqIframe.on("load", function () { $("body").addClass("oh").find("> .wrapper, #confirmDialog").addClass("fmoreblur"); if (bAppended) { bAppended = false; setTimeout(function () { _this.jqIframe.hide().css({visibility: "unset"}); _this.jqIframe.fadeIn("fast"); }, 100); } }); } hideLoginForm(){ let _this = this; _this.updateTimer(true); _this.jqIframe.fadeOut("fast", function () { $(this).remove(); _this.jqIframe = $(); }); $("body").removeClass("oh").find("> .wrapper, #confirmDialog").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')}`; } } /******************************************************************** * TABS CLASS ********************************************************************/ class Tabs { constructor(tabObj) { let _this = this; $(tabObj).each(function () { $(this).find(".tab-btn li a").each(function () { $(this).closest(".tabs").find("." + $(this).attr("id")).hide(); $(this).click(function () { _this.select(this, true); }); }); _this.select($(this).find(".tab-btn li a:first"), false); }); } select(_tab, _eff) { _tab = $(_tab); if (!_tab.parent().hasClass("ts")) { let _parent = _tab.closest(".tabs"); _parent.find(".ts").removeClass("ts"); _tab.parent().addClass("ts"); _parent.find(".sbox").stop(true, true).hide(); if (_eff) { _parent.find("." + _tab.attr("id")).fadeIn("fast"); } else { _parent.find("." + _tab.attr("id")).show(); } } } } /******************************************************************** * AJAX LOADER CLASS ********************************************************************/ class AjaxLoader { jqAjax = {}; disabled = false; disabledFadeOut = false; jqCallerObject = $(); jqCloneVisibleObject = $(); constructor() { let _this = this; _this.jqAjax = $("#ajax_loader"); _this.jqRoundAjaxLoader = $('
'); if (!_this.jqAjax.length) { // Create ajax loader _this.jqAjax = $("
").hide(); _this.jqAjax.find(">div").append(_this.jqRoundAjaxLoader.clone()); $("body").append(_this.jqAjax); } $(document).ajaxStart(function () { _this.showLoader(); }).ajaxStop(function () { _this.hideLoader(); }); } showLoader(callback){ let _this = this; if (!_this.disabled) { if (_this.jqCallerObject.length) { _this.jqCloneVisibleObject = _this.jqRoundAjaxLoader.clone(); _this.jqCallerObject.hide().after(_this.jqCloneVisibleObject).parent().addClass('callerAjaxObject'); } else { //_this.jqAjax.find(">div").css({"opacity" : "0.8"}); //_this.jqAjax.siblings().not(_this.jqAjax).addClass("fblur"); _this.jqAjax.fadeIn("fast", function () { if ($.isFunction(callback)) callback(); }); } } } hideLoader(force) { let _this = this; if (!_this.disabledFadeOut || $.isDefined(force) && force) { _this.disabledFadeOut = false; if (_this.jqCallerObject.length) { _this.jqCloneVisibleObject.remove(); _this.jqCallerObject.show().parent().removeClass('callerAjaxObject'); _this.jqCallerObject = $(); _this.jqCloneVisibleObject = $(); } else { if (_this.jqAjax.is(":visible")) { //_this.jqAjax.siblings().removeClass("fblur"); _this.jqAjax.fadeOut("fast", function () { $(this).hide(); }); } } } } } /******************************************************************** * CONFIRM DIALOG CLASS * ******************************************************************/ class ConfirmDialog { jqDialog = {}; isVisible = false; closeButton = true; constructor(sIDClass) { let _this = this; sIDClass = defaultVal(sIDClass, "mainWin"); // Check if dialog already exists _this.jqDialog = $("#confirmDialog."+sIDClass); if(!_this.jqDialog.length){ _this.jqDialog = $("
    ").hide(); $("body").append(_this.jqDialog); } if(jQuery().draggable) _this.jqDialog.find(".dialogContainer").draggable({ containment: "parent", handle: ".header" }); _this.jqDialog.find(".header").css({opacity : 0.9}); } show(oCfg){ let _this = this; if (oCfg) { if (oCfg.message && oCfg.buttons) { _this.populateButtons(oCfg.buttons); _this.jqDialog.find(".body").html(oCfg.message); } _this.jqDialog.find(".header").html((oCfg.title ? oCfg.title : "...")); // Add close button if exists if (oCfg.closeBtn) { _this.jqDialog.find(".header").append($("").click(function () { _this.hide(); })); } if (oCfg.callbackAfterAppend && $.isFunction(oCfg.callbackAfterAppend)) oCfg.callbackAfterAppend(_this.jqDialog); } let jqForm = _this.jqDialog.find("> div"); jqForm.fadeIn("fast"); _this.jqDialog.removeClass("ajax").fadeIn("fast"); //_this.jqDialog.siblings().not("#ajax_loader").addClass("fblur"); jqForm.css({top: ($(window).height() - jqForm.height()) / 3 + "px"}); _this.isVisible = true; } setCustomContentAndShow(oObj) { let _this = this; if (_this.isVisible) { if (oObj && oObj.message) _this.jqDialog.find(".body").html(oObj.message); } else { _this.show(oObj); } } hide(bShowAjaxLoader) { let _this = this; bShowAjaxLoader = defaultVal(bShowAjaxLoader, false); if (bShowAjaxLoader) { CBase.ajaxLoader.jqObj = _this.jqDialog.addClass("ajax"); } else _this.jqDialog.fadeOut("fast"); //_this.jqDialog.siblings().removeClass("fblur"); _this.jqDialog.find("> div").stop(true, true).fadeOut("fast"); _this.isVisible = false; } populateButtons(d) { if ($.isDefined(d)) { let i, _this = this; let cnt = _this.jqDialog.find(".buttons ul"); cnt.html(""); for (i in d) { if ($.isDefined(d[i].lbl) && $.isDefined(d[i].id)) { _this.addBtn(cnt, d[i]); } } } } addBtn(cnt, d) { let _this = this; let oLi = $("" + d.lbl + ""); if ("click" in d) { oLi.find("> a").click(function () { d.click({target: this, object: _this.jqDialog}); }); } if ("hidden" in d && d.hidden) oLi.hide(); cnt.append(oLi); } } /******************************************************************** * CUSTOM 2FA REQUEST ONTROLLER * ******************************************************************/ class C2FAController { jqObj = false; sCfgKey = "vcfg"; oValidator = false; jqSubmitButton = $(); // Submit to automatically call after paste event constructor(jqObj) { let _this = this; _this.jqObj = jqObj; } chk2FACode() { let _this = this, sCode = ""; if (_this.oValidator && _this.oValidator.isFormValid()) { _this.jqObj.find("input:text").each(function () { sCode += $(this).val(); }); return sCode; } else { _this.jqObj.find(".v-error:first input:text").focus(); } return false; } show2FAError(d, jqMsgContainer) { let _this = this; let sMsg = ("code" in d ? d.code : ("msg" in d ? d.msg : "Two-Factor Authentication Error!")); _this.jqObj.find("input:text").parent().addClass("v-error"); if (typeof jqMsgContainer === "undefined") _this.jqObj.find("p.msg-error").html(sMsg).fadeIn("fast"); else jqMsgContainer.html(sMsg).fadeIn("fast"); return false; } bindSingleField2FARequestInputs(){ let _this = this; let jqInputs = _this.jqObj.find("input:text"); if (jqInputs.length) { jqInputs.unbind('focus blur click paste').bind({ focus: function () { $(this).parent().addClass("focus"); this.setSelectionRange(0, this.value.length); }, blur: function () { $(this).parent().removeClass("focus"); }, click: function () { this.setSelectionRange(0, this.value.length); }, paste: function (e) { // access the clipboard using the api let jqOne = $(this); let pastedData = e.originalEvent.clipboardData.getData('text'); if (pastedData.length) { for (var i = 0; i < pastedData.length; i++) { if (jqOne.length) jqOne.val(pastedData.charAt(i)).blur(); jqOne = jqOne.parent().next().find("input:text"); } if (jqOne.length) { jqOne.focus(); } else { _this.jqObj.find("input:text:focus").blur(); // Submit form on last input if (_this.jqSubmitButton.length) _this.jqSubmitButton.click(); // If button - then click else _this.jqObj.find("input:first").closest("form").submit(); // else submit parent form } } } }); jqInputs.unbind('keyup change input').bind('keyup change input', function (e) { e.stopImmediatePropagation(); let jqObj = $(this); let val = jqObj.val(); let valLength = val.length; let maxCount = jqObj.attr('maxlength'); if (valLength > maxCount) jqObj.val(jqObj.val().substring(0, maxCount)); let ctrl = (e.ctrlKey || CBase.os.mac && e.metaKey); if ( e.type == "keyup" && !e.shiftKey && !ctrl && e.which != CBase.iKeys.TAB && e.which != CBase.iKeys.SHIFT && e.which != CBase.iKeys.KEY_V ) { // Delete button if (e.which == CBase.iKeys.BACKSPACE) { let jqInp = jqObj.parent().prev().find("input:text"); if (jqInp.length) jqInp.focus(); return false; } if (_this.oValidator && _this.oValidator.checkThis(jqObj)) { let jqInp = jqObj.parent().next().find("input:text"); if (jqInp.length) jqInp.focus(); else { jqObj.blur(); // Submit form on last input if (_this.jqSubmitButton.length) _this.jqSubmitButton.click(); // If button - then click else _this.jqObj.find("input:first").closest("form").submit(); // else submit parent form } } else jqObj.focus(); } }); // Setup Validator if ($.isFunction(Validator) && _this.sCfgKey in CBase.dt) { _this.oValidator = new Validator(CBase.dt[_this.sCfgKey], "#" + _this.jqObj.attr("id"), CBase.gM); _this.oValidator.hideError = function (caller) { let jqCaller = $(caller); if (jqCaller.length) { jqCaller.removeClass("err"); if (!jqCaller.parent().find(".err").length) jqCaller.parent().removeClass("v-error").find(".errMsg").hide().html(""); } // Hide base Error _this.jqObj.find("p.msg-error").fadeOut("fast"); }; _this.oValidator.showError = function (caller, msg) { let jqCaller = $(caller); if (jqCaller.length) { let jqErr = jqCaller.addClass("err").parent().addClass("v-error").find(".errMsg"); if (!jqErr.length) jqCaller.parent().append("
    " + msg + "
    "); else jqErr.show().html(msg); } }; } else pr("Missing cfg parts!") } } } /******************************************************************** * GLOBAL MESSAGE * ******************************************************************/ class FormMsg { iInt = 0; jqCnt = $(); jqMessage = $(); hideChecks = false; msg = { msgok : { t : "Data successfully saved", p : "Form data has been successfully saved" }, msgerror : { t : "Data save error", p : "An error occurred while saving data, please check fields and try again" } }; constructor(sCntSelector) { let _this = this; sCntSelector = defaultVal(sCntSelector, ".form-data h2.title"); _this.jqCnt = $("#data " + sCntSelector); if (_this.jqCnt.length) { _this.jqMessage = $("
    ").hide(); _this.jqCnt.append(_this.jqMessage); // Set translations if (CBase.gM) { for (let i in _this.msg) { _this.msg[i]["t"] = CBase.getMessageTranslation(_this.msg[i]["t"]); _this.msg[i]["p"] = CBase.getMessageTranslation(_this.msg[i]["p"]); } } } } show(red, autohide, title, description){ let _this = this; clearTimeout(_this.iInt); // Set auto-hide timer autohide = defaultVal(autohide, 4000); autohide = (autohide === true ? 4000 : autohide); red = defaultVal(red, ""); title = defaultValNotFalse(title, (red ? _this.msg.msgerror.t : _this.msg.msgok.t)); description = defaultValNotFalse(description, (red ? _this.msg.msgerror.p : _this.msg.msgok.p)); if (_this.jqMessage.length) { _this.jqMessage.removeClass("error"); // Set color if (red) _this.jqMessage.addClass("error"); // Set text _this.jqMessage.html(title); if (description.length) _this.jqMessage.append("" + description + ""); let hide = _this.hideChecks; _this.hideChecks = false; let offset = _this.jqMessage.parent().offset().top - 30; if (isNaN(offset) && offset < 0) offset = 0; $("html").animate({scrollTop: offset}, 400, function () { _this.jqMessage.stop(true, true).fadeIn("fast", function () { if (autohide) { _this.iInt = setTimeout(function () { _this.hide(hide); }, autohide); } }); }); } } hide(hideChecks){ let _this = this; hideChecks = defaultVal(hideChecks, false); _this.jqMessage.stop(true, true).fadeOut("fast"); if (hideChecks) CBase.oForm.jqBlank.find(".v-ok").removeClass("v-ok"); } } /******************************************************************** * CHECKBOXES * ******************************************************************/ class CheckBoxes { NO = "No"; YES = "Yes"; constructor() { } bindSliderCheckboxes(obj){ if ($.isDefined(obj)) { obj = $(".content > .cnt"); } let no = $.isDefined(CBase.gM.no) ? CBase.gM.no : this.NO; let yes = $.isDefined(CBase.gM.yes) ? CBase.gM.yes : this.YES; obj.find(".chk-value").each(function () { let parent = $(this).parent(); let y = (parent.find(".on").length ? parent.find(".on").text() : yes); let n = (parent.find(".off").length ? parent.find(".off").text() : no); let elem = $(this).wrap("
    "); elem = elem.parent().append( "
    " + "
    " + y + "
    " + n + "
    " + "
    "); if (elem.find("input").val()) { elem.find(".slider").addClass("sw-on"); } else { elem.find(".slider").removeClass("sw-on"); } if (elem.parent().is("li")) { elem.parent().click(function (e) { e.stopImmediatePropagation(); elem.click(); }); } elem.click(function (e) { e.stopImmediatePropagation(); let val = $(this).find("input"); let jqSlider = $(this).find(".slider").removeClass("sw0"); if (!val.is(":disabled")) { if (parseInt(val.val())) { val.val(""); jqSlider.removeClass("sw-on"); } else { val.val(1); jqSlider.addClass("sw-on"); } val.change(); } }); }); } bindSliderCheckboxesUpdate(jqObject) { jqObject.find(".chk-value").each(function () { let jqSlider = $(this).parent().find(".slider").addClass("sw0"); if ($(this).val() && $(this).val() !== "0") { jqSlider.addClass("sw-on"); } else { jqSlider.removeClass("sw-on"); } }); } bindBaseCheckboxes(obj) { if (!$.isDefined(obj)) { obj = $(".content > .cnt"); } // Bind checkboxes obj.find(".ncheckbox ul.pblocks li > .chk.disabled").parent().addClass("disabled"); obj.find(".ncheckbox ul.pblocks li > .chk:not(.disabled)").parent().click(function (e) { e.stopPropagation(); $(this).find(".chk").click(); }); obj.find(".ncheckbox .chk").parent().find("label").click(function (e) { e.stopPropagation(); $(this).parent().find(".chk").click(); }); obj.find(".ncheckbox .chk").click(function (e) { let jqObj = $(this), r = {}, sbox = {}; e.stopPropagation(); if (!jqObj.hasClass("disabled")) { if (jqObj.hasClass("chked")) { jqObj.removeClass("chked"); // Unticks mark tick all rows marker r = jqObj.closest(".sbox").find(".ckh_all:first .chk"); if (r.length && r.hasClass("chkedall")) { r.removeClass("chkedall chked"); } } else { jqObj.addClass("chked"); // Ticks mark tick all rows marker sbox = jqObj.closest(".sbox"); r = sbox.find(".ckh_all:first .chk"); if (r.length) { if (sbox.find(".ncheckbox .chk:not(.no-sbox-sel)").length == sbox.find(".ncheckbox .chk.chked:not(.no-sbox-sel)").length) { r.addClass("chkedall chked"); } } } jqObj.trigger("change"); } }); } } /******************************************************************** * JS BASE CLASS * ******************************************************************/ class CmsBase { dt = {}; gM = {}; os = {}; browser = {}; settings = {}; checkboxes = {}; ajaxLoader = {}; onResize = {}; oSession = null; oDialog = {}; oForm = {}; oTable = {}; jsModule = {}; url = null; debug = false; oConsole = false; 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 }; constructor() { let _this = this; // Load base js params if ($.isDefined(Vars.data)) { _this.dt = {}; for (let i in Vars.data) { if (i === 'gL' || i === 'gM') { _this.gM = $.parseJSON(Vars.data[i]); } else { _this.dt[i] = $.parseJSON(Vars.data[i]); } } } // Global clicks $('html').bind("click", function (event) { _this.hideSettMenu(event, $(".settbox")); _this.hideSettMenu(event, $(".actions a.dd")); _this.hideSubMenu(event, $(".sub-menu").closest("a")); $("#users-online").hide(); }); if (typeof BrsConsole === 'function') { _this.debug = true; _this.oConsole = new BrsConsole(_this); window.onerror = function (msg, url, lineNo, columnNo, error) { pr({msg: msg, url: url, lineNo: lineNo, columnNo: columnNo, error: error}); return false; }; } // Init subclasses _this.url = new BaseUrl(defaultVal(_this.dt.baseUrl, false)); _this.oSession = new BaseSession( ($.isDefined(_this.dt.sessionTime) ? _this.dt.sessionTime : 3600), ("sessionLoginLink" in _this.dt ? _this.dt.sessionLoginLink : "") ); _this.settings = typeof (Settings) != "undefined" ? new Settings() : {}; _this.ajaxLoader = new AjaxLoader(); _this.checkboxes = new CheckBoxes(); _this.message = new FormMsg(); _this.oDialog = new ConfirmDialog(); // Additional actions _this.getDevice(); _this.bindActions(); _this.resizeForm(); } // BIND ACTIONS bindActions() { this.bindMenuActions(); this.bindLeftMenuActions(); this.bindLayoutActions(); } resizeForm() { this.recalculateMenu(); this.resizeLeftMenu(); if ($.isDefined(this.onResize)) { for (let i in this.onResize) { if ($.isFunction(this.onResize[i])) this.onResize[i](); } } } // Global functions vNewMessages = {}; getMessageTranslation(sMsg){ let _this = this; if (_this.gM && _this.gM[sMsg]) return _this.gM[sMsg]; else _this.vNewMessages[sMsg]; return sMsg; } getDevice(){ let 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) } } ajax(data, url, onSuccess) { let _this = this; let jqAjaxCode = $("#ajaxcode"); if (jqAjaxCode.length) { $.extend(($.isDefined(data) ? data : {}), {ajaxCode: jqAjaxCode.val()}) } if (!$.isDefined(url) || $.isDefined(url) && !url) { url = window.location; } $.ajax({ url: url, type: "POST", data: data, dataType: "json", success: function (d) { if (d) { // Update session timer _this.oSession.updateTimer(); // Check if login request sent if (d.error && d.show_login_frm) { _this.oSession.callLoginForm(); return false; } } if ($.isFunction(onSuccess)) { onSuccess(d); } } }); } // Gather base fields getFields(obj, exclude, sKeyAttr) { let key; obj = defaultVal(obj, $(".cnt")); sKeyAttr = defaultValNotFalse(sKeyAttr, defaultValNotFalse(obj.data('attr-key'), "id")); exclude = defaultValNotFalse(exclude, ".skip"); let 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")) { let 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; } // MENU BLOCK bindMenuActions(){ let _this = this; _this.Mnu = {timeout: 0, oTimeout: 0}; /*$(".menu:not(.settbox) li > a").click(function(){ $(this).closest("ul").find("li.active").removeClass("active"); $(this).parent().addClass("active"); });*/ // iDevice mode if (this.browser.idevice) { $(".settbox > .sett > a").bind({ click: function (event) { if ($(".settbox_cnt").is(":visible")) { _this.hideSettMenu(event, this); } else { _this.showSettMenu(event, this); } } }); // Default mode } else { $(".settbox > .sett > a").bind({ mouseenter: function (event) { if (_this.Mnu.timeout) window.clearTimeout(_this.Mnu.timeout); let box = this; _this.Mnu.timeout = window.setTimeout(function () { _this.showSettMenu(event, box); }, 300); }, click: function (event) { _this.showSettMenu(event, this); } }); $(".settbox").bind({ mouseleave: function (event) { if (_this.Mnu.timeout) window.clearTimeout(_this.Mnu.timeout); let box = this; _this.Mnu.timeout = window.setTimeout(function () { _this.hideSettMenu(event, box); }, 300); } }); } // Apend default actions $(".inset li").each(function () { $(".settbox_cnt ul").append($(this)); }); // Sub-menu actions $("div.sub-menu").each(function () { $(this).find("li > div").each(function () { $(this).wrap(""); $(this).closest("li").attr("href", ""); $(this).closest("li").attr("id", ""); }); }); // Bind Sub-menu action events $(".sub-menu").each(function () { let pt = $(this); // iDevice mode if (_this.browser.idevice) { pt.closest("a").bind({ click: function () { return true; } }); } else { pt.closest("a").bind({ mouseenter: function (event) { if (_this.Mnu.timeout) window.clearTimeout(_this.Mnu.timeout); let box = this; _this.Mnu.timeout = window.setTimeout(function () { _this.showSubMenu(event, box); }, 200); }, click: function (event) { _this.showSubMenu(event, this); } }); pt.closest("a").bind({ mouseleave: function (event) { if (_this.Mnu.timeout) window.clearTimeout(_this.Mnu.timeout); _this.hideSubMenu(event, this); } }); } }); } bindLayoutActions() { let jqOUsers = $("#users-online"); if (jqOUsers.length) { if (this.browser.idevice) { $(".online-users").bind({ click: function () { if ($(".settbox_cnt").is(":visible")) { jqOUsers.hide(); } else { jqOUsers.fadeIn("fast"); } } }); } else { $(".online-users").bind({ mouseenter: function () { jqOUsers.fadeIn("fast"); }, click: function () { jqOUsers.fadeIn("fast"); } }); jqOUsers.bind({ mouseleave: function () { jqOUsers.hide(); } }); } } } showSettMenu(event, obj) { let box = $(obj).find(".box_cnt"); if (box.is(":hidden")) { box.closest("a").addClass("active"); box.stop(true, true).fadeIn("fast"); } event.stopPropagation(); } hideSettMenu(event, obj) { let box = $(obj).find(".box_cnt"); if (box.is(":visible")) { box.closest(".active").removeClass("active"); box.stop(true, true).fadeOut("fast"); } } showSubMenu(event, obj) { let box = $(obj).find(".sub-menu"); if (box.is(":hidden") && box.find("li").length > 1) { box.closest("a").addClass("oactive"); box.stop(true, true).fadeIn(100); } event.stopPropagation(); } hideSubMenu(event, obj) { let box = $(obj).find(".sub-menu"); if (box.is(":visible")) { box.closest(".oactive").removeClass("oactive"); box.stop(true, true).fadeOut("fast"); } } recalculateMenu() { let t = 0, mm = $(".menu:first"), ww = mm.width(); mm.find(".fh").removeClass("fh"); mm.find("> li").each(function () { t += $(this).outerWidth(); if (ww < t) { $(this).addClass("fh"); } }); this.appendMenuListElem(ww, t); } appendMenuListElem() { let mm = $(".menu:first"), dd = $(".settbox_cnt > ul"); if (dd.length) { mm.find(".sl-last").remove(); dd.find(".m-link").remove(); mm.find(".fh:first").before(mm.find("li.last").clone().addClass("sl-last")); mm.find(".fh:not(.last)").each(function () { var elem = $(this).clone(true).addClass("m-link"); elem.find(".sub-menu").remove(); dd.append(elem); }); } } // MAIL LEFT MENU resizeLeftMenu() { let h, win = $(window).height(), ds = $(".dummy-space").height(); let cont = $(".content > .cnt").outerHeight(), tmenu = $(".menu-cnt").height(), lmenu = $(".lc-menu").height(); let winb = win - tmenu - cont; let ac = lmenu - ds; if (winb > 0) { h = win - ac - tmenu; if (h > 0) { $(".dummy-space").css("height", h + "px"); } else if (ds) { $(".dummy-space").css("height", "0px"); } } else { h = cont - (lmenu - ds); if (h >= 0) { $(".dummy-space").css({height: h + "px"}); } } } bindLeftMenuActions() { let _this = this; $(".lc-menu .collapse").click(function () { let jqWrapper = $(this).closest(".wrapper"); jqWrapper.toggleClass("lc-menu-short"); _this.settings.saveProperty({leftmenu: (jqWrapper.hasClass("lc-menu-short") ? 0 : 1)}, false, false); }); if (!$(".lc-menu .collapse").is(":visible")) $(".lc-menu .collapse").fadeIn("fast"); } getObjectClass(oJsModule) { let sModName = "", _this = this; oJsModule = (!defaultVal(oJsModule, false) ? _this.jsModule : oJsModule); if (oJsModule.hasOwnProperty("sModName") && oJsModule.sModName) { sModName = oJsModule.sModName; } else { sModName = /(\w+)\(/.exec(oJsModule.constructor.toString())[1]; if (sModName.length) sModName = sModName.charAt(0).toLocaleLowerCase() + sModName.slice(1); oJsModule.sModName = sModName; } return sModName; } roundNumber(num, dec) { return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); } formatNumber(number, decimals, dec_point, thousands_sep) { let n = number, prec = decimals; var toFixedFix = function (n, prec) { let k = Math.pow(10, prec); return (Math.round(n * k) / k).toString(); }; n = !isFinite(+n) ? 0 : +n; prec = !isFinite(+prec) ? 0 : Math.abs(prec); let sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep; let dec = (typeof dec_point === 'undefined') ? '.' : dec_point; let s = (prec > 0) ? toFixedFix(n, prec) : toFixedFix(Math.round(n), prec); //fix for IE parseFloat(0.55).toFixed(0) = 0; let abs = toFixedFix(Math.abs(n), prec); let _, 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); } let 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; } scrollToSeeElement(jqElement, fnCallback) { let iScrollTo = false; let winH = window.innerHeight; let jqHtml = $("html"), winS2Top = jqHtml.scrollTop(); let 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). copyToClipboard(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")) { let 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); } } } xPos = 0; yPos = 0; findDocumentXY(e){ let _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); } initJsModule(){ let _this = this; // Init module if set if (_this.dt && _this.dt.JsModuleTitle) { _this.jsModule = new window[_this.dt.JsModuleTitle](); } } } /* * BIND ACTIONS */ $(function () { $(document).bind({ mousemove: function (e) { CBase.findDocumentXY(e); }, keydown: function (e) { if (CBase.os.win || CBase.os.mac || CBase.os.linux) { // Bind ESC button if (e.which == CBase.iKeys.ESC) { // Close popup if (CBase.oDialog.isVisible) CBase.oDialog.hide(); // Close drop-boxes let searchDD = $(".search li.dropBox > ul:visible"); if (searchDD.length) searchDD.closest("li").click(); } } } }); });