const getClass = obj => { return {}.toString.call(obj).slice(8, -1); }; const jqId = myid => `\u0023${(myid.replace(/([:.\[\],=@])/g, "\\$1"))}`; const jQueryNowYmd = () => new Date(jQuery.now()).toISOString().substr(0, 10); const smoothScrollIntoView = targetElement => targetElement[0].scrollIntoView({ behavior: "smooth" }); const redirect = url => window.location.assign(url); const reload = () => window.location.reload(); const urlUtils = { encodeQueryParam: (key, value) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`, appendParamToUrl: (url, param) => url.indexOf('?') === -1 ? `${url}?${param}` : `${url}&${param}`, currentFullUrl: () => window.location.host + window.location.href.toString().split(window.location.host)[1] }; $.urlParam = (name) => { let results = new RegExp('[\?&]' + name + '=([^]*)').exec(window.location.href); return results[1] || 0; }; const typeUtils = { isNumber: (variable) => (typeof variable === 'number' || variable instanceof Number), isString: (variable) => (typeof variable === 'string' || variable instanceof String), isArray: (variable) => (Array.isArray(variable)), isFunction: (variable) => (typeof variable === 'function'), isObject: (variable) => (variable !== null && typeof variable === 'object'), isNull: (variable) => (variable === null), isUndefined: (variable) => (variable === undefined) }; const numberUtils = { toInt: (value) => parseInt(value, 10) || 0, filterInt: value => /^([-+])?([0-9]+|Infinity)$/.test(value) ? Number(value) : NaN, randomInt: (m, n) => Math.floor( Math.random() * (parseInt(n) - parseInt(m) + 1) ) + parseInt(m) }; const stringUtils = { elide: (str, maxLength) => str.length <= maxLength ? str : `${str.substring(0, maxLength - 1)}\u2026`, truncate: (str, maxlength = 110) => str.length > maxlength ? `${(str.slice(0, maxlength - 3))}\u002E\u002E\u002E` : str, ucFirst: str => str.charAt(0).toUpperCase() + str.slice(1), lcFirst: str => str.charAt(0).toLowerCase() + str.slice(1), ucWords: str => str.replace(/^(.)|\s(.)/g, v => v.toUpperCase()) }; const dateUtils = { newDate: () => new Date(), isValidDate: date => date && !isNaN(date.getTime()), DateFormats: { "mysql": "yy-mm-dd", // jQuery.datepicker.ISO_8601 || jQuery.datepicker.ATOM || jQuery.datepicker.W3C "ru": "dd.mm.yy", "en": "dd/mm/yy" } }; const momentFromFormat = (dateString, formatFrom, formatTo) => moment(dateString, formatFrom).format(formatTo); const toIsoDateString = dateString => dateUtils.getNewDate(dateString).toISOString(); const toLocaleDateStringLong = dateString => { const localeDateStringOptions = { "ru-RU": { weekday: "long", year: "numeric", month: "long", day: "numeric" } }; let oDate = dateUtils.getNewDate(dateString), sLocale = "ru-RU", oOpts = localeDateStringOptions[sLocale]; return oDate.toLocaleDateString(sLocale, oOpts); }; const arrayUtils = { max: arr => Math.max.apply(null, arr), min: arr => Math.min.apply(null, arr), range: (start, stop, step) => Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + (i * step)) }; const symbolEntities = { nbsp: String.fromCharCode(32), hash: String.fromCharCode(35), plus: String.fromCharCode(43), colon: String.fromCharCode(58), equal: String.fromCharCode(61), laquo: String.fromCharCode(171), raquo: String.fromCharCode(187) }; const generatePureLoader = () => { let html = $("
").addClass("loader"), range = arrayUtils.range(1, 27, 1); for (let key in range) { html.append($("")); } return html; }; const initSelectpicker = oSelectpicker => { oSelectpicker.on({ "loaded.bs.select": (e) => { let $el = $(e.target), $lis = $el.data("selectpicker").$lis; console.log("Bootstrap-select init with instance %o", $el.data("selectpicker")); $lis.each((index, element) => { let sTooltipTitle = $el.find("option").eq(index + 1).attr("title"); $(element).attr("title", sTooltipTitle).tooltip({ container: "body", html: true, placement: "top", title: sTooltipTitle }); }); if (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)) { $el.selectpicker("mobile"); } }, "hidden.bs.select": (e) => $(".tooltip").tooltip("hide") }).selectpicker({ liveSearch: true, liveSearchPlaceholder: "Поиск\u2026", liveSearchNormalize: false, liveSearchStyle: "contains", noneResultsText: "Совпадений не найдено {0}", showMenuArrow: false, showTick: false, style: "btn-default" }); }; const removeSelectedOptionFromSelect = (oSelectpicker, val) => { oSelectpicker.find('[data-index="' + val + '"]').prop("selected", false); oSelectpicker.selectpicker("refresh"); }; const removeSelectedOptionFromList = (optVal, selId, outId) => { let oSelectpicker = $(jqId(selId)), oParagraph = $('[data-id="' + optVal + '"]'), oOutput = $(jqId(outId)); removeSelectedOptionFromSelect(oSelectpicker, optVal); oOutput.find("br").remove(); oParagraph.remove(); oSelectpicker.selectpicker("render"); }; const getSelection = select => { if (!select.options) { return ""; } let selectedOptions = [], data = { selectpicker: {}, output: {}, paragraph: {} }, len = select.options.length, labThemeLine = ""; for (let i = 0; i < len; i++) { if (select.options[i].selected) { if (!select.options[i].value.length) { i++; } data.selectpicker.id = select.id; data.output.id = select.dataset.output; data.paragraph.id = select.options[i].dataset.index; data.paragraph.text = select.options[i].text; labThemeLine = "" + data.paragraph.text + "" + "
"; selectedOptions.push(labThemeLine); } } return selectedOptions.join("