diff --git a/about.json b/about.json
index 08d6da1..eb1acce 100644
--- a/about.json
+++ b/about.json
@@ -9,6 +9,7 @@
"minimum_discourse_version": null,
"maximum_discourse_version": null,
"assets": {
+ "jsuites": "assets/jsuites.js",
"jspreadsheet": "assets/jspreadsheet.js"
},
"modifiers": {
diff --git a/assets/jspreadsheet.js b/assets/jspreadsheet.js
index 9802e04..01b2e38 100644
--- a/assets/jspreadsheet.js
+++ b/assets/jspreadsheet.js
@@ -1,13314 +1,3 @@
-/**
- * (c) jSuites Javascript Web Components
- *
- * Website: https://jsuites.net
- * Description: Create amazing web based applications.
- *
- * MIT License
- *
- */
-(function (global, factory) {
- typeof exports === "object" && typeof module !== "undefined"
- ? (module.exports = factory())
- : typeof define === "function" && define.amd
- ? define(factory)
- : (global.jSuites = factory());
-})(this, function () {
- "use strict";
-
- var jSuites = {};
-
- var Version = "4.14.3";
-
- var Events = function () {
- document.jsuitesComponents = [];
-
- var find = function (DOMElement, component) {
- if (
- DOMElement[component.type] &&
- DOMElement[component.type] == component
- ) {
- return true;
- }
- if (DOMElement.component && DOMElement.component == component) {
- return true;
- }
- if (DOMElement.parentNode) {
- return find(DOMElement.parentNode, component);
- }
- return false;
- };
-
- var isOpened = function (e) {
- if (document.jsuitesComponents && document.jsuitesComponents.length > 0) {
- for (var i = 0; i < document.jsuitesComponents.length; i++) {
- if (
- document.jsuitesComponents[i] &&
- !find(e, document.jsuitesComponents[i])
- ) {
- document.jsuitesComponents[i].close();
- }
- }
- }
- };
-
- // Width of the border
- var cornerSize = 15;
-
- // Current element
- var element = null;
-
- // Controllers
- var editorAction = false;
-
- // Event state
- var state = {
- x: null,
- y: null,
- };
-
- // Tooltip element
- var tooltip = document.createElement("div");
- tooltip.classList.add("jtooltip");
-
- // Events
- var mouseDown = function (e) {
- // Check if this is the floating
- var item = jSuites.findElement(e.target, "jpanel");
- // Jfloating found
- if (item && !item.classList.contains("readonly")) {
- // Add focus to the chart container
- item.focus();
- // Keep the tracking information
- var rect = e.target.getBoundingClientRect();
- editorAction = {
- e: item,
- x: e.clientX,
- y: e.clientY,
- w: rect.width,
- h: rect.height,
- d: item.style.cursor,
- resizing: item.style.cursor ? true : false,
- actioned: false,
- };
-
- // Make sure width and height styling is OK
- if (!item.style.width) {
- item.style.width = rect.width + "px";
- }
-
- if (!item.style.height) {
- item.style.height = rect.height + "px";
- }
-
- // Remove any selection from the page
- var s = window.getSelection();
- if (s.rangeCount) {
- for (var i = 0; i < s.rangeCount; i++) {
- s.removeRange(s.getRangeAt(i));
- }
- }
-
- e.preventDefault();
- e.stopPropagation();
- } else {
- // No floating action found
- editorAction = false;
- }
-
- // Verify current components tracking
- if (e.changedTouches && e.changedTouches[0]) {
- var x = e.changedTouches[0].clientX;
- var y = e.changedTouches[0].clientY;
- } else {
- var x = e.clientX;
- var y = e.clientY;
- }
-
- // Which component I am clicking
- var path = e.path || (e.composedPath && e.composedPath());
-
- // If path available get the first element in the chain
- if (path) {
- element = path[0];
- } else {
- // Try to guess using the coordinates
- if (e.target && e.target.shadowRoot) {
- var d = e.target.shadowRoot;
- } else {
- var d = document;
- }
- // Get the first target element
- element = d.elementFromPoint(x, y);
- }
-
- isOpened(element);
- };
-
- var mouseUp = function (e) {
- if (editorAction && editorAction.e) {
- if (typeof editorAction.e.refresh == "function" && state.actioned) {
- editorAction.e.refresh();
- }
- editorAction.e.style.cursor = "";
- }
-
- // Reset
- state = {
- x: null,
- y: null,
- };
-
- editorAction = false;
- };
-
- var mouseMove = function (e) {
- if (editorAction) {
- var x = e.clientX || e.pageX;
- var y = e.clientY || e.pageY;
-
- // Action on going
- if (!editorAction.resizing) {
- if (state.x == null && state.y == null) {
- state.x = x;
- state.y = y;
- }
-
- var dx = x - state.x;
- var dy = y - state.y;
- var top = editorAction.e.offsetTop + dy;
- var left = editorAction.e.offsetLeft + dx;
-
- // Update position
- editorAction.e.style.top = top + "px";
- editorAction.e.style.left = left + "px";
- editorAction.e.style.cursor = "move";
-
- state.x = x;
- state.y = y;
-
- // Update element
- if (typeof editorAction.e.refresh == "function") {
- state.actioned = true;
- editorAction.e.refresh("position", top, left);
- }
- } else {
- var width = null;
- var height = null;
-
- if (
- editorAction.d == "e-resize" ||
- editorAction.d == "ne-resize" ||
- editorAction.d == "se-resize"
- ) {
- // Update width
- width = editorAction.w + (x - editorAction.x);
- editorAction.e.style.width = width + "px";
-
- // Update Height
- if (e.shiftKey) {
- var newHeight =
- (x - editorAction.x) * (editorAction.h / editorAction.w);
- height = editorAction.h + newHeight;
- editorAction.e.style.height = height + "px";
- } else {
- var newHeight = false;
- }
- }
-
- if (!newHeight) {
- if (
- editorAction.d == "s-resize" ||
- editorAction.d == "se-resize" ||
- editorAction.d == "sw-resize"
- ) {
- height = editorAction.h + (y - editorAction.y);
- editorAction.e.style.height = height + "px";
- }
- }
-
- // Update element
- if (typeof editorAction.e.refresh == "function") {
- state.actioned = true;
- editorAction.e.refresh("dimensions", width, height);
- }
- }
- } else {
- // Resizing action
- var item = jSuites.findElement(e.target, "jpanel");
- // Found eligible component
- if (item) {
- if (item.getAttribute("tabindex")) {
- var rect = item.getBoundingClientRect();
- if (e.clientY - rect.top < cornerSize) {
- if (rect.width - (e.clientX - rect.left) < cornerSize) {
- item.style.cursor = "ne-resize";
- } else if (e.clientX - rect.left < cornerSize) {
- item.style.cursor = "nw-resize";
- } else {
- item.style.cursor = "n-resize";
- }
- } else if (rect.height - (e.clientY - rect.top) < cornerSize) {
- if (rect.width - (e.clientX - rect.left) < cornerSize) {
- item.style.cursor = "se-resize";
- } else if (e.clientX - rect.left < cornerSize) {
- item.style.cursor = "sw-resize";
- } else {
- item.style.cursor = "s-resize";
- }
- } else if (rect.width - (e.clientX - rect.left) < cornerSize) {
- item.style.cursor = "e-resize";
- } else if (e.clientX - rect.left < cornerSize) {
- item.style.cursor = "w-resize";
- } else {
- item.style.cursor = "";
- }
- }
- }
- }
- };
-
- var mouseOver = function (e) {
- var message = e.target.getAttribute("data-tooltip");
- if (message) {
- // Instructions
- tooltip.innerText = message;
-
- // Position
- if (e.changedTouches && e.changedTouches[0]) {
- var x = e.changedTouches[0].clientX;
- var y = e.changedTouches[0].clientY;
- } else {
- var x = e.clientX;
- var y = e.clientY;
- }
-
- tooltip.style.top = y + "px";
- tooltip.style.left = x + "px";
- document.body.appendChild(tooltip);
- } else if (tooltip.innerText) {
- tooltip.innerText = "";
- document.body.removeChild(tooltip);
- }
- };
-
- var dblClick = function (e) {
- var item = jSuites.findElement(e.target, "jpanel");
- if (item && typeof item.dblclick == "function") {
- // Create edition
- item.dblclick(e);
- }
- };
-
- var contextMenu = function (e) {
- var item = document.activeElement;
- if (item && typeof item.contextmenu == "function") {
- // Create edition
- item.contextmenu(e);
-
- e.preventDefault();
- e.stopImmediatePropagation();
- } else {
- // Search for possible context menus
- item = jSuites.findElement(e.target, function (o) {
- return o.tagName && o.getAttribute("aria-contextmenu-id");
- });
-
- if (item) {
- var o = document.querySelector("#" + item);
- if (!o) {
- console.error("JSUITES: contextmenu id not found: " + item);
- } else {
- o.contextmenu.open(e);
- e.preventDefault();
- e.stopImmediatePropagation();
- }
- }
- }
- };
-
- var keyDown = function (e) {
- var item = document.activeElement;
- if (item) {
- if (e.key == "Delete" && typeof item.delete == "function") {
- item.delete();
- e.preventDefault();
- e.stopImmediatePropagation();
- }
- }
-
- if (document.jsuitesComponents && document.jsuitesComponents.length) {
- if (
- (item =
- document.jsuitesComponents[document.jsuitesComponents.length - 1])
- ) {
- if (e.key == "Escape" && typeof item.close == "function") {
- item.close();
- e.preventDefault();
- e.stopImmediatePropagation();
- }
- }
- }
- };
-
- document.addEventListener("mouseup", mouseUp);
- document.addEventListener("mousedown", mouseDown);
- document.addEventListener("mousemove", mouseMove);
- document.addEventListener("mouseover", mouseOver);
- document.addEventListener("dblclick", dblClick);
- document.addEventListener("keydown", keyDown);
- document.addEventListener("contextmenu", contextMenu);
- };
-
- /**
- * Global jsuites event
- */
- if (typeof document !== "undefined" && !document.jsuitesComponents) {
- Events();
- }
-
- jSuites.version = Version;
-
- jSuites.setExtensions = function (o) {
- if (typeof o == "object") {
- var k = Object.keys(o);
- for (var i = 0; i < k.length; i++) {
- jSuites[k[i]] = o[k[i]];
- }
- }
- };
-
- jSuites.tracking = function (component, state) {
- if (state == true) {
- document.jsuitesComponents = document.jsuitesComponents.filter(function (
- v
- ) {
- return v !== null;
- });
-
- // Start after all events
- setTimeout(function () {
- document.jsuitesComponents.push(component);
- }, 0);
- } else {
- var index = document.jsuitesComponents.indexOf(component);
- if (index >= 0) {
- document.jsuitesComponents.splice(index, 1);
- }
- }
- };
-
- /**
- * Get or set a property from a JSON from a string.
- */
- jSuites.path = function (str, val) {
- str = str.split(".");
- if (str.length) {
- var o = this;
- var p = null;
- while (str.length > 1) {
- // Get the property
- p = str.shift();
- // Check if the property exists
- if (o.hasOwnProperty(p)) {
- o = o[p];
- } else {
- // Property does not exists
- if (val === undefined) {
- return undefined;
- } else {
- // Create the property
- o[p] = {};
- // Next property
- o = o[p];
- }
- }
- }
- // Get the property
- p = str.shift();
- // Set or get the value
- if (val !== undefined) {
- o[p] = val;
- // Success
- return true;
- } else {
- // Return the value
- if (o) {
- return o[p];
- }
- }
- }
- // Something went wrong
- return false;
- };
-
- // Update dictionary
- jSuites.setDictionary = function (d) {
- if (!document.dictionary) {
- document.dictionary = {};
- }
- // Replace the key into the dictionary and append the new ones
- var k = Object.keys(d);
- for (var i = 0; i < k.length; i++) {
- document.dictionary[k[i]] = d[k[i]];
- }
-
- // Translations
- var t = null;
- for (var i = 0; i < jSuites.calendar.weekdays.length; i++) {
- t = jSuites.translate(jSuites.calendar.weekdays[i]);
- if (jSuites.calendar.weekdays[i]) {
- jSuites.calendar.weekdays[i] = t;
- jSuites.calendar.weekdaysShort[i] = t.substr(0, 3);
- }
- }
- for (var i = 0; i < jSuites.calendar.months.length; i++) {
- t = jSuites.translate(jSuites.calendar.months[i]);
- if (t) {
- jSuites.calendar.months[i] = t;
- jSuites.calendar.monthsShort[i] = t.substr(0, 3);
- }
- }
- };
-
- // Translate
- jSuites.translate = function (t) {
- if (document.dictionary) {
- return document.dictionary[t] || t;
- } else {
- return t;
- }
- };
-
- jSuites.ajax = function (options, complete) {
- if (Array.isArray(options)) {
- // Create multiple request controller
- var multiple = {
- instance: [],
- complete: complete,
- };
-
- if (options.length > 0) {
- for (var i = 0; i < options.length; i++) {
- options[i].multiple = multiple;
- multiple.instance.push(jSuites.ajax(options[i]));
- }
- }
-
- return multiple;
- }
-
- if (!options.data) {
- options.data = {};
- }
-
- if (options.type) {
- options.method = options.type;
- }
-
- // Default method
- if (!options.method) {
- options.method = "GET";
- }
-
- // Default type
- if (!options.dataType) {
- options.dataType = "json";
- }
-
- if (options.data) {
- // Parse object to variables format
- var parseData = function (value, key) {
- var vars = [];
- if (value) {
- var keys = Object.keys(value);
- if (keys.length) {
- for (var i = 0; i < keys.length; i++) {
- if (key) {
- var k = key + "[" + keys[i] + "]";
- } else {
- var k = keys[i];
- }
-
- if (value[k] instanceof FileList) {
- vars[k] = value[keys[i]];
- } else if (
- value[keys[i]] === null ||
- value[keys[i]] === undefined
- ) {
- vars[k] = "";
- } else if (typeof value[keys[i]] == "object") {
- var r = parseData(value[keys[i]], k);
- var o = Object.keys(r);
- for (var j = 0; j < o.length; j++) {
- vars[o[j]] = r[o[j]];
- }
- } else {
- vars[k] = value[keys[i]];
- }
- }
- }
- }
-
- return vars;
- };
-
- var d = parseData(options.data);
- var k = Object.keys(d);
-
- // Data form
- if (options.method == "GET") {
- if (k.length) {
- var data = [];
- for (var i = 0; i < k.length; i++) {
- data.push(k[i] + "=" + encodeURIComponent(d[k[i]]));
- }
-
- if (options.url.indexOf("?") < 0) {
- options.url += "?";
- }
- options.url += data.join("&");
- }
- } else {
- var data = new FormData();
- for (var i = 0; i < k.length; i++) {
- if (d[k[i]] instanceof FileList) {
- if (d[k[i]].length) {
- for (var j = 0; j < d[k[i]].length; j++) {
- data.append(k[i], d[k[i]][j], d[k[i]][j].name);
- }
- }
- } else {
- data.append(k[i], d[k[i]]);
- }
- }
- }
- }
-
- var httpRequest = new XMLHttpRequest();
- httpRequest.open(options.method, options.url, true);
- httpRequest.setRequestHeader("X-Requested-With", "XMLHttpRequest");
-
- // Content type
- if (options.contentType) {
- httpRequest.setRequestHeader("Content-Type", options.contentType);
- }
-
- // Headers
- if (options.method == "POST") {
- httpRequest.setRequestHeader("Accept", "application/json");
- } else {
- if (options.dataType == "blob") {
- httpRequest.responseType = "blob";
- } else {
- if (!options.contentType) {
- if (options.dataType == "json") {
- httpRequest.setRequestHeader("Content-Type", "text/json");
- } else if (options.dataType == "html") {
- httpRequest.setRequestHeader("Content-Type", "text/html");
- }
- }
- }
- }
-
- // No cache
- if (options.cache != true) {
- httpRequest.setRequestHeader("pragma", "no-cache");
- httpRequest.setRequestHeader("cache-control", "no-cache");
- }
-
- // Authentication
- if (options.withCredentials == true) {
- httpRequest.withCredentials = true;
- }
-
- // Before send
- if (typeof options.beforeSend == "function") {
- options.beforeSend(httpRequest);
- }
-
- // Before send
- if (typeof jSuites.ajax.beforeSend == "function") {
- jSuites.ajax.beforeSend(httpRequest);
- }
-
- if (document.ajax && typeof document.ajax.beforeSend == "function") {
- document.ajax.beforeSend(httpRequest);
- }
-
- httpRequest.onload = function () {
- if (httpRequest.status === 200) {
- if (options.dataType == "json") {
- try {
- var result = JSON.parse(httpRequest.responseText);
-
- if (options.success && typeof options.success == "function") {
- options.success(result);
- }
- } catch (err) {
- if (options.error && typeof options.error == "function") {
- options.error(err, result);
- }
- }
- } else {
- if (options.dataType == "blob") {
- var result = httpRequest.response;
- } else {
- var result = httpRequest.responseText;
- }
-
- if (options.success && typeof options.success == "function") {
- options.success(result);
- }
- }
- } else {
- if (options.error && typeof options.error == "function") {
- options.error(httpRequest.responseText, httpRequest.status);
- }
- }
-
- // Global queue
- if (jSuites.ajax.queue && jSuites.ajax.queue.length > 0) {
- jSuites.ajax.send(jSuites.ajax.queue.shift());
- }
-
- // Global complete method
- if (jSuites.ajax.requests && jSuites.ajax.requests.length) {
- // Get index of this request in the container
- var index = jSuites.ajax.requests.indexOf(httpRequest);
- // Remove from the ajax requests container
- jSuites.ajax.requests.splice(index, 1);
- // Deprected: Last one?
- if (!jSuites.ajax.requests.length) {
- // Object event
- if (options.complete && typeof options.complete == "function") {
- options.complete(result);
- }
- }
- // Group requests
- if (options.group) {
- if (
- jSuites.ajax.oncomplete &&
- typeof jSuites.ajax.oncomplete[options.group] == "function"
- ) {
- if (!jSuites.ajax.pending(options.group)) {
- jSuites.ajax.oncomplete[options.group]();
- jSuites.ajax.oncomplete[options.group] = null;
- }
- }
- }
- // Multiple requests controller
- if (options.multiple && options.multiple.instance) {
- // Get index of this request in the container
- var index = options.multiple.instance.indexOf(httpRequest);
- // Remove from the ajax requests container
- options.multiple.instance.splice(index, 1);
- // If this is the last one call method complete
- if (!options.multiple.instance.length) {
- if (
- options.multiple.complete &&
- typeof options.multiple.complete == "function"
- ) {
- options.multiple.complete(result);
- }
- }
- }
- }
- };
-
- // Keep the options
- httpRequest.options = options;
- // Data
- httpRequest.data = data;
-
- // Queue
- if (options.queue == true && jSuites.ajax.requests.length > 0) {
- jSuites.ajax.queue.push(httpRequest);
- } else {
- jSuites.ajax.send(httpRequest);
- }
-
- return httpRequest;
- };
-
- jSuites.ajax.send = function (httpRequest) {
- if (httpRequest.data) {
- if (Array.isArray(httpRequest.data)) {
- httpRequest.send(httpRequest.data.join("&"));
- } else {
- httpRequest.send(httpRequest.data);
- }
- } else {
- httpRequest.send();
- }
-
- jSuites.ajax.requests.push(httpRequest);
- };
-
- jSuites.ajax.exists = function (url, __callback) {
- var http = new XMLHttpRequest();
- http.open("HEAD", url, false);
- http.send();
- if (http.status) {
- __callback(http.status);
- }
- };
-
- jSuites.ajax.pending = function (group) {
- var n = 0;
- var o = jSuites.ajax.requests;
- if (o && o.length) {
- for (var i = 0; i < o.length; i++) {
- if (!group || group == o[i].options.group) {
- n++;
- }
- }
- }
- return n;
- };
-
- jSuites.ajax.oncomplete = {};
- jSuites.ajax.requests = [];
- jSuites.ajax.queue = [];
-
- jSuites.alert = function (message) {
- if (jSuites.getWindowWidth() < 800 && jSuites.dialog) {
- jSuites.dialog.open({
- title: "Alert",
- message: message,
- });
- } else {
- alert(message);
- }
- };
-
- jSuites.animation = {};
-
- jSuites.animation.slideLeft = function (element, direction, done) {
- if (direction == true) {
- element.classList.add("slide-left-in");
- setTimeout(function () {
- element.classList.remove("slide-left-in");
- if (typeof done == "function") {
- done();
- }
- }, 400);
- } else {
- element.classList.add("slide-left-out");
- setTimeout(function () {
- element.classList.remove("slide-left-out");
- if (typeof done == "function") {
- done();
- }
- }, 400);
- }
- };
-
- jSuites.animation.slideRight = function (element, direction, done) {
- if (direction == true) {
- element.classList.add("slide-right-in");
- setTimeout(function () {
- element.classList.remove("slide-right-in");
- if (typeof done == "function") {
- done();
- }
- }, 400);
- } else {
- element.classList.add("slide-right-out");
- setTimeout(function () {
- element.classList.remove("slide-right-out");
- if (typeof done == "function") {
- done();
- }
- }, 400);
- }
- };
-
- jSuites.animation.slideTop = function (element, direction, done) {
- if (direction == true) {
- element.classList.add("slide-top-in");
- setTimeout(function () {
- element.classList.remove("slide-top-in");
- if (typeof done == "function") {
- done();
- }
- }, 400);
- } else {
- element.classList.add("slide-top-out");
- setTimeout(function () {
- element.classList.remove("slide-top-out");
- if (typeof done == "function") {
- done();
- }
- }, 400);
- }
- };
-
- jSuites.animation.slideBottom = function (element, direction, done) {
- if (direction == true) {
- element.classList.add("slide-bottom-in");
- setTimeout(function () {
- element.classList.remove("slide-bottom-in");
- if (typeof done == "function") {
- done();
- }
- }, 400);
- } else {
- element.classList.add("slide-bottom-out");
- setTimeout(function () {
- element.classList.remove("slide-bottom-out");
- if (typeof done == "function") {
- done();
- }
- }, 100);
- }
- };
-
- jSuites.animation.fadeIn = function (element, done) {
- element.style.display = "";
- element.classList.add("fade-in");
- setTimeout(function () {
- element.classList.remove("fade-in");
- if (typeof done == "function") {
- done();
- }
- }, 2000);
- };
-
- jSuites.animation.fadeOut = function (element, done) {
- element.classList.add("fade-out");
- setTimeout(function () {
- element.style.display = "none";
- element.classList.remove("fade-out");
- if (typeof done == "function") {
- done();
- }
- }, 1000);
- };
-
- jSuites.calendar = function (el, options) {
- // Already created, update options
- if (el.calendar) {
- return el.calendar.setOptions(options, true);
- }
-
- // New instance
- var obj = { type: "calendar" };
- obj.options = {};
-
- // Date
- obj.date = null;
-
- /**
- * Update options
- */
- obj.setOptions = function (options, reset) {
- // Default configuration
- var defaults = {
- // Render type: [ default | year-month-picker ]
- type: "default",
- // Restrictions
- validRange: null,
- // Starting weekday - 0 for sunday, 6 for saturday
- startingDay: null,
- // Date format
- format: "DD/MM/YYYY",
- // Allow keyboard date entry
- readonly: true,
- // Today is default
- today: false,
- // Show timepicker
- time: false,
- // Show the reset button
- resetButton: true,
- // Placeholder
- placeholder: "",
- // Translations can be done here
- months: jSuites.calendar.monthsShort,
- monthsFull: jSuites.calendar.months,
- weekdays: jSuites.calendar.weekdays,
- textDone: jSuites.translate("Done"),
- textReset: jSuites.translate("Reset"),
- textUpdate: jSuites.translate("Update"),
- // Value
- value: null,
- // Fullscreen (this is automatic set for screensize < 800)
- fullscreen: false,
- // Create the calendar closed as default
- opened: false,
- // Events
- onopen: null,
- onclose: null,
- onchange: null,
- onupdate: null,
- // Internal mode controller
- mode: null,
- position: null,
- // Data type
- dataType: null,
- };
-
- // Loop through our object
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- if (typeof obj.options[property] == "undefined" || reset === true) {
- obj.options[property] = defaults[property];
- }
- }
- }
-
- // Reset button
- if (obj.options.resetButton == false) {
- calendarReset.style.display = "none";
- } else {
- calendarReset.style.display = "";
- }
-
- // Readonly
- if (obj.options.readonly) {
- el.setAttribute("readonly", "readonly");
- } else {
- el.removeAttribute("readonly");
- }
-
- // Placeholder
- if (obj.options.placeholder) {
- el.setAttribute("placeholder", obj.options.placeholder);
- } else {
- el.removeAttribute("placeholder");
- }
-
- if (jSuites.isNumeric(obj.options.value) && obj.options.value > 0) {
- obj.options.value = jSuites.calendar.numToDate(obj.options.value);
- // Data type numberic
- obj.options.dataType = "numeric";
- }
-
- // Texts
- calendarReset.innerHTML = obj.options.textReset;
- calendarConfirm.innerHTML = obj.options.textDone;
- calendarControlsUpdateButton.innerHTML = obj.options.textUpdate;
-
- // Define mask
- el.setAttribute("data-mask", obj.options.format.toLowerCase());
-
- // Value
- if (!obj.options.value && obj.options.today) {
- var value = jSuites.calendar.now();
- } else {
- var value = obj.options.value;
- }
-
- // Set internal date
- if (value) {
- // Force the update
- obj.options.value = null;
- // New value
- obj.setValue(value);
- }
-
- return obj;
- };
-
- /**
- * Open the calendar
- */
- obj.open = function (value) {
- if (!calendar.classList.contains("jcalendar-focus")) {
- if (!calendar.classList.contains("jcalendar-inline")) {
- // Current
- jSuites.calendar.current = obj;
- // Start tracking
- jSuites.tracking(obj, true);
- // Create the days
- obj.getDays();
- // Render months
- if (obj.options.type == "year-month-picker") {
- obj.getMonths();
- }
- // Get time
- if (obj.options.time) {
- calendarSelectHour.value = obj.date[3];
- calendarSelectMin.value = obj.date[4];
- }
-
- // Show calendar
- calendar.classList.add("jcalendar-focus");
-
- // Get the position of the corner helper
- if (jSuites.getWindowWidth() < 800 || obj.options.fullscreen) {
- calendar.classList.add("jcalendar-fullsize");
- // Animation
- jSuites.animation.slideBottom(calendarContent, 1);
- } else {
- calendar.classList.remove("jcalendar-fullsize");
-
- var rect = el.getBoundingClientRect();
- var rectContent = calendarContent.getBoundingClientRect();
-
- if (obj.options.position) {
- calendarContainer.style.position = "fixed";
- if (window.innerHeight < rect.bottom + rectContent.height) {
- calendarContainer.style.top =
- rect.top - (rectContent.height + 2) + "px";
- } else {
- calendarContainer.style.top = rect.top + rect.height + 2 + "px";
- }
- calendarContainer.style.left = rect.left + "px";
- } else {
- if (window.innerHeight < rect.bottom + rectContent.height) {
- var d = -1 * (rect.height + rectContent.height + 2);
- if (d + rect.top < 0) {
- d = -1 * (rect.top + rect.height);
- }
- calendarContainer.style.top = d + "px";
- } else {
- calendarContainer.style.top = 2 + "px";
- }
-
- if (window.innerWidth < rect.left + rectContent.width) {
- var d =
- window.innerWidth - (rect.left + rectContent.width + 20);
- calendarContainer.style.left = d + "px";
- } else {
- calendarContainer.style.left = "0px";
- }
- }
- }
-
- // Events
- if (typeof obj.options.onopen == "function") {
- obj.options.onopen(el);
- }
- }
- }
- };
-
- obj.close = function (ignoreEvents, update) {
- if (calendar.classList.contains("jcalendar-focus")) {
- if (update !== false) {
- var element = calendar.querySelector(".jcalendar-selected");
-
- if (typeof update == "string") {
- var value = update;
- } else if (
- !element ||
- element.classList.contains("jcalendar-disabled")
- ) {
- var value = obj.options.value;
- } else {
- var value = obj.getValue();
- }
-
- obj.setValue(value);
- }
-
- // Events
- if (!ignoreEvents && typeof obj.options.onclose == "function") {
- obj.options.onclose(el);
- }
- // Hide
- calendar.classList.remove("jcalendar-focus");
- // Stop tracking
- jSuites.tracking(obj, false);
- // Current
- jSuites.calendar.current = null;
- }
-
- return obj.options.value;
- };
-
- obj.prev = function () {
- // Check if the visualization is the days picker or years picker
- if (obj.options.mode == "years") {
- obj.date[0] = obj.date[0] - 12;
-
- // Update picker table of days
- obj.getYears();
- } else if (obj.options.mode == "months") {
- obj.date[0] = parseInt(obj.date[0]) - 1;
- // Update picker table of months
- obj.getMonths();
- } else {
- // Go to the previous month
- if (obj.date[1] < 2) {
- obj.date[0] = obj.date[0] - 1;
- obj.date[1] = 12;
- } else {
- obj.date[1] = obj.date[1] - 1;
- }
-
- // Update picker table of days
- obj.getDays();
- }
- };
-
- obj.next = function () {
- // Check if the visualization is the days picker or years picker
- if (obj.options.mode == "years") {
- obj.date[0] = parseInt(obj.date[0]) + 12;
-
- // Update picker table of days
- obj.getYears();
- } else if (obj.options.mode == "months") {
- obj.date[0] = parseInt(obj.date[0]) + 1;
- // Update picker table of months
- obj.getMonths();
- } else {
- // Go to the previous month
- if (obj.date[1] > 11) {
- obj.date[0] = parseInt(obj.date[0]) + 1;
- obj.date[1] = 1;
- } else {
- obj.date[1] = parseInt(obj.date[1]) + 1;
- }
-
- // Update picker table of days
- obj.getDays();
- }
- };
-
- /**
- * Set today
- */
- obj.setToday = function () {
- // Today
- var value = new Date().toISOString().substr(0, 10);
- // Change value
- obj.setValue(value);
- // Value
- return value;
- };
-
- obj.setValue = function (val) {
- if (!val) {
- val = "" + val;
- }
- // Values
- var newValue = val;
- var oldValue = obj.options.value;
-
- if (oldValue != newValue) {
- // Set label
- if (!newValue) {
- obj.date = null;
- var val = "";
- } else {
- var value = obj.setLabel(newValue, obj.options);
- var date = newValue.split(" ");
- if (!date[1]) {
- date[1] = "00:00:00";
- }
- var time = date[1].split(":");
- var date = date[0].split("-");
- var y = parseInt(date[0]);
- var m = parseInt(date[1]);
- var d = parseInt(date[2]);
- var h = parseInt(time[0]);
- var i = parseInt(time[1]);
- obj.date = [y, m, d, h, i, 0];
- var val = obj.setLabel(newValue, obj.options);
- }
-
- // New value
- obj.options.value = newValue;
-
- if (typeof obj.options.onchange == "function") {
- obj.options.onchange(el, newValue, oldValue);
- }
-
- // Lemonade JS
- if (el.value != val) {
- el.value = val;
- if (typeof el.oninput == "function") {
- el.oninput({
- type: "input",
- target: el,
- value: el.value,
- });
- }
- }
- }
-
- obj.getDays();
- };
-
- obj.getValue = function () {
- if (obj.date) {
- if (obj.options.time) {
- return (
- jSuites.two(obj.date[0]) +
- "-" +
- jSuites.two(obj.date[1]) +
- "-" +
- jSuites.two(obj.date[2]) +
- " " +
- jSuites.two(obj.date[3]) +
- ":" +
- jSuites.two(obj.date[4]) +
- ":" +
- jSuites.two(0)
- );
- } else {
- return (
- jSuites.two(obj.date[0]) +
- "-" +
- jSuites.two(obj.date[1]) +
- "-" +
- jSuites.two(obj.date[2]) +
- " " +
- jSuites.two(0) +
- ":" +
- jSuites.two(0) +
- ":" +
- jSuites.two(0)
- );
- }
- } else {
- return "";
- }
- };
-
- /**
- * Calendar
- */
- obj.update = function (element, v) {
- if (element.classList.contains("jcalendar-disabled")) {
- // Do nothing
- } else {
- var elements = calendar.querySelector(".jcalendar-selected");
- if (elements) {
- elements.classList.remove("jcalendar-selected");
- }
- element.classList.add("jcalendar-selected");
-
- if (element.classList.contains("jcalendar-set-month")) {
- obj.date[1] = v;
- obj.date[2] = 1; // first day of the month
- } else {
- obj.date[2] = element.innerText;
- }
-
- if (!obj.options.time) {
- obj.close();
- } else {
- obj.date[3] = calendarSelectHour.value;
- obj.date[4] = calendarSelectMin.value;
- }
- }
-
- // Update
- updateActions();
- };
-
- /**
- * Set to blank
- */
- obj.reset = function () {
- // Close calendar
- obj.setValue("");
- obj.date = null;
- obj.close(false, false);
- };
-
- /**
- * Get calendar days
- */
- obj.getDays = function () {
- // Mode
- obj.options.mode = "days";
-
- // Setting current values in case of NULLs
- var date = new Date();
-
- // Current selection
- var year =
- obj.date && jSuites.isNumeric(obj.date[0])
- ? obj.date[0]
- : parseInt(date.getFullYear());
- var month =
- obj.date && jSuites.isNumeric(obj.date[1])
- ? obj.date[1]
- : parseInt(date.getMonth()) + 1;
- var day =
- obj.date && jSuites.isNumeric(obj.date[2])
- ? obj.date[2]
- : parseInt(date.getDate());
- var hour =
- obj.date && jSuites.isNumeric(obj.date[3])
- ? obj.date[3]
- : parseInt(date.getHours());
- var min =
- obj.date && jSuites.isNumeric(obj.date[4])
- ? obj.date[4]
- : parseInt(date.getMinutes());
-
- // Selection container
- obj.date = [year, month, day, hour, min, 0];
-
- // Update title
- calendarLabelYear.innerHTML = year;
- calendarLabelMonth.innerHTML = obj.options.months[month - 1];
-
- // Current month and Year
- var isCurrentMonthAndYear =
- date.getMonth() == month - 1 && date.getFullYear() == year
- ? true
- : false;
- var currentDay = date.getDate();
-
- // Number of days in the month
- var date = new Date(year, month, 0, 0, 0);
- var numberOfDays = date.getDate();
-
- // First day
- var date = new Date(year, month - 1, 0, 0, 0);
- var firstDay = date.getDay() + 1;
-
- // Index value
- var index = obj.options.startingDay || 0;
-
- // First of day relative to the starting calendar weekday
- firstDay = firstDay - index;
-
- // Reset table
- calendarBody.innerHTML = "";
-
- // Weekdays Row
- var row = document.createElement("tr");
- row.setAttribute("align", "center");
- calendarBody.appendChild(row);
-
- // Create weekdays row
- for (var i = 0; i < 7; i++) {
- var cell = document.createElement("td");
- cell.classList.add("jcalendar-weekday");
- cell.innerHTML = obj.options.weekdays[index].substr(0, 1);
- row.appendChild(cell);
- // Next week day
- index++;
- // Restart index
- if (index > 6) {
- index = 0;
- }
- }
-
- // Index of days
- var index = 0;
- var d = 0;
-
- // Calendar table
- for (var j = 0; j < 6; j++) {
- // Reset cells container
- var row = document.createElement("tr");
- row.setAttribute("align", "center");
- // Data control
- var emptyRow = true;
- // Create cells
- for (var i = 0; i < 7; i++) {
- // Create cell
- var cell = document.createElement("td");
- cell.classList.add("jcalendar-set-day");
-
- if (index >= firstDay && index < firstDay + numberOfDays) {
- // Day cell
- d++;
- cell.innerHTML = d;
-
- // Selected
- if (d == day) {
- cell.classList.add("jcalendar-selected");
- }
-
- // Current selection day is today
- if (isCurrentMonthAndYear && currentDay == d) {
- cell.style.fontWeight = "bold";
- }
-
- // Current selection day
- var current = jSuites.calendar.now(
- new Date(year, month - 1, d),
- true
- );
-
- // Available ranges
- if (obj.options.validRange) {
- if (
- !obj.options.validRange[0] ||
- current >= obj.options.validRange[0]
- ) {
- var test1 = true;
- } else {
- var test1 = false;
- }
-
- if (
- !obj.options.validRange[1] ||
- current <= obj.options.validRange[1]
- ) {
- var test2 = true;
- } else {
- var test2 = false;
- }
-
- if (!(test1 && test2)) {
- cell.classList.add("jcalendar-disabled");
- }
- }
-
- // Control
- emptyRow = false;
- }
- // Day cell
- row.appendChild(cell);
- // Index
- index++;
- }
-
- // Add cell to the calendar body
- if (emptyRow == false) {
- calendarBody.appendChild(row);
- }
- }
-
- // Show time controls
- if (obj.options.time) {
- calendarControlsTime.style.display = "";
- } else {
- calendarControlsTime.style.display = "none";
- }
-
- // Update
- updateActions();
- };
-
- obj.getMonths = function () {
- // Mode
- obj.options.mode = "months";
-
- // Loading month labels
- var months = obj.options.months;
-
- // Value
- var value = obj.options.value;
-
- // Current date
- var date = new Date();
- var currentYear = parseInt(date.getFullYear());
- var currentMonth = parseInt(date.getMonth()) + 1;
- var selectedYear =
- obj.date && jSuites.isNumeric(obj.date[0]) ? obj.date[0] : currentYear;
- var selectedMonth =
- obj.date && jSuites.isNumeric(obj.date[1]) ? obj.date[1] : currentMonth;
-
- // Update title
- calendarLabelYear.innerHTML = obj.date[0];
- calendarLabelMonth.innerHTML = months[selectedMonth - 1];
-
- // Table
- var table = document.createElement("table");
- table.setAttribute("width", "100%");
-
- // Row
- var row = null;
-
- // Calendar table
- for (var i = 0; i < 12; i++) {
- if (!(i % 4)) {
- // Reset cells container
- var row = document.createElement("tr");
- row.setAttribute("align", "center");
- table.appendChild(row);
- }
-
- // Create cell
- var cell = document.createElement("td");
- cell.classList.add("jcalendar-set-month");
- cell.setAttribute("data-value", i + 1);
- cell.innerText = months[i];
-
- if (obj.options.validRange) {
- var current = selectedYear + "-" + jSuites.two(i + 1);
- if (
- !obj.options.validRange[0] ||
- current >= obj.options.validRange[0].substr(0, 7)
- ) {
- var test1 = true;
- } else {
- var test1 = false;
- }
-
- if (
- !obj.options.validRange[1] ||
- current <= obj.options.validRange[1].substr(0, 7)
- ) {
- var test2 = true;
- } else {
- var test2 = false;
- }
-
- if (!(test1 && test2)) {
- cell.classList.add("jcalendar-disabled");
- }
- }
-
- if (i + 1 == selectedMonth) {
- cell.classList.add("jcalendar-selected");
- }
-
- if (currentYear == selectedYear && i + 1 == currentMonth) {
- cell.style.fontWeight = "bold";
- }
-
- row.appendChild(cell);
- }
-
- calendarBody.innerHTML = '
|
';
- calendarBody.children[0].children[0].appendChild(table);
-
- // Update
- updateActions();
- };
-
- obj.getYears = function () {
- // Mode
- obj.options.mode = "years";
-
- // Current date
- var date = new Date();
- var currentYear = date.getFullYear();
- var selectedYear =
- obj.date && jSuites.isNumeric(obj.date[0])
- ? obj.date[0]
- : parseInt(date.getFullYear());
-
- // Array of years
- var y = [];
- for (var i = 0; i < 25; i++) {
- y[i] = parseInt(obj.date[0]) + (i - 12);
- }
-
- // Assembling the year tables
- var table = document.createElement("table");
- table.setAttribute("width", "100%");
-
- for (var i = 0; i < 25; i++) {
- if (!(i % 5)) {
- // Reset cells container
- var row = document.createElement("tr");
- row.setAttribute("align", "center");
- table.appendChild(row);
- }
-
- // Create cell
- var cell = document.createElement("td");
- cell.classList.add("jcalendar-set-year");
- cell.innerText = y[i];
-
- if (selectedYear == y[i]) {
- cell.classList.add("jcalendar-selected");
- }
-
- if (currentYear == y[i]) {
- cell.style.fontWeight = "bold";
- }
-
- row.appendChild(cell);
- }
-
- calendarBody.innerHTML = ' |
';
- calendarBody.firstChild.firstChild.appendChild(table);
-
- // Update
- updateActions();
- };
-
- obj.setLabel = function (value, mixed) {
- return jSuites.calendar.getDateString(value, mixed);
- };
-
- obj.fromFormatted = function (value, format) {
- return jSuites.calendar.extractDateFromString(value, format);
- };
-
- var mouseUpControls = function (e) {
- var element = jSuites.findElement(e.target, "jcalendar-container");
- if (element) {
- var action = e.target.className;
-
- // Object id
- if (action == "jcalendar-prev") {
- obj.prev();
- } else if (action == "jcalendar-next") {
- obj.next();
- } else if (action == "jcalendar-month") {
- obj.getMonths();
- } else if (action == "jcalendar-year") {
- obj.getYears();
- } else if (action == "jcalendar-set-year") {
- obj.date[0] = e.target.innerText;
- if (obj.options.type == "year-month-picker") {
- obj.getMonths();
- } else {
- obj.getDays();
- }
- } else if (e.target.classList.contains("jcalendar-set-month")) {
- var month = parseInt(e.target.getAttribute("data-value"));
- if (obj.options.type == "year-month-picker") {
- obj.update(e.target, month);
- } else {
- obj.date[1] = month;
- obj.getDays();
- }
- } else if (
- action == "jcalendar-confirm" ||
- action == "jcalendar-update" ||
- action == "jcalendar-close"
- ) {
- obj.close();
- } else if (action == "jcalendar-backdrop") {
- obj.close(false, false);
- } else if (action == "jcalendar-reset") {
- obj.reset();
- } else if (
- e.target.classList.contains("jcalendar-set-day") &&
- e.target.innerText
- ) {
- obj.update(e.target);
- }
- } else {
- obj.close();
- }
- };
-
- var keyUpControls = function (e) {
- if (e.target.value && e.target.value.length > 3) {
- var test = jSuites.calendar.extractDateFromString(
- e.target.value,
- obj.options.format
- );
- if (test) {
- obj.setValue(test);
- }
- }
- };
-
- // Update actions button
- var updateActions = function () {
- var currentDay = calendar.querySelector(".jcalendar-selected");
-
- if (currentDay && currentDay.classList.contains("jcalendar-disabled")) {
- calendarControlsUpdateButton.setAttribute("disabled", "disabled");
- calendarSelectHour.setAttribute("disabled", "disabled");
- calendarSelectMin.setAttribute("disabled", "disabled");
- } else {
- calendarControlsUpdateButton.removeAttribute("disabled");
- calendarSelectHour.removeAttribute("disabled");
- calendarSelectMin.removeAttribute("disabled");
- }
-
- // Event
- if (typeof obj.options.onupdate == "function") {
- obj.options.onupdate(el, obj.getValue());
- }
- };
-
- var calendar = null;
- var calendarReset = null;
- var calendarConfirm = null;
- var calendarContainer = null;
- var calendarContent = null;
- var calendarLabelYear = null;
- var calendarLabelMonth = null;
- var calendarTable = null;
- var calendarBody = null;
-
- var calendarControls = null;
- var calendarControlsTime = null;
- var calendarControlsUpdate = null;
- var calendarControlsUpdateButton = null;
- var calendarSelectHour = null;
- var calendarSelectMin = null;
-
- var init = function () {
- // Get value from initial element if that is an input
- if (el.tagName == "INPUT" && el.value) {
- options.value = el.value;
- }
-
- // Calendar DOM elements
- calendarReset = document.createElement("div");
- calendarReset.className = "jcalendar-reset";
-
- calendarConfirm = document.createElement("div");
- calendarConfirm.className = "jcalendar-confirm";
-
- calendarControls = document.createElement("div");
- calendarControls.className = "jcalendar-controls";
- calendarControls.style.borderBottom = "1px solid #ddd";
- calendarControls.appendChild(calendarReset);
- calendarControls.appendChild(calendarConfirm);
-
- calendarContainer = document.createElement("div");
- calendarContainer.className = "jcalendar-container";
-
- calendarContent = document.createElement("div");
- calendarContent.className = "jcalendar-content";
- calendarContainer.appendChild(calendarContent);
-
- // Main element
- if (el.tagName == "DIV") {
- calendar = el;
- calendar.classList.add("jcalendar-inline");
- } else {
- // Add controls to the screen
- calendarContent.appendChild(calendarControls);
-
- calendar = document.createElement("div");
- calendar.className = "jcalendar";
- }
- calendar.classList.add("jcalendar-container");
- calendar.appendChild(calendarContainer);
-
- // Table container
- var calendarTableContainer = document.createElement("div");
- calendarTableContainer.className = "jcalendar-table";
- calendarContent.appendChild(calendarTableContainer);
-
- // Previous button
- var calendarHeaderPrev = document.createElement("td");
- calendarHeaderPrev.setAttribute("colspan", "2");
- calendarHeaderPrev.className = "jcalendar-prev";
-
- // Header with year and month
- calendarLabelYear = document.createElement("span");
- calendarLabelYear.className = "jcalendar-year";
- calendarLabelMonth = document.createElement("span");
- calendarLabelMonth.className = "jcalendar-month";
-
- var calendarHeaderTitle = document.createElement("td");
- calendarHeaderTitle.className = "jcalendar-header";
- calendarHeaderTitle.setAttribute("colspan", "3");
- calendarHeaderTitle.appendChild(calendarLabelMonth);
- calendarHeaderTitle.appendChild(calendarLabelYear);
-
- var calendarHeaderNext = document.createElement("td");
- calendarHeaderNext.setAttribute("colspan", "2");
- calendarHeaderNext.className = "jcalendar-next";
-
- var calendarHeader = document.createElement("thead");
- var calendarHeaderRow = document.createElement("tr");
- calendarHeaderRow.appendChild(calendarHeaderPrev);
- calendarHeaderRow.appendChild(calendarHeaderTitle);
- calendarHeaderRow.appendChild(calendarHeaderNext);
- calendarHeader.appendChild(calendarHeaderRow);
-
- calendarTable = document.createElement("table");
- calendarBody = document.createElement("tbody");
- calendarTable.setAttribute("cellpadding", "0");
- calendarTable.setAttribute("cellspacing", "0");
- calendarTable.appendChild(calendarHeader);
- calendarTable.appendChild(calendarBody);
- calendarTableContainer.appendChild(calendarTable);
-
- calendarSelectHour = document.createElement("select");
- calendarSelectHour.className = "jcalendar-select";
- calendarSelectHour.onchange = function () {
- obj.date[3] = this.value;
-
- // Event
- if (typeof obj.options.onupdate == "function") {
- obj.options.onupdate(el, obj.getValue());
- }
- };
-
- for (var i = 0; i < 24; i++) {
- var element = document.createElement("option");
- element.value = i;
- element.innerHTML = jSuites.two(i);
- calendarSelectHour.appendChild(element);
- }
-
- calendarSelectMin = document.createElement("select");
- calendarSelectMin.className = "jcalendar-select";
- calendarSelectMin.onchange = function () {
- obj.date[4] = this.value;
-
- // Event
- if (typeof obj.options.onupdate == "function") {
- obj.options.onupdate(el, obj.getValue());
- }
- };
-
- for (var i = 0; i < 60; i++) {
- var element = document.createElement("option");
- element.value = i;
- element.innerHTML = jSuites.two(i);
- calendarSelectMin.appendChild(element);
- }
-
- // Footer controls
- var calendarControlsFooter = document.createElement("div");
- calendarControlsFooter.className = "jcalendar-controls";
-
- calendarControlsTime = document.createElement("div");
- calendarControlsTime.className = "jcalendar-time";
- calendarControlsTime.style.maxWidth = "140px";
- calendarControlsTime.appendChild(calendarSelectHour);
- calendarControlsTime.appendChild(calendarSelectMin);
-
- calendarControlsUpdateButton = document.createElement("button");
- calendarControlsUpdateButton.setAttribute("type", "button");
- calendarControlsUpdateButton.className = "jcalendar-update";
-
- calendarControlsUpdate = document.createElement("div");
- calendarControlsUpdate.style.flexGrow = "10";
- calendarControlsUpdate.appendChild(calendarControlsUpdateButton);
- calendarControlsFooter.appendChild(calendarControlsTime);
-
- // Only show the update button for input elements
- if (el.tagName == "INPUT") {
- calendarControlsFooter.appendChild(calendarControlsUpdate);
- }
-
- calendarContent.appendChild(calendarControlsFooter);
-
- var calendarBackdrop = document.createElement("div");
- calendarBackdrop.className = "jcalendar-backdrop";
- calendar.appendChild(calendarBackdrop);
-
- // Handle events
- el.addEventListener("keyup", keyUpControls);
-
- // Add global events
- calendar.addEventListener("swipeleft", function (e) {
- jSuites.animation.slideLeft(calendarTable, 0, function () {
- obj.next();
- jSuites.animation.slideRight(calendarTable, 1);
- });
- e.preventDefault();
- e.stopPropagation();
- });
-
- calendar.addEventListener("swiperight", function (e) {
- jSuites.animation.slideRight(calendarTable, 0, function () {
- obj.prev();
- jSuites.animation.slideLeft(calendarTable, 1);
- });
- e.preventDefault();
- e.stopPropagation();
- });
-
- el.onmouseup = function () {
- obj.open();
- };
-
- if ("ontouchend" in document.documentElement === true) {
- calendar.addEventListener("touchend", mouseUpControls);
- } else {
- calendar.addEventListener("mouseup", mouseUpControls);
- }
-
- // Global controls
- if (!jSuites.calendar.hasEvents) {
- // Execute only one time
- jSuites.calendar.hasEvents = true;
- // Enter and Esc
- document.addEventListener("keydown", jSuites.calendar.keydown);
- }
-
- // Set configuration
- obj.setOptions(options);
-
- // Append element to the DOM
- if (el.tagName == "INPUT") {
- el.parentNode.insertBefore(calendar, el.nextSibling);
- // Add properties
- el.setAttribute("autocomplete", "off");
- // Element
- el.classList.add("jcalendar-input");
- // Value
- el.value = obj.setLabel(obj.getValue(), obj.options);
- } else {
- // Get days
- obj.getDays();
- // Hour
- if (obj.options.time) {
- calendarSelectHour.value = obj.date[3];
- calendarSelectMin.value = obj.date[4];
- }
- }
-
- // Default opened
- if (obj.options.opened == true) {
- obj.open();
- }
-
- // Change method
- el.change = obj.setValue;
-
- // Global generic value handler
- el.val = function (val) {
- if (val === undefined) {
- return obj.getValue();
- } else {
- obj.setValue(val);
- }
- };
-
- // Keep object available from the node
- el.calendar = calendar.calendar = obj;
- };
-
- init();
-
- return obj;
- };
-
- jSuites.calendar.keydown = function (e) {
- var calendar = null;
- if ((calendar = jSuites.calendar.current)) {
- if (e.which == 13) {
- // ENTER
- calendar.close(false, true);
- } else if (e.which == 27) {
- // ESC
- calendar.close(false, false);
- }
- }
- };
-
- jSuites.calendar.prettify = function (d, texts) {
- if (!texts) {
- var texts = {
- justNow: "Just now",
- xMinutesAgo: "{0}m ago",
- xHoursAgo: "{0}h ago",
- xDaysAgo: "{0}d ago",
- xWeeksAgo: "{0}w ago",
- xMonthsAgo: "{0} mon ago",
- xYearsAgo: "{0}y ago",
- };
- }
-
- var d1 = new Date();
- var d2 = new Date(d);
- var total = parseInt((d1 - d2) / 1000 / 60);
-
- String.prototype.format = function (o) {
- return this.replace("{0}", o);
- };
-
- if (total == 0) {
- var text = texts.justNow;
- } else if (total < 90) {
- var text = texts.xMinutesAgo.format(total);
- } else if (total < 1440) {
- // One day
- var text = texts.xHoursAgo.format(Math.round(total / 60));
- } else if (total < 20160) {
- // 14 days
- var text = texts.xDaysAgo.format(Math.round(total / 1440));
- } else if (total < 43200) {
- // 30 days
- var text = texts.xWeeksAgo.format(Math.round(total / 10080));
- } else if (total < 1036800) {
- // 24 months
- var text = texts.xMonthsAgo.format(Math.round(total / 43200));
- } else {
- // 24 months+
- var text = texts.xYearsAgo.format(Math.round(total / 525600));
- }
-
- return text;
- };
-
- jSuites.calendar.prettifyAll = function () {
- var elements = document.querySelectorAll(".prettydate");
- for (var i = 0; i < elements.length; i++) {
- if (elements[i].getAttribute("data-date")) {
- elements[i].innerHTML = jSuites.calendar.prettify(
- elements[i].getAttribute("data-date")
- );
- } else {
- if (elements[i].innerHTML) {
- elements[i].setAttribute("title", elements[i].innerHTML);
- elements[i].setAttribute("data-date", elements[i].innerHTML);
- elements[i].innerHTML = jSuites.calendar.prettify(
- elements[i].innerHTML
- );
- }
- }
- }
- };
-
- jSuites.calendar.now = function (date, dateOnly) {
- if (Array.isArray(date)) {
- var y = date[0];
- var m = date[1];
- var d = date[2];
- var h = date[3];
- var i = date[4];
- var s = date[5];
- } else {
- if (!date) {
- var date = new Date();
- }
- var y = date.getFullYear();
- var m = date.getMonth() + 1;
- var d = date.getDate();
- var h = date.getHours();
- var i = date.getMinutes();
- var s = date.getSeconds();
- }
-
- if (dateOnly == true) {
- return jSuites.two(y) + "-" + jSuites.two(m) + "-" + jSuites.two(d);
- } else {
- return (
- jSuites.two(y) +
- "-" +
- jSuites.two(m) +
- "-" +
- jSuites.two(d) +
- " " +
- jSuites.two(h) +
- ":" +
- jSuites.two(i) +
- ":" +
- jSuites.two(s)
- );
- }
- };
-
- jSuites.calendar.toArray = function (value) {
- var date = value.split(value.indexOf("T") !== -1 ? "T" : " ");
- var time = date[1];
- var date = date[0].split("-");
- var y = parseInt(date[0]);
- var m = parseInt(date[1]);
- var d = parseInt(date[2]);
-
- if (time) {
- var time = time.split(":");
- var h = parseInt(time[0]);
- var i = parseInt(time[1]);
- } else {
- var h = 0;
- var i = 0;
- }
- return [y, m, d, h, i, 0];
- };
-
- // Helper to extract date from a string
- jSuites.calendar.extractDateFromString = function (date, format) {
- if (date > 0 && Number(date) == date) {
- var d = new Date(Math.round((date - 25569) * 86400 * 1000));
- return (
- d.getFullYear() +
- "-" +
- jSuites.two(d.getMonth()) +
- "-" +
- jSuites.two(d.getDate()) +
- " 00:00:00"
- );
- }
-
- var o = jSuites.mask(date, { mask: format }, true);
- if (o.date[0] && o.date[1]) {
- if (!o.date[2]) {
- o.date[2] = 1;
- }
-
- return (
- o.date[0] +
- "-" +
- jSuites.two(o.date[1]) +
- "-" +
- jSuites.two(o.date[2]) +
- " " +
- jSuites.two(o.date[3]) +
- ":" +
- jSuites.two(o.date[4]) +
- ":" +
- jSuites.two(o.date[5])
- );
- }
- return "";
- };
-
- var excelInitialTime = Date.UTC(1900, 0, 0);
- var excelLeapYearBug = Date.UTC(1900, 1, 29);
- var millisecondsPerDay = 86400000;
-
- /**
- * Date to number
- */
- jSuites.calendar.dateToNum = function (jsDate) {
- if (typeof jsDate === "string") {
- jsDate = new Date(jsDate + " GMT+0");
- }
- var jsDateInMilliseconds = jsDate.getTime();
-
- if (jsDateInMilliseconds >= excelLeapYearBug) {
- jsDateInMilliseconds += millisecondsPerDay;
- }
-
- jsDateInMilliseconds -= excelInitialTime;
-
- return jsDateInMilliseconds / millisecondsPerDay;
- };
-
- /**
- * Number to date
- */
- // !IMPORTANT!
- // Excel incorrectly considers 1900 to be a leap year
- jSuites.calendar.numToDate = function (excelSerialNumber) {
- var jsDateInMilliseconds =
- excelInitialTime + excelSerialNumber * millisecondsPerDay;
-
- if (jsDateInMilliseconds >= excelLeapYearBug) {
- jsDateInMilliseconds -= millisecondsPerDay;
- }
-
- const d = new Date(jsDateInMilliseconds);
-
- var date = [
- d.getUTCFullYear(),
- d.getUTCMonth() + 1,
- d.getUTCDate(),
- d.getUTCHours(),
- d.getUTCMinutes(),
- d.getUTCSeconds(),
- ];
-
- return jSuites.calendar.now(date);
- };
-
- // Helper to convert date into string
- jSuites.calendar.getDateString = function (value, options) {
- if (!options) {
- var options = {};
- }
-
- // Labels
- if (options && typeof options == "object") {
- var format = options.format;
- } else {
- var format = options;
- }
-
- if (!format) {
- format = "YYYY-MM-DD";
- }
-
- // Convert to number of hours
- if (typeof value == "number" && format.indexOf("[h]") >= 0) {
- var result = parseFloat(24 * Number(value));
- if (format.indexOf("mm") >= 0) {
- var h = ("" + result).split(".");
- if (h[1]) {
- var d = 60 * parseFloat("0." + h[1]);
- d = parseFloat(d.toFixed(2));
- } else {
- var d = 0;
- }
- result = parseInt(h[0]) + ":" + jSuites.two(d);
- }
- return result;
- }
-
- // Date instance
- if (value instanceof Date) {
- value = jSuites.calendar.now(value);
- } else if (value && jSuites.isNumeric(value)) {
- value = jSuites.calendar.numToDate(value);
- }
-
- // Tokens
- var tokens = [
- "DAY",
- "WD",
- "DDDD",
- "DDD",
- "DD",
- "D",
- "Q",
- "HH24",
- "HH12",
- "HH",
- "H",
- "AM/PM",
- "MI",
- "SS",
- "MS",
- "YYYY",
- "YYY",
- "YY",
- "Y",
- "MONTH",
- "MON",
- "MMMMM",
- "MMMM",
- "MMM",
- "MM",
- "M",
- ".",
- ];
-
- // Expression to extract all tokens from the string
- var e = new RegExp(tokens.join("|"), "gi");
- // Extract
- var t = format.match(e);
-
- // Compatibility with excel
- for (var i = 0; i < t.length; i++) {
- if (t[i].toUpperCase() == "MM") {
- // Not a month, correct to minutes
- if (t[i - 1] && t[i - 1].toUpperCase().indexOf("H") >= 0) {
- t[i] = "mi";
- } else if (t[i - 2] && t[i - 2].toUpperCase().indexOf("H") >= 0) {
- t[i] = "mi";
- } else if (t[i + 1] && t[i + 1].toUpperCase().indexOf("S") >= 0) {
- t[i] = "mi";
- } else if (t[i + 2] && t[i + 2].toUpperCase().indexOf("S") >= 0) {
- t[i] = "mi";
- }
- }
- }
-
- // Object
- var o = {
- tokens: t,
- };
-
- // Value
- if (value) {
- var d = "" + value;
- var splitStr = d.indexOf("T") !== -1 ? "T" : " ";
- d = d.split(splitStr);
-
- var h = 0;
- var m = 0;
- var s = 0;
-
- if (d[1]) {
- h = d[1].split(":");
- m = h[1] ? h[1] : 0;
- s = h[2] ? h[2] : 0;
- h = h[0] ? h[0] : 0;
- }
-
- d = d[0].split("-");
-
- if (
- d[0] &&
- d[1] &&
- d[2] &&
- d[0] > 0 &&
- d[1] > 0 &&
- d[1] < 13 &&
- d[2] > 0 &&
- d[2] < 32
- ) {
- // Data
- o.data = [d[0], d[1], d[2], h, m, s];
-
- // Value
- o.value = [];
-
- // Calendar instance
- var calendar = new Date(
- o.data[0],
- o.data[1] - 1,
- o.data[2],
- o.data[3],
- o.data[4],
- o.data[5]
- );
-
- // Get method
- var get = function (i) {
- // Token
- var t = this.tokens[i];
- // Case token
- var s = t.toUpperCase();
- var v = null;
-
- if (s === "YYYY") {
- v = this.data[0];
- } else if (s === "YYY") {
- v = this.data[0].substring(1, 4);
- } else if (s === "YY") {
- v = this.data[0].substring(2, 4);
- } else if (s === "Y") {
- v = this.data[0].substring(3, 4);
- } else if (t === "MON") {
- v = jSuites.calendar.months[calendar.getMonth()]
- .substr(0, 3)
- .toUpperCase();
- } else if (t === "mon") {
- v = jSuites.calendar.months[calendar.getMonth()]
- .substr(0, 3)
- .toLowerCase();
- } else if (t === "MONTH") {
- v = jSuites.calendar.months[calendar.getMonth()].toUpperCase();
- } else if (t === "month") {
- v = jSuites.calendar.months[calendar.getMonth()].toLowerCase();
- } else if (s === "MMMMM") {
- v = jSuites.calendar.months[calendar.getMonth()].substr(0, 1);
- } else if (s === "MMMM" || t === "Month") {
- v = jSuites.calendar.months[calendar.getMonth()];
- } else if (s === "MMM" || t == "Mon") {
- v = jSuites.calendar.months[calendar.getMonth()].substr(0, 3);
- } else if (s === "MM") {
- v = jSuites.two(this.data[1]);
- } else if (s === "M") {
- v = calendar.getMonth() + 1;
- } else if (t === "DAY") {
- v = jSuites.calendar.weekdays[calendar.getDay()].toUpperCase();
- } else if (t === "day") {
- v = jSuites.calendar.weekdays[calendar.getDay()].toLowerCase();
- } else if (s === "DDDD" || t == "Day") {
- v = jSuites.calendar.weekdays[calendar.getDay()];
- } else if (s === "DDD") {
- v = jSuites.calendar.weekdays[calendar.getDay()].substr(0, 3);
- } else if (s === "DD") {
- v = jSuites.two(this.data[2]);
- } else if (s === "D") {
- v = this.data[2];
- } else if (s === "Q") {
- v = Math.floor((calendar.getMonth() + 3) / 3);
- } else if (s === "HH24" || s === "HH") {
- v = jSuites.two(this.data[3]);
- } else if (s === "HH12") {
- if (this.data[3] > 12) {
- v = jSuites.two(this.data[3] - 12);
- } else {
- v = jSuites.two(this.data[3]);
- }
- } else if (s === "H") {
- v = this.data[3];
- } else if (s === "MI") {
- v = jSuites.two(this.data[4]);
- } else if (s === "SS") {
- v = jSuites.two(this.data[5]);
- } else if (s === "MS") {
- v = calendar.getMilliseconds();
- } else if (s === "AM/PM") {
- if (this.data[3] >= 12) {
- v = "PM";
- } else {
- v = "AM";
- }
- } else if (s === "WD") {
- v = jSuites.calendar.weekdays[calendar.getDay()];
- }
-
- if (v === null) {
- this.value[i] = this.tokens[i];
- } else {
- this.value[i] = v;
- }
- };
-
- for (var i = 0; i < o.tokens.length; i++) {
- get.call(o, i);
- }
- // Put pieces together
- value = o.value.join("");
- } else {
- value = "";
- }
- }
-
- return value;
- };
-
- // Jsuites calendar labels
- jSuites.calendar.weekdays = [
- "Sunday",
- "Monday",
- "Tuesday",
- "Wednesday",
- "Thursday",
- "Friday",
- "Saturday",
- ];
- jSuites.calendar.months = [
- "January",
- "February",
- "March",
- "April",
- "May",
- "June",
- "July",
- "August",
- "September",
- "October",
- "November",
- "December",
- ];
- jSuites.calendar.weekdaysShort = [
- "Sun",
- "Mon",
- "Tue",
- "Wed",
- "Thu",
- "Fri",
- "Sat",
- ];
- jSuites.calendar.monthsShort = [
- "Jan",
- "Feb",
- "Mar",
- "Apr",
- "May",
- "Jun",
- "Jul",
- "Aug",
- "Sep",
- "Oct",
- "Nov",
- "Dec",
- ];
-
- jSuites.color = function (el, options) {
- // Already created, update options
- if (el.color) {
- return el.color.setOptions(options, true);
- }
-
- // New instance
- var obj = { type: "color" };
- obj.options = {};
-
- var container = null;
- var backdrop = null;
- var content = null;
- var resetButton = null;
- var closeButton = null;
- var tabs = null;
- var jsuitesTabs = null;
-
- /**
- * Update options
- */
- obj.setOptions = function (options, reset) {
- /**
- * @typedef {Object} defaults
- * @property {(string|Array)} value - Initial value of the compontent
- * @property {string} placeholder - The default instruction text on the element
- * @property {requestCallback} onchange - Method to be execute after any changes on the element
- * @property {requestCallback} onclose - Method to be execute when the element is closed
- * @property {string} doneLabel - Label for button done
- * @property {string} resetLabel - Label for button reset
- * @property {string} resetValue - Value for button reset
- * @property {Bool} showResetButton - Active or note for button reset - default false
- */
- var defaults = {
- placeholder: "",
- value: null,
- onopen: null,
- onclose: null,
- onchange: null,
- closeOnChange: true,
- palette: null,
- position: null,
- doneLabel: "Done",
- resetLabel: "Reset",
- fullscreen: false,
- opened: false,
- };
-
- if (!options) {
- options = {};
- }
-
- if (options && !options.palette) {
- // Default pallete
- options.palette = jSuites.palette();
- }
-
- // Loop through our object
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- if (typeof obj.options[property] == "undefined" || reset === true) {
- obj.options[property] = defaults[property];
- }
- }
- }
-
- // Update the text of the controls, if they have already been created
- if (resetButton) {
- resetButton.innerHTML = obj.options.resetLabel;
- }
- if (closeButton) {
- closeButton.innerHTML = obj.options.doneLabel;
- }
-
- // Update the pallete
- if (obj.options.palette && jsuitesTabs) {
- jsuitesTabs.updateContent(0, table());
- }
-
- // Value
- if (typeof obj.options.value === "string") {
- el.value = obj.options.value;
- if (el.tagName === "INPUT") {
- el.style.color = el.value;
- el.style.backgroundColor = el.value;
- }
- }
-
- // Placeholder
- if (obj.options.placeholder) {
- el.setAttribute("placeholder", obj.options.placeholder);
- } else {
- if (el.getAttribute("placeholder")) {
- el.removeAttribute("placeholder");
- }
- }
-
- return obj;
- };
-
- obj.select = function (color) {
- // Remove current selected mark
- var selected = container.querySelector(".jcolor-selected");
- if (selected) {
- selected.classList.remove("jcolor-selected");
- }
-
- // Mark cell as selected
- if (obj.values[color]) {
- obj.values[color].classList.add("jcolor-selected");
- }
-
- obj.options.value = color;
- };
-
- /**
- * Open color pallete
- */
- obj.open = function () {
- if (!container.classList.contains("jcolor-focus")) {
- // Start tracking
- jSuites.tracking(obj, true);
-
- // Show color picker
- container.classList.add("jcolor-focus");
-
- // Select current color
- if (obj.options.value) {
- obj.select(obj.options.value);
- }
-
- // Reset margin
- content.style.marginTop = "";
- content.style.marginLeft = "";
-
- var rectContent = content.getBoundingClientRect();
- var availableWidth = jSuites.getWindowWidth();
- var availableHeight = jSuites.getWindowHeight();
-
- if (availableWidth < 800 || obj.options.fullscreen == true) {
- content.classList.add("jcolor-fullscreen");
- jSuites.animation.slideBottom(content, 1);
- backdrop.style.display = "block";
- } else {
- if (content.classList.contains("jcolor-fullscreen")) {
- content.classList.remove("jcolor-fullscreen");
- backdrop.style.display = "";
- }
-
- if (obj.options.position) {
- content.style.position = "fixed";
- } else {
- content.style.position = "";
- }
-
- if (rectContent.left + rectContent.width > availableWidth) {
- content.style.marginLeft =
- -1 *
- (rectContent.left + rectContent.width - (availableWidth - 20)) +
- "px";
- }
- if (rectContent.top + rectContent.height > availableHeight) {
- content.style.marginTop =
- -1 *
- (rectContent.top +
- rectContent.height -
- (availableHeight - 20)) +
- "px";
- }
- }
-
- if (typeof obj.options.onopen == "function") {
- obj.options.onopen(el);
- }
-
- jsuitesTabs.setBorder(jsuitesTabs.getActive());
-
- // Update sliders
- if (obj.options.value) {
- var rgb = HexToRgb(obj.options.value);
-
- rgbInputs.forEach(function (rgbInput, index) {
- rgbInput.value = rgb[index];
- rgbInput.dispatchEvent(new Event("input"));
- });
- }
- }
- };
-
- /**
- * Close color pallete
- */
- obj.close = function (ignoreEvents) {
- if (container.classList.contains("jcolor-focus")) {
- // Remove focus
- container.classList.remove("jcolor-focus");
- // Make sure backdrop is hidden
- backdrop.style.display = "";
- // Call related events
- if (!ignoreEvents && typeof obj.options.onclose == "function") {
- obj.options.onclose(el);
- }
- // Stop the object
- jSuites.tracking(obj, false);
- }
-
- return obj.options.value;
- };
-
- /**
- * Set value
- */
- obj.setValue = function (color) {
- if (!color) {
- color = "";
- }
-
- if (color != obj.options.value) {
- obj.options.value = color;
- slidersResult = color;
-
- // Remove current selecded mark
- obj.select(color);
-
- // Onchange
- if (typeof obj.options.onchange == "function") {
- obj.options.onchange(el, color);
- }
-
- // Changes
- if (el.value != obj.options.value) {
- // Set input value
- el.value = obj.options.value;
- if (el.tagName === "INPUT") {
- el.style.color = el.value;
- el.style.backgroundColor = el.value;
- }
-
- // Element onchange native
- if (typeof el.oninput == "function") {
- el.oninput({
- type: "input",
- target: el,
- value: el.value,
- });
- }
- }
-
- if (obj.options.closeOnChange == true) {
- obj.close();
- }
- }
- };
-
- /**
- * Get value
- */
- obj.getValue = function () {
- return obj.options.value;
- };
-
- var backdropClickControl = false;
-
- // Converts a number in decimal to hexadecimal
- var decToHex = function (num) {
- var hex = num.toString(16);
- return hex.length === 1 ? "0" + hex : hex;
- };
-
- // Converts a color in rgb to hexadecimal
- var rgbToHex = function (r, g, b) {
- return "#" + decToHex(r) + decToHex(g) + decToHex(b);
- };
-
- // Converts a number in hexadecimal to decimal
- var hexToDec = function (hex) {
- return parseInt("0x" + hex);
- };
-
- // Converts a color in hexadecimal to rgb
- var HexToRgb = function (hex) {
- return [
- hexToDec(hex.substr(1, 2)),
- hexToDec(hex.substr(3, 2)),
- hexToDec(hex.substr(5, 2)),
- ];
- };
-
- var table = function () {
- // Content of the first tab
- var tableContainer = document.createElement("div");
- tableContainer.className = "jcolor-grid";
-
- // Cells
- obj.values = [];
-
- // Table pallete
- var t = document.createElement("table");
- t.setAttribute("cellpadding", "7");
- t.setAttribute("cellspacing", "0");
-
- for (var j = 0; j < obj.options.palette.length; j++) {
- var tr = document.createElement("tr");
- for (var i = 0; i < obj.options.palette[j].length; i++) {
- var td = document.createElement("td");
- var color = obj.options.palette[j][i];
- if (color.length < 7 && color.substr(0, 1) !== "#") {
- color = "#" + color;
- }
- td.style.backgroundColor = color;
- td.setAttribute("data-value", color);
- td.innerHTML = "";
- tr.appendChild(td);
-
- // Selected color
- if (obj.options.value == color) {
- td.classList.add("jcolor-selected");
- }
-
- // Possible values
- obj.values[color] = td;
- }
- t.appendChild(tr);
- }
-
- // Append to the table
- tableContainer.appendChild(t);
-
- return tableContainer;
- };
-
- // Canvas where the image will be rendered
- var canvas = document.createElement("canvas");
- canvas.width = 200;
- canvas.height = 160;
- var context = canvas.getContext("2d");
-
- var resizeCanvas = function () {
- // Specifications necessary to correctly obtain colors later in certain positions
- var m = tabs.firstChild.getBoundingClientRect();
- canvas.width = m.width - 14;
- gradient();
- };
-
- var gradient = function () {
- var g = context.createLinearGradient(0, 0, canvas.width, 0);
- // Create color gradient
- g.addColorStop(0, "rgb(255,0,0)");
- g.addColorStop(0.15, "rgb(255,0,255)");
- g.addColorStop(0.33, "rgb(0,0,255)");
- g.addColorStop(0.49, "rgb(0,255,255)");
- g.addColorStop(0.67, "rgb(0,255,0)");
- g.addColorStop(0.84, "rgb(255,255,0)");
- g.addColorStop(1, "rgb(255,0,0)");
- context.fillStyle = g;
- context.fillRect(0, 0, canvas.width, canvas.height);
- g = context.createLinearGradient(0, 0, 0, canvas.height);
- g.addColorStop(0, "rgba(255,255,255,1)");
- g.addColorStop(0.5, "rgba(255,255,255,0)");
- g.addColorStop(0.5, "rgba(0,0,0,0)");
- g.addColorStop(1, "rgba(0,0,0,1)");
- context.fillStyle = g;
- context.fillRect(0, 0, canvas.width, canvas.height);
- };
-
- var hsl = function () {
- var element = document.createElement("div");
- element.className = "jcolor-hsl";
-
- var point = document.createElement("div");
- point.className = "jcolor-point";
-
- var div = document.createElement("div");
- div.appendChild(canvas);
- div.appendChild(point);
- element.appendChild(div);
-
- // Moves the marquee point to the specified position
- var update = function (buttons, x, y) {
- if (buttons === 1) {
- var rect = element.getBoundingClientRect();
- var left = x - rect.left;
- var top = y - rect.top;
- if (left < 0) {
- left = 0;
- }
- if (top < 0) {
- top = 0;
- }
- if (left > rect.width) {
- left = rect.width;
- }
- if (top > rect.height) {
- top = rect.height;
- }
- point.style.left = left + "px";
- point.style.top = top + "px";
- var pixel = context.getImageData(left, top, 1, 1).data;
- slidersResult = rgbToHex(pixel[0], pixel[1], pixel[2]);
- }
- };
-
- // Applies the point's motion function to the div that contains it
- element.addEventListener("mousedown", function (e) {
- update(e.buttons, e.clientX, e.clientY);
- });
-
- element.addEventListener("mousemove", function (e) {
- update(e.buttons, e.clientX, e.clientY);
- });
-
- element.addEventListener("touchmove", function (e) {
- update(1, e.changedTouches[0].clientX, e.changedTouches[0].clientY);
- });
-
- return element;
- };
-
- var slidersResult = "";
-
- var rgbInputs = [];
-
- var changeInputColors = function () {
- if (slidersResult !== "") {
- for (var j = 0; j < rgbInputs.length; j++) {
- var currentColor = HexToRgb(slidersResult);
-
- currentColor[j] = 0;
-
- var newGradient = "linear-gradient(90deg, rgb(";
- newGradient += currentColor.join(", ");
- newGradient += "), rgb(";
-
- currentColor[j] = 255;
-
- newGradient += currentColor.join(", ");
- newGradient += "))";
-
- rgbInputs[j].style.backgroundImage = newGradient;
- }
- }
- };
-
- var sliders = function () {
- // Content of the third tab
- var slidersElement = document.createElement("div");
- slidersElement.className = "jcolor-sliders";
-
- var slidersBody = document.createElement("div");
-
- // Creates a range-type input with the specified name
- var createSliderInput = function (name) {
- var inputContainer = document.createElement("div");
- inputContainer.className = "jcolor-sliders-input-container";
-
- var label = document.createElement("label");
- label.innerText = name;
-
- var subContainer = document.createElement("div");
- subContainer.className = "jcolor-sliders-input-subcontainer";
-
- var input = document.createElement("input");
- input.type = "range";
- input.min = 0;
- input.max = 255;
- input.value = 0;
-
- inputContainer.appendChild(label);
- subContainer.appendChild(input);
-
- var value = document.createElement("div");
- value.innerText = input.value;
-
- input.addEventListener("input", function () {
- value.innerText = input.value;
- });
-
- subContainer.appendChild(value);
- inputContainer.appendChild(subContainer);
-
- slidersBody.appendChild(inputContainer);
-
- return input;
- };
-
- // Creates red, green and blue inputs
- rgbInputs = [
- createSliderInput("Red"),
- createSliderInput("Green"),
- createSliderInput("Blue"),
- ];
-
- slidersElement.appendChild(slidersBody);
-
- // Element that prints the current color
- var slidersResultColor = document.createElement("div");
- slidersResultColor.className = "jcolor-sliders-final-color";
-
- var resultElement = document.createElement("div");
- resultElement.style.visibility = "hidden";
- resultElement.innerText = "a";
- slidersResultColor.appendChild(resultElement);
-
- // Update the element that prints the current color
- var updateResult = function () {
- var resultColor = rgbToHex(
- parseInt(rgbInputs[0].value),
- parseInt(rgbInputs[1].value),
- parseInt(rgbInputs[2].value)
- );
-
- resultElement.innerText = resultColor;
- resultElement.style.color = resultColor;
- resultElement.style.removeProperty("visibility");
-
- slidersResult = resultColor;
- };
-
- // Apply the update function to color inputs
- rgbInputs.forEach(function (rgbInput) {
- rgbInput.addEventListener("input", function () {
- updateResult();
- changeInputColors();
- });
- });
-
- slidersElement.appendChild(slidersResultColor);
-
- return slidersElement;
- };
-
- var init = function () {
- // Initial options
- obj.setOptions(options);
-
- // Add a proper input tag when the element is an input
- if (el.tagName == "INPUT") {
- el.classList.add("jcolor-input");
- el.readOnly = true;
- }
-
- // Table container
- container = document.createElement("div");
- container.className = "jcolor";
-
- // Table container
- backdrop = document.createElement("div");
- backdrop.className = "jcolor-backdrop";
- container.appendChild(backdrop);
-
- // Content
- content = document.createElement("div");
- content.className = "jcolor-content";
-
- // Controls
- var controls = document.createElement("div");
- controls.className = "jcolor-controls";
- content.appendChild(controls);
-
- // Reset button
- resetButton = document.createElement("div");
- resetButton.className = "jcolor-reset";
- resetButton.innerHTML = obj.options.resetLabel;
- controls.appendChild(resetButton);
-
- // Close button
- closeButton = document.createElement("div");
- closeButton.className = "jcolor-close";
- closeButton.innerHTML = obj.options.doneLabel;
- controls.appendChild(closeButton);
-
- // Element that will be used to create the tabs
- tabs = document.createElement("div");
- content.appendChild(tabs);
-
- // Starts the jSuites tabs component
- jsuitesTabs = jSuites.tabs(tabs, {
- animation: true,
- data: [
- {
- title: "Grid",
- contentElement: table(),
- },
- {
- title: "Spectrum",
- contentElement: hsl(),
- },
- {
- title: "Sliders",
- contentElement: sliders(),
- },
- ],
- onchange: function (element, instance, index) {
- if (index === 1) {
- resizeCanvas();
- } else {
- var color = slidersResult !== "" ? slidersResult : obj.getValue();
-
- if (index === 2 && color) {
- var rgb = HexToRgb(color);
-
- rgbInputs.forEach(function (rgbInput, index) {
- rgbInput.value = rgb[index];
- rgbInput.dispatchEvent(new Event("input"));
- });
- }
- }
- },
- palette: "modern",
- });
-
- container.appendChild(content);
-
- // Insert picker after the element
- if (el.tagName == "INPUT") {
- el.parentNode.insertBefore(container, el.nextSibling);
- } else {
- el.appendChild(container);
- }
-
- container.addEventListener("click", function (e) {
- if (e.target.tagName == "TD") {
- var value = e.target.getAttribute("data-value");
- if (value) {
- obj.setValue(value);
- }
- } else if (e.target.classList.contains("jcolor-reset")) {
- obj.setValue("");
- obj.close();
- } else if (e.target.classList.contains("jcolor-close")) {
- if (jsuitesTabs.getActive() > 0) {
- obj.setValue(slidersResult);
- }
- obj.close();
- } else if (e.target.classList.contains("jcolor-backdrop")) {
- obj.close();
- } else {
- obj.open();
- }
- });
-
- /**
- * If element is focus open the picker
- */
- el.addEventListener("mouseup", function (e) {
- obj.open();
- });
-
- // If the picker is open on the spectrum tab, it changes the canvas size when the window size is changed
- window.addEventListener("resize", function () {
- if (
- container.classList.contains("jcolor-focus") &&
- jsuitesTabs.getActive() == 1
- ) {
- resizeCanvas();
- }
- });
-
- // Default opened
- if (obj.options.opened == true) {
- obj.open();
- }
-
- // Change
- el.change = obj.setValue;
-
- // Global generic value handler
- el.val = function (val) {
- if (val === undefined) {
- return obj.getValue();
- } else {
- obj.setValue(val);
- }
- };
-
- // Keep object available from the node
- el.color = obj;
-
- // Container shortcut
- container.color = obj;
- };
-
- obj.toHex = function (rgb) {
- var hex = function (x) {
- return ("0" + parseInt(x).toString(16)).slice(-2);
- };
- if (/^#[0-9A-F]{6}$/i.test(rgb)) {
- return rgb;
- } else {
- rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
- return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
- }
- };
-
- init();
-
- return obj;
- };
-
- jSuites.contextmenu = function (el, options) {
- // New instance
- var obj = { type: "contextmenu" };
- obj.options = {};
-
- // Default configuration
- var defaults = {
- items: null,
- onclick: null,
- };
-
- // Loop through our object
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- obj.options[property] = defaults[property];
- }
- }
-
- // Class definition
- el.classList.add("jcontextmenu");
-
- /**
- * Open contextmenu
- */
- obj.open = function (e, items) {
- if (items) {
- // Update content
- obj.options.items = items;
- // Create items
- obj.create(items);
- }
-
- // Close current contextmenu
- if (jSuites.contextmenu.current) {
- jSuites.contextmenu.current.close();
- }
-
- // Add to the opened components monitor
- jSuites.tracking(obj, true);
-
- // Show context menu
- el.classList.add("jcontextmenu-focus");
-
- // Current
- jSuites.contextmenu.current = obj;
-
- // Coordinates
- if (
- (obj.options.items && obj.options.items.length > 0) ||
- el.children.length
- ) {
- if (e.target) {
- if (e.changedTouches && e.changedTouches[0]) {
- x = e.changedTouches[0].clientX;
- y = e.changedTouches[0].clientY;
- } else {
- var x = e.clientX;
- var y = e.clientY;
- }
- } else {
- var x = e.x;
- var y = e.y;
- }
-
- var rect = el.getBoundingClientRect();
-
- if (window.innerHeight < y + rect.height) {
- var h = y - rect.height;
- if (h < 0) {
- h = 0;
- }
- el.style.top = h + "px";
- } else {
- el.style.top = y + "px";
- }
-
- if (window.innerWidth < x + rect.width) {
- if (x - rect.width > 0) {
- el.style.left = x - rect.width + "px";
- } else {
- el.style.left = "10px";
- }
- } else {
- el.style.left = x + "px";
- }
- }
- };
-
- obj.isOpened = function () {
- return el.classList.contains("jcontextmenu-focus") ? true : false;
- };
-
- /**
- * Close menu
- */
- obj.close = function () {
- if (el.classList.contains("jcontextmenu-focus")) {
- el.classList.remove("jcontextmenu-focus");
- }
- jSuites.tracking(obj, false);
- };
-
- /**
- * Create items based on the declared objectd
- * @param {object} items - List of object
- */
- obj.create = function (items) {
- // Update content
- el.innerHTML = "";
-
- // Add header contextmenu
- var itemHeader = createHeader();
- el.appendChild(itemHeader);
-
- // Append items
- for (var i = 0; i < items.length; i++) {
- var itemContainer = createItemElement(items[i]);
- el.appendChild(itemContainer);
- }
- };
-
- /**
- * createHeader for context menu
- * @private
- * @returns {HTMLElement}
- */
- function createHeader() {
- var header = document.createElement("div");
- header.classList.add("header");
- header.addEventListener("click", function (e) {
- e.preventDefault();
- e.stopPropagation();
- });
- var title = document.createElement("a");
- title.classList.add("title");
- title.innerHTML = jSuites.translate("Menu");
-
- header.appendChild(title);
-
- var closeButton = document.createElement("a");
- closeButton.classList.add("close");
- closeButton.innerHTML = jSuites.translate("close");
- closeButton.addEventListener("click", function (e) {
- obj.close();
- });
-
- header.appendChild(closeButton);
-
- return header;
- }
-
- /**
- * Private function for create a new Item element
- * @param {type} item
- * @returns {jsuitesL#15.jSuites.contextmenu.createItemElement.itemContainer}
- */
- function createItemElement(item) {
- if (item.type && (item.type == "line" || item.type == "divisor")) {
- var itemContainer = document.createElement("hr");
- } else {
- var itemContainer = document.createElement("div");
- var itemText = document.createElement("a");
- itemText.innerHTML = item.title;
-
- if (item.tooltip) {
- itemContainer.setAttribute("title", item.tooltip);
- }
-
- if (item.icon) {
- itemContainer.setAttribute("data-icon", item.icon);
- }
-
- if (item.id) {
- itemContainer.id = item.id;
- }
-
- if (item.disabled) {
- itemContainer.className = "jcontextmenu-disabled";
- } else if (item.onclick) {
- itemContainer.method = item.onclick;
- itemContainer.addEventListener("mousedown", function (e) {
- e.preventDefault();
- });
- itemContainer.addEventListener("mouseup", function (e) {
- // Execute method
- this.method(this, e);
- });
- }
- itemContainer.appendChild(itemText);
-
- if (item.submenu) {
- var itemIconSubmenu = document.createElement("span");
- itemIconSubmenu.innerHTML = "►";
- itemContainer.appendChild(itemIconSubmenu);
- itemContainer.classList.add("jcontexthassubmenu");
- var el_submenu = document.createElement("div");
- // Class definition
- el_submenu.classList.add("jcontextmenu");
- // Focusable
- el_submenu.setAttribute("tabindex", "900");
-
- // Append items
- var submenu = item.submenu;
- for (var i = 0; i < submenu.length; i++) {
- var itemContainerSubMenu = createItemElement(submenu[i]);
- el_submenu.appendChild(itemContainerSubMenu);
- }
-
- itemContainer.appendChild(el_submenu);
- } else if (item.shortcut) {
- var itemShortCut = document.createElement("span");
- itemShortCut.innerHTML = item.shortcut;
- itemContainer.appendChild(itemShortCut);
- }
- }
- return itemContainer;
- }
-
- if (typeof obj.options.onclick == "function") {
- el.addEventListener("click", function (e) {
- obj.options.onclick(obj, e);
- });
- }
-
- // Create items
- if (obj.options.items) {
- obj.create(obj.options.items);
- }
-
- window.addEventListener("mousewheel", function () {
- obj.close();
- });
-
- el.contextmenu = obj;
-
- return obj;
- };
-
- jSuites.dropdown = function (el, options) {
- // Already created, update options
- if (el.dropdown) {
- return el.dropdown.setOptions(options, true);
- }
-
- // New instance
- var obj = { type: "dropdown" };
- obj.options = {};
-
- // Success
- var success = function (data, val) {
- // Set data
- if (data && data.length) {
- // Sort
- if (obj.options.sortResults !== false) {
- if (typeof obj.options.sortResults == "function") {
- data.sort(obj.options.sortResults);
- } else {
- data.sort(sortData);
- }
- }
-
- obj.setData(data);
- }
-
- // Onload method
- if (typeof obj.options.onload == "function") {
- obj.options.onload(el, obj, data, val);
- }
-
- // Set value
- if (val) {
- applyValue(val);
- }
-
- // Component value
- if (val === undefined || val === null) {
- obj.options.value = "";
- }
- el.value = obj.options.value;
-
- // Open dropdown
- if (obj.options.opened == true) {
- obj.open();
- }
- };
-
- // Default sort
- var sortData = function (itemA, itemB) {
- var testA, testB;
- if (typeof itemA == "string") {
- testA = itemA;
- } else {
- if (itemA.text) {
- testA = itemA.text;
- } else if (itemA.name) {
- testA = itemA.name;
- }
- }
-
- if (typeof itemB == "string") {
- testB = itemB;
- } else {
- if (itemB.text) {
- testB = itemB.text;
- } else if (itemB.name) {
- testB = itemB.name;
- }
- }
-
- if (typeof testA == "string" || typeof testB == "string") {
- if (typeof testA != "string") {
- testA = "" + testA;
- }
- if (typeof testB != "string") {
- testB = "" + testB;
- }
- return testA.localeCompare(testB);
- } else {
- return testA - testB;
- }
- };
-
- /**
- * Reset the options for the dropdown
- */
- var resetValue = function () {
- // Reset value container
- obj.value = {};
- // Remove selected
- for (var i = 0; i < obj.items.length; i++) {
- if (obj.items[i].selected == true) {
- if (obj.items[i].element) {
- obj.items[i].element.classList.remove("jdropdown-selected");
- }
- obj.items[i].selected = null;
- }
- }
- // Reset options
- obj.options.value = "";
- };
-
- /**
- * Apply values to the dropdown
- */
- var applyValue = function (values) {
- // Reset the current values
- resetValue();
-
- // Read values
- if (values !== null) {
- if (!values) {
- if (typeof obj.value[""] !== "undefined") {
- obj.value[""] = "";
- }
- } else {
- if (!Array.isArray(values)) {
- values = ("" + values).split(";");
- }
- for (var i = 0; i < values.length; i++) {
- obj.value[values[i]] = "";
- }
- }
- }
-
- // Update the DOM
- for (var i = 0; i < obj.items.length; i++) {
- if (typeof obj.value[Value(i)] !== "undefined") {
- if (obj.items[i].element) {
- obj.items[i].element.classList.add("jdropdown-selected");
- }
- obj.items[i].selected = true;
-
- // Keep label
- obj.value[Value(i)] = Text(i);
- }
- }
-
- // Global value
- obj.options.value = Object.keys(obj.value).join(";");
-
- // Update labels
- obj.header.value = obj.getText();
- };
-
- // Get the value of one item
- var Value = function (k, v) {
- // Legacy purposes
- if (!obj.options.format) {
- var property = "value";
- } else {
- var property = "id";
- }
-
- if (obj.items[k]) {
- if (v !== undefined) {
- return (obj.items[k].data[property] = v);
- } else {
- return obj.items[k].data[property];
- }
- }
-
- return "";
- };
-
- // Get the label of one item
- var Text = function (k, v) {
- // Legacy purposes
- if (!obj.options.format) {
- var property = "text";
- } else {
- var property = "name";
- }
-
- if (obj.items[k]) {
- if (v !== undefined) {
- return (obj.items[k].data[property] = v);
- } else {
- return obj.items[k].data[property];
- }
- }
-
- return "";
- };
-
- var getValue = function () {
- return Object.keys(obj.value);
- };
-
- var getText = function () {
- var data = [];
- var k = Object.keys(obj.value);
- for (var i = 0; i < k.length; i++) {
- data.push(obj.value[k[i]]);
- }
- return data;
- };
-
- obj.setOptions = function (options, reset) {
- if (!options) {
- options = {};
- }
-
- // Default configuration
- var defaults = {
- url: null,
- data: [],
- format: 0,
- multiple: false,
- autocomplete: false,
- remoteSearch: false,
- lazyLoading: false,
- type: null,
- width: null,
- maxWidth: null,
- opened: false,
- value: null,
- placeholder: "",
- newOptions: false,
- position: false,
- onchange: null,
- onload: null,
- onopen: null,
- onclose: null,
- onfocus: null,
- onblur: null,
- oninsert: null,
- onbeforeinsert: null,
- sortResults: false,
- autofocus: false,
- };
-
- // Loop through our object
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- if (typeof obj.options[property] == "undefined" || reset === true) {
- obj.options[property] = defaults[property];
- }
- }
- }
-
- // Force autocomplete search
- if (
- obj.options.remoteSearch == true ||
- obj.options.type === "searchbar"
- ) {
- obj.options.autocomplete = true;
- }
-
- // New options
- if (obj.options.newOptions == true) {
- obj.header.classList.add("jdropdown-add");
- } else {
- obj.header.classList.remove("jdropdown-add");
- }
-
- // Autocomplete
- if (obj.options.autocomplete == true) {
- obj.header.removeAttribute("readonly");
- } else {
- obj.header.setAttribute("readonly", "readonly");
- }
-
- // Place holder
- if (obj.options.placeholder) {
- obj.header.setAttribute("placeholder", obj.options.placeholder);
- } else {
- obj.header.removeAttribute("placeholder");
- }
-
- // Remove specific dropdown typing to add again
- el.classList.remove("jdropdown-searchbar");
- el.classList.remove("jdropdown-picker");
- el.classList.remove("jdropdown-list");
-
- if (obj.options.type == "searchbar") {
- el.classList.add("jdropdown-searchbar");
- } else if (obj.options.type == "list") {
- el.classList.add("jdropdown-list");
- } else if (obj.options.type == "picker") {
- el.classList.add("jdropdown-picker");
- } else {
- if (jSuites.getWindowWidth() < 800) {
- if (obj.options.autocomplete) {
- el.classList.add("jdropdown-searchbar");
- obj.options.type = "searchbar";
- } else {
- el.classList.add("jdropdown-picker");
- obj.options.type = "picker";
- }
- } else {
- if (obj.options.width) {
- el.style.width = obj.options.width;
- el.style.minWidth = obj.options.width;
- } else {
- el.style.removeProperty("width");
- el.style.removeProperty("min-width");
- }
-
- el.classList.add("jdropdown-default");
- obj.options.type = "default";
- }
- }
-
- // Close button
- if (obj.options.type == "searchbar") {
- containerHeader.appendChild(closeButton);
- } else {
- container.insertBefore(closeButton, container.firstChild);
- }
-
- // Load the content
- if (obj.options.url && !options.data) {
- jSuites.ajax({
- url: obj.options.url,
- method: "GET",
- dataType: "json",
- success: function (data) {
- if (data) {
- success(data, obj.options.value);
- }
- },
- });
- } else {
- success(obj.options.data, obj.options.value);
- }
-
- // Return the instance
- return obj;
- };
-
- // Helpers
- var containerHeader = null;
- var container = null;
- var content = null;
- var closeButton = null;
- var resetButton = null;
- var backdrop = null;
-
- var keyTimer = null;
-
- /**
- * Init dropdown
- */
- var init = function () {
- // Do not accept null
- if (!options) {
- options = {};
- }
-
- // If the element is a SELECT tag, create a configuration object
- if (el.tagName == "SELECT") {
- var ret = jSuites.dropdown.extractFromDom(el, options);
- el = ret.el;
- options = ret.options;
- }
-
- // Place holder
- if (!options.placeholder && el.getAttribute("placeholder")) {
- options.placeholder = el.getAttribute("placeholder");
- }
-
- // Value container
- obj.value = {};
- // Containers
- obj.items = [];
- obj.groups = [];
- // Search options
- obj.search = "";
- obj.results = null;
-
- // Create dropdown
- el.classList.add("jdropdown");
-
- // Header container
- containerHeader = document.createElement("div");
- containerHeader.className = "jdropdown-container-header";
-
- // Header
- obj.header = document.createElement("input");
- obj.header.className = "jdropdown-header";
- obj.header.type = "text";
- obj.header.setAttribute("autocomplete", "off");
- obj.header.onfocus = function () {
- if (typeof obj.options.onfocus == "function") {
- obj.options.onfocus(el);
- }
- };
-
- obj.header.onblur = function () {
- if (typeof obj.options.onblur == "function") {
- obj.options.onblur(el);
- }
- };
-
- obj.header.onkeyup = function (e) {
- if (obj.options.autocomplete == true && !keyTimer) {
- if (obj.search != obj.header.value.trim()) {
- keyTimer = setTimeout(function () {
- obj.find(obj.header.value.trim());
- keyTimer = null;
- }, 400);
- }
-
- if (!el.classList.contains("jdropdown-focus")) {
- obj.open();
- }
- } else {
- if (!obj.options.autocomplete) {
- obj.next(e.key);
- }
- }
- };
-
- // Global controls
- if (!jSuites.dropdown.hasEvents) {
- // Execute only one time
- jSuites.dropdown.hasEvents = true;
- // Enter and Esc
- document.addEventListener("keydown", jSuites.dropdown.keydown);
- }
-
- // Container
- container = document.createElement("div");
- container.className = "jdropdown-container";
-
- // Dropdown content
- content = document.createElement("div");
- content.className = "jdropdown-content";
-
- // Close button
- closeButton = document.createElement("div");
- closeButton.className = "jdropdown-close";
- closeButton.innerHTML = "Done";
-
- // Reset button
- resetButton = document.createElement("div");
- resetButton.className = "jdropdown-reset";
- resetButton.innerHTML = "x";
- resetButton.onclick = function () {
- obj.reset();
- obj.close();
- };
-
- // Create backdrop
- backdrop = document.createElement("div");
- backdrop.className = "jdropdown-backdrop";
-
- // Append elements
- containerHeader.appendChild(obj.header);
-
- container.appendChild(content);
- el.appendChild(containerHeader);
- el.appendChild(container);
- el.appendChild(backdrop);
-
- // Set the otiptions
- obj.setOptions(options);
-
- if ("ontouchsend" in document.documentElement === true) {
- el.addEventListener("touchsend", jSuites.dropdown.mouseup);
- } else {
- el.addEventListener("mouseup", jSuites.dropdown.mouseup);
- }
-
- // Lazyloading
- if (obj.options.lazyLoading == true) {
- jSuites.lazyLoading(content, {
- loadUp: obj.loadUp,
- loadDown: obj.loadDown,
- });
- }
-
- content.onwheel = function (e) {
- e.stopPropagation();
- };
-
- // Change method
- el.change = obj.setValue;
-
- // Global generic value handler
- el.val = function (val) {
- if (val === undefined) {
- return obj.getValue(obj.options.multiple ? true : false);
- } else {
- obj.setValue(val);
- }
- };
-
- // Keep object available from the node
- el.dropdown = obj;
- };
-
- /**
- * Get the current remote source of data URL
- */
- obj.getUrl = function () {
- return obj.options.url;
- };
-
- /**
- * Set the new data from a remote source
- * @param {string} url - url from the remote source
- * @param {function} callback - callback when the data is loaded
- */
- obj.setUrl = function (url, callback) {
- obj.options.url = url;
-
- jSuites.ajax({
- url: obj.options.url,
- method: "GET",
- dataType: "json",
- success: function (data) {
- obj.setData(data);
- // Callback
- if (typeof callback == "function") {
- callback(obj);
- }
- },
- });
- };
-
- /**
- * Set ID for one item
- */
- obj.setId = function (item, v) {
- // Legacy purposes
- if (!obj.options.format) {
- var property = "value";
- } else {
- var property = "id";
- }
-
- if (typeof item == "object") {
- item[property] = v;
- } else {
- obj.items[item].data[property] = v;
- }
- };
-
- /**
- * Add a new item
- * @param {string} title - title of the new item
- * @param {string} id - value/id of the new item
- */
- obj.add = function (title, id) {
- if (!title) {
- var current = obj.options.autocomplete == true ? obj.header.value : "";
- var title = prompt(jSuites.translate("Add A New Option"), current);
- if (!title) {
- return false;
- }
- }
-
- // Id
- if (!id) {
- id = jSuites.guid();
- }
-
- // Create new item
- if (!obj.options.format) {
- var item = {
- value: id,
- text: title,
- };
- } else {
- var item = {
- id: id,
- name: title,
- };
- }
-
- // Callback
- if (typeof obj.options.onbeforeinsert == "function") {
- var ret = obj.options.onbeforeinsert(obj, item);
- if (ret === false) {
- return false;
- } else if (ret) {
- item = ret;
- }
- }
-
- // Add item to the main list
- obj.options.data.push(item);
-
- // Create DOM
- var newItem = obj.createItem(item);
-
- // Append DOM to the list
- content.appendChild(newItem.element);
-
- // Callback
- if (typeof obj.options.oninsert == "function") {
- obj.options.oninsert(obj, item, newItem);
- }
-
- // Show content
- if (content.style.display == "none") {
- content.style.display = "";
- }
-
- // Search?
- if (obj.results) {
- obj.results.push(newItem);
- }
-
- return item;
- };
-
- /**
- * Create a new item
- */
- obj.createItem = function (data, group, groupName) {
- // Keep the correct source of data
- if (!obj.options.format) {
- if (!data.value && data.id !== undefined) {
- data.value = data.id;
- //delete data.id;
- }
- if (!data.text && data.name !== undefined) {
- data.text = data.name;
- //delete data.name;
- }
- } else {
- if (!data.id && data.value !== undefined) {
- data.id = data.value;
- //delete data.value;
- }
- if (!data.name && data.text !== undefined) {
- data.name = data.text;
- //delete data.text;
- }
- }
-
- // Create item
- var item = {};
- item.element = document.createElement("div");
- item.element.className = "jdropdown-item";
- item.element.indexValue = obj.items.length;
- item.data = data;
-
- // Groupd DOM
- if (group) {
- item.group = group;
- }
-
- // Id
- if (data.id) {
- item.element.setAttribute("id", data.id);
- }
-
- // Disabled
- if (data.disabled == true) {
- item.element.setAttribute("data-disabled", true);
- }
-
- // Tooltip
- if (data.tooltip) {
- item.element.setAttribute("title", data.tooltip);
- }
-
- // Image
- if (data.image) {
- var image = document.createElement("img");
- image.className = "jdropdown-image";
- image.src = data.image;
- if (!data.title) {
- image.classList.add("jdropdown-image-small");
- }
- item.element.appendChild(image);
- } else if (data.icon) {
- var icon = document.createElement("span");
- icon.className = "jdropdown-icon material-icons";
- icon.innerText = data.icon;
- if (!data.title) {
- icon.classList.add("jdropdown-icon-small");
- }
- if (data.color) {
- icon.style.color = data.color;
- }
- item.element.appendChild(icon);
- } else if (data.color) {
- var color = document.createElement("div");
- color.className = "jdropdown-color";
- color.style.backgroundColor = data.color;
- item.element.appendChild(color);
- }
-
- // Set content
- if (!obj.options.format) {
- var text = data.text;
- } else {
- var text = data.name;
- }
-
- var node = document.createElement("div");
- node.className = "jdropdown-description";
- node.innerHTML = text || " ";
-
- // Title
- if (data.title) {
- var title = document.createElement("div");
- title.className = "jdropdown-title";
- title.innerText = data.title;
- node.appendChild(title);
- }
-
- // Set content
- if (!obj.options.format) {
- var val = data.value;
- } else {
- var val = data.id;
- }
-
- // Value
- if (obj.value[val]) {
- item.element.classList.add("jdropdown-selected");
- item.selected = true;
- }
-
- // Keep DOM accessible
- obj.items.push(item);
-
- // Add node to item
- item.element.appendChild(node);
-
- return item;
- };
-
- obj.appendData = function (data) {
- // Create elements
- if (data.length) {
- // Helpers
- var items = [];
- var groups = [];
-
- // Prepare data
- for (var i = 0; i < data.length; i++) {
- // Process groups
- if (data[i].group) {
- if (!groups[data[i].group]) {
- groups[data[i].group] = [];
- }
- groups[data[i].group].push(i);
- } else {
- items.push(i);
- }
- }
-
- // Number of items counter
- var counter = 0;
-
- // Groups
- var groupNames = Object.keys(groups);
-
- // Append groups in case exists
- if (groupNames.length > 0) {
- for (var i = 0; i < groupNames.length; i++) {
- // Group container
- var group = document.createElement("div");
- group.className = "jdropdown-group";
- // Group name
- var groupName = document.createElement("div");
- groupName.className = "jdropdown-group-name";
- groupName.innerHTML = groupNames[i];
- // Group arrow
- var groupArrow = document.createElement("i");
- groupArrow.className =
- "jdropdown-group-arrow jdropdown-group-arrow-down";
- groupName.appendChild(groupArrow);
- // Group items
- var groupContent = document.createElement("div");
- groupContent.className = "jdropdown-group-items";
- for (var j = 0; j < groups[groupNames[i]].length; j++) {
- var item = obj.createItem(
- data[groups[groupNames[i]][j]],
- group,
- groupNames[i]
- );
-
- if (obj.options.lazyLoading == false || counter < 200) {
- groupContent.appendChild(item.element);
- counter++;
- }
- }
- // Group itens
- group.appendChild(groupName);
- group.appendChild(groupContent);
- // Keep group DOM
- obj.groups.push(group);
- // Only add to the screen if children on the group
- if (groupContent.children.length > 0) {
- // Add DOM to the content
- content.appendChild(group);
- }
- }
- }
-
- if (items.length) {
- for (var i = 0; i < items.length; i++) {
- var item = obj.createItem(data[items[i]]);
- if (obj.options.lazyLoading == false || counter < 200) {
- content.appendChild(item.element);
- counter++;
- }
- }
- }
- }
- };
-
- obj.setData = function (data) {
- // Reset current value
- resetValue();
-
- // Make sure the content container is blank
- content.innerHTML = "";
-
- // Reset
- obj.header.value = "";
-
- // Reset items and values
- obj.items = [];
-
- // Prepare data
- if (data && data.length) {
- for (var i = 0; i < data.length; i++) {
- // Compatibility
- if (typeof data[i] != "object") {
- // Correct format
- if (!obj.options.format) {
- data[i] = {
- value: data[i],
- text: data[i],
- };
- } else {
- data[i] = {
- id: data[i],
- name: data[i],
- };
- }
- }
- }
-
- // Append data
- obj.appendData(data);
-
- // Update data
- obj.options.data = data;
- } else {
- // Update data
- obj.options.data = [];
- }
-
- obj.close();
- };
-
- obj.getData = function () {
- return obj.options.data;
- };
-
- /**
- * Get position of the item
- */
- obj.getPosition = function (val) {
- for (var i = 0; i < obj.items.length; i++) {
- if (Value(i) == val) {
- return i;
- }
- }
- return false;
- };
-
- /**
- * Get dropdown current text
- */
- obj.getText = function (asArray) {
- // Get value
- var v = getText();
- // Return value
- if (asArray) {
- return v;
- } else {
- return v.join("; ");
- }
- };
-
- /**
- * Get dropdown current value
- */
- obj.getValue = function (asArray) {
- // Get value
- var v = getValue();
- // Return value
- if (asArray) {
- return v;
- } else {
- return v.join(";");
- }
- };
-
- /**
- * Change event
- */
- var change = function (oldValue) {
- // Lemonade JS
- if (el.value != obj.options.value) {
- el.value = obj.options.value;
- if (typeof el.oninput == "function") {
- el.oninput({
- type: "input",
- target: el,
- value: el.value,
- });
- }
- }
-
- // Events
- if (typeof obj.options.onchange == "function") {
- obj.options.onchange(el, obj, oldValue, obj.options.value);
- }
- };
-
- /**
- * Set value
- */
- obj.setValue = function (newValue) {
- // Current value
- var oldValue = obj.getValue();
- // New value
- if (Array.isArray(newValue)) {
- newValue = newValue.join(";");
- }
-
- if (oldValue !== newValue) {
- // Set value
- applyValue(newValue);
-
- // Change
- change(oldValue);
- }
- };
-
- obj.resetSelected = function () {
- obj.setValue(null);
- };
-
- obj.selectIndex = function (index, force) {
- // Make sure is a number
- var index = parseInt(index);
-
- // Only select those existing elements
- if (
- obj.items &&
- obj.items[index] &&
- (force === true || obj.items[index].data.disabled !== true)
- ) {
- // Reset cursor to a new position
- obj.setCursor(index, false);
-
- // Behaviour
- if (!obj.options.multiple) {
- // Update value
- if (obj.items[index].selected) {
- obj.setValue(null);
- } else {
- obj.setValue(Value(index));
- }
-
- // Close component
- obj.close();
- } else {
- // Old value
- var oldValue = obj.options.value;
-
- // Toggle option
- if (obj.items[index].selected) {
- obj.items[index].element.classList.remove("jdropdown-selected");
- obj.items[index].selected = false;
-
- delete obj.value[Value(index)];
- } else {
- // Select element
- obj.items[index].element.classList.add("jdropdown-selected");
- obj.items[index].selected = true;
-
- // Set value
- obj.value[Value(index)] = Text(index);
- }
-
- // Global value
- obj.options.value = Object.keys(obj.value).join(";");
-
- // Update labels for multiple dropdown
- if (obj.options.autocomplete == false) {
- obj.header.value = getText().join("; ");
- }
-
- // Events
- change(oldValue);
- }
- }
- };
-
- obj.selectItem = function (item) {
- obj.selectIndex(item.indexValue);
- };
-
- var exists = function (k, result) {
- for (var j = 0; j < result.length; j++) {
- if (!obj.options.format) {
- if (result[j].value == k) {
- return true;
- }
- } else {
- if (result[j].id == k) {
- return true;
- }
- }
- }
- return false;
- };
-
- obj.find = function (str) {
- if (obj.search == str.trim()) {
- return false;
- }
-
- // Search term
- obj.search = str;
-
- // Reset index
- obj.setCursor();
-
- // Remove nodes from all groups
- if (obj.groups.length) {
- for (var i = 0; i < obj.groups.length; i++) {
- obj.groups[i].lastChild.innerHTML = "";
- }
- }
-
- // Remove all nodes
- content.innerHTML = "";
-
- // Remove current items in the remote search
- if (obj.options.remoteSearch == true) {
- // Reset results
- obj.results = null;
- // URL
- var url =
- obj.options.url +
- (obj.options.url.indexOf("?") > 0 ? "&" : "?") +
- "q=" +
- str;
- // Remote search
- jSuites.ajax({
- url: url,
- method: "GET",
- dataType: "json",
- success: function (result) {
- // Reset items
- obj.items = [];
-
- // Add the current selected items to the results in case they are not there
- var current = Object.keys(obj.value);
- if (current.length) {
- for (var i = 0; i < current.length; i++) {
- if (!exists(current[i], result)) {
- if (!obj.options.format) {
- result.unshift({
- value: current[i],
- text: obj.value[current[i]],
- });
- } else {
- result.unshift({
- id: current[i],
- name: obj.value[current[i]],
- });
- }
- }
- }
- }
- // Append data
- obj.appendData(result);
- // Show or hide results
- if (!result.length) {
- content.style.display = "none";
- } else {
- content.style.display = "";
- }
- },
- });
- } else {
- // Search terms
- str = new RegExp(str, "gi");
-
- // Reset search
- var results = [];
-
- // Append options
- for (var i = 0; i < obj.items.length; i++) {
- // Item label
- var label = Text(i);
- // Item title
- var title = obj.items[i].data.title || "";
- // Group name
- var groupName = obj.items[i].data.group || "";
- // Synonym
- var synonym = obj.items[i].data.synonym || "";
- if (synonym) {
- synonym = synonym.join(" ");
- }
-
- if (
- str == null ||
- obj.items[i].selected == true ||
- label.match(str) ||
- title.match(str) ||
- groupName.match(str) ||
- synonym.match(str)
- ) {
- results.push(obj.items[i]);
- }
- }
-
- if (!results.length) {
- content.style.display = "none";
-
- // Results
- obj.results = null;
- } else {
- content.style.display = "";
-
- // Results
- obj.results = results;
-
- // Show 200 items at once
- var number = results.length || 0;
-
- // Lazyloading
- if (obj.options.lazyLoading == true && number > 200) {
- number = 200;
- }
-
- for (var i = 0; i < number; i++) {
- if (obj.results[i].group) {
- if (!obj.results[i].group.parentNode) {
- content.appendChild(obj.results[i].group);
- }
- obj.results[i].group.lastChild.appendChild(
- obj.results[i].element
- );
- } else {
- content.appendChild(obj.results[i].element);
- }
- }
- }
- }
-
- // Auto focus
- if (obj.options.autofocus == true) {
- obj.first();
- }
- };
-
- obj.open = function () {
- // Focus
- if (!el.classList.contains("jdropdown-focus")) {
- // Current dropdown
- jSuites.dropdown.current = obj;
-
- // Start tracking
- jSuites.tracking(obj, true);
-
- // Add focus
- el.classList.add("jdropdown-focus");
-
- // Animation
- if (jSuites.getWindowWidth() < 800) {
- if (obj.options.type == null || obj.options.type == "picker") {
- jSuites.animation.slideBottom(container, 1);
- }
- }
-
- // Filter
- if (obj.options.autocomplete == true) {
- obj.header.value = obj.search;
- obj.header.focus();
- }
-
- // Set cursor for the first or first selected element
- var k = getValue();
- if (k[0]) {
- var cursor = obj.getPosition(k[0]);
- if (cursor !== false) {
- obj.setCursor(cursor);
- }
- }
-
- // Container Size
- if (!obj.options.type || obj.options.type == "default") {
- var rect = el.getBoundingClientRect();
- var rectContainer = container.getBoundingClientRect();
-
- if (obj.options.position) {
- container.style.position = "fixed";
- if (window.innerHeight < rect.bottom + rectContainer.height) {
- container.style.top = "";
- container.style.bottom = window.innerHeight - rect.top + 1 + "px";
- } else {
- container.style.top = rect.bottom + "px";
- container.style.bottom = "";
- }
- container.style.left = rect.left + "px";
- } else {
- if (window.innerHeight < rect.bottom + rectContainer.height) {
- container.style.top = "";
- container.style.bottom = rect.height + 1 + "px";
- } else {
- container.style.top = "";
- container.style.bottom = "";
- }
- }
-
- container.style.minWidth = rect.width + "px";
-
- if (obj.options.maxWidth) {
- container.style.maxWidth = obj.options.maxWidth;
- }
-
- if (!obj.items.length && obj.options.autocomplete == true) {
- content.style.display = "none";
- } else {
- content.style.display = "";
- }
- }
- }
-
- // Events
- if (typeof obj.options.onopen == "function") {
- obj.options.onopen(el);
- }
- };
-
- obj.close = function (ignoreEvents) {
- if (el.classList.contains("jdropdown-focus")) {
- // Update labels
- obj.header.value = obj.getText();
- // Remove cursor
- obj.setCursor();
- // Events
- if (!ignoreEvents && typeof obj.options.onclose == "function") {
- obj.options.onclose(el);
- }
- // Blur
- if (obj.header.blur) {
- obj.header.blur();
- }
- // Remove focus
- el.classList.remove("jdropdown-focus");
- // Start tracking
- jSuites.tracking(obj, false);
- // Current dropdown
- jSuites.dropdown.current = null;
- }
-
- return obj.getValue();
- };
-
- /**
- * Set cursor
- */
- obj.setCursor = function (index, setPosition) {
- // Remove current cursor
- if (obj.currentIndex != null) {
- // Remove visual cursor
- if (obj.items && obj.items[obj.currentIndex]) {
- obj.items[obj.currentIndex].element.classList.remove(
- "jdropdown-cursor"
- );
- }
- }
-
- if (index == undefined) {
- obj.currentIndex = null;
- } else {
- index = parseInt(index);
-
- // Cursor only for visible items
- if (obj.items[index].element.parentNode) {
- obj.items[index].element.classList.add("jdropdown-cursor");
- obj.currentIndex = index;
-
- // Update scroll to the cursor element
- if (setPosition !== false && obj.items[obj.currentIndex].element) {
- var container = content.scrollTop;
- var element = obj.items[obj.currentIndex].element;
- content.scrollTop =
- element.offsetTop - element.scrollTop + element.clientTop - 95;
- }
- }
- }
- };
-
- // Compatibility
- obj.resetCursor = obj.setCursor;
- obj.updateCursor = obj.setCursor;
-
- /**
- * Reset cursor and selected items
- */
- obj.reset = function () {
- // Reset cursor
- obj.setCursor();
-
- // Reset selected
- obj.setValue(null);
- };
-
- /**
- * First available item
- */
- obj.first = function () {
- if (obj.options.lazyLoading === true) {
- obj.loadFirst();
- }
-
- var items = content.querySelectorAll(".jdropdown-item");
- if (items.length) {
- var newIndex = items[0].indexValue;
- obj.setCursor(newIndex);
- }
- };
-
- /**
- * Last available item
- */
- obj.last = function () {
- if (obj.options.lazyLoading === true) {
- obj.loadLast();
- }
-
- var items = content.querySelectorAll(".jdropdown-item");
- if (items.length) {
- var newIndex = items[items.length - 1].indexValue;
- obj.setCursor(newIndex);
- }
- };
-
- obj.next = function (letter) {
- var newIndex = null;
-
- if (letter) {
- if (letter.length == 1) {
- // Current index
- var current = obj.currentIndex || -1;
- // Letter
- letter = letter.toLowerCase();
-
- var e = null;
- var l = null;
- var items = content.querySelectorAll(".jdropdown-item");
- if (items.length) {
- for (var i = 0; i < items.length; i++) {
- if (items[i].indexValue > current) {
- if ((e = obj.items[items[i].indexValue])) {
- if ((l = e.element.innerText[0])) {
- l = l.toLowerCase();
- if (letter == l) {
- newIndex = items[i].indexValue;
- break;
- }
- }
- }
- }
- }
- obj.setCursor(newIndex);
- }
- }
- } else {
- if (obj.currentIndex == undefined || obj.currentIndex == null) {
- obj.first();
- } else {
- var element = obj.items[obj.currentIndex].element;
-
- var next = element.nextElementSibling;
- if (next) {
- if (next.classList.contains("jdropdown-group")) {
- next = next.lastChild.firstChild;
- }
- newIndex = next.indexValue;
- } else {
- if (
- element.parentNode.classList.contains("jdropdown-group-items")
- ) {
- if ((next = element.parentNode.parentNode.nextElementSibling)) {
- if (next.classList.contains("jdropdown-group")) {
- next = next.lastChild.firstChild;
- } else if (next.classList.contains("jdropdown-item")) {
- newIndex = next.indexValue;
- } else {
- next = null;
- }
- }
-
- if (next) {
- newIndex = next.indexValue;
- }
- }
- }
-
- if (newIndex !== null) {
- obj.setCursor(newIndex);
- }
- }
- }
- };
-
- obj.prev = function () {
- var newIndex = null;
-
- if (obj.currentIndex === null) {
- obj.first();
- } else {
- var element = obj.items[obj.currentIndex].element;
-
- var prev = element.previousElementSibling;
- if (prev) {
- if (prev.classList.contains("jdropdown-group")) {
- prev = prev.lastChild.lastChild;
- }
- newIndex = prev.indexValue;
- } else {
- if (element.parentNode.classList.contains("jdropdown-group-items")) {
- if ((prev = element.parentNode.parentNode.previousElementSibling)) {
- if (prev.classList.contains("jdropdown-group")) {
- prev = prev.lastChild.lastChild;
- } else if (prev.classList.contains("jdropdown-item")) {
- newIndex = prev.indexValue;
- } else {
- prev = null;
- }
- }
-
- if (prev) {
- newIndex = prev.indexValue;
- }
- }
- }
- }
-
- if (newIndex !== null) {
- obj.setCursor(newIndex);
- }
- };
-
- obj.loadFirst = function () {
- // Search
- if (obj.results) {
- var results = obj.results;
- } else {
- var results = obj.items;
- }
-
- // Show 200 items at once
- var number = results.length || 0;
-
- // Lazyloading
- if (obj.options.lazyLoading == true && number > 200) {
- number = 200;
- }
-
- // Reset container
- content.innerHTML = "";
-
- // First 200 items
- for (var i = 0; i < number; i++) {
- if (results[i].group) {
- if (!results[i].group.parentNode) {
- content.appendChild(results[i].group);
- }
- results[i].group.lastChild.appendChild(results[i].element);
- } else {
- content.appendChild(results[i].element);
- }
- }
-
- // Scroll go to the begin
- content.scrollTop = 0;
- };
-
- obj.loadLast = function () {
- // Search
- if (obj.results) {
- var results = obj.results;
- } else {
- var results = obj.items;
- }
-
- // Show first page
- var number = results.length;
-
- // Max 200 items
- if (number > 200) {
- number = number - 200;
-
- // Reset container
- content.innerHTML = "";
-
- // First 200 items
- for (var i = number; i < results.length; i++) {
- if (results[i].group) {
- if (!results[i].group.parentNode) {
- content.appendChild(results[i].group);
- }
- results[i].group.lastChild.appendChild(results[i].element);
- } else {
- content.appendChild(results[i].element);
- }
- }
-
- // Scroll go to the begin
- content.scrollTop = content.scrollHeight;
- }
- };
-
- obj.loadUp = function () {
- var test = false;
-
- // Search
- if (obj.results) {
- var results = obj.results;
- } else {
- var results = obj.items;
- }
-
- var items = content.querySelectorAll(".jdropdown-item");
- var fistItem = items[0].indexValue;
- fistItem = obj.items[fistItem];
- var index = results.indexOf(fistItem) - 1;
-
- if (index > 0) {
- var number = 0;
-
- while (index > 0 && results[index] && number < 200) {
- if (results[index].group) {
- if (!results[index].group.parentNode) {
- content.insertBefore(results[index].group, content.firstChild);
- }
- results[index].group.lastChild.insertBefore(
- results[index].element,
- results[index].group.lastChild.firstChild
- );
- } else {
- content.insertBefore(results[index].element, content.firstChild);
- }
-
- index--;
- number++;
- }
-
- // New item added
- test = true;
- }
-
- return test;
- };
-
- obj.loadDown = function () {
- var test = false;
-
- // Search
- if (obj.results) {
- var results = obj.results;
- } else {
- var results = obj.items;
- }
-
- var items = content.querySelectorAll(".jdropdown-item");
- var lastItem = items[items.length - 1].indexValue;
- lastItem = obj.items[lastItem];
- var index = results.indexOf(lastItem) + 1;
-
- if (index < results.length) {
- var number = 0;
- while (index < results.length && results[index] && number < 200) {
- if (results[index].group) {
- if (!results[index].group.parentNode) {
- content.appendChild(results[index].group);
- }
- results[index].group.lastChild.appendChild(results[index].element);
- } else {
- content.appendChild(results[index].element);
- }
-
- index++;
- number++;
- }
-
- // New item added
- test = true;
- }
-
- return test;
- };
-
- init();
-
- return obj;
- };
-
- jSuites.dropdown.keydown = function (e) {
- var dropdown = null;
- if ((dropdown = jSuites.dropdown.current)) {
- if (e.which == 13 || e.which == 9) {
- // enter or tab
- if (
- dropdown.header.value &&
- dropdown.currentIndex == null &&
- dropdown.options.newOptions
- ) {
- // if they typed something in, but it matched nothing, and newOptions are allowed, start that flow
- dropdown.add();
- } else {
- // Quick Select/Filter
- if (
- dropdown.currentIndex == null &&
- dropdown.options.autocomplete == true &&
- dropdown.header.value != ""
- ) {
- dropdown.find(dropdown.header.value);
- }
- dropdown.selectIndex(dropdown.currentIndex);
- }
- } else if (e.which == 38) {
- // up arrow
- if (dropdown.currentIndex == null) {
- dropdown.first();
- } else if (dropdown.currentIndex > 0) {
- dropdown.prev();
- }
- e.preventDefault();
- } else if (e.which == 40) {
- // down arrow
- if (dropdown.currentIndex == null) {
- dropdown.first();
- } else if (dropdown.currentIndex + 1 < dropdown.items.length) {
- dropdown.next();
- }
- e.preventDefault();
- } else if (e.which == 36) {
- dropdown.first();
- if (!e.target.classList.contains("jdropdown-header")) {
- e.preventDefault();
- }
- } else if (e.which == 35) {
- dropdown.last();
- if (!e.target.classList.contains("jdropdown-header")) {
- e.preventDefault();
- }
- } else if (e.which == 27) {
- dropdown.close();
- } else if (e.which == 33) {
- // page up
- if (dropdown.currentIndex == null) {
- dropdown.first();
- } else if (dropdown.currentIndex > 0) {
- for (var i = 0; i < 7; i++) {
- dropdown.prev();
- }
- }
- e.preventDefault();
- } else if (e.which == 34) {
- // page down
- if (dropdown.currentIndex == null) {
- dropdown.first();
- } else if (dropdown.currentIndex + 1 < dropdown.items.length) {
- for (var i = 0; i < 7; i++) {
- dropdown.next();
- }
- }
- e.preventDefault();
- }
- }
- };
-
- jSuites.dropdown.mouseup = function (e) {
- var element = jSuites.findElement(e.target, "jdropdown");
- if (element) {
- var dropdown = element.dropdown;
- if (e.target.classList.contains("jdropdown-header")) {
- if (
- element.classList.contains("jdropdown-focus") &&
- element.classList.contains("jdropdown-default")
- ) {
- var rect = element.getBoundingClientRect();
-
- if (e.changedTouches && e.changedTouches[0]) {
- var x = e.changedTouches[0].clientX;
- var y = e.changedTouches[0].clientY;
- } else {
- var x = e.clientX;
- var y = e.clientY;
- }
-
- if (rect.width - (x - rect.left) < 30) {
- if (e.target.classList.contains("jdropdown-add")) {
- dropdown.add();
- } else {
- dropdown.close();
- }
- } else {
- if (dropdown.options.autocomplete == false) {
- dropdown.close();
- }
- }
- } else {
- dropdown.open();
- }
- } else if (e.target.classList.contains("jdropdown-group-name")) {
- var items = e.target.nextSibling.children;
- if (e.target.nextSibling.style.display != "none") {
- for (var i = 0; i < items.length; i++) {
- if (items[i].style.display != "none") {
- dropdown.selectItem(items[i]);
- }
- }
- }
- } else if (e.target.classList.contains("jdropdown-group-arrow")) {
- if (e.target.classList.contains("jdropdown-group-arrow-down")) {
- e.target.classList.remove("jdropdown-group-arrow-down");
- e.target.classList.add("jdropdown-group-arrow-up");
- e.target.parentNode.nextSibling.style.display = "none";
- } else {
- e.target.classList.remove("jdropdown-group-arrow-up");
- e.target.classList.add("jdropdown-group-arrow-down");
- e.target.parentNode.nextSibling.style.display = "";
- }
- } else if (e.target.classList.contains("jdropdown-item")) {
- dropdown.selectItem(e.target);
- } else if (e.target.classList.contains("jdropdown-image")) {
- dropdown.selectItem(e.target.parentNode);
- } else if (e.target.classList.contains("jdropdown-description")) {
- dropdown.selectItem(e.target.parentNode);
- } else if (e.target.classList.contains("jdropdown-title")) {
- dropdown.selectItem(e.target.parentNode.parentNode);
- } else if (
- e.target.classList.contains("jdropdown-close") ||
- e.target.classList.contains("jdropdown-backdrop")
- ) {
- dropdown.close();
- }
- }
- };
-
- jSuites.dropdown.extractFromDom = function (el, options) {
- // Keep reference
- var select = el;
- if (!options) {
- options = {};
- }
- // Prepare configuration
- if (
- el.getAttribute("multiple") &&
- (!options || options.multiple == undefined)
- ) {
- options.multiple = true;
- }
- if (
- el.getAttribute("placeholder") &&
- (!options || options.placeholder == undefined)
- ) {
- options.placeholder = el.getAttribute("placeholder");
- }
- if (
- el.getAttribute("data-autocomplete") &&
- (!options || options.autocomplete == undefined)
- ) {
- options.autocomplete = true;
- }
- if (!options || options.width == undefined) {
- options.width = el.offsetWidth;
- }
- if (el.value && (!options || options.value == undefined)) {
- options.value = el.value;
- }
- if (!options || options.data == undefined) {
- options.data = [];
- for (var j = 0; j < el.children.length; j++) {
- if (el.children[j].tagName == "OPTGROUP") {
- for (var i = 0; i < el.children[j].children.length; i++) {
- options.data.push({
- value: el.children[j].children[i].value,
- text: el.children[j].children[i].innerHTML,
- group: el.children[j].getAttribute("label"),
- });
- }
- } else {
- options.data.push({
- value: el.children[j].value,
- text: el.children[j].innerHTML,
- });
- }
- }
- }
- if (!options || options.onchange == undefined) {
- options.onchange = function (a, b, c, d) {
- if (options.multiple == true) {
- if (obj.items[b].classList.contains("jdropdown-selected")) {
- select.options[b].setAttribute("selected", "selected");
- } else {
- select.options[b].removeAttribute("selected");
- }
- } else {
- select.value = d;
- }
- };
- }
- // Create DIV
- var div = document.createElement("div");
- el.parentNode.insertBefore(div, el);
- el.style.display = "none";
- el = div;
-
- return { el: el, options: options };
- };
-
- jSuites.editor = function (el, options) {
- // New instance
- var obj = { type: "editor" };
- obj.options = {};
-
- // Default configuration
- var defaults = {
- // Initial HTML content
- value: null,
- // Initial snippet
- snippet: null,
- // Add toolbar
- toolbar: null,
- // Website parser is to read websites and images from cross domain
- remoteParser: null,
- // Placeholder
- placeholder: null,
- // Parse URL
- parseURL: false,
- filterPaste: true,
- // Accept drop files
- dropZone: false,
- dropAsSnippet: false,
- acceptImages: false,
- acceptFiles: false,
- maxFileSize: 5000000,
- allowImageResize: true,
- // Style
- border: true,
- padding: true,
- maxHeight: null,
- height: null,
- focus: false,
- // Events
- onclick: null,
- onfocus: null,
- onblur: null,
- onload: null,
- onkeyup: null,
- onkeydown: null,
- onchange: null,
- userSearch: null,
- };
-
- // Loop through our object
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- obj.options[property] = defaults[property];
- }
- }
-
- // Private controllers
- var imageResize = 0;
- var editorTimer = null;
- var editorAction = null;
- var files = [];
-
- // Make sure element is empty
- el.innerHTML = "";
-
- // Keep the reference for the container
- obj.el = el;
-
- if (typeof obj.options.onclick == "function") {
- el.onclick = function (e) {
- obj.options.onclick(el, obj, e);
- };
- }
-
- // Prepare container
- el.classList.add("jeditor-container");
-
- // Padding
- if (obj.options.padding == true) {
- el.classList.add("jeditor-padding");
- }
-
- // Border
- if (obj.options.border == false) {
- el.style.border = "0px";
- }
-
- // Snippet
- var snippet = document.createElement("div");
- snippet.className = "jsnippet";
- snippet.setAttribute("contenteditable", false);
-
- // Toolbar
- var toolbar = document.createElement("div");
- toolbar.className = "jeditor-toolbar";
-
- // Create editor
- var editor = document.createElement("div");
- editor.setAttribute("contenteditable", true);
- editor.setAttribute("spellcheck", false);
- editor.className = "jeditor";
-
- // Placeholder
- if (obj.options.placeholder) {
- editor.setAttribute("data-placeholder", obj.options.placeholder);
- }
-
- // Max height
- if (obj.options.maxHeight || obj.options.height) {
- editor.style.overflowY = "auto";
-
- if (obj.options.maxHeight) {
- editor.style.maxHeight = obj.options.maxHeight;
- }
- if (obj.options.height) {
- editor.style.height = obj.options.height;
- }
- }
-
- // Set editor initial value
- if (obj.options.value) {
- var value = obj.options.value;
- } else {
- var value = el.innerHTML ? el.innerHTML : "";
- }
-
- if (!value) {
- var value = "";
- }
-
- /**
- * Onchange event controllers
- */
- var change = function (e) {
- if (typeof obj.options.onchange == "function") {
- obj.options.onchange(el, obj, e);
- }
-
- // Update value
- obj.options.value = obj.getData();
-
- // Lemonade JS
- if (el.value != obj.options.value) {
- el.value = obj.options.value;
- if (typeof el.oninput == "function") {
- el.oninput({
- type: "input",
- target: el,
- value: el.value,
- });
- }
- }
- };
-
- // Create node
- var createUserSearchNode = function () {
- // Get coordinates from caret
- var sel = window.getSelection
- ? window.getSelection()
- : document.selection;
- var range = sel.getRangeAt(0);
- range.deleteContents();
- // Append text node
- var input = document.createElement("a");
- input.innerText = "@";
- input.searchable = true;
- range.insertNode(input);
- var node = range.getBoundingClientRect();
- range.collapse(false);
- // Position
- userSearch.style.position = "fixed";
- userSearch.style.top = node.top + node.height + 10 + "px";
- userSearch.style.left = node.left + 2 + "px";
- };
-
- /**
- * Extract images from a HTML string
- */
- var extractImageFromHtml = function (html) {
- // Create temp element
- var div = document.createElement("div");
- div.innerHTML = html;
-
- // Extract images
- var img = div.querySelectorAll("img");
-
- if (img.length) {
- for (var i = 0; i < img.length; i++) {
- obj.addImage(img[i].src);
- }
- }
- };
-
- /**
- * Insert node at caret
- */
- var insertNodeAtCaret = function (newNode) {
- var sel, range;
-
- if (window.getSelection) {
- sel = window.getSelection();
- if (sel.rangeCount) {
- range = sel.getRangeAt(0);
- var selectedText = range.toString();
- range.deleteContents();
- range.insertNode(newNode);
- // move the cursor after element
- range.setStartAfter(newNode);
- range.setEndAfter(newNode);
- sel.removeAllRanges();
- sel.addRange(range);
- }
- }
- };
-
- var updateTotalImages = function () {
- var o = null;
- if ((o = snippet.children[0])) {
- // Make sure is a grid
- if (!o.classList.contains("jslider-grid")) {
- o.classList.add("jslider-grid");
- }
- // Quantify of images
- var number = o.children.length;
- // Set the configuration of the grid
- o.setAttribute("data-number", number > 4 ? 4 : number);
- // Total of images inside the grid
- if (number > 4) {
- o.setAttribute("data-total", number - 4);
- } else {
- o.removeAttribute("data-total");
- }
- }
- };
-
- /**
- * Append image to the snippet
- */
- var appendImage = function (image) {
- if (!snippet.innerHTML) {
- appendElement({});
- }
- snippet.children[0].appendChild(image);
- updateTotalImages();
- };
-
- /**
- * Append snippet
- * @Param object data
- */
- var appendElement = function (data) {
- // Reset snippet
- snippet.innerHTML = "";
-
- // Attributes
- var a = ["image", "title", "description", "host", "url"];
-
- for (var i = 0; i < a.length; i++) {
- var div = document.createElement("div");
- div.className = "jsnippet-" + a[i];
- div.setAttribute("data-k", a[i]);
- snippet.appendChild(div);
- if (data[a[i]]) {
- if (a[i] == "image") {
- if (!Array.isArray(data.image)) {
- data.image = [data.image];
- }
- for (var j = 0; j < data.image.length; j++) {
- var img = document.createElement("img");
- img.src = data.image[j];
- div.appendChild(img);
- }
- } else {
- div.innerHTML = data[a[i]];
- }
- }
- }
-
- editor.appendChild(document.createElement("br"));
- editor.appendChild(snippet);
- };
-
- var verifyEditor = function () {
- clearTimeout(editorTimer);
- editorTimer = setTimeout(function () {
- var snippet = editor.querySelector(".jsnippet");
- if (!snippet) {
- var html = editor.innerHTML.replace(/\n/g, " ");
- var container = document.createElement("div");
- container.innerHTML = html;
- var text = container.innerText;
- var url = jSuites.editor.detectUrl(text);
-
- if (url) {
- if (
- url[0].substr(-3) == "jpg" ||
- url[0].substr(-3) == "png" ||
- url[0].substr(-3) == "gif"
- ) {
- obj.addImage(url[0], true);
- } else {
- var id = jSuites.editor.youtubeParser(url[0]);
- obj.parseWebsite(url[0], id);
- }
- }
- }
- }, 1000);
- };
-
- obj.parseContent = function () {
- verifyEditor();
- };
-
- obj.parseWebsite = function (url, youtubeId) {
- if (!obj.options.remoteParser) {
- console.log("The remoteParser is not defined");
- } else {
- // Youtube definitions
- if (youtubeId) {
- var url = "https://www.youtube.com/watch?v=" + youtubeId;
- }
-
- var p = {
- title: "",
- description: "",
- image: "",
- host: url.split("/")[2],
- url: url,
- };
-
- jSuites.ajax({
- url: obj.options.remoteParser + encodeURI(url.trim()),
- method: "GET",
- dataType: "json",
- success: function (result) {
- // Get title
- if (result.title) {
- p.title = result.title;
- }
- // Description
- if (result.description) {
- p.description = result.description;
- }
- // Host
- if (result.host) {
- p.host = result.host;
- }
- // Url
- if (result.url) {
- p.url = result.url;
- }
- // Append snippet
- appendElement(p);
- // Add image
- if (result.image) {
- obj.addImage(result.image, true);
- } else if (result["og:image"]) {
- obj.addImage(result["og:image"], true);
- }
- },
- });
- }
- };
-
- /**
- * Set editor value
- */
- obj.setData = function (o) {
- if (typeof o == "object") {
- editor.innerHTML = o.content;
- } else {
- editor.innerHTML = o;
- }
-
- if (obj.options.focus) {
- jSuites.editor.setCursor(editor, true);
- }
-
- // Reset files container
- files = [];
- };
-
- obj.getFiles = function () {
- var f = editor.querySelectorAll(".jfile");
- var d = [];
- for (var i = 0; i < f.length; i++) {
- if (files[f[i].src]) {
- d.push(files[f[i].src]);
- }
- }
- return d;
- };
-
- obj.getText = function () {
- return editor.innerText;
- };
-
- /**
- * Get editor data
- */
- obj.getData = function (json) {
- if (!json) {
- var data = editor.innerHTML;
- } else {
- var data = {
- content: "",
- };
-
- // Get snippet
- if (snippet.innerHTML) {
- var index = 0;
- data.snippet = {};
- for (var i = 0; i < snippet.children.length; i++) {
- // Get key from element
- var key = snippet.children[i].getAttribute("data-k");
- if (key) {
- if (key == "image") {
- if (!data.snippet.image) {
- data.snippet.image = [];
- }
- // Get all images
- for (var j = 0; j < snippet.children[i].children.length; j++) {
- data.snippet.image.push(
- snippet.children[i].children[j].getAttribute("src")
- );
- }
- } else {
- data.snippet[key] = snippet.children[i].innerHTML;
- }
- }
- }
- }
-
- // Get files
- var f = Object.keys(files);
- if (f.length) {
- data.files = [];
- for (var i = 0; i < f.length; i++) {
- data.files.push(files[f[i]]);
- }
- }
-
- // Users
- if (userSearch) {
- // Get tag users
- var tagged = editor.querySelectorAll("a[data-user]");
- if (tagged.length) {
- data.users = [];
- for (var i = 0; i < tagged.length; i++) {
- var userId = tagged[i].getAttribute("data-user");
- if (userId) {
- data.users.push(userId);
- }
- }
- data.users = data.users.join(",");
- }
- }
-
- // Get content
- var d = document.createElement("div");
- d.innerHTML = editor.innerHTML;
- var s = d.querySelector(".jsnippet");
- if (s) {
- s.remove();
- }
-
- var text = d.innerHTML;
- text = text.replace(/
/g, "\n");
- text = text.replace(/<\/div>/g, "\n");
- text = text.replace(/<(?:.|\n)*?>/gm, "");
- data.content = text.trim();
- }
-
- return data;
- };
-
- // Reset
- obj.reset = function () {
- editor.innerHTML = "";
- snippet.innerHTML = "";
- files = [];
- };
-
- obj.addPdf = function (data) {
- if (data.result.substr(0, 4) != "data") {
- console.error("Invalid source");
- } else {
- var canvas = document.createElement("canvas");
- canvas.width = 60;
- canvas.height = 60;
-
- var img = new Image();
- var ctx = canvas.getContext("2d");
- ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
-
- canvas.toBlob(function (blob) {
- var newImage = document.createElement("img");
- newImage.src = window.URL.createObjectURL(blob);
- newImage.title = data.name;
- newImage.className = "jfile pdf";
-
- files[newImage.src] = {
- file: newImage.src,
- extension: "pdf",
- content: data.result,
- };
-
- insertNodeAtCaret(newImage);
- });
- }
- };
-
- obj.addImage = function (src, asSnippet) {
- if (!src) {
- src = "";
- }
-
- if (src.substr(0, 4) != "data" && !obj.options.remoteParser) {
- console.error("remoteParser not defined in your initialization");
- } else {
- // This is to process cross domain images
- if (src.substr(0, 4) == "data") {
- var extension = src.split(";");
- extension = extension[0].split("/");
- extension = extension[1];
- } else {
- var extension = src.substr(src.lastIndexOf(".") + 1);
- // Work for cross browsers
- src = obj.options.remoteParser + src;
- }
-
- var img = new Image();
-
- img.onload = function onload() {
- var canvas = document.createElement("canvas");
- canvas.width = img.width;
- canvas.height = img.height;
-
- var ctx = canvas.getContext("2d");
- ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
-
- canvas.toBlob(function (blob) {
- var newImage = document.createElement("img");
- newImage.src = window.URL.createObjectURL(blob);
- newImage.classList.add("jfile");
- newImage.setAttribute("tabindex", "900");
- files[newImage.src] = {
- file: newImage.src,
- extension: extension,
- content: canvas.toDataURL(),
- };
-
- if (obj.options.dropAsSnippet || asSnippet) {
- appendImage(newImage);
- // Just to understand the attachment is part of a snippet
- files[newImage.src].snippet = true;
- } else {
- insertNodeAtCaret(newImage);
- }
-
- change();
- });
- };
-
- img.src = src;
- }
- };
-
- obj.addFile = function (files) {
- var reader = [];
-
- for (var i = 0; i < files.length; i++) {
- if (files[i].size > obj.options.maxFileSize) {
- alert("The file is too big");
- } else {
- // Only PDF or Images
- var type = files[i].type.split("/");
-
- if (type[0] == "image") {
- type = 1;
- } else if (type[1] == "pdf") {
- type = 2;
- } else {
- type = 0;
- }
-
- if (type) {
- // Create file
- reader[i] = new FileReader();
- reader[i].index = i;
- reader[i].type = type;
- reader[i].name = files[i].name;
- reader[i].date = files[i].lastModified;
- reader[i].size = files[i].size;
- reader[i].addEventListener(
- "load",
- function (data) {
- // Get result
- if (data.target.type == 2) {
- if (obj.options.acceptFiles == true) {
- obj.addPdf(data.target);
- }
- } else {
- obj.addImage(data.target.result);
- }
- },
- false
- );
-
- reader[i].readAsDataURL(files[i]);
- } else {
- alert("The extension is not allowed");
- }
- }
- }
- };
-
- // Destroy
- obj.destroy = function () {
- editor.removeEventListener("mouseup", editorMouseUp);
- editor.removeEventListener("mousedown", editorMouseDown);
- editor.removeEventListener("mousemove", editorMouseMove);
- editor.removeEventListener("keyup", editorKeyUp);
- editor.removeEventListener("keydown", editorKeyDown);
- editor.removeEventListener("dragstart", editorDragStart);
- editor.removeEventListener("dragenter", editorDragEnter);
- editor.removeEventListener("dragover", editorDragOver);
- editor.removeEventListener("drop", editorDrop);
- editor.removeEventListener("paste", editorPaste);
- editor.removeEventListener("blur", editorBlur);
- editor.removeEventListener("focus", editorFocus);
-
- el.editor = null;
- el.classList.remove("jeditor-container");
-
- toolbar.remove();
- snippet.remove();
- editor.remove();
- };
-
- var isLetter = function (str) {
- var regex =
- /([\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]+)/g;
- return str.match(regex) ? 1 : 0;
- };
-
- // Event handlers
- var editorMouseUp = function (e) {
- if (editorAction && editorAction.e) {
- editorAction.e.classList.remove("resizing");
- }
-
- editorAction = false;
- };
-
- var editorMouseDown = function (e) {
- var close = function (snippet) {
- var rect = snippet.getBoundingClientRect();
- if (
- rect.width - (e.clientX - rect.left) < 40 &&
- e.clientY - rect.top < 40
- ) {
- snippet.innerHTML = "";
- snippet.remove();
- }
- };
-
- if (e.target.tagName == "IMG") {
- if (e.target.style.cursor) {
- var rect = e.target.getBoundingClientRect();
- editorAction = {
- e: e.target,
- x: e.clientX,
- y: e.clientY,
- w: rect.width,
- h: rect.height,
- d: e.target.style.cursor,
- };
-
- if (!e.target.width) {
- e.target.width = rect.width + "px";
- }
-
- if (!e.target.height) {
- e.target.height = rect.height + "px";
- }
-
- var s = window.getSelection();
- if (s.rangeCount) {
- for (var i = 0; i < s.rangeCount; i++) {
- s.removeRange(s.getRangeAt(i));
- }
- }
-
- e.target.classList.add("resizing");
- } else {
- editorAction = true;
- }
- } else {
- if (e.target.classList.contains("jsnippet")) {
- close(e.target);
- } else if (e.target.parentNode.classList.contains("jsnippet")) {
- close(e.target.parentNode);
- }
-
- editorAction = true;
- }
- };
-
- var editorMouseMove = function (e) {
- if (
- e.target.tagName == "IMG" &&
- !e.target.parentNode.classList.contains("jsnippet-image") &&
- obj.options.allowImageResize == true
- ) {
- if (e.target.getAttribute("tabindex")) {
- var rect = e.target.getBoundingClientRect();
- if (e.clientY - rect.top < 5) {
- if (rect.width - (e.clientX - rect.left) < 5) {
- e.target.style.cursor = "ne-resize";
- } else if (e.clientX - rect.left < 5) {
- e.target.style.cursor = "nw-resize";
- } else {
- e.target.style.cursor = "n-resize";
- }
- } else if (rect.height - (e.clientY - rect.top) < 5) {
- if (rect.width - (e.clientX - rect.left) < 5) {
- e.target.style.cursor = "se-resize";
- } else if (e.clientX - rect.left < 5) {
- e.target.style.cursor = "sw-resize";
- } else {
- e.target.style.cursor = "s-resize";
- }
- } else if (rect.width - (e.clientX - rect.left) < 5) {
- e.target.style.cursor = "e-resize";
- } else if (e.clientX - rect.left < 5) {
- e.target.style.cursor = "w-resize";
- } else {
- e.target.style.cursor = "";
- }
- }
- }
-
- // Move
- if (e.which == 1 && editorAction && editorAction.d) {
- if (
- editorAction.d == "e-resize" ||
- editorAction.d == "ne-resize" ||
- editorAction.d == "se-resize"
- ) {
- editorAction.e.width = editorAction.w + (e.clientX - editorAction.x);
-
- if (e.shiftKey) {
- var newHeight =
- (e.clientX - editorAction.x) * (editorAction.h / editorAction.w);
- editorAction.e.height = editorAction.h + newHeight;
- } else {
- var newHeight = null;
- }
- }
-
- if (!newHeight) {
- if (
- editorAction.d == "s-resize" ||
- editorAction.d == "se-resize" ||
- editorAction.d == "sw-resize"
- ) {
- if (!e.shiftKey) {
- editorAction.e.height =
- editorAction.h + (e.clientY - editorAction.y);
- }
- }
- }
- }
- };
-
- var editorKeyUp = function (e) {
- if (!editor.innerHTML) {
- editor.innerHTML = "
";
- }
-
- if (userSearch) {
- var t = jSuites.getNode();
- if (t) {
- if (t.searchable === true) {
- if (t.innerText && t.innerText.substr(0, 1) == "@") {
- userSearchInstance(t.innerText.substr(1));
- }
- } else if (t.searchable === false) {
- if (t.innerText !== t.getAttribute("data-label")) {
- t.searchable = true;
- t.removeAttribute("href");
- }
- }
- }
- }
-
- if (typeof obj.options.onkeyup == "function") {
- obj.options.onkeyup(el, obj, e);
- }
- };
-
- var editorKeyDown = function (e) {
- // Check for URL
- if (obj.options.parseURL == true) {
- verifyEditor();
- }
-
- if (userSearch) {
- if (e.key == "@") {
- createUserSearchNode(editor);
- e.preventDefault();
- } else {
- if (userSearchInstance.isOpened()) {
- userSearchInstance.keydown(e);
- }
- }
- }
-
- if (typeof obj.options.onkeydown == "function") {
- obj.options.onkeydown(el, obj, e);
- }
-
- if (e.key == "Delete") {
- if (
- e.target.tagName == "IMG" &&
- e.target.parentNode.classList.contains("jsnippet-image")
- ) {
- e.target.remove();
- updateTotalImages();
- }
- }
- };
-
- // Elements to be removed
- var remove = [
- HTMLUnknownElement,
- HTMLAudioElement,
- HTMLEmbedElement,
- HTMLIFrameElement,
- HTMLTextAreaElement,
- HTMLInputElement,
- HTMLScriptElement,
- ];
-
- // Valid properties
- var validProperty = [
- "width",
- "height",
- "align",
- "border",
- "src",
- "tabindex",
- ];
-
- // Valid CSS attributes
- var validStyle = [
- "color",
- "font-weight",
- "font-size",
- "background",
- "background-color",
- "margin",
- ];
-
- var parse = function (element) {
- // Remove attributes
- if (element.attributes && element.attributes.length) {
- var image = null;
- var style = null;
- // Process style attribute
- var elementStyle = element.getAttribute("style");
- if (elementStyle) {
- style = [];
- var t = elementStyle.split(";");
- for (var j = 0; j < t.length; j++) {
- var v = t[j].trim().split(":");
- if (validStyle.indexOf(v[0].trim()) >= 0) {
- var k = v.shift();
- var v = v.join(":");
- style.push(k + ":" + v);
- }
- }
- }
- // Process image
- if (element.tagName.toUpperCase() == "IMG") {
- if (!obj.options.acceptImages || !element.src) {
- element.parentNode.removeChild(element);
- } else {
- // Check if is data
- element.setAttribute("tabindex", "900");
- // Check attributes for persistance
- obj.addImage(element.src);
- }
- }
- // Remove attributes
- var attr = [];
- var numAttributes = element.attributes.length - 1;
- if (numAttributes > 0) {
- for (var i = numAttributes; i >= 0; i--) {
- attr.push(element.attributes[i].name);
- }
- attr.forEach(function (v) {
- if (validProperty.indexOf(v) == -1) {
- element.removeAttribute(v);
- }
- });
- }
- element.style = "";
- // Add valid style
- if (style && style.length) {
- element.setAttribute("style", style.join(";"));
- }
- }
- // Parse children
- if (element.children.length) {
- for (var i = 0; i < element.children.length; i++) {
- parse(element.children[i]);
- }
- }
-
- if (remove.indexOf(element.constructor) >= 0) {
- element.remove();
- }
- };
-
- var filter = function (data) {
- if (data) {
- data = data.replace(new RegExp("", "gsi"), "");
- }
- var parser = new DOMParser();
- var d = parser.parseFromString(data, "text/html");
- parse(d);
- var span = document.createElement("span");
- span.innerHTML = d.firstChild.innerHTML;
- return span;
- };
-
- var editorPaste = function (e) {
- if (obj.options.filterPaste == true) {
- if (e.clipboardData || e.originalEvent.clipboardData) {
- var html = (e.originalEvent || e).clipboardData.getData("text/html");
- var text = (e.originalEvent || e).clipboardData.getData("text/plain");
- var file = (e.originalEvent || e).clipboardData.files;
- } else if (window.clipboardData) {
- var html = window.clipboardData.getData("Html");
- var text = window.clipboardData.getData("Text");
- var file = window.clipboardData.files;
- }
-
- if (file.length) {
- // Paste a image from the clipboard
- obj.addFile(file);
- } else {
- if (!html) {
- html = text.split("\r\n");
- if (!e.target.innerText) {
- html.map(function (v) {
- var d = document.createElement("div");
- d.innerText = v;
- editor.appendChild(d);
- });
- } else {
- html = html.map(function (v) {
- return "" + v + "
";
- });
- document.execCommand("insertHtml", false, html.join(""));
- }
- } else {
- var d = filter(html);
- // Paste to the editor
- //insertNodeAtCaret(d);
- document.execCommand("insertHtml", false, d.innerHTML);
- }
- }
-
- e.preventDefault();
- }
- };
-
- var editorDragStart = function (e) {
- if (editorAction && editorAction.e) {
- e.preventDefault();
- }
- };
-
- var editorDragEnter = function (e) {
- if (editorAction || obj.options.dropZone == false) {
- // Do nothing
- } else {
- el.classList.add("jeditor-dragging");
- e.preventDefault();
- }
- };
-
- var editorDragOver = function (e) {
- if (editorAction || obj.options.dropZone == false) {
- // Do nothing
- } else {
- if (editorTimer) {
- clearTimeout(editorTimer);
- }
-
- editorTimer = setTimeout(function () {
- el.classList.remove("jeditor-dragging");
- }, 100);
- e.preventDefault();
- }
- };
-
- var editorDrop = function (e) {
- if (editorAction || obj.options.dropZone == false) {
- // Do nothing
- } else {
- // Position caret on the drop
- var range = null;
- if (document.caretRangeFromPoint) {
- range = document.caretRangeFromPoint(e.clientX, e.clientY);
- } else if (e.rangeParent) {
- range = document.createRange();
- range.setStart(e.rangeParent, e.rangeOffset);
- }
- var sel = window.getSelection();
- sel.removeAllRanges();
- sel.addRange(range);
- sel.anchorNode.parentNode.focus();
-
- var html = (e.originalEvent || e).dataTransfer.getData("text/html");
- var text = (e.originalEvent || e).dataTransfer.getData("text/plain");
- var file = (e.originalEvent || e).dataTransfer.files;
-
- if (file.length) {
- obj.addFile(file);
- } else if (text) {
- extractImageFromHtml(html);
- }
-
- el.classList.remove("jeditor-dragging");
- e.preventDefault();
- }
- };
-
- var editorBlur = function (e) {
- if (userSearch && userSearchInstance.isOpened()) {
- userSearchInstance.close();
- }
-
- // Blur
- if (typeof obj.options.onblur == "function") {
- obj.options.onblur(el, obj, e);
- }
-
- change(e);
- };
-
- var editorFocus = function (e) {
- // Focus
- if (typeof obj.options.onfocus == "function") {
- obj.options.onfocus(el, obj, e);
- }
- };
-
- editor.addEventListener("mouseup", editorMouseUp);
- editor.addEventListener("mousedown", editorMouseDown);
- editor.addEventListener("mousemove", editorMouseMove);
- editor.addEventListener("keyup", editorKeyUp);
- editor.addEventListener("keydown", editorKeyDown);
- editor.addEventListener("dragstart", editorDragStart);
- editor.addEventListener("dragenter", editorDragEnter);
- editor.addEventListener("dragover", editorDragOver);
- editor.addEventListener("drop", editorDrop);
- editor.addEventListener("paste", editorPaste);
- editor.addEventListener("focus", editorFocus);
- editor.addEventListener("blur", editorBlur);
-
- // Onload
- if (typeof obj.options.onload == "function") {
- obj.options.onload(el, obj, editor);
- }
-
- // Set value to the editor
- editor.innerHTML = value;
-
- // Append editor to the containre
- el.appendChild(editor);
-
- // Snippet
- if (obj.options.snippet) {
- appendElement(obj.options.snippet);
- }
-
- // Default toolbar
- if (obj.options.toolbar == null) {
- obj.options.toolbar = jSuites.editor.getDefaultToolbar();
- }
-
- // Add toolbar
- if (obj.options.toolbar) {
- // Append to the DOM
- el.appendChild(toolbar);
- // Create toolbar
- jSuites.toolbar(toolbar, {
- container: true,
- responsive: true,
- items: obj.options.toolbar,
- });
- }
-
- // Add user search
- var userSearch = null;
- var userSearchInstance = null;
- if (obj.options.userSearch) {
- userSearch = document.createElement("div");
- el.appendChild(userSearch);
-
- // Component
- userSearchInstance = jSuites.search(userSearch, {
- data: obj.options.userSearch,
- placeholder: jSuites.translate("Type the name a user"),
- onselect: function (a, b, c, d) {
- if (userSearchInstance.isOpened()) {
- var t = jSuites.getNode();
- if (
- t &&
- t.searchable == true &&
- t.innerText.trim() &&
- t.innerText.substr(1)
- ) {
- t.innerText = "@" + c;
- t.href = "/" + c;
- t.setAttribute("data-user", d);
- t.setAttribute("data-label", t.innerText);
- t.searchable = false;
- jSuites.focus(t);
- }
- }
- },
- });
- }
-
- // Focus to the editor
- if (obj.options.focus) {
- jSuites.editor.setCursor(
- editor,
- obj.options.focus == "initial" ? true : false
- );
- }
-
- // Change method
- el.change = obj.setData;
-
- // Global generic value handler
- el.val = function (val) {
- if (val === undefined) {
- // Data type
- var o = el.getAttribute("data-html") === "true" ? false : true;
- return obj.getData(o);
- } else {
- obj.setData(val);
- }
- };
-
- el.editor = obj;
-
- return obj;
- };
-
- jSuites.editor.setCursor = function (element, first) {
- element.focus();
- document.execCommand("selectAll");
- var sel = window.getSelection();
- var range = sel.getRangeAt(0);
- if (first == true) {
- var node = range.startContainer;
- var size = 0;
- } else {
- var node = range.endContainer;
- var size = node.length;
- }
- range.setStart(node, size);
- range.setEnd(node, size);
- sel.removeAllRanges();
- sel.addRange(range);
- };
-
- jSuites.editor.getDomain = function (url) {
- return url
- .replace("http://", "")
- .replace("https://", "")
- .replace("www.", "")
- .split(/[/?#]/)[0]
- .split(/:/g)[0];
- };
-
- jSuites.editor.detectUrl = function (text) {
- var expression =
- /(((https?:\/\/)|(www\.))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]+)/gi;
- var links = text.match(expression);
-
- if (links) {
- if (links[0].substr(0, 3) == "www") {
- links[0] = "http://" + links[0];
- }
- }
-
- return links;
- };
-
- jSuites.editor.youtubeParser = function (url) {
- var regExp =
- /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
- var match = url.match(regExp);
-
- return match && match[7].length == 11 ? match[7] : false;
- };
-
- jSuites.editor.getDefaultToolbar = function () {
- return [
- {
- content: "undo",
- onclick: function () {
- document.execCommand("undo");
- },
- },
- {
- content: "redo",
- onclick: function () {
- document.execCommand("redo");
- },
- },
- {
- type: "divisor",
- },
- {
- content: "format_bold",
- onclick: function (a, b, c) {
- document.execCommand("bold");
-
- if (document.queryCommandState("bold")) {
- c.classList.add("selected");
- } else {
- c.classList.remove("selected");
- }
- },
- },
- {
- content: "format_italic",
- onclick: function (a, b, c) {
- document.execCommand("italic");
-
- if (document.queryCommandState("italic")) {
- c.classList.add("selected");
- } else {
- c.classList.remove("selected");
- }
- },
- },
- {
- content: "format_underline",
- onclick: function (a, b, c) {
- document.execCommand("underline");
-
- if (document.queryCommandState("underline")) {
- c.classList.add("selected");
- } else {
- c.classList.remove("selected");
- }
- },
- },
- {
- type: "divisor",
- },
- {
- content: "format_list_bulleted",
- onclick: function (a, b, c) {
- document.execCommand("insertUnorderedList");
-
- if (document.queryCommandState("insertUnorderedList")) {
- c.classList.add("selected");
- } else {
- c.classList.remove("selected");
- }
- },
- },
- {
- content: "format_list_numbered",
- onclick: function (a, b, c) {
- document.execCommand("insertOrderedList");
-
- if (document.queryCommandState("insertOrderedList")) {
- c.classList.add("selected");
- } else {
- c.classList.remove("selected");
- }
- },
- },
- {
- content: "format_indent_increase",
- onclick: function (a, b, c) {
- document.execCommand("indent", true, null);
-
- if (document.queryCommandState("indent")) {
- c.classList.add("selected");
- } else {
- c.classList.remove("selected");
- }
- },
- },
- {
- content: "format_indent_decrease",
- onclick: function () {
- document.execCommand("outdent");
-
- if (document.queryCommandState("outdent")) {
- this.classList.add("selected");
- } else {
- this.classList.remove("selected");
- }
- },
- } /*,
- {
- icon: ['format_align_left', 'format_align_right', 'format_align_center'],
- onclick: function() {
- document.execCommand('justifyCenter');
-
- if (document.queryCommandState("justifyCenter")) {
- this.classList.add('selected');
- } else {
- this.classList.remove('selected');
- }
- }
- }
- {
- type:'select',
- items: ['Verdana','Arial','Courier New'],
- onchange: function() {
- }
- },
- {
- type:'select',
- items: ['10px','12px','14px','16px','18px','20px','22px'],
- onchange: function() {
- }
- },
- {
- icon:'format_align_left',
- onclick: function() {
- document.execCommand('JustifyLeft');
-
- if (document.queryCommandState("JustifyLeft")) {
- this.classList.add('selected');
- } else {
- this.classList.remove('selected');
- }
- }
- },
- {
- icon:'format_align_center',
- onclick: function() {
- document.execCommand('justifyCenter');
-
- if (document.queryCommandState("justifyCenter")) {
- this.classList.add('selected');
- } else {
- this.classList.remove('selected');
- }
- }
- },
- {
- icon:'format_align_right',
- onclick: function() {
- document.execCommand('justifyRight');
-
- if (document.queryCommandState("justifyRight")) {
- this.classList.add('selected');
- } else {
- this.classList.remove('selected');
- }
- }
- },
- {
- icon:'format_align_justify',
- onclick: function() {
- document.execCommand('justifyFull');
-
- if (document.queryCommandState("justifyFull")) {
- this.classList.add('selected');
- } else {
- this.classList.remove('selected');
- }
- }
- },
- {
- icon:'format_list_bulleted',
- onclick: function() {
- document.execCommand('insertUnorderedList');
-
- if (document.queryCommandState("insertUnorderedList")) {
- this.classList.add('selected');
- } else {
- this.classList.remove('selected');
- }
- }
- }*/,
- ];
- };
-
- jSuites.form = function (el, options) {
- var obj = {};
- obj.options = {};
-
- // Default configuration
- var defaults = {
- url: null,
- message: "Are you sure? There are unsaved information in your form",
- ignore: false,
- currentHash: null,
- submitButton: null,
- validations: null,
- onbeforeload: null,
- onload: null,
- onbeforesave: null,
- onsave: null,
- onbeforeremove: null,
- onremove: null,
- onerror: function (el, message) {
- jSuites.alert(message);
- },
- };
-
- // Loop through our object
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- obj.options[property] = defaults[property];
- }
- }
-
- // Validations
- if (!obj.options.validations) {
- obj.options.validations = {};
- }
-
- // Submit Button
- if (!obj.options.submitButton) {
- obj.options.submitButton = el.querySelector("input[type=submit]");
- }
-
- if (obj.options.submitButton && obj.options.url) {
- obj.options.submitButton.onclick = function () {
- obj.save();
- };
- }
-
- if (!obj.options.validations.email) {
- obj.options.validations.email = jSuites.validations.email;
- }
-
- if (!obj.options.validations.length) {
- obj.options.validations.length = jSuites.validations.length;
- }
-
- if (!obj.options.validations.required) {
- obj.options.validations.required = jSuites.validations.required;
- }
-
- obj.setUrl = function (url) {
- obj.options.url = url;
- };
-
- obj.load = function () {
- jSuites.ajax({
- url: obj.options.url,
- method: "GET",
- dataType: "json",
- queue: true,
- success: function (data) {
- // Overwrite values from the backend
- if (typeof obj.options.onbeforeload == "function") {
- var ret = obj.options.onbeforeload(el, data);
- if (ret) {
- data = ret;
- }
- }
- // Apply values to the form
- jSuites.form.setElements(el, data);
- // Onload methods
- if (typeof obj.options.onload == "function") {
- obj.options.onload(el, data);
- }
- },
- });
- };
-
- obj.save = function () {
- var test = obj.validate();
-
- if (test) {
- obj.options.onerror(el, test);
- } else {
- var data = jSuites.form.getElements(el, true);
-
- if (typeof obj.options.onbeforesave == "function") {
- var data = obj.options.onbeforesave(el, data);
-
- if (data === false) {
- return;
- }
- }
-
- jSuites.ajax({
- url: obj.options.url,
- method: "POST",
- dataType: "json",
- data: data,
- success: function (result) {
- if (typeof obj.options.onsave == "function") {
- obj.options.onsave(el, data, result);
- }
- },
- });
- }
- };
-
- obj.remove = function () {
- if (typeof obj.options.onbeforeremove == "function") {
- var ret = obj.options.onbeforeremove(el, obj);
- if (ret === false) {
- return false;
- }
- }
-
- jSuites.ajax({
- url: obj.options.url,
- method: "DELETE",
- dataType: "json",
- success: function (result) {
- if (typeof obj.options.onremove == "function") {
- obj.options.onremove(el, obj, result);
- }
-
- obj.reset();
- },
- });
- };
-
- var addError = function (element) {
- // Add error in the element
- element.classList.add("error");
- // Submit button
- if (obj.options.submitButton) {
- obj.options.submitButton.setAttribute("disabled", true);
- }
- // Return error message
- var error =
- element.getAttribute("data-error") || "There is an error in the form";
- element.setAttribute("title", error);
- return error;
- };
-
- var delError = function (element) {
- var error = false;
- // Remove class from this element
- element.classList.remove("error");
- element.removeAttribute("title");
- // Get elements in the form
- var elements = el.querySelectorAll("input, select, textarea, div[name]");
- // Run all elements
- for (var i = 0; i < elements.length; i++) {
- if (elements[i].getAttribute("data-validation")) {
- if (elements[i].classList.contains("error")) {
- error = true;
- }
- }
- }
-
- if (obj.options.submitButton) {
- if (error) {
- obj.options.submitButton.setAttribute("disabled", true);
- } else {
- obj.options.submitButton.removeAttribute("disabled");
- }
- }
- };
-
- obj.validateElement = function (element) {
- // Test results
- var test = false;
- // Value
- var value = jSuites.form.getValue(element);
- // Validation
- var validation = element.getAttribute("data-validation");
- // Parse
- if (
- typeof obj.options.validations[validation] == "function" &&
- !obj.options.validations[validation](value, element)
- ) {
- // Not passed in the test
- test = addError(element);
- } else {
- if (element.classList.contains("error")) {
- delError(element);
- }
- }
-
- return test;
- };
-
- obj.reset = function () {
- // Get elements in the form
- var name = null;
- var elements = el.querySelectorAll("input, select, textarea, div[name]");
- // Run all elements
- for (var i = 0; i < elements.length; i++) {
- if ((name = elements[i].getAttribute("name"))) {
- if (elements[i].type == "checkbox" || elements[i].type == "radio") {
- elements[i].checked = false;
- } else {
- if (typeof elements[i].val == "function") {
- elements[i].val("");
- } else {
- elements[i].value = "";
- }
- }
- }
- }
- };
-
- // Run form validation
- obj.validate = function () {
- var test = [];
- // Get elements in the form
- var elements = el.querySelectorAll("input, select, textarea, div[name]");
- // Run all elements
- for (var i = 0; i < elements.length; i++) {
- // Required
- if (elements[i].getAttribute("data-validation")) {
- var res = obj.validateElement(elements[i]);
- if (res) {
- test.push(res);
- }
- }
- }
- if (test.length > 0) {
- return test.join("
");
- } else {
- return false;
- }
- };
-
- // Check the form
- obj.getError = function () {
- // Validation
- return obj.validation() ? true : false;
- };
-
- // Return the form hash
- obj.setHash = function () {
- return obj.getHash(jSuites.form.getElements(el));
- };
-
- // Get the form hash
- obj.getHash = function (str) {
- var hash = 0,
- i,
- chr;
-
- if (str.length === 0) {
- return hash;
- } else {
- for (i = 0; i < str.length; i++) {
- chr = str.charCodeAt(i);
- hash = (hash << 5) - hash + chr;
- hash |= 0;
- }
- }
-
- return hash;
- };
-
- // Is there any change in the form since start tracking?
- obj.isChanged = function () {
- var hash = obj.setHash();
- return obj.options.currentHash != hash;
- };
-
- // Restart tracking
- obj.resetTracker = function () {
- obj.options.currentHash = obj.setHash();
- obj.options.ignore = false;
- };
-
- // Ignore flag
- obj.setIgnore = function (ignoreFlag) {
- obj.options.ignore = ignoreFlag ? true : false;
- };
-
- // Start tracking in one second
- setTimeout(function () {
- obj.options.currentHash = obj.setHash();
- }, 1000);
-
- // Validations
- el.addEventListener("keyup", function (e) {
- if (e.target.getAttribute("data-validation")) {
- obj.validateElement(e.target);
- }
- });
-
- // Alert
- if (!jSuites.form.hasEvents) {
- window.addEventListener("beforeunload", function (e) {
- if (obj.isChanged() && obj.options.ignore == false) {
- var confirmationMessage = obj.options.message
- ? obj.options.message
- : "o/";
-
- if (confirmationMessage) {
- if (typeof e == "undefined") {
- e = window.event;
- }
-
- if (e) {
- e.returnValue = confirmationMessage;
- }
-
- return confirmationMessage;
- } else {
- return void 0;
- }
- }
- });
-
- jSuites.form.hasEvents = true;
- }
-
- el.form = obj;
-
- return obj;
- };
-
- // Get value from one element
- jSuites.form.getValue = function (element) {
- var value = null;
- if (element.type == "checkbox") {
- if (element.checked == true) {
- value = element.value || true;
- }
- } else if (element.type == "radio") {
- if (element.checked == true) {
- value = element.value;
- }
- } else if (element.type == "file") {
- value = element.files;
- } else if (element.tagName == "select" && element.multiple == true) {
- value = [];
- var options = element.querySelectorAll("options[selected]");
- for (var j = 0; j < options.length; j++) {
- value.push(options[j].value);
- }
- } else if (typeof element.val == "function") {
- value = element.val();
- } else {
- value = element.value || "";
- }
-
- return value;
- };
-
- // Get form elements
- jSuites.form.getElements = function (el, asArray) {
- var data = {};
- var name = null;
- var elements = el.querySelectorAll("input, select, textarea, div[name]");
-
- for (var i = 0; i < elements.length; i++) {
- if ((name = elements[i].getAttribute("name"))) {
- data[name] = jSuites.form.getValue(elements[i]) || "";
- }
- }
-
- return asArray == true ? data : JSON.stringify(data);
- };
-
- //Get form elements
- jSuites.form.setElements = function (el, data) {
- var name = null;
- var value = null;
- var elements = el.querySelectorAll("input, select, textarea, div[name]");
- for (var i = 0; i < elements.length; i++) {
- // Attributes
- var type = elements[i].getAttribute("type");
- if ((name = elements[i].getAttribute("name"))) {
- // Transform variable names in pathname
- name = name.replace(new RegExp(/\[(.*?)\]/gi), ".$1");
- value = null;
- // Seach for the data in the path
- if (name.match(/\./)) {
- var tmp = jSuites.path.call(data, name) || "";
- if (typeof tmp !== "undefined") {
- value = tmp;
- }
- } else {
- if (typeof data[name] !== "undefined") {
- value = data[name];
- }
- }
- // Set the values
- if (value !== null) {
- if (type == "checkbox" || type == "radio") {
- elements[i].checked = value ? true : false;
- } else if (type == "file") {
- // Do nothing
- } else {
- if (typeof elements[i].val == "function") {
- elements[i].val(value);
- } else {
- elements[i].value = value;
- }
- }
- }
- }
- }
- };
-
- // Legacy
- jSuites.tracker = jSuites.form;
-
- jSuites.focus = function (el) {
- if (el.innerText.length) {
- var range = document.createRange();
- var sel = window.getSelection();
- var node = el.childNodes[el.childNodes.length - 1];
- range.setStart(node, node.length);
- range.collapse(true);
- sel.removeAllRanges();
- sel.addRange(range);
- el.scrollLeft = el.scrollWidth;
- }
- };
-
- jSuites.isNumeric = function (num) {
- if (typeof num === "string") {
- num = num.trim();
- }
- return !isNaN(num) && num !== null && num !== "";
- };
-
- jSuites.guid = function () {
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
- /[xy]/g,
- function (c) {
- var r = (Math.random() * 16) | 0,
- v = c == "x" ? r : (r & 0x3) | 0x8;
- return v.toString(16);
- }
- );
- };
-
- jSuites.getNode = function () {
- var node = document.getSelection().anchorNode;
- if (node) {
- return node.nodeType == 3 ? node.parentNode : node;
- } else {
- return null;
- }
- };
- /**
- * Generate hash from a string
- */
- jSuites.hash = function (str) {
- var hash = 0,
- i,
- chr;
-
- if (str.length === 0) {
- return hash;
- } else {
- for (i = 0; i < str.length; i++) {
- chr = str.charCodeAt(i);
- if (chr > 32) {
- hash = (hash << 5) - hash + chr;
- hash |= 0;
- }
- }
- }
- return hash;
- };
-
- /**
- * Generate a random color
- */
- jSuites.randomColor = function (h) {
- var lum = -0.25;
- var hex = String(
- "#" + Math.random().toString(16).slice(2, 8).toUpperCase()
- ).replace(/[^0-9a-f]/gi, "");
- if (hex.length < 6) {
- hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
- }
- var rgb = [],
- c,
- i;
- for (i = 0; i < 3; i++) {
- c = parseInt(hex.substr(i * 2, 2), 16);
- c = Math.round(Math.min(Math.max(0, c + c * lum), 255)).toString(16);
- rgb.push(("00" + c).substr(c.length));
- }
-
- // Return hex
- if (h == true) {
- return (
- "#" +
- jSuites.two(rgb[0].toString(16)) +
- jSuites.two(rgb[1].toString(16)) +
- jSuites.two(rgb[2].toString(16))
- );
- }
-
- return rgb;
- };
-
- jSuites.getWindowWidth = function () {
- var w = window,
- d = document,
- e = d.documentElement,
- g = d.getElementsByTagName("body")[0],
- x = w.innerWidth || e.clientWidth || g.clientWidth;
- return x;
- };
-
- jSuites.getWindowHeight = function () {
- var w = window,
- d = document,
- e = d.documentElement,
- g = d.getElementsByTagName("body")[0],
- y = w.innerHeight || e.clientHeight || g.clientHeight;
- return y;
- };
-
- jSuites.getPosition = function (e) {
- if (e.changedTouches && e.changedTouches[0]) {
- var x = e.changedTouches[0].pageX;
- var y = e.changedTouches[0].pageY;
- } else {
- var x = window.Event
- ? e.pageX
- : e.clientX +
- (document.documentElement.scrollLeft
- ? document.documentElement.scrollLeft
- : document.body.scrollLeft);
- var y = window.Event
- ? e.pageY
- : e.clientY +
- (document.documentElement.scrollTop
- ? document.documentElement.scrollTop
- : document.body.scrollTop);
- }
-
- return [x, y];
- };
-
- jSuites.click = function (el) {
- if (el.click) {
- el.click();
- } else {
- var evt = new MouseEvent("click", {
- bubbles: true,
- cancelable: true,
- view: window,
- });
- el.dispatchEvent(evt);
- }
- };
-
- jSuites.findElement = function (element, condition) {
- var foundElement = false;
-
- function path(element) {
- if (element && !foundElement) {
- if (typeof condition == "function") {
- foundElement = condition(element);
- } else if (typeof condition == "string") {
- if (element.classList && element.classList.contains(condition)) {
- foundElement = element;
- }
- }
- }
-
- if (element.parentNode && !foundElement) {
- path(element.parentNode);
- }
- }
-
- path(element);
-
- return foundElement;
- };
-
- // Two digits
- jSuites.two = function (value) {
- value = "" + value;
- if (value.length == 1) {
- value = "0" + value;
- }
- return value;
- };
-
- jSuites.sha512 = function (str) {
- function int64(msint_32, lsint_32) {
- this.highOrder = msint_32;
- this.lowOrder = lsint_32;
- }
-
- var H = [
- new int64(0x6a09e667, 0xf3bcc908),
- new int64(0xbb67ae85, 0x84caa73b),
- new int64(0x3c6ef372, 0xfe94f82b),
- new int64(0xa54ff53a, 0x5f1d36f1),
- new int64(0x510e527f, 0xade682d1),
- new int64(0x9b05688c, 0x2b3e6c1f),
- new int64(0x1f83d9ab, 0xfb41bd6b),
- new int64(0x5be0cd19, 0x137e2179),
- ];
-
- var K = [
- new int64(0x428a2f98, 0xd728ae22),
- new int64(0x71374491, 0x23ef65cd),
- new int64(0xb5c0fbcf, 0xec4d3b2f),
- new int64(0xe9b5dba5, 0x8189dbbc),
- new int64(0x3956c25b, 0xf348b538),
- new int64(0x59f111f1, 0xb605d019),
- new int64(0x923f82a4, 0xaf194f9b),
- new int64(0xab1c5ed5, 0xda6d8118),
- new int64(0xd807aa98, 0xa3030242),
- new int64(0x12835b01, 0x45706fbe),
- new int64(0x243185be, 0x4ee4b28c),
- new int64(0x550c7dc3, 0xd5ffb4e2),
- new int64(0x72be5d74, 0xf27b896f),
- new int64(0x80deb1fe, 0x3b1696b1),
- new int64(0x9bdc06a7, 0x25c71235),
- new int64(0xc19bf174, 0xcf692694),
- new int64(0xe49b69c1, 0x9ef14ad2),
- new int64(0xefbe4786, 0x384f25e3),
- new int64(0x0fc19dc6, 0x8b8cd5b5),
- new int64(0x240ca1cc, 0x77ac9c65),
- new int64(0x2de92c6f, 0x592b0275),
- new int64(0x4a7484aa, 0x6ea6e483),
- new int64(0x5cb0a9dc, 0xbd41fbd4),
- new int64(0x76f988da, 0x831153b5),
- new int64(0x983e5152, 0xee66dfab),
- new int64(0xa831c66d, 0x2db43210),
- new int64(0xb00327c8, 0x98fb213f),
- new int64(0xbf597fc7, 0xbeef0ee4),
- new int64(0xc6e00bf3, 0x3da88fc2),
- new int64(0xd5a79147, 0x930aa725),
- new int64(0x06ca6351, 0xe003826f),
- new int64(0x14292967, 0x0a0e6e70),
- new int64(0x27b70a85, 0x46d22ffc),
- new int64(0x2e1b2138, 0x5c26c926),
- new int64(0x4d2c6dfc, 0x5ac42aed),
- new int64(0x53380d13, 0x9d95b3df),
- new int64(0x650a7354, 0x8baf63de),
- new int64(0x766a0abb, 0x3c77b2a8),
- new int64(0x81c2c92e, 0x47edaee6),
- new int64(0x92722c85, 0x1482353b),
- new int64(0xa2bfe8a1, 0x4cf10364),
- new int64(0xa81a664b, 0xbc423001),
- new int64(0xc24b8b70, 0xd0f89791),
- new int64(0xc76c51a3, 0x0654be30),
- new int64(0xd192e819, 0xd6ef5218),
- new int64(0xd6990624, 0x5565a910),
- new int64(0xf40e3585, 0x5771202a),
- new int64(0x106aa070, 0x32bbd1b8),
- new int64(0x19a4c116, 0xb8d2d0c8),
- new int64(0x1e376c08, 0x5141ab53),
- new int64(0x2748774c, 0xdf8eeb99),
- new int64(0x34b0bcb5, 0xe19b48a8),
- new int64(0x391c0cb3, 0xc5c95a63),
- new int64(0x4ed8aa4a, 0xe3418acb),
- new int64(0x5b9cca4f, 0x7763e373),
- new int64(0x682e6ff3, 0xd6b2b8a3),
- new int64(0x748f82ee, 0x5defb2fc),
- new int64(0x78a5636f, 0x43172f60),
- new int64(0x84c87814, 0xa1f0ab72),
- new int64(0x8cc70208, 0x1a6439ec),
- new int64(0x90befffa, 0x23631e28),
- new int64(0xa4506ceb, 0xde82bde9),
- new int64(0xbef9a3f7, 0xb2c67915),
- new int64(0xc67178f2, 0xe372532b),
- new int64(0xca273ece, 0xea26619c),
- new int64(0xd186b8c7, 0x21c0c207),
- new int64(0xeada7dd6, 0xcde0eb1e),
- new int64(0xf57d4f7f, 0xee6ed178),
- new int64(0x06f067aa, 0x72176fba),
- new int64(0x0a637dc5, 0xa2c898a6),
- new int64(0x113f9804, 0xbef90dae),
- new int64(0x1b710b35, 0x131c471b),
- new int64(0x28db77f5, 0x23047d84),
- new int64(0x32caab7b, 0x40c72493),
- new int64(0x3c9ebe0a, 0x15c9bebc),
- new int64(0x431d67c4, 0x9c100d4c),
- new int64(0x4cc5d4be, 0xcb3e42b6),
- new int64(0x597f299c, 0xfc657e2a),
- new int64(0x5fcb6fab, 0x3ad6faec),
- new int64(0x6c44198c, 0x4a475817),
- ];
-
- var W = new Array(64);
- var a, b, c, d, e, f, g, h, i, j;
- var T1, T2;
- var charsize = 8;
-
- function utf8_encode(str) {
- return unescape(encodeURIComponent(str));
- }
-
- function str2binb(str) {
- var bin = [];
- var mask = (1 << charsize) - 1;
- var len = str.length * charsize;
-
- for (var i = 0; i < len; i += charsize) {
- bin[i >> 5] |=
- (str.charCodeAt(i / charsize) & mask) << (32 - charsize - (i % 32));
- }
-
- return bin;
- }
-
- function binb2hex(binarray) {
- var hex_tab = "0123456789abcdef";
- var str = "";
- var length = binarray.length * 4;
- var srcByte;
-
- for (var i = 0; i < length; i += 1) {
- srcByte = binarray[i >> 2] >> ((3 - (i % 4)) * 8);
- str +=
- hex_tab.charAt((srcByte >> 4) & 0xf) + hex_tab.charAt(srcByte & 0xf);
- }
-
- return str;
- }
-
- function safe_add_2(x, y) {
- var lsw, msw, lowOrder, highOrder;
-
- lsw = (x.lowOrder & 0xffff) + (y.lowOrder & 0xffff);
- msw = (x.lowOrder >>> 16) + (y.lowOrder >>> 16) + (lsw >>> 16);
- lowOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
-
- lsw = (x.highOrder & 0xffff) + (y.highOrder & 0xffff) + (msw >>> 16);
- msw = (x.highOrder >>> 16) + (y.highOrder >>> 16) + (lsw >>> 16);
- highOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
-
- return new int64(highOrder, lowOrder);
- }
-
- function safe_add_4(a, b, c, d) {
- var lsw, msw, lowOrder, highOrder;
-
- lsw =
- (a.lowOrder & 0xffff) +
- (b.lowOrder & 0xffff) +
- (c.lowOrder & 0xffff) +
- (d.lowOrder & 0xffff);
- msw =
- (a.lowOrder >>> 16) +
- (b.lowOrder >>> 16) +
- (c.lowOrder >>> 16) +
- (d.lowOrder >>> 16) +
- (lsw >>> 16);
- lowOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
-
- lsw =
- (a.highOrder & 0xffff) +
- (b.highOrder & 0xffff) +
- (c.highOrder & 0xffff) +
- (d.highOrder & 0xffff) +
- (msw >>> 16);
- msw =
- (a.highOrder >>> 16) +
- (b.highOrder >>> 16) +
- (c.highOrder >>> 16) +
- (d.highOrder >>> 16) +
- (lsw >>> 16);
- highOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
-
- return new int64(highOrder, lowOrder);
- }
-
- function safe_add_5(a, b, c, d, e) {
- var lsw, msw, lowOrder, highOrder;
-
- lsw =
- (a.lowOrder & 0xffff) +
- (b.lowOrder & 0xffff) +
- (c.lowOrder & 0xffff) +
- (d.lowOrder & 0xffff) +
- (e.lowOrder & 0xffff);
- msw =
- (a.lowOrder >>> 16) +
- (b.lowOrder >>> 16) +
- (c.lowOrder >>> 16) +
- (d.lowOrder >>> 16) +
- (e.lowOrder >>> 16) +
- (lsw >>> 16);
- lowOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
-
- lsw =
- (a.highOrder & 0xffff) +
- (b.highOrder & 0xffff) +
- (c.highOrder & 0xffff) +
- (d.highOrder & 0xffff) +
- (e.highOrder & 0xffff) +
- (msw >>> 16);
- msw =
- (a.highOrder >>> 16) +
- (b.highOrder >>> 16) +
- (c.highOrder >>> 16) +
- (d.highOrder >>> 16) +
- (e.highOrder >>> 16) +
- (lsw >>> 16);
- highOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
-
- return new int64(highOrder, lowOrder);
- }
-
- function maj(x, y, z) {
- return new int64(
- (x.highOrder & y.highOrder) ^
- (x.highOrder & z.highOrder) ^
- (y.highOrder & z.highOrder),
- (x.lowOrder & y.lowOrder) ^
- (x.lowOrder & z.lowOrder) ^
- (y.lowOrder & z.lowOrder)
- );
- }
-
- function ch(x, y, z) {
- return new int64(
- (x.highOrder & y.highOrder) ^ (~x.highOrder & z.highOrder),
- (x.lowOrder & y.lowOrder) ^ (~x.lowOrder & z.lowOrder)
- );
- }
-
- function rotr(x, n) {
- if (n <= 32) {
- return new int64(
- (x.highOrder >>> n) | (x.lowOrder << (32 - n)),
- (x.lowOrder >>> n) | (x.highOrder << (32 - n))
- );
- } else {
- return new int64(
- (x.lowOrder >>> n) | (x.highOrder << (32 - n)),
- (x.highOrder >>> n) | (x.lowOrder << (32 - n))
- );
- }
- }
-
- function sigma0(x) {
- var rotr28 = rotr(x, 28);
- var rotr34 = rotr(x, 34);
- var rotr39 = rotr(x, 39);
-
- return new int64(
- rotr28.highOrder ^ rotr34.highOrder ^ rotr39.highOrder,
- rotr28.lowOrder ^ rotr34.lowOrder ^ rotr39.lowOrder
- );
- }
-
- function sigma1(x) {
- var rotr14 = rotr(x, 14);
- var rotr18 = rotr(x, 18);
- var rotr41 = rotr(x, 41);
-
- return new int64(
- rotr14.highOrder ^ rotr18.highOrder ^ rotr41.highOrder,
- rotr14.lowOrder ^ rotr18.lowOrder ^ rotr41.lowOrder
- );
- }
-
- function gamma0(x) {
- var rotr1 = rotr(x, 1),
- rotr8 = rotr(x, 8),
- shr7 = shr(x, 7);
-
- return new int64(
- rotr1.highOrder ^ rotr8.highOrder ^ shr7.highOrder,
- rotr1.lowOrder ^ rotr8.lowOrder ^ shr7.lowOrder
- );
- }
-
- function gamma1(x) {
- var rotr19 = rotr(x, 19);
- var rotr61 = rotr(x, 61);
- var shr6 = shr(x, 6);
-
- return new int64(
- rotr19.highOrder ^ rotr61.highOrder ^ shr6.highOrder,
- rotr19.lowOrder ^ rotr61.lowOrder ^ shr6.lowOrder
- );
- }
-
- function shr(x, n) {
- if (n <= 32) {
- return new int64(
- x.highOrder >>> n,
- (x.lowOrder >>> n) | (x.highOrder << (32 - n))
- );
- } else {
- return new int64(0, x.highOrder << (32 - n));
- }
- }
-
- var str = utf8_encode(str);
- var strlen = str.length * charsize;
- str = str2binb(str);
-
- str[strlen >> 5] |= 0x80 << (24 - (strlen % 32));
- str[(((strlen + 128) >> 10) << 5) + 31] = strlen;
-
- for (var i = 0; i < str.length; i += 32) {
- a = H[0];
- b = H[1];
- c = H[2];
- d = H[3];
- e = H[4];
- f = H[5];
- g = H[6];
- h = H[7];
-
- for (var j = 0; j < 80; j++) {
- if (j < 16) {
- W[j] = new int64(str[j * 2 + i], str[j * 2 + i + 1]);
- } else {
- W[j] = safe_add_4(
- gamma1(W[j - 2]),
- W[j - 7],
- gamma0(W[j - 15]),
- W[j - 16]
- );
- }
-
- T1 = safe_add_5(h, sigma1(e), ch(e, f, g), K[j], W[j]);
- T2 = safe_add_2(sigma0(a), maj(a, b, c));
- h = g;
- g = f;
- f = e;
- e = safe_add_2(d, T1);
- d = c;
- c = b;
- b = a;
- a = safe_add_2(T1, T2);
- }
-
- H[0] = safe_add_2(a, H[0]);
- H[1] = safe_add_2(b, H[1]);
- H[2] = safe_add_2(c, H[2]);
- H[3] = safe_add_2(d, H[3]);
- H[4] = safe_add_2(e, H[4]);
- H[5] = safe_add_2(f, H[5]);
- H[6] = safe_add_2(g, H[6]);
- H[7] = safe_add_2(h, H[7]);
- }
-
- var binarray = [];
- for (var i = 0; i < H.length; i++) {
- binarray.push(H[i].highOrder);
- binarray.push(H[i].lowOrder);
- }
-
- return binb2hex(binarray);
- };
-
- if (!jSuites.login) {
- jSuites.login = {};
- jSuites.login.sha512 = jSuites.sha512;
- }
-
- jSuites.image = jSuites.upload = function (el, options) {
- var obj = {};
- obj.options = {};
-
- // Default configuration
- var defaults = {
- type: "image",
- extension: "*",
- input: false,
- minWidth: false,
- maxWidth: null,
- maxHeight: null,
- maxJpegSizeBytes: null, // For example, 350Kb would be 350000
- onchange: null,
- multiple: false,
- remoteParser: null,
- text: {
- extensionNotAllowed: "The extension is not allowed",
- },
- };
-
- // Loop through our object
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- obj.options[property] = defaults[property];
- }
- }
-
- // Multiple
- if (obj.options.multiple == true) {
- el.setAttribute("data-multiple", true);
- }
-
- // Container
- el.content = [];
-
- // Upload icon
- el.classList.add("jupload");
-
- if (obj.options.input == true) {
- el.classList.add("input");
- }
-
- obj.add = function (data) {
- // Reset container for single files
- if (obj.options.multiple == false) {
- el.content = [];
- el.innerText = "";
- }
-
- // Append to the element
- if (obj.options.type == "image") {
- var img = document.createElement("img");
- img.setAttribute("src", data.file);
- img.setAttribute("tabindex", -1);
- if (!el.getAttribute("name")) {
- img.className = "jfile";
- img.content = data;
- }
- el.appendChild(img);
- } else {
- if (data.name) {
- var name = data.name;
- } else {
- var name = data.file;
- }
- var div = document.createElement("div");
- div.innerText = name || obj.options.type;
- div.classList.add("jupload-item");
- div.setAttribute("tabindex", -1);
- el.appendChild(div);
- }
-
- if (data.content) {
- data.file = jSuites.guid();
- }
-
- // Push content
- el.content.push(data);
-
- // Onchange
- if (typeof obj.options.onchange == "function") {
- obj.options.onchange(el, data);
- }
- };
-
- obj.addFromFile = function (file) {
- var type = file.type.split("/");
- if (type[0] == obj.options.type) {
- var readFile = new FileReader();
- readFile.addEventListener("load", function (v) {
- var data = {
- file: v.srcElement.result,
- extension: file.name.substr(file.name.lastIndexOf(".") + 1),
- name: file.name,
- size: file.size,
- lastmodified: file.lastModified,
- content: v.srcElement.result,
- };
-
- obj.add(data);
- });
-
- readFile.readAsDataURL(file);
- } else {
- alert(obj.options.text.extensionNotAllowed);
- }
- };
-
- obj.addFromUrl = function (src) {
- if (src.substr(0, 4) != "data" && !obj.options.remoteParser) {
- console.error("remoteParser not defined in your initialization");
- } else {
- // This is to process cross domain images
- if (src.substr(0, 4) == "data") {
- var extension = src.split(";");
- extension = extension[0].split("/");
- var type = extension[0].replace("data:", "");
- if (type == obj.options.type) {
- var data = {
- file: src,
- name: "",
- extension: extension[1],
- content: src,
- };
- obj.add(data);
- } else {
- alert(obj.options.text.extensionNotAllowed);
- }
- } else {
- var extension = src.substr(src.lastIndexOf(".") + 1);
- // Work for cross browsers
- src = obj.options.remoteParser + src;
- // Get remove content
- jSuites.ajax({
- url: src,
- type: "GET",
- dataType: "blob",
- success: function (data) {
- //add(extension[0].replace('data:',''), data);
- },
- });
- }
- }
- };
-
- var getDataURL = function (canvas, type) {
- var compression = 0.92;
- var lastContentLength = null;
- var content = canvas.toDataURL(type, compression);
- while (
- obj.options.maxJpegSizeBytes &&
- type === "image/jpeg" &&
- content.length > obj.options.maxJpegSizeBytes &&
- content.length !== lastContentLength
- ) {
- // Apply the compression
- compression *= 0.9;
- lastContentLength = content.length;
- content = canvas.toDataURL(type, compression);
- }
- return content;
- };
-
- var mime = obj.options.type + "/" + obj.options.extension;
- var input = document.createElement("input");
- input.type = "file";
- input.setAttribute("accept", mime);
- input.onchange = function () {
- for (var i = 0; i < this.files.length; i++) {
- obj.addFromFile(this.files[i]);
- }
- };
-
- // Allow multiple files
- if (obj.options.multiple == true) {
- input.setAttribute("multiple", true);
- }
-
- var current = null;
-
- el.addEventListener("click", function (e) {
- current = null;
- if (!el.children.length || e.target === el) {
- jSuites.click(input);
- } else {
- if (e.target.parentNode == el) {
- current = e.target;
- }
- }
- });
-
- el.addEventListener("dblclick", function (e) {
- jSuites.click(input);
- });
-
- el.addEventListener("dragenter", function (e) {
- el.style.border = "1px dashed #000";
- });
-
- el.addEventListener("dragleave", function (e) {
- el.style.border = "1px solid #eee";
- });
-
- el.addEventListener("dragstop", function (e) {
- el.style.border = "1px solid #eee";
- });
-
- el.addEventListener("dragover", function (e) {
- e.preventDefault();
- });
-
- el.addEventListener("keydown", function (e) {
- if (current && e.which == 46) {
- var index = Array.prototype.indexOf.call(el.children, current);
- if (index >= 0) {
- el.content.splice(index, 1);
- current.remove();
- current = null;
- }
- }
- });
-
- el.addEventListener("drop", function (e) {
- e.preventDefault();
- e.stopPropagation();
-
- var html = (e.originalEvent || e).dataTransfer.getData("text/html");
- var file = (e.originalEvent || e).dataTransfer.files;
-
- if (file.length) {
- for (var i = 0; i < e.dataTransfer.files.length; i++) {
- obj.addFromFile(e.dataTransfer.files[i]);
- }
- } else if (html) {
- if (obj.options.multiple == false) {
- el.innerText = "";
- }
-
- // Create temp element
- var div = document.createElement("div");
- div.innerHTML = html;
-
- // Extract images
- var img = div.querySelectorAll("img");
-
- if (img.length) {
- for (var i = 0; i < img.length; i++) {
- obj.addFromUrl(img[i].src);
- }
- }
- }
-
- el.style.border = "1px solid #eee";
-
- return false;
- });
-
- el.val = function (val) {
- if (val === undefined) {
- return el.content && el.content.length ? el.content : null;
- } else {
- // Reset
- el.innerText = "";
- el.content = [];
-
- if (val) {
- if (Array.isArray(val)) {
- for (var i = 0; i < val.length; i++) {
- if (typeof val[i] == "string") {
- obj.add({ file: val[i] });
- } else {
- obj.add(val[i]);
- }
- }
- } else if (typeof val == "string") {
- obj.add({ file: val });
- }
- }
- }
- };
-
- el.upload = el.image = obj;
-
- return obj;
- };
-
- jSuites.image.create = function (data) {
- var img = document.createElement("img");
- img.setAttribute("src", data.file);
- img.className = "jfile";
- img.setAttribute("tabindex", -1);
- img.content = data;
-
- return img;
- };
-
- jSuites.lazyLoading = function (el, options) {
- var obj = {};
-
- // Mandatory options
- if (!options.loadUp || typeof options.loadUp != "function") {
- options.loadUp = function () {
- return false;
- };
- }
- if (!options.loadDown || typeof options.loadDown != "function") {
- options.loadDown = function () {
- return false;
- };
- }
- // Timer ms
- if (!options.timer) {
- options.timer = 100;
- }
-
- // Timer
- var timeControlLoading = null;
-
- // Controls
- var scrollControls = function (e) {
- if (timeControlLoading == null) {
- var event = false;
- var scrollTop = el.scrollTop;
- if (el.scrollTop + el.clientHeight * 2 >= el.scrollHeight) {
- if (options.loadDown()) {
- if (scrollTop == el.scrollTop) {
- el.scrollTop = el.scrollTop - el.clientHeight;
- }
- event = true;
- }
- } else if (el.scrollTop <= el.clientHeight) {
- if (options.loadUp()) {
- if (scrollTop == el.scrollTop) {
- el.scrollTop = el.scrollTop + el.clientHeight;
- }
- event = true;
- }
- }
-
- timeControlLoading = setTimeout(function () {
- timeControlLoading = null;
- }, options.timer);
-
- if (event) {
- if (typeof options.onupdate == "function") {
- options.onupdate();
- }
- }
- }
- };
-
- // Onscroll
- el.onscroll = function (e) {
- scrollControls(e);
- };
-
- el.onwheel = function (e) {
- scrollControls(e);
- };
-
- return obj;
- };
-
- jSuites.loading = (function () {
- var obj = {};
-
- var loading = null;
-
- obj.show = function () {
- if (!loading) {
- loading = document.createElement("div");
- loading.className = "jloading";
- }
- document.body.appendChild(loading);
- };
-
- obj.hide = function () {
- if (loading && loading.parentNode) {
- document.body.removeChild(loading);
- }
- };
-
- return obj;
- })();
-
- jSuites.mask = (function () {
- // Currency
- var tokens = {
- // Text
- text: ["@"],
- // Currency tokens
- currency: ["#(.{1})##0?(.{1}0+)?( ?;(.*)?)?", "#"],
- // Percentage
- percentage: ["0{1}(.{1}0+)?%"],
- // Number
- numeric: ["0{1}(.{1}0+)?"],
- // Data tokens
- datetime: [
- "YYYY",
- "YYY",
- "YY",
- "MMMMM",
- "MMMM",
- "MMM",
- "MM",
- "DDDDD",
- "DDDD",
- "DDD",
- "DD",
- "DY",
- "DAY",
- "WD",
- "D",
- "Q",
- "HH24",
- "HH12",
- "HH",
- "\\[H\\]",
- "H",
- "AM/PM",
- "PM",
- "AM",
- "MI",
- "SS",
- "MS",
- "MONTH",
- "MON",
- "Y",
- "M",
- ],
- // Other
- general: ["A", "0", "[0-9a-zA-Z$]+", "."],
- };
-
- var getDate = function () {
- if (this.mask.toLowerCase().indexOf("[h]") !== -1) {
- var m = 0;
- if (this.date[4]) {
- m = parseFloat(this.date[4] / 60);
- }
- var v = parseInt(this.date[3]) + m;
- v /= 24;
- } else if (
- !(this.date[0] && this.date[1] && this.date[2]) &&
- (this.date[3] || this.date[4])
- ) {
- v =
- jSuites.two(this.date[3]) +
- ":" +
- jSuites.two(this.date[4]) +
- ":" +
- jSuites.two(this.date[5]);
- } else {
- if (this.date[0] && this.date[1] && !this.date[2]) {
- this.date[2] = 1;
- }
- v =
- jSuites.two(this.date[0]) +
- "-" +
- jSuites.two(this.date[1]) +
- "-" +
- jSuites.two(this.date[2]);
-
- if (this.date[3] || this.date[4] || this.date[5]) {
- v +=
- " " +
- jSuites.two(this.date[3]) +
- ":" +
- jSuites.two(this.date[4]) +
- ":" +
- jSuites.two(this.date[5]);
- }
- }
-
- return v;
- };
-
- var isBlank = function (v) {
- return v === null || v === "" || v === undefined ? true : false;
- };
-
- var isFormula = function (value) {
- return ("" + value).chartAt(0) == "=";
- };
-
- var isNumeric = function (t) {
- return t === "currency" || t === "percentage" || t === "numeric"
- ? true
- : false;
- };
- /**
- * Get the decimal defined in the mask configuration
- */
- var getDecimal = function (v) {
- if (v && Number(v) == v) {
- return ".";
- } else {
- if (this.options.decimal) {
- return this.options.decimal;
- } else {
- if (this.locale) {
- var t = Intl.NumberFormat(this.locale).format(1.1);
- return (this.options.decimal = t[1]);
- } else {
- if (!v) {
- v = this.mask;
- }
- var e = new RegExp("0{1}(.{1})0+", "ig");
- var t = e.exec(v);
- if (t && t[1] && t[1].length == 1) {
- // Save decimal
- this.options.decimal = t[1];
- // Return decimal
- return t[1];
- } else {
- // Did not find any decimal last resort the default
- var e = new RegExp("#{1}(.{1})#+", "ig");
- var t = e.exec(v);
- if (t && t[1] && t[1].length == 1) {
- if (t[1] === ",") {
- this.options.decimal = ".";
- } else {
- this.options.decimal = ",";
- }
- } else {
- this.options.decimal = "1.1".toLocaleString().substring(1, 2);
- }
- }
- }
- }
- }
-
- if (this.options.decimal) {
- return this.options.decimal;
- } else {
- return null;
- }
- };
-
- var ParseValue = function (v, decimal) {
- if (v == "") {
- return "";
- }
-
- // Get decimal
- if (!decimal) {
- decimal = getDecimal.call(this);
- }
-
- // New value
- v = ("" + v).split(decimal);
-
- // Signal
- var signal = v[0].match(/[-]+/g);
- if (signal && signal.length) {
- signal = true;
- } else {
- signal = false;
- }
-
- v[0] = v[0].match(/[0-9]+/g);
-
- if (v[0]) {
- if (signal) {
- v[0].unshift("-");
- }
- v[0] = v[0].join("");
- } else {
- if (signal) {
- v[0] = "-";
- }
- }
-
- if (v[0] || v[1]) {
- if (v[1] !== undefined) {
- v[1] = v[1].match(/[0-9]+/g);
- if (v[1]) {
- v[1] = v[1].join("");
- } else {
- v[1] = "";
- }
- }
- } else {
- return "";
- }
- return v;
- };
-
- var FormatValue = function (v, event) {
- if (v == "") {
- return "";
- }
- // Get decimal
- var d = getDecimal.call(this);
- // Convert value
- var o = this.options;
- // Parse value
- v = ParseValue.call(this, v);
- if (v == "") {
- return "";
- }
- // Temporary value
- if (v[0]) {
- var t = parseFloat(v[0] + ".1");
- if (o.style == "percent") {
- t /= 100;
- }
- } else {
- var t = null;
- }
-
- if (
- (v[0] == "-" || v[0] == "-00") &&
- !v[1] &&
- event &&
- event.inputType == "deleteContentBackward"
- ) {
- return "";
- }
-
- var n = new Intl.NumberFormat(this.locale, o).format(t);
- n = n.split(d);
- if (typeof n[1] !== "undefined") {
- var s = n[1].replace(/[0-9]*/g, "");
- if (s) {
- n[2] = s;
- }
- }
-
- if (v[1] !== undefined) {
- n[1] = d + v[1];
- } else {
- n[1] = "";
- }
-
- return n.join("");
- };
-
- var Format = function (e, event) {
- var v = Value.call(e);
- if (!v) {
- return;
- }
-
- // Get decimal
- var d = getDecimal.call(this);
- var n = FormatValue.call(this, v, event);
- var t = n.length - v.length;
- var index = Caret.call(e) + t;
- // Set value and update caret
- Value.call(e, n, index, true);
- };
-
- var Extract = function (v) {
- // Keep the raw value
- var current = ParseValue.call(this, v);
- if (current) {
- // Negative values
- if (current[0] === "-") {
- current[0] = "-0";
- }
- return parseFloat(current.join("."));
- }
- return null;
- };
-
- /**
- * Caret getter and setter methods
- */
- var Caret = function (index, adjustNumeric) {
- if (index === undefined) {
- if (this.tagName == "DIV") {
- var pos = 0;
- var s = window.getSelection();
- if (s) {
- if (s.rangeCount !== 0) {
- var r = s.getRangeAt(0);
- var p = r.cloneRange();
- p.selectNodeContents(this);
- p.setEnd(r.endContainer, r.endOffset);
- pos = p.toString().length;
- }
- }
- return pos;
- } else {
- return this.selectionStart;
- }
- } else {
- // Get the current value
- var n = Value.call(this);
-
- // Review the position
- if (adjustNumeric) {
- var p = null;
- for (var i = 0; i < n.length; i++) {
- if (n[i].match(/[\-0-9]/g) || n[i] == "." || n[i] == ",") {
- p = i;
- }
- }
-
- // If the string has no numbers
- if (p === null) {
- p = n.indexOf(" ");
- }
-
- if (index >= p) {
- index = p + 1;
- }
- }
-
- // Do not update caret
- if (index > n.length) {
- index = n.length;
- }
-
- if (index) {
- // Set caret
- if (this.tagName == "DIV") {
- var s = window.getSelection();
- var r = document.createRange();
-
- if (this.childNodes[0]) {
- r.setStart(this.childNodes[0], index);
- s.removeAllRanges();
- s.addRange(r);
- }
- } else {
- this.selectionStart = index;
- this.selectionEnd = index;
- }
- }
- }
- };
-
- /**
- * Value getter and setter method
- */
- var Value = function (v, updateCaret, adjustNumeric) {
- if (this.tagName == "DIV") {
- if (v === undefined) {
- var v = this.innerText;
- if (this.value && this.value.length > v.length) {
- v = this.value;
- }
- return v;
- } else {
- if (this.innerText !== v) {
- this.innerText = v;
-
- if (updateCaret) {
- Caret.call(this, updateCaret, adjustNumeric);
- }
- }
- }
- } else {
- if (v === undefined) {
- return this.value;
- } else {
- if (this.value !== v) {
- this.value = v;
- if (updateCaret) {
- Caret.call(this, updateCaret, adjustNumeric);
- }
- }
- }
- }
- };
-
- // Labels
- var weekDaysFull = jSuites.calendar.weekdays;
- var weekDays = jSuites.calendar.weekdaysShort;
- var monthsFull = jSuites.calendar.months;
- var months = jSuites.calendar.monthsShort;
-
- var parser = {
- YEAR: function (v, s) {
- var y = "" + new Date().getFullYear();
-
- if (typeof this.values[this.index] === "undefined") {
- this.values[this.index] = "";
- }
- if (parseInt(v) >= 0 && parseInt(v) <= 10) {
- if (this.values[this.index].length < s) {
- this.values[this.index] += v;
- }
- }
- if (this.values[this.index].length == s) {
- if (s == 2) {
- var y = y.substr(0, 2) + this.values[this.index];
- } else if (s == 3) {
- var y = y.substr(0, 1) + this.values[this.index];
- } else if (s == 4) {
- var y = this.values[this.index];
- }
- this.date[0] = y;
- this.index++;
- }
- },
- YYYY: function (v) {
- parser.YEAR.call(this, v, 4);
- },
- YYY: function (v) {
- parser.YEAR.call(this, v, 3);
- },
- YY: function (v) {
- parser.YEAR.call(this, v, 2);
- },
- FIND: function (v, a) {
- if (isBlank(this.values[this.index])) {
- this.values[this.index] = "";
- }
- var pos = 0;
- var count = 0;
- var value = (this.values[this.index] + v).toLowerCase();
- for (var i = 0; i < a.length; i++) {
- if (a[i].toLowerCase().indexOf(value) == 0) {
- pos = i;
- count++;
- }
- }
- if (count > 1) {
- this.values[this.index] += v;
- } else if (count == 1) {
- // Jump number of chars
- var t = a[pos].length - this.values[this.index].length - 1;
- this.position += t;
-
- this.values[this.index] = a[pos];
- this.index++;
- return pos;
- }
- },
- MMM: function (v) {
- var ret = parser.FIND.call(this, v, months);
- if (ret !== undefined) {
- this.date[1] = ret + 1;
- }
- },
- MMMM: function (v) {
- var ret = parser.FIND.call(this, v, monthsFull);
- if (ret !== undefined) {
- this.date[1] = ret + 1;
- }
- },
- MMMMM: function (v) {
- if (isBlank(this.values[this.index])) {
- this.values[this.index] = "";
- }
- var pos = 0;
- var count = 0;
- var value = (this.values[this.index] + v).toLowerCase();
- for (var i = 0; i < monthsFull.length; i++) {
- if (monthsFull[i][0].toLowerCase().indexOf(value) == 0) {
- this.values[this.index] = monthsFull[i][0];
- this.date[1] = i + 1;
- this.index++;
- break;
- }
- }
- },
- MM: function (v) {
- if (isBlank(this.values[this.index])) {
- if (parseInt(v) > 1 && parseInt(v) < 10) {
- this.date[1] = this.values[this.index] = "0" + v;
- this.index++;
- } else if (parseInt(v) < 2) {
- this.values[this.index] = v;
- }
- } else {
- if (this.values[this.index] == 1 && parseInt(v) < 3) {
- this.date[1] = this.values[this.index] += v;
- this.index++;
- } else if (
- this.values[this.index] == 0 &&
- parseInt(v) > 0 &&
- parseInt(v) < 10
- ) {
- this.date[1] = this.values[this.index] += v;
- this.index++;
- }
- }
- },
- M: function (v) {
- var test = false;
- if (parseInt(v) >= 0 && parseInt(v) < 10) {
- if (isBlank(this.values[this.index])) {
- this.values[this.index] = v;
- if (v > 1) {
- this.date[1] = this.values[this.index];
- this.index++;
- }
- } else {
- if (this.values[this.index] == 1 && parseInt(v) < 3) {
- this.date[1] = this.values[this.index] += v;
- this.index++;
- } else if (this.values[this.index] == 0 && parseInt(v) > 0) {
- this.date[1] = this.values[this.index] += v;
- this.index++;
- } else {
- var test = true;
- }
- }
- } else {
- var test = true;
- }
-
- // Re-test
- if (test == true) {
- var t = parseInt(this.values[this.index]);
- if (t > 0 && t < 12) {
- this.date[2] = this.values[this.index];
- this.index++;
- // Repeat the character
- this.position--;
- }
- }
- },
- D: function (v) {
- var test = false;
- if (parseInt(v) >= 0 && parseInt(v) < 10) {
- if (isBlank(this.values[this.index])) {
- this.values[this.index] = v;
- if (parseInt(v) > 3) {
- this.date[2] = this.values[this.index];
- this.index++;
- }
- } else {
- if (this.values[this.index] == 3 && parseInt(v) < 2) {
- this.date[2] = this.values[this.index] += v;
- this.index++;
- } else if (
- this.values[this.index] == 1 ||
- this.values[this.index] == 2
- ) {
- this.date[2] = this.values[this.index] += v;
- this.index++;
- } else if (this.values[this.index] == 0 && parseInt(v) > 0) {
- this.date[2] = this.values[this.index] += v;
- this.index++;
- } else {
- var test = true;
- }
- }
- } else {
- var test = true;
- }
-
- // Re-test
- if (test == true) {
- var t = parseInt(this.values[this.index]);
- if (t > 0 && t < 32) {
- this.date[2] = this.values[this.index];
- this.index++;
- // Repeat the character
- this.position--;
- }
- }
- },
- DD: function (v) {
- if (isBlank(this.values[this.index])) {
- if (parseInt(v) > 3 && parseInt(v) < 10) {
- this.date[2] = this.values[this.index] = "0" + v;
- this.index++;
- } else if (parseInt(v) < 10) {
- this.values[this.index] = v;
- }
- } else {
- if (this.values[this.index] == 3 && parseInt(v) < 2) {
- this.date[2] = this.values[this.index] += v;
- this.index++;
- } else if (
- (this.values[this.index] == 1 || this.values[this.index] == 2) &&
- parseInt(v) < 10
- ) {
- this.date[2] = this.values[this.index] += v;
- this.index++;
- } else if (
- this.values[this.index] == 0 &&
- parseInt(v) > 0 &&
- parseInt(v) < 10
- ) {
- this.date[2] = this.values[this.index] += v;
- this.index++;
- }
- }
- },
- DDD: function (v) {
- parser.FIND.call(this, v, weekDays);
- },
- DDDD: function (v) {
- parser.FIND.call(this, v, weekDaysFull);
- },
- HH12: function (v, two) {
- if (isBlank(this.values[this.index])) {
- if (parseInt(v) > 1 && parseInt(v) < 10) {
- if (two) {
- v = 0 + v;
- }
- this.date[3] = this.values[this.index] = v;
- this.index++;
- } else if (parseInt(v) < 10) {
- this.values[this.index] = v;
- }
- } else {
- if (this.values[this.index] == 1 && parseInt(v) < 3) {
- this.date[3] = this.values[this.index] += v;
- this.index++;
- } else if (this.values[this.index] < 1 && parseInt(v) < 10) {
- this.date[3] = this.values[this.index] += v;
- this.index++;
- }
- }
- },
- HH24: function (v, two) {
- var test = false;
- if (parseInt(v) >= 0 && parseInt(v) < 10) {
- if (
- this.values[this.index] == null ||
- this.values[this.index] == ""
- ) {
- if (parseInt(v) > 2 && parseInt(v) < 10) {
- if (two) {
- v = 0 + v;
- }
- this.date[3] = this.values[this.index] = v;
- this.index++;
- } else if (parseInt(v) < 10) {
- this.values[this.index] = v;
- }
- } else {
- if (this.values[this.index] == 2 && parseInt(v) < 4) {
- this.date[3] = this.values[this.index] += v;
- this.index++;
- } else if (this.values[this.index] < 2 && parseInt(v) < 10) {
- this.date[3] = this.values[this.index] += v;
- this.index++;
- }
- }
- }
- },
- HH: function (v) {
- parser["HH24"].call(this, v, 1);
- },
- H: function (v) {
- parser["HH24"].call(this, v, 0);
- },
- "\\[H\\]": function (v) {
- if (this.values[this.index] == undefined) {
- this.values[this.index] = "";
- }
- if (v.match(/[0-9]/g)) {
- this.date[3] = this.values[this.index] += v;
- } else {
- if (this.values[this.index].match(/[0-9]/g)) {
- this.date[3] = this.values[this.index];
- this.index++;
- // Repeat the character
- this.position--;
- }
- }
- },
- N60: function (v, i) {
- if (this.values[this.index] == null || this.values[this.index] == "") {
- if (parseInt(v) > 5 && parseInt(v) < 10) {
- this.date[i] = this.values[this.index] = "0" + v;
- this.index++;
- } else if (parseInt(v) < 10) {
- this.values[this.index] = v;
- }
- } else {
- if (parseInt(v) < 10) {
- this.date[i] = this.values[this.index] += v;
- this.index++;
- }
- }
- },
- MI: function (v) {
- parser.N60.call(this, v, 4);
- },
- SS: function (v) {
- parser.N60.call(this, v, 5);
- },
- "AM/PM": function (v) {
- this.values[this.index] = "";
- if (v) {
- if (this.date[3] > 12) {
- this.values[this.index] = "PM";
- } else {
- this.values[this.index] = "AM";
- }
- }
- this.index++;
- },
- WD: function (v) {
- if (typeof this.values[this.index] === "undefined") {
- this.values[this.index] = "";
- }
- if (parseInt(v) >= 0 && parseInt(v) < 7) {
- this.values[this.index] = v;
- }
- if (this.value[this.index].length == 1) {
- this.index++;
- }
- },
- "0{1}(.{1}0+)?": function (v) {
- // Get decimal
- var decimal = getDecimal.call(this);
- // Negative number
- var neg = false;
- // Create if is blank
- if (isBlank(this.values[this.index])) {
- this.values[this.index] = "";
- } else {
- if (this.values[this.index] == "-") {
- neg = true;
- }
- }
- var current = ParseValue.call(this, this.values[this.index], decimal);
- if (current) {
- this.values[this.index] = current.join(decimal);
- }
- // New entry
- if (parseInt(v) >= 0 && parseInt(v) < 10) {
- // Replace the zero for a number
- if (this.values[this.index] == "0" && v > 0) {
- this.values[this.index] = "";
- } else if (this.values[this.index] == "-0" && v > 0) {
- this.values[this.index] = "-";
- }
- // Don't add up zeros because does not mean anything here
- if (
- (this.values[this.index] != "0" &&
- this.values[this.index] != "-0") ||
- v == decimal
- ) {
- this.values[this.index] += v;
- }
- } else if (decimal && v == decimal) {
- if (this.values[this.index].indexOf(decimal) == -1) {
- if (!this.values[this.index]) {
- this.values[this.index] = "0";
- }
- this.values[this.index] += v;
- }
- } else if (v == "-") {
- // Negative signed
- neg = true;
- }
-
- if (neg === true && this.values[this.index][0] !== "-") {
- this.values[this.index] = "-" + this.values[this.index];
- }
- },
- "0{1}(.{1}0+)?%": function (v) {
- parser["0{1}(.{1}0+)?"].call(this, v);
-
- if (this.values[this.index].match(/[\-0-9]/g)) {
- if (
- this.values[this.index] &&
- this.values[this.index].indexOf("%") == -1
- ) {
- this.values[this.index] += "%";
- }
- } else {
- this.values[this.index] = "";
- }
- },
- "#(.{1})##0?(.{1}0+)?( ?;(.*)?)?": function (v) {
- // Parse number
- parser["0{1}(.{1}0+)?"].call(this, v);
- // Get decimal
- var decimal = getDecimal.call(this);
- // Get separator
- var separator = this.tokens[this.index].substr(1, 1);
- // Negative
- var negative = this.values[this.index][0] === "-" ? true : false;
- // Current value
- var current = ParseValue.call(this, this.values[this.index], decimal);
-
- // Get main and decimal parts
- if (current !== "") {
- // Format number
- var n = current[0].match(/[0-9]/g);
- if (n) {
- // Format
- n = n.join("");
- var t = [];
- var s = 0;
- for (var j = n.length - 1; j >= 0; j--) {
- t.push(n[j]);
- s++;
- if (!(s % 3)) {
- t.push(separator);
- }
- }
- t = t.reverse();
- current[0] = t.join("");
- if (current[0].substr(0, 1) == separator) {
- current[0] = current[0].substr(1);
- }
- } else {
- current[0] = "";
- }
-
- // Value
- this.values[this.index] = current.join(decimal);
-
- // Negative
- if (negative) {
- this.values[this.index] = "-" + this.values[this.index];
- }
- }
- },
- 0: function (v) {
- if (v.match(/[0-9]/g)) {
- this.values[this.index] = v;
- this.index++;
- }
- },
- "[0-9a-zA-Z$]+": function (v) {
- if (isBlank(this.values[this.index])) {
- this.values[this.index] = "";
- }
- var t = this.tokens[this.index];
- var s = this.values[this.index];
- var i = s.length;
-
- if (t[i] == v) {
- this.values[this.index] += v;
-
- if (this.values[this.index] == t) {
- this.index++;
- }
- } else {
- this.values[this.index] = t;
- this.index++;
-
- if (v.match(/[\-0-9]/g)) {
- // Repeat the character
- this.position--;
- }
- }
- },
- A: function (v) {
- if (v.match(/[a-zA-Z]/gi)) {
- this.values[this.index] = v;
- this.index++;
- }
- },
- ".": function (v) {
- parser["[0-9a-zA-Z$]+"].call(this, v);
- },
- "@": function (v) {
- if (isBlank(this.values[this.index])) {
- this.values[this.index] = "";
- }
- this.values[this.index] += v;
- },
- };
-
- /**
- * Get the tokens in the mask string
- */
- var getTokens = function (str) {
- if (this.type == "general") {
- var t = [].concat(tokens.general);
- } else {
- var t = [].concat(
- tokens.currency,
- tokens.datetime,
- tokens.percentage,
- tokens.numeric,
- tokens.text,
- tokens.general
- );
- }
- // Expression to extract all tokens from the string
- var e = new RegExp(t.join("|"), "gi");
- // Extract
- return str.match(e);
- };
-
- /**
- * Get the method of one given token
- */
- var getMethod = function (str) {
- if (!this.type) {
- var types = Object.keys(tokens);
- } else if (this.type == "text") {
- var types = ["text"];
- } else if (this.type == "general") {
- var types = ["general"];
- } else if (this.type == "datetime") {
- var types = ["numeric", "datetime", "general"];
- } else {
- var types = ["currency", "percentage", "numeric", "general"];
- }
-
- // Found
- for (var i = 0; i < types.length; i++) {
- var type = types[i];
- for (var j = 0; j < tokens[type].length; j++) {
- var e = new RegExp(tokens[type][j], "gi");
- var r = str.match(e);
- if (r) {
- return { type: type, method: tokens[type][j] };
- }
- }
- }
- };
-
- /**
- * Identify each method for each token
- */
- var getMethods = function (t) {
- var result = [];
- for (var i = 0; i < t.length; i++) {
- var m = getMethod.call(this, t[i]);
- if (m) {
- result.push(m.method);
- } else {
- result.push(null);
- }
- }
-
- // Compatibility with excel
- for (var i = 0; i < result.length; i++) {
- if (result[i] == "MM") {
- // Not a month, correct to minutes
- if (result[i - 1] && result[i - 1].indexOf("H") >= 0) {
- result[i] = "MI";
- } else if (result[i - 2] && result[i - 2].indexOf("H") >= 0) {
- result[i] = "MI";
- } else if (result[i + 1] && result[i + 1].indexOf("S") >= 0) {
- result[i] = "MI";
- } else if (result[i + 2] && result[i + 2].indexOf("S") >= 0) {
- result[i] = "MI";
- }
- }
- }
-
- return result;
- };
-
- /**
- * Get the type for one given token
- */
- var getType = function (str) {
- var m = getMethod.call(this, str);
- if (m) {
- var type = m.type;
- }
-
- if (type) {
- var numeric = 0;
- // Make sure the correct type
- var t = getTokens.call(this, str);
- for (var i = 0; i < t.length; i++) {
- m = getMethod.call(this, t[i]);
- if (m && isNumeric(m.type)) {
- numeric++;
- }
- }
- if (numeric > 1) {
- type = "general";
- }
- }
-
- return type;
- };
-
- /**
- * Parse character per character using the detected tokens in the mask
- */
- var parse = function () {
- // Parser method for this position
- if (typeof parser[this.methods[this.index]] == "function") {
- parser[this.methods[this.index]].call(this, this.value[this.position]);
- this.position++;
- } else {
- this.values[this.index] = this.tokens[this.index];
- this.index++;
- }
- };
-
- var isFormula = function (value) {
- var v = ("" + value)[0];
- return v == "=" ? true : false;
- };
-
- var toPlainString = function (num) {
- return ("" + +num).replace(
- /(-?)(\d*)\.?(\d*)e([+-]\d+)/,
- function (a, b, c, d, e) {
- return e < 0
- ? b + "0." + Array(1 - e - c.length).join(0) + c + d
- : b + c + d + Array(e - d.length + 1).join(0);
- }
- );
- };
-
- /**
- * Mask function
- * @param {mixed|string} JS input or a string to be parsed
- * @param {object|string} When the first param is a string, the second is the mask or object with the mask options
- */
- var obj = function (e, config, returnObject) {
- // Options
- var r = null;
- var t = null;
- var o = {
- // Element
- input: null,
- // Current value
- value: null,
- // Mask options
- options: {},
- // New values for each token found
- values: [],
- // Token position
- index: 0,
- // Character position
- position: 0,
- // Date raw values
- date: [0, 0, 0, 0, 0, 0],
- // Raw number for the numeric values
- number: 0,
- };
-
- // This is a JavaScript Event
- if (typeof e == "object") {
- // Element
- o.input = e.target;
- // Current value
- o.value = Value.call(e.target);
- // Current caret position
- o.caret = Caret.call(e.target);
- // Mask
- if ((t = e.target.getAttribute("data-mask"))) {
- o.mask = t;
- }
- // Type
- if ((t = e.target.getAttribute("data-type"))) {
- o.type = t;
- }
- // Options
- if (e.target.mask) {
- if (e.target.mask.options) {
- o.options = e.target.mask.options;
- }
- if (e.target.mask.locale) {
- o.locale = e.target.mask.locale;
- }
- } else {
- // Locale
- if ((t = e.target.getAttribute("data-locale"))) {
- o.locale = t;
- if (o.mask) {
- o.options.style = o.mask;
- }
- }
- }
- // Extra configuration
- if (e.target.attributes && e.target.attributes.length) {
- for (var i = 0; i < e.target.attributes.length; i++) {
- var k = e.target.attributes[i].name;
- var v = e.target.attributes[i].value;
- if (k.substr(0, 4) == "data") {
- o.options[k.substr(5)] = v;
- }
- }
- }
- } else {
- // Options
- if (typeof config == "string") {
- // Mask
- o.mask = config;
- } else {
- // Mask
- var k = Object.keys(config);
- for (var i = 0; i < k.length; i++) {
- o[k[i]] = config[k[i]];
- }
- }
-
- if (typeof e === "number") {
- // Get decimal
- getDecimal.call(o, o.mask);
- // Replace to the correct decimal
- e = ("" + e).replace(".", o.options.decimal);
- }
-
- // Current
- o.value = e;
-
- if (o.input) {
- // Value
- Value.call(o.input, e);
- // Focus
- jSuites.focus(o.input);
- // Caret
- o.caret = Caret.call(o.input);
- }
- }
-
- // Mask detected start the process
- if (!isFormula(o.value) && (o.mask || o.locale)) {
- // Compatibility fixes
- if (o.mask) {
- // Remove []
- o.mask = o.mask.replace(new RegExp(/\[h]/), "|h|");
- o.mask = o.mask.replace(new RegExp(/\[.*?\]/), "");
- o.mask = o.mask.replace(new RegExp(/\|h\|/), "[h]");
- if (o.mask.indexOf(";") !== -1) {
- var t = o.mask.split(";");
- o.mask = t[0];
- }
- // Excel mask TODO: Improve
- if (o.mask.indexOf("##") !== -1) {
- var d = o.mask.split(";");
- if (d[0]) {
- d[0] = d[0].replace("*", "\t");
- d[0] = d[0].replace(new RegExp(/_-/g), " ");
- d[0] = d[0].replace(new RegExp(/_/g), "");
- d[0] = d[0].replace("##0.###", "##0.000");
- d[0] = d[0].replace("##0.##", "##0.00");
- d[0] = d[0].replace("##0.#", "##0.0");
- d[0] = d[0].replace("##0,###", "##0,000");
- d[0] = d[0].replace("##0,##", "##0,00");
- d[0] = d[0].replace("##0,#", "##0,0");
- }
- o.mask = d[0];
- }
- // Get type
- if (!o.type) {
- o.type = getType.call(o, o.mask);
- }
- // Get tokens
- o.tokens = getTokens.call(o, o.mask);
- }
- // On new input
- if (
- typeof e !== "object" ||
- !e.inputType ||
- !e.inputType.indexOf("insert") ||
- !e.inputType.indexOf("delete")
- ) {
- // Start transformation
- if (o.locale) {
- if (o.input) {
- Format.call(o, o.input, e);
- } else {
- var newValue = FormatValue.call(o, o.value);
- }
- } else {
- // Get tokens
- o.methods = getMethods.call(o, o.tokens);
- // Go through all tokes
- while (
- o.position < o.value.length &&
- typeof o.tokens[o.index] !== "undefined"
- ) {
- // Get the appropriate parser
- parse.call(o);
- }
-
- // New value
- var newValue = o.values.join("");
-
- // Add tokens to the end of string only if string is not empty
- if (isNumeric(o.type) && newValue !== "") {
- // Complement things in the end of the mask
- while (typeof o.tokens[o.index] !== "undefined") {
- var t = getMethod.call(o, o.tokens[o.index]);
- if (t && t.type == "general") {
- o.values[o.index] = o.tokens[o.index];
- }
- o.index++;
- }
-
- var adjustNumeric = true;
- } else {
- var adjustNumeric = false;
- }
-
- // New value
- newValue = o.values.join("");
-
- // Reset value
- if (o.input) {
- t = newValue.length - o.value.length;
- if (t > 0) {
- var caret = o.caret + t;
- } else {
- var caret = o.caret;
- }
- Value.call(o.input, newValue, caret, adjustNumeric);
- }
- }
- }
-
- // Update raw data
- if (o.input) {
- var label = null;
- if (isNumeric(o.type)) {
- // Extract the number
- o.number = Extract.call(o, Value.call(o.input));
- // Keep the raw data as a property of the tag
- if (o.type == "percentage") {
- label = o.number / 100;
- } else {
- label = o.number;
- }
- } else if (o.type == "datetime") {
- label = getDate.call(o);
-
- if (o.date[0] && o.date[1] && o.date[2]) {
- o.input.setAttribute("data-completed", true);
- }
- }
-
- if (label) {
- o.input.setAttribute("data-value", label);
- }
- }
-
- if (newValue !== undefined) {
- if (returnObject) {
- return o;
- } else {
- return newValue;
- }
- }
- }
- };
-
- // Get the type of the mask
- obj.getType = getType;
-
- // Extract the tokens from a mask
- obj.prepare = function (str, o) {
- if (!o) {
- o = {};
- }
- return getTokens.call(o, str);
- };
-
- /**
- * Apply the mask to a element (legacy)
- */
- obj.apply = function (e) {
- var v = Value.call(e.target);
- if (e.key.length == 1) {
- v += e.key;
- }
- Value.call(e.target, obj(v, e.target.getAttribute("data-mask")));
- };
-
- /**
- * Legacy support
- */
- obj.run = function (value, mask, decimal) {
- return obj(value, { mask: mask, decimal: decimal });
- };
-
- /**
- * Extract number from masked string
- */
- obj.extract = function (v, options, returnObject) {
- if (isBlank(v)) {
- return v;
- }
- if (typeof options != "object") {
- return value;
- } else {
- options = Object.assign({}, options);
-
- if (!options.options) {
- options.options = {};
- }
- }
-
- // Compatibility
- if (!options.mask && options.format) {
- options.mask = options.format;
- }
-
- // Remove []
- if (options.mask) {
- if (options.mask.indexOf(";") !== -1) {
- var t = options.mask.split(";");
- options.mask = t[0];
- }
- options.mask = options.mask.replace(new RegExp(/\[.*?\]/), "");
- }
-
- // Get decimal
- getDecimal.call(options, options.mask);
-
- var type = null;
- if (options.type == "percent" || options.options.style == "percent") {
- type = "percentage";
- } else if (options.mask) {
- type = getType.call(options, options.mask);
- }
-
- if (type === "general") {
- var o = obj(v, options, true);
-
- value = v;
- } else if (type === "datetime") {
- if (v instanceof Date) {
- var t = jSuites.calendar.getDateString(value, options.mask);
- }
-
- var o = obj(v, options, true);
-
- if (jSuites.isNumeric(v)) {
- value = v;
- } else {
- var value = getDate.call(o);
- var t = jSuites.calendar.now(o.date);
- value = jSuites.calendar.dateToNum(t);
- }
- } else {
- var value = Extract.call(options, v);
- // Percentage
- if (type == "percentage") {
- value /= 100;
- }
- var o = options;
- }
-
- o.value = value;
-
- if (!o.type && type) {
- o.type = type;
- }
-
- if (returnObject) {
- return o;
- } else {
- return value;
- }
- };
-
- /**
- * Render
- */
- obj.render = function (value, options, fullMask) {
- if (isBlank(value)) {
- return value;
- }
-
- if (typeof options != "object") {
- return value;
- } else {
- options = Object.assign({}, options);
-
- if (!options.options) {
- options.options = {};
- }
- }
-
- // Compatibility
- if (!options.mask && options.format) {
- options.mask = options.format;
- }
-
- // Remove []
- if (options.mask) {
- if (options.mask.indexOf(";") !== -1) {
- var t = options.mask.split(";");
- options.mask = t[0];
- }
- options.mask = options.mask.replace(new RegExp(/\[h]/), "|h|");
- options.mask = options.mask.replace(new RegExp(/\[.*?\]/), "");
- options.mask = options.mask.replace(new RegExp(/\|h\|/), "[h]");
- }
-
- var type = null;
- if (options.type == "percent" || options.options.style == "percent") {
- type = "percentage";
- } else if (options.mask) {
- type = getType.call(options, options.mask);
- } else if (value instanceof Date) {
- type = "datetime";
- }
-
- // Fill with blanks
- var fillWithBlanks = false;
-
- if (type == "datetime" || options.type == "calendar") {
- var t = jSuites.calendar.getDateString(value, options.mask);
- if (t) {
- value = t;
- }
-
- if (options.mask && fullMask) {
- fillWithBlanks = true;
- }
- } else {
- // Percentage
- if (type == "percentage") {
- value *= 100;
- }
- // Number of decimal places
- if (typeof value === "number") {
- var t = null;
- if (options.mask && fullMask) {
- var d = getDecimal.call(options, options.mask);
- if (options.mask.indexOf(d) !== -1) {
- d = options.mask.split(d);
- d = "" + d[1].match(/[0-9]+/g);
- d = d.length;
- t = value.toFixed(d);
- } else {
- t = value.toFixed(0);
- }
- } else if (options.locale && fullMask) {
- // Append zeros
- var d = ("" + value).split(".");
- if (options.options) {
- if (typeof d[1] === "undefined") {
- d[1] = "";
- }
- var len = d[1].length;
- if (options.options.minimumFractionDigits > len) {
- for (
- var i = 0;
- i < options.options.minimumFractionDigits - len;
- i++
- ) {
- d[1] += "0";
- }
- }
- }
- if (!d[1].length) {
- t = d[0];
- } else {
- t = d.join(".");
- }
- var len = d[1].length;
- if (
- options.options &&
- options.options.maximumFractionDigits < len
- ) {
- t = parseFloat(t).toFixed(options.options.maximumFractionDigits);
- }
- } else {
- t = toPlainString(value);
- }
-
- if (t !== null) {
- value = t;
- // Get decimal
- getDecimal.call(options, options.mask);
- // Replace to the correct decimal
- if (options.options.decimal) {
- value = value.replace(".", options.options.decimal);
- }
- }
- } else {
- if (options.mask && fullMask) {
- fillWithBlanks = true;
- }
- }
- }
-
- if (fillWithBlanks) {
- var s = options.mask.length - value.length;
- if (s > 0) {
- for (var i = 0; i < s; i++) {
- value += " ";
- }
- }
- }
-
- value = obj(value, options);
-
- // Numeric mask, number of zeros
- if (fullMask && type === "numeric") {
- var maskZeros = options.mask.match(new RegExp(/^[0]+$/gm));
- if (maskZeros && maskZeros.length === 1) {
- var maskLength = maskZeros[0].length;
- if (maskLength > 3) {
- value = "" + value;
- while (value.length < maskLength) {
- value = "0" + value;
- }
- }
- }
- }
-
- return value;
- };
-
- obj.set = function (e, m) {
- if (m) {
- e.setAttribute("data-mask", m);
- // Reset the value
- var event = new Event("input", {
- bubbles: true,
- cancelable: true,
- });
- e.dispatchEvent(event);
- }
- };
-
- if (typeof document !== "undefined") {
- document.addEventListener("input", function (e) {
- if (e.target.getAttribute("data-mask") || e.target.mask) {
- obj(e);
- }
- });
- }
-
- return obj;
- })();
-
- jSuites.modal = function (el, options) {
- var obj = {};
- obj.options = {};
-
- // Default configuration
- var defaults = {
- url: null,
- onopen: null,
- onclose: null,
- closed: false,
- width: null,
- height: null,
- title: null,
- padding: null,
- backdrop: true,
- };
-
- // Loop through our object
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- obj.options[property] = defaults[property];
- }
- }
-
- // Title
- if (!obj.options.title && el.getAttribute("title")) {
- obj.options.title = el.getAttribute("title");
- }
-
- var temp = document.createElement("div");
- while (el.children[0]) {
- temp.appendChild(el.children[0]);
- }
-
- obj.content = document.createElement("div");
- obj.content.className = "jmodal_content";
- obj.content.innerHTML = el.innerHTML;
-
- while (temp.children[0]) {
- obj.content.appendChild(temp.children[0]);
- }
-
- obj.container = document.createElement("div");
- obj.container.className = "jmodal";
- obj.container.appendChild(obj.content);
-
- if (obj.options.padding) {
- obj.content.style.padding = obj.options.padding;
- }
- if (obj.options.width) {
- obj.container.style.width = obj.options.width;
- }
- if (obj.options.height) {
- obj.container.style.height = obj.options.height;
- }
- if (obj.options.title) {
- obj.container.setAttribute("title", obj.options.title);
- } else {
- obj.container.classList.add("no-title");
- }
- el.innerHTML = "";
- el.style.display = "none";
- el.appendChild(obj.container);
-
- // Backdrop
- if (obj.options.backdrop) {
- var backdrop = document.createElement("div");
- backdrop.className = "jmodal_backdrop";
- backdrop.onclick = function () {
- obj.close();
- };
- el.appendChild(backdrop);
- }
-
- obj.open = function () {
- el.style.display = "block";
- // Fullscreen
- var rect = obj.container.getBoundingClientRect();
- if (jSuites.getWindowWidth() < rect.width) {
- obj.container.style.top = "";
- obj.container.style.left = "";
- obj.container.classList.add("jmodal_fullscreen");
- jSuites.animation.slideBottom(obj.container, 1);
- } else {
- if (obj.options.backdrop) {
- backdrop.style.display = "block";
- }
- }
- // Event
- if (typeof obj.options.onopen == "function") {
- obj.options.onopen(el, obj);
- }
- };
-
- obj.resetPosition = function () {
- obj.container.style.top = "";
- obj.container.style.left = "";
- };
-
- obj.isOpen = function () {
- return el.style.display != "none" ? true : false;
- };
-
- obj.close = function () {
- if (obj.isOpen()) {
- el.style.display = "none";
- if (obj.options.backdrop) {
- // Backdrop
- backdrop.style.display = "";
- }
- // Remove fullscreen class
- obj.container.classList.remove("jmodal_fullscreen");
- // Event
- if (typeof obj.options.onclose == "function") {
- obj.options.onclose(el, obj);
- }
- }
- };
-
- if (!jSuites.modal.hasEvents) {
- // Position
- var tracker = null;
-
- document.addEventListener("keydown", function (e) {
- if (e.which == 27) {
- var modals = document.querySelectorAll(".jmodal");
- for (var i = 0; i < modals.length; i++) {
- modals[i].parentNode.modal.close();
- }
- }
- });
-
- document.addEventListener("mouseup", function (e) {
- var item = jSuites.findElement(e.target, "jmodal");
- if (item) {
- // Get target info
- var rect = item.getBoundingClientRect();
-
- if (e.changedTouches && e.changedTouches[0]) {
- var x = e.changedTouches[0].clientX;
- var y = e.changedTouches[0].clientY;
- } else {
- var x = e.clientX;
- var y = e.clientY;
- }
-
- if (rect.width - (x - rect.left) < 50 && y - rect.top < 50) {
- item.parentNode.modal.close();
- }
- }
-
- if (tracker) {
- tracker.element.style.cursor = "auto";
- tracker = null;
- }
- });
-
- document.addEventListener("mousedown", function (e) {
- var item = jSuites.findElement(e.target, "jmodal");
- if (item) {
- // Get target info
- var rect = item.getBoundingClientRect();
-
- if (e.changedTouches && e.changedTouches[0]) {
- var x = e.changedTouches[0].clientX;
- var y = e.changedTouches[0].clientY;
- } else {
- var x = e.clientX;
- var y = e.clientY;
- }
-
- if (rect.width - (x - rect.left) < 50 && y - rect.top < 50) {
- // Do nothing
- } else {
- if (e.target.getAttribute("title") && y - rect.top < 50) {
- if (document.selection) {
- document.selection.empty();
- } else if (window.getSelection) {
- window.getSelection().removeAllRanges();
- }
-
- tracker = {
- left: rect.left,
- top: rect.top,
- x: e.clientX,
- y: e.clientY,
- width: rect.width,
- height: rect.height,
- element: item,
- };
- }
- }
- }
- });
-
- document.addEventListener("mousemove", function (e) {
- if (tracker) {
- e = e || window.event;
- if (e.buttons) {
- var mouseButton = e.buttons;
- } else if (e.button) {
- var mouseButton = e.button;
- } else {
- var mouseButton = e.which;
- }
-
- if (mouseButton) {
- tracker.element.style.top =
- tracker.top + (e.clientY - tracker.y) + tracker.height / 2 + "px";
- tracker.element.style.left =
- tracker.left + (e.clientX - tracker.x) + tracker.width / 2 + "px";
- tracker.element.style.cursor = "move";
- } else {
- tracker.element.style.cursor = "auto";
- }
- }
- });
-
- jSuites.modal.hasEvents = true;
- }
-
- if (obj.options.url) {
- jSuites.ajax({
- url: obj.options.url,
- method: "GET",
- dataType: "text/html",
- success: function (data) {
- obj.content.innerHTML = data;
-
- if (!obj.options.closed) {
- obj.open();
- }
- },
- });
- } else {
- if (!obj.options.closed) {
- obj.open();
- }
- }
-
- // Keep object available from the node
- el.modal = obj;
-
- return obj;
- };
-
- jSuites.notification = function (options) {
- var obj = {};
- obj.options = {};
-
- // Default configuration
- var defaults = {
- icon: null,
- name: "Notification",
- date: null,
- error: null,
- title: null,
- message: null,
- timeout: 4000,
- autoHide: true,
- closeable: true,
- };
-
- // Loop through our object
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- obj.options[property] = defaults[property];
- }
- }
-
- var notification = document.createElement("div");
- notification.className = "jnotification";
-
- if (obj.options.error) {
- notification.classList.add("jnotification-error");
- }
-
- var notificationContainer = document.createElement("div");
- notificationContainer.className = "jnotification-container";
- notification.appendChild(notificationContainer);
-
- var notificationHeader = document.createElement("div");
- notificationHeader.className = "jnotification-header";
- notificationContainer.appendChild(notificationHeader);
-
- var notificationImage = document.createElement("div");
- notificationImage.className = "jnotification-image";
- notificationHeader.appendChild(notificationImage);
-
- if (obj.options.icon) {
- var notificationIcon = document.createElement("img");
- notificationIcon.src = obj.options.icon;
- notificationImage.appendChild(notificationIcon);
- }
-
- var notificationName = document.createElement("div");
- notificationName.className = "jnotification-name";
- notificationName.innerHTML = obj.options.name;
- notificationHeader.appendChild(notificationName);
-
- if (obj.options.closeable == true) {
- var notificationClose = document.createElement("div");
- notificationClose.className = "jnotification-close";
- notificationClose.onclick = function () {
- obj.hide();
- };
- notificationHeader.appendChild(notificationClose);
- }
-
- var notificationDate = document.createElement("div");
- notificationDate.className = "jnotification-date";
- notificationHeader.appendChild(notificationDate);
-
- var notificationContent = document.createElement("div");
- notificationContent.className = "jnotification-content";
- notificationContainer.appendChild(notificationContent);
-
- if (obj.options.title) {
- var notificationTitle = document.createElement("div");
- notificationTitle.className = "jnotification-title";
- notificationTitle.innerHTML = obj.options.title;
- notificationContent.appendChild(notificationTitle);
- }
-
- var notificationMessage = document.createElement("div");
- notificationMessage.className = "jnotification-message";
- notificationMessage.innerHTML = obj.options.message;
- notificationContent.appendChild(notificationMessage);
-
- obj.show = function () {
- document.body.appendChild(notification);
- if (jSuites.getWindowWidth() > 800) {
- jSuites.animation.fadeIn(notification);
- } else {
- jSuites.animation.slideTop(notification, 1);
- }
- };
-
- obj.hide = function () {
- if (jSuites.getWindowWidth() > 800) {
- jSuites.animation.fadeOut(notification, function () {
- if (notification.parentNode) {
- notification.parentNode.removeChild(notification);
- if (notificationTimeout) {
- clearTimeout(notificationTimeout);
- }
- }
- });
- } else {
- jSuites.animation.slideTop(notification, 0, function () {
- if (notification.parentNode) {
- notification.parentNode.removeChild(notification);
- if (notificationTimeout) {
- clearTimeout(notificationTimeout);
- }
- }
- });
- }
- };
-
- obj.show();
-
- if (obj.options.autoHide == true) {
- var notificationTimeout = setTimeout(function () {
- obj.hide();
- }, obj.options.timeout);
- }
-
- if (jSuites.getWindowWidth() < 800) {
- notification.addEventListener("swipeup", function (e) {
- obj.hide();
- e.preventDefault();
- e.stopPropagation();
- });
- }
-
- return obj;
- };
-
- jSuites.notification.isVisible = function () {
- var j = document.querySelector(".jnotification");
- return j && j.parentNode ? true : false;
- };
-
- // More palettes https://coolors.co/ or https://gka.github.io/palettes/#/10|s|003790,005647,ffffe0|ffffe0,ff005e,93003a|1|1
- jSuites.palette = (function () {
- /**
- * Available palettes
- */
- var palette = {
- material: [
- [
- "#ffebee",
- "#fce4ec",
- "#f3e5f5",
- "#e8eaf6",
- "#e3f2fd",
- "#e0f7fa",
- "#e0f2f1",
- "#e8f5e9",
- "#f1f8e9",
- "#f9fbe7",
- "#fffde7",
- "#fff8e1",
- "#fff3e0",
- "#fbe9e7",
- "#efebe9",
- "#fafafa",
- "#eceff1",
- ],
- [
- "#ffcdd2",
- "#f8bbd0",
- "#e1bee7",
- "#c5cae9",
- "#bbdefb",
- "#b2ebf2",
- "#b2dfdb",
- "#c8e6c9",
- "#dcedc8",
- "#f0f4c3",
- "#fff9c4",
- "#ffecb3",
- "#ffe0b2",
- "#ffccbc",
- "#d7ccc8",
- "#f5f5f5",
- "#cfd8dc",
- ],
- [
- "#ef9a9a",
- "#f48fb1",
- "#ce93d8",
- "#9fa8da",
- "#90caf9",
- "#80deea",
- "#80cbc4",
- "#a5d6a7",
- "#c5e1a5",
- "#e6ee9c",
- "#fff59d",
- "#ffe082",
- "#ffcc80",
- "#ffab91",
- "#bcaaa4",
- "#eeeeee",
- "#b0bec5",
- ],
- [
- "#e57373",
- "#f06292",
- "#ba68c8",
- "#7986cb",
- "#64b5f6",
- "#4dd0e1",
- "#4db6ac",
- "#81c784",
- "#aed581",
- "#dce775",
- "#fff176",
- "#ffd54f",
- "#ffb74d",
- "#ff8a65",
- "#a1887f",
- "#e0e0e0",
- "#90a4ae",
- ],
- [
- "#ef5350",
- "#ec407a",
- "#ab47bc",
- "#5c6bc0",
- "#42a5f5",
- "#26c6da",
- "#26a69a",
- "#66bb6a",
- "#9ccc65",
- "#d4e157",
- "#ffee58",
- "#ffca28",
- "#ffa726",
- "#ff7043",
- "#8d6e63",
- "#bdbdbd",
- "#78909c",
- ],
- [
- "#f44336",
- "#e91e63",
- "#9c27b0",
- "#3f51b5",
- "#2196f3",
- "#00bcd4",
- "#009688",
- "#4caf50",
- "#8bc34a",
- "#cddc39",
- "#ffeb3b",
- "#ffc107",
- "#ff9800",
- "#ff5722",
- "#795548",
- "#9e9e9e",
- "#607d8b",
- ],
- [
- "#e53935",
- "#d81b60",
- "#8e24aa",
- "#3949ab",
- "#1e88e5",
- "#00acc1",
- "#00897b",
- "#43a047",
- "#7cb342",
- "#c0ca33",
- "#fdd835",
- "#ffb300",
- "#fb8c00",
- "#f4511e",
- "#6d4c41",
- "#757575",
- "#546e7a",
- ],
- [
- "#d32f2f",
- "#c2185b",
- "#7b1fa2",
- "#303f9f",
- "#1976d2",
- "#0097a7",
- "#00796b",
- "#388e3c",
- "#689f38",
- "#afb42b",
- "#fbc02d",
- "#ffa000",
- "#f57c00",
- "#e64a19",
- "#5d4037",
- "#616161",
- "#455a64",
- ],
- [
- "#c62828",
- "#ad1457",
- "#6a1b9a",
- "#283593",
- "#1565c0",
- "#00838f",
- "#00695c",
- "#2e7d32",
- "#558b2f",
- "#9e9d24",
- "#f9a825",
- "#ff8f00",
- "#ef6c00",
- "#d84315",
- "#4e342e",
- "#424242",
- "#37474f",
- ],
- [
- "#b71c1c",
- "#880e4f",
- "#4a148c",
- "#1a237e",
- "#0d47a1",
- "#006064",
- "#004d40",
- "#1b5e20",
- "#33691e",
- "#827717",
- "#f57f17",
- "#ff6f00",
- "#e65100",
- "#bf360c",
- "#3e2723",
- "#212121",
- "#263238",
- ],
- ],
- fire: [
- [
- "0b1a6d",
- "840f38",
- "b60718",
- "de030b",
- "ff0c0c",
- "fd491c",
- "fc7521",
- "faa331",
- "fbb535",
- "ffc73a",
- ],
- [
- "071147",
- "5f0b28",
- "930513",
- "be0309",
- "ef0000",
- "fa3403",
- "fb670b",
- "f9991b",
- "faad1e",
- "ffc123",
- ],
- [
- "03071e",
- "370617",
- "6a040f",
- "9d0208",
- "d00000",
- "dc2f02",
- "e85d04",
- "f48c06",
- "faa307",
- "ffba08",
- ],
- [
- "020619",
- "320615",
- "61040d",
- "8c0207",
- "bc0000",
- "c82a02",
- "d05203",
- "db7f06",
- "e19405",
- "efab00",
- ],
- [
- "020515",
- "2d0513",
- "58040c",
- "7f0206",
- "aa0000",
- "b62602",
- "b94903",
- "c57205",
- "ca8504",
- "d89b00",
- ],
- ],
- baby: [
- [
- "eddcd2",
- "fff1e6",
- "fde2e4",
- "fad2e1",
- "c5dedd",
- "dbe7e4",
- "f0efeb",
- "d6e2e9",
- "bcd4e6",
- "99c1de",
- ],
- [
- "e1c4b3",
- "ffd5b5",
- "fab6ba",
- "f5a8c4",
- "aacecd",
- "bfd5cf",
- "dbd9d0",
- "baceda",
- "9dc0db",
- "7eb1d5",
- ],
- [
- "daa990",
- "ffb787",
- "f88e95",
- "f282a9",
- "8fc4c3",
- "a3c8be",
- "cec9b3",
- "9dbcce",
- "82acd2",
- "649dcb",
- ],
- [
- "d69070",
- "ff9c5e",
- "f66770",
- "f05f8f",
- "74bbb9",
- "87bfae",
- "c5b993",
- "83aac3",
- "699bca",
- "4d89c2",
- ],
- [
- "c97d5d",
- "f58443",
- "eb4d57",
- "e54a7b",
- "66a9a7",
- "78ae9c",
- "b5a67e",
- "7599b1",
- "5c88b7",
- "4978aa",
- ],
- ],
- chart: [
- [
- "#C1D37F",
- "#4C5454",
- "#FFD275",
- "#66586F",
- "#D05D5B",
- "#C96480",
- "#95BF8F",
- "#6EA240",
- "#0F0F0E",
- "#EB8258",
- "#95A3B3",
- "#995D81",
- ],
- ],
- };
-
- /**
- * Get a pallete
- */
- var component = function (o) {
- // Otherwise get palette value
- if (palette[o]) {
- return palette[o];
- } else {
- return palette.material;
- }
- };
-
- component.get = function (o) {
- // Otherwise get palette value
- if (palette[o]) {
- return palette[o];
- } else {
- return palette;
- }
- };
-
- component.set = function (o, v) {
- palette[o] = v;
- };
-
- return component;
- })();
-
- jSuites.picker = function (el, options) {
- // Already created, update options
- if (el.picker) {
- return el.picker.setOptions(options, true);
- }
-
- // New instance
- var obj = { type: "picker" };
- obj.options = {};
-
- var dropdownHeader = null;
- var dropdownContent = null;
-
- /**
- * Create the content options
- */
- var createContent = function () {
- dropdownContent.innerHTML = "";
-
- // Create items
- var keys = Object.keys(obj.options.data);
-
- // Go though all options
- for (var i = 0; i < keys.length; i++) {
- // Item
- var dropdownItem = document.createElement("div");
- dropdownItem.classList.add("jpicker-item");
- dropdownItem.k = keys[i];
- dropdownItem.v = obj.options.data[keys[i]];
- // Label
- dropdownItem.innerHTML = obj.getLabel(keys[i]);
- // Append
- dropdownContent.appendChild(dropdownItem);
- }
- };
-
- /**
- * Set or reset the options for the picker
- */
- obj.setOptions = function (options, reset) {
- // Default configuration
- var defaults = {
- value: 0,
- data: null,
- render: null,
- onchange: null,
- onselect: null,
- onopen: null,
- onclose: null,
- onload: null,
- width: null,
- header: true,
- right: false,
- content: false,
- columns: null,
- height: null,
- };
-
- // Legacy purpose only
- if (options && options.options) {
- options.data = options.options;
- }
-
- // Loop through the initial configuration
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- if (typeof obj.options[property] == "undefined" || reset === true) {
- obj.options[property] = defaults[property];
- }
- }
- }
-
- // Start using the options
- if (obj.options.header === false) {
- dropdownHeader.style.display = "none";
- } else {
- dropdownHeader.style.display = "";
- }
-
- // Width
- if (obj.options.width) {
- dropdownHeader.style.width = parseInt(obj.options.width) + "px";
- } else {
- dropdownHeader.style.width = "";
- }
-
- // Height
- if (obj.options.height) {
- dropdownContent.style.maxHeight = obj.options.height + "px";
- dropdownContent.style.overflow = "scroll";
- } else {
- dropdownContent.style.overflow = "";
- }
-
- if (obj.options.columns > 0) {
- dropdownContent.classList.add("jpicker-columns");
- dropdownContent.style.width = obj.options.width
- ? obj.options.width
- : 36 * obj.options.columns + "px";
- }
-
- if (isNaN(obj.options.value)) {
- obj.options.value = "0";
- }
-
- // Create list from data
- createContent();
-
- // Set value
- obj.setValue(obj.options.value);
-
- // Set options all returns the own instance
- return obj;
- };
-
- obj.getValue = function () {
- return obj.options.value;
- };
-
- obj.setValue = function (v) {
- // Set label
- obj.setLabel(v);
-
- // Update value
- obj.options.value = String(v);
-
- // Lemonade JS
- if (el.value != obj.options.value) {
- el.value = obj.options.value;
- if (typeof el.oninput == "function") {
- el.oninput({
- type: "input",
- target: el,
- value: el.value,
- });
- }
- }
-
- if (dropdownContent.children[v].getAttribute("type") !== "generic") {
- obj.close();
- }
- };
-
- obj.getLabel = function (v) {
- var label = obj.options.data[v] || null;
- if (typeof obj.options.render == "function") {
- label = obj.options.render(label);
- }
- return label;
- };
-
- obj.setLabel = function (v) {
- if (obj.options.content) {
- var label = '' + obj.options.content + "";
- } else {
- var label = obj.getLabel(v);
- }
-
- dropdownHeader.innerHTML = label;
- };
-
- obj.open = function () {
- if (!el.classList.contains("jpicker-focus")) {
- // Start tracking the element
- jSuites.tracking(obj, true);
-
- // Open picker
- el.classList.add("jpicker-focus");
- el.focus();
-
- var top = 0;
- var left = 0;
-
- dropdownContent.style.marginLeft = "";
-
- var rectHeader = dropdownHeader.getBoundingClientRect();
- var rectContent = dropdownContent.getBoundingClientRect();
-
- if (window.innerHeight < rectHeader.bottom + rectContent.height) {
- top = -1 * (rectContent.height + 4);
- } else {
- top = rectHeader.height + 4;
- }
-
- if (obj.options.right === true) {
- left = -1 * rectContent.width + rectHeader.width;
- }
-
- if (rectContent.left + left < 0) {
- left = left + rectContent.left + 10;
- }
- if (rectContent.left + rectContent.width > window.innerWidth) {
- left =
- -1 *
- (10 + rectContent.left + rectContent.width - window.innerWidth);
- }
-
- dropdownContent.style.marginTop = parseInt(top) + "px";
- dropdownContent.style.marginLeft = parseInt(left) + "px";
-
- //dropdownContent.style.marginTop
- if (typeof obj.options.onopen == "function") {
- obj.options.onopen(el, obj);
- }
- }
- };
-
- obj.close = function () {
- if (el.classList.contains("jpicker-focus")) {
- el.classList.remove("jpicker-focus");
-
- // Start tracking the element
- jSuites.tracking(obj, false);
-
- if (typeof obj.options.onclose == "function") {
- obj.options.onclose(el, obj);
- }
- }
- };
-
- /**
- * Create floating picker
- */
- var init = function () {
- // Class
- el.classList.add("jpicker");
- el.setAttribute("tabindex", "900");
- el.onmousedown = function (e) {
- if (!el.classList.contains("jpicker-focus")) {
- obj.open();
- }
- };
-
- // Dropdown Header
- dropdownHeader = document.createElement("div");
- dropdownHeader.classList.add("jpicker-header");
-
- // Dropdown content
- dropdownContent = document.createElement("div");
- dropdownContent.classList.add("jpicker-content");
- dropdownContent.onclick = function (e) {
- var item = jSuites.findElement(e.target, "jpicker-item");
- if (item) {
- if (item.parentNode === dropdownContent) {
- // Update label
- obj.setValue(item.k);
- // Call method
- if (typeof obj.options.onchange == "function") {
- obj.options.onchange.call(
- obj,
- el,
- obj,
- item.v,
- item.v,
- item.k,
- e
- );
- }
- }
- }
- };
-
- // Append content and header
- el.appendChild(dropdownHeader);
- el.appendChild(dropdownContent);
-
- // Default value
- el.value = options.value || 0;
-
- // Set options
- obj.setOptions(options);
-
- if (typeof obj.options.onload == "function") {
- obj.options.onload(el, obj);
- }
-
- // Change
- el.change = obj.setValue;
-
- // Global generic value handler
- el.val = function (val) {
- if (val === undefined) {
- return obj.getValue();
- } else {
- obj.setValue(val);
- }
- };
-
- // Reference
- el.picker = obj;
- };
-
- init();
-
- return obj;
- };
-
- jSuites.progressbar = function (el, options) {
- var obj = {};
- obj.options = {};
-
- // Default configuration
- var defaults = {
- value: 0,
- onchange: null,
- width: null,
- };
-
- // Loop through the initial configuration
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- obj.options[property] = defaults[property];
- }
- }
-
- // Class
- el.classList.add("jprogressbar");
- el.setAttribute("tabindex", 1);
- el.setAttribute("data-value", obj.options.value);
-
- var bar = document.createElement("div");
- bar.style.width = obj.options.value + "%";
- bar.style.color = "#fff";
- el.appendChild(bar);
-
- if (obj.options.width) {
- el.style.width = obj.options.width;
- }
-
- // Set value
- obj.setValue = function (value) {
- value = parseInt(value);
- obj.options.value = value;
- bar.style.width = value + "%";
- el.setAttribute("data-value", value + "%");
-
- if (value < 6) {
- el.style.color = "#000";
- } else {
- el.style.color = "#fff";
- }
-
- // Update value
- obj.options.value = value;
-
- if (typeof obj.options.onchange == "function") {
- obj.options.onchange(el, value);
- }
-
- // Lemonade JS
- if (el.value != obj.options.value) {
- el.value = obj.options.value;
- if (typeof el.oninput == "function") {
- el.oninput({
- type: "input",
- target: el,
- value: el.value,
- });
- }
- }
- };
-
- obj.getValue = function () {
- return obj.options.value;
- };
-
- var action = function (e) {
- if (e.which) {
- // Get target info
- var rect = el.getBoundingClientRect();
-
- if (e.changedTouches && e.changedTouches[0]) {
- var x = e.changedTouches[0].clientX;
- var y = e.changedTouches[0].clientY;
- } else {
- var x = e.clientX;
- var y = e.clientY;
- }
-
- obj.setValue(Math.round(((x - rect.left) / rect.width) * 100));
- }
- };
-
- // Events
- if ("touchstart" in document.documentElement === true) {
- el.addEventListener("touchstart", action);
- el.addEventListener("touchend", action);
- } else {
- el.addEventListener("mousedown", action);
- el.addEventListener("mousemove", action);
- }
-
- // Change
- el.change = obj.setValue;
-
- // Global generic value handler
- el.val = function (val) {
- if (val === undefined) {
- return obj.getValue();
- } else {
- obj.setValue(val);
- }
- };
-
- // Reference
- el.progressbar = obj;
-
- return obj;
- };
-
- jSuites.rating = function (el, options) {
- // Already created, update options
- if (el.rating) {
- return el.rating.setOptions(options, true);
- }
-
- // New instance
- var obj = {};
- obj.options = {};
-
- obj.setOptions = function (options, reset) {
- // Default configuration
- var defaults = {
- number: 5,
- value: 0,
- tooltip: ["Very bad", "Bad", "Average", "Good", "Very good"],
- onchange: null,
- };
-
- // Loop through the initial configuration
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- if (typeof obj.options[property] == "undefined" || reset === true) {
- obj.options[property] = defaults[property];
- }
- }
- }
-
- // Make sure the container is empty
- el.innerHTML = "";
-
- // Add elements
- for (var i = 0; i < obj.options.number; i++) {
- var div = document.createElement("div");
- div.setAttribute("data-index", i + 1);
- div.setAttribute("title", obj.options.tooltip[i]);
- el.appendChild(div);
- }
-
- // Selected option
- if (obj.options.value) {
- for (var i = 0; i < obj.options.number; i++) {
- if (i < obj.options.value) {
- el.children[i].classList.add("jrating-selected");
- }
- }
- }
-
- return obj;
- };
-
- // Set value
- obj.setValue = function (index) {
- for (var i = 0; i < obj.options.number; i++) {
- if (i < index) {
- el.children[i].classList.add("jrating-selected");
- } else {
- el.children[i].classList.remove("jrating-over");
- el.children[i].classList.remove("jrating-selected");
- }
- }
-
- obj.options.value = index;
-
- if (typeof obj.options.onchange == "function") {
- obj.options.onchange(el, index);
- }
-
- // Lemonade JS
- if (el.value != obj.options.value) {
- el.value = obj.options.value;
- if (typeof el.oninput == "function") {
- el.oninput({
- type: "input",
- target: el,
- value: el.value,
- });
- }
- }
- };
-
- obj.getValue = function () {
- return obj.options.value;
- };
-
- var init = function () {
- // Start plugin
- obj.setOptions(options);
-
- // Class
- el.classList.add("jrating");
-
- // Events
- el.addEventListener("click", function (e) {
- var index = e.target.getAttribute("data-index");
- if (index != undefined) {
- if (index == obj.options.value) {
- obj.setValue(0);
- } else {
- obj.setValue(index);
- }
- }
- });
-
- el.addEventListener("mouseover", function (e) {
- var index = e.target.getAttribute("data-index");
- for (var i = 0; i < obj.options.number; i++) {
- if (i < index) {
- el.children[i].classList.add("jrating-over");
- } else {
- el.children[i].classList.remove("jrating-over");
- }
- }
- });
-
- el.addEventListener("mouseout", function (e) {
- for (var i = 0; i < obj.options.number; i++) {
- el.children[i].classList.remove("jrating-over");
- }
- });
-
- // Change
- el.change = obj.setValue;
-
- // Global generic value handler
- el.val = function (val) {
- if (val === undefined) {
- return obj.getValue();
- } else {
- obj.setValue(val);
- }
- };
-
- // Reference
- el.rating = obj;
- };
-
- init();
-
- return obj;
- };
-
- jSuites.search = function (el, options) {
- if (el.search) {
- return el.search;
- }
-
- var index = null;
-
- var select = function (e) {
- if (e.target.classList.contains("jsearch_item")) {
- var element = e.target;
- } else {
- var element = e.target.parentNode;
- }
-
- obj.selectIndex(element);
- e.preventDefault();
- };
-
- var createList = function (data) {
- // Reset container
- container.innerHTML = "";
- // Print results
- if (!data.length) {
- // Show container
- el.style.display = "";
- } else {
- // Show container
- el.style.display = "block";
-
- // Show items (only 10)
- var len = data.length < 11 ? data.length : 10;
- for (var i = 0; i < len; i++) {
- if (typeof data[i] == "string") {
- var text = data[i];
- var value = data[i];
- } else {
- // Legacy
- var text = data[i].text;
- if (!text && data[i].name) {
- text = data[i].name;
- }
- var value = data[i].value;
- if (!value && data[i].id) {
- value = data[i].id;
- }
- }
-
- var div = document.createElement("div");
- div.setAttribute("data-value", value);
- div.setAttribute("data-text", text);
- div.className = "jsearch_item";
-
- if (data[i].id) {
- div.setAttribute("id", data[i].id);
- }
-
- if (obj.options.forceSelect && i == 0) {
- div.classList.add("selected");
- }
- var img = document.createElement("img");
- if (data[i].image) {
- img.src = data[i].image;
- } else {
- img.style.display = "none";
- }
- div.appendChild(img);
-
- var item = document.createElement("div");
- item.innerHTML = text;
- div.appendChild(item);
-
- // Append item to the container
- container.appendChild(div);
- }
- }
- };
-
- var execute = function (str) {
- if (str != obj.terms) {
- // New terms
- obj.terms = str;
- // New index
- if (obj.options.forceSelect) {
- index = 0;
- } else {
- index = null;
- }
- // Array or remote search
- if (Array.isArray(obj.options.data)) {
- var test = function (o) {
- if (typeof o == "string") {
- if (("" + o).toLowerCase().search(str.toLowerCase()) >= 0) {
- return true;
- }
- } else {
- for (var key in o) {
- var value = o[key];
- if (("" + value).toLowerCase().search(str.toLowerCase()) >= 0) {
- return true;
- }
- }
- }
- return false;
- };
-
- var results = obj.options.data.filter(function (item) {
- return test(item);
- });
-
- // Show items
- createList(results);
- } else {
- // Get remove results
- jSuites.ajax({
- url: obj.options.data + str,
- method: "GET",
- dataType: "json",
- success: function (data) {
- // Show items
- createList(data);
- },
- });
- }
- }
- };
-
- // Search timer
- var timer = null;
-
- // Search methods
- var obj = function (str) {
- if (timer) {
- clearTimeout(timer);
- }
- timer = setTimeout(function () {
- execute(str);
- }, 500);
- };
- if (options.forceSelect === null) {
- options.forceSelect = true;
- }
- obj.options = {
- data: options.data || null,
- input: options.input || null,
- searchByNode: options.searchByNode || null,
- onselect: options.onselect || null,
- forceSelect: options.forceSelect,
- onbeforesearch: options.onbeforesearch || null,
- };
-
- obj.selectIndex = function (item) {
- var id = item.getAttribute("id");
- var text = item.getAttribute("data-text");
- var value = item.getAttribute("data-value");
- // Onselect
- if (typeof obj.options.onselect == "function") {
- obj.options.onselect(obj, text, value, id);
- }
- // Close container
- obj.close();
- };
-
- obj.open = function () {
- el.style.display = "block";
- };
-
- obj.close = function () {
- if (timer) {
- clearTimeout(timer);
- }
- // Current terms
- obj.terms = "";
- // Remove results
- container.innerHTML = "";
- // Hide
- el.style.display = "";
- };
-
- obj.isOpened = function () {
- return el.style.display ? true : false;
- };
-
- obj.keydown = function (e) {
- if (obj.isOpened()) {
- if (e.key == "Enter") {
- // Enter
- if (index !== null && container.children[index]) {
- obj.selectIndex(container.children[index]);
- e.preventDefault();
- } else {
- obj.close();
- }
- } else if (e.key === "ArrowUp") {
- // Up
- if (index !== null && container.children[0]) {
- container.children[index].classList.remove("selected");
- if (!obj.options.forceSelect && index === 0) {
- index = null;
- } else {
- index = Math.max(0, index - 1);
- container.children[index].classList.add("selected");
- }
- }
- e.preventDefault();
- } else if (e.key === "ArrowDown") {
- // Down
- if (index == null) {
- index = -1;
- } else {
- container.children[index].classList.remove("selected");
- }
- if (index < 9 && container.children[index + 1]) {
- index++;
- }
- container.children[index].classList.add("selected");
- e.preventDefault();
- }
- }
- };
-
- obj.keyup = function (e) {
- if (!obj.options.searchByNode) {
- if (obj.options.input.tagName === "DIV") {
- var terms = obj.options.input.innerText;
- } else {
- var terms = obj.options.input.value;
- }
- } else {
- // Current node
- var node = jSuites.getNode();
- if (node) {
- var terms = node.innerText;
- }
- }
-
- if (typeof obj.options.onbeforesearch == "function") {
- var ret = obj.options.onbeforesearch(obj, terms);
- if (ret) {
- terms = ret;
- } else {
- if (ret === false) {
- // Ignore event
- return;
- }
- }
- }
-
- obj(terms);
- };
-
- // Add events
- if (obj.options.input) {
- obj.options.input.addEventListener("keyup", obj.keyup);
- obj.options.input.addEventListener("keydown", obj.keydown);
- }
-
- // Append element
- var container = document.createElement("div");
- container.classList.add("jsearch_container");
- container.onmousedown = select;
- el.appendChild(container);
-
- el.classList.add("jsearch");
- el.search = obj;
-
- return obj;
- };
-
- jSuites.slider = function (el, options) {
- var obj = {};
- obj.options = {};
- obj.currentImage = null;
-
- if (options) {
- obj.options = options;
- }
-
- // Focus
- el.setAttribute("tabindex", "900");
-
- // Items
- obj.options.items = [];
-
- if (!el.classList.contains("jslider")) {
- el.classList.add("jslider");
- el.classList.add("unselectable");
-
- if (obj.options.height) {
- el.style.minHeight = obj.options.height;
- }
- if (obj.options.width) {
- el.style.width = obj.options.width;
- }
- if (obj.options.grid) {
- el.classList.add("jslider-grid");
- var number = el.children.length;
- if (number > 4) {
- el.setAttribute("data-total", number - 4);
- }
- el.setAttribute("data-number", number > 4 ? 4 : number);
- }
-
- // Add slider counter
- var counter = document.createElement("div");
- counter.classList.add("jslider-counter");
-
- // Move children inside
- if (el.children.length > 0) {
- // Keep children items
- for (var i = 0; i < el.children.length; i++) {
- obj.options.items.push(el.children[i]);
-
- // counter click event
- var item = document.createElement("div");
- item.onclick = function () {
- var index = Array.prototype.slice
- .call(counter.children)
- .indexOf(this);
- obj.show((obj.currentImage = obj.options.items[index]));
- };
- counter.appendChild(item);
- }
- }
- // Add caption
- var caption = document.createElement("div");
- caption.className = "jslider-caption";
-
- // Add close buttom
- var controls = document.createElement("div");
- var close = document.createElement("div");
- close.className = "jslider-close";
- close.innerHTML = "";
-
- close.onclick = function () {
- obj.close();
- };
- controls.appendChild(caption);
- controls.appendChild(close);
- }
-
- obj.updateCounter = function (index) {
- for (var i = 0; i < counter.children.length; i++) {
- if (counter.children[i].classList.contains("jslider-counter-focus")) {
- counter.children[i].classList.remove("jslider-counter-focus");
- break;
- }
- }
- counter.children[index].classList.add("jslider-counter-focus");
- };
-
- obj.show = function (target) {
- if (!target) {
- var target = el.children[0];
- }
-
- // Focus element
- el.classList.add("jslider-focus");
- el.classList.remove("jslider-grid");
- el.appendChild(controls);
- el.appendChild(counter);
-
- // Update counter
- var index = obj.options.items.indexOf(target);
- obj.updateCounter(index);
-
- // Remove display
- for (var i = 0; i < el.children.length; i++) {
- el.children[i].style.display = "";
- }
- target.style.display = "block";
-
- // Is there any previous
- if (target.previousElementSibling) {
- el.classList.add("jslider-left");
- } else {
- el.classList.remove("jslider-left");
- }
-
- // Is there any next
- if (
- target.nextElementSibling &&
- target.nextElementSibling.tagName == "IMG"
- ) {
- el.classList.add("jslider-right");
- } else {
- el.classList.remove("jslider-right");
- }
-
- obj.currentImage = target;
-
- // Vertical image
- if (obj.currentImage.offsetHeight > obj.currentImage.offsetWidth) {
- obj.currentImage.classList.add("jslider-vertical");
- }
-
- controls.children[0].innerText = obj.currentImage.getAttribute("title");
- };
-
- obj.open = function () {
- obj.show();
-
- // Event
- if (typeof obj.options.onopen == "function") {
- obj.options.onopen(el);
- }
- };
-
- obj.close = function () {
- // Remove control classes
- el.classList.remove("jslider-focus");
- el.classList.remove("jslider-left");
- el.classList.remove("jslider-right");
- // Show as a grid depending on the configuration
- if (obj.options.grid) {
- el.classList.add("jslider-grid");
- }
- // Remove display
- for (var i = 0; i < el.children.length; i++) {
- el.children[i].style.display = "";
- }
- // Remove controls from the component
- counter.remove();
- controls.remove();
- // Current image
- obj.currentImage = null;
- // Event
- if (typeof obj.options.onclose == "function") {
- obj.options.onclose(el);
- }
- };
-
- obj.reset = function () {
- el.innerHTML = "";
- };
-
- obj.next = function () {
- var nextImage = obj.currentImage.nextElementSibling;
- if (nextImage && nextImage.tagName === "IMG") {
- obj.show(obj.currentImage.nextElementSibling);
- }
- };
-
- obj.prev = function () {
- if (obj.currentImage.previousElementSibling) {
- obj.show(obj.currentImage.previousElementSibling);
- }
- };
-
- var mouseUp = function (e) {
- // Open slider
- if (e.target.tagName == "IMG") {
- obj.show(e.target);
- } else if (
- !e.target.classList.contains("jslider-close") &&
- !(
- e.target.parentNode.classList.contains("jslider-counter") ||
- e.target.classList.contains("jslider-counter")
- )
- ) {
- // Arrow controls
- var offsetX = e.offsetX || e.changedTouches[0].clientX;
- if (e.target.clientWidth - offsetX < 40) {
- // Show next image
- obj.next();
- } else if (offsetX < 40) {
- // Show previous image
- obj.prev();
- }
- }
- };
-
- if ("ontouchend" in document.documentElement === true) {
- el.addEventListener("touchend", mouseUp);
- } else {
- el.addEventListener("mouseup", mouseUp);
- }
-
- // Add global events
- el.addEventListener("swipeleft", function (e) {
- obj.next();
- e.preventDefault();
- e.stopPropagation();
- });
-
- el.addEventListener("swiperight", function (e) {
- obj.prev();
- e.preventDefault();
- e.stopPropagation();
- });
-
- el.addEventListener("keydown", function (e) {
- if (e.which == 27) {
- obj.close();
- }
- });
-
- el.slider = obj;
-
- return obj;
- };
-
- jSuites.sorting = function (el, options) {
- var obj = {};
- obj.options = {};
-
- var defaults = {
- pointer: null,
- direction: null,
- ondragstart: null,
- ondragend: null,
- ondrop: null,
- };
-
- var dragElement = null;
-
- // Loop through the initial configuration
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- obj.options[property] = defaults[property];
- }
- }
-
- el.classList.add("jsorting");
-
- el.addEventListener("dragstart", function (e) {
- var position = Array.prototype.indexOf.call(
- e.target.parentNode.children,
- e.target
- );
- dragElement = {
- element: e.target,
- o: position,
- d: position,
- };
- e.target.style.opacity = "0.25";
-
- if (typeof obj.options.ondragstart == "function") {
- obj.options.ondragstart(el, e.target, e);
- }
- });
-
- el.addEventListener("dragover", function (e) {
- e.preventDefault();
-
- if (getElement(e.target) && dragElement) {
- if (
- e.target.getAttribute("draggable") == "true" &&
- dragElement.element != e.target
- ) {
- if (!obj.options.direction) {
- var condition = e.target.clientHeight / 2 > e.offsetY;
- } else {
- var condition = e.target.clientWidth / 2 > e.offsetX;
- }
-
- if (condition) {
- e.target.parentNode.insertBefore(dragElement.element, e.target);
- } else {
- e.target.parentNode.insertBefore(
- dragElement.element,
- e.target.nextSibling
- );
- }
-
- dragElement.d = Array.prototype.indexOf.call(
- e.target.parentNode.children,
- dragElement.element
- );
- }
- }
- });
-
- el.addEventListener("dragleave", function (e) {
- e.preventDefault();
- });
-
- el.addEventListener("dragend", function (e) {
- e.preventDefault();
-
- if (dragElement) {
- if (typeof obj.options.ondragend == "function") {
- obj.options.ondragend(el, dragElement.element, e);
- }
-
- // Cancelled put element to the original position
- if (dragElement.o < dragElement.d) {
- e.target.parentNode.insertBefore(
- dragElement.element,
- e.target.parentNode.children[dragElement.o]
- );
- } else {
- e.target.parentNode.insertBefore(
- dragElement.element,
- e.target.parentNode.children[dragElement.o].nextSibling
- );
- }
-
- dragElement.element.style.opacity = "";
- dragElement = null;
- }
- });
-
- el.addEventListener("drop", function (e) {
- e.preventDefault();
-
- if (dragElement && dragElement.o != dragElement.d) {
- if (typeof obj.options.ondrop == "function") {
- obj.options.ondrop(
- el,
- dragElement.o,
- dragElement.d,
- dragElement.element,
- e.target,
- e
- );
- }
- }
-
- dragElement.element.style.opacity = "";
- dragElement = null;
- });
-
- var getElement = function (element) {
- var sorting = false;
-
- function path(element) {
- if (element.className) {
- if (element.classList.contains("jsorting")) {
- sorting = true;
- }
- }
-
- if (!sorting) {
- path(element.parentNode);
- }
- }
-
- path(element);
-
- return sorting;
- };
-
- for (var i = 0; i < el.children.length; i++) {
- if (!el.children[i].hasAttribute("draggable")) {
- el.children[i].setAttribute("draggable", "true");
- }
- }
-
- el.val = function () {
- var id = null;
- var data = [];
- for (var i = 0; i < el.children.length; i++) {
- if ((id = el.children[i].getAttribute("data-id"))) {
- data.push(id);
- }
- }
- return data;
- };
-
- return el;
- };
-
- jSuites.tabs = function (el, options) {
- var obj = {};
- obj.options = {};
-
- // Default configuration
- var defaults = {
- data: [],
- position: null,
- allowCreate: false,
- allowChangePosition: false,
- onclick: null,
- onload: null,
- onchange: null,
- oncreate: null,
- ondelete: null,
- onbeforecreate: null,
- onchangeposition: null,
- animation: false,
- hideHeaders: false,
- padding: null,
- palette: null,
- maxWidth: null,
- };
-
- // Loop through the initial configuration
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- obj.options[property] = defaults[property];
- }
- }
-
- // Class
- el.classList.add("jtabs");
-
- var prev = null;
- var next = null;
- var border = null;
-
- // Helpers
- var setBorder = function (index) {
- if (obj.options.animation) {
- setTimeout(function () {
- var rect = obj.headers.children[index].getBoundingClientRect();
-
- if (obj.options.palette == "modern") {
- border.style.width = rect.width - 4 + "px";
- border.style.left =
- obj.headers.children[index].offsetLeft + 2 + "px";
- } else {
- border.style.width = rect.width + "px";
- border.style.left = obj.headers.children[index].offsetLeft + "px";
- }
-
- if (obj.options.position == "bottom") {
- border.style.top = "0px";
- } else {
- border.style.bottom = "0px";
- }
- }, 150);
- }
- };
-
- var updateControls = function (x) {
- if (typeof obj.headers.scrollTo == "function") {
- obj.headers.scrollTo({
- left: x,
- behavior: "smooth",
- });
- } else {
- obj.headers.scrollLeft = x;
- }
-
- if (x <= 1) {
- prev.classList.add("disabled");
- } else {
- prev.classList.remove("disabled");
- }
-
- if (x >= obj.headers.scrollWidth - obj.headers.offsetWidth) {
- next.classList.add("disabled");
- } else {
- next.classList.remove("disabled");
- }
-
- if (obj.headers.scrollWidth <= obj.headers.offsetWidth) {
- prev.style.display = "none";
- next.style.display = "none";
- } else {
- prev.style.display = "";
- next.style.display = "";
- }
- };
-
- obj.setBorder = setBorder;
-
- // Set value
- obj.open = function (index) {
- var previous = null;
- for (var i = 0; i < obj.headers.children.length; i++) {
- if (obj.headers.children[i].classList.contains("jtabs-selected")) {
- // Current one
- previous = i;
- }
- // Remote selected
- obj.headers.children[i].classList.remove("jtabs-selected");
- if (obj.content.children[i]) {
- obj.content.children[i].classList.remove("jtabs-selected");
- }
- }
-
- obj.headers.children[index].classList.add("jtabs-selected");
- if (obj.content.children[index]) {
- obj.content.children[index].classList.add("jtabs-selected");
- }
-
- if (previous != index && typeof obj.options.onchange == "function") {
- if (obj.content.children[index]) {
- obj.options.onchange(
- el,
- obj,
- index,
- obj.headers.children[index],
- obj.content.children[index]
- );
- }
- }
-
- // Hide
- if (
- obj.options.hideHeaders == true &&
- obj.headers.children.length < 3 &&
- obj.options.allowCreate == false
- ) {
- obj.headers.parentNode.style.display = "none";
- } else {
- // Set border
- setBorder(index);
-
- obj.headers.parentNode.style.display = "";
-
- var x1 = obj.headers.children[index].offsetLeft;
- var x2 = x1 + obj.headers.children[index].offsetWidth;
- var r1 = obj.headers.scrollLeft;
- var r2 = r1 + obj.headers.offsetWidth;
-
- if (!(r1 <= x1 && r2 >= x2)) {
- // Out of the viewport
- updateControls(x1 - 1);
- }
- }
- };
-
- obj.selectIndex = function (a) {
- var index = Array.prototype.indexOf.call(obj.headers.children, a);
- if (index >= 0) {
- obj.open(index);
- }
-
- return index;
- };
-
- obj.rename = function (i, title) {
- if (!title) {
- title = prompt("New title", obj.headers.children[i].innerText);
- }
- obj.headers.children[i].innerText = title;
- obj.open(i);
- };
-
- obj.create = function (title, url) {
- if (typeof obj.options.onbeforecreate == "function") {
- var ret = obj.options.onbeforecreate(el);
- if (ret === false) {
- return false;
- } else {
- title = ret;
- }
- }
-
- var div = obj.appendElement(title);
-
- if (typeof obj.options.oncreate == "function") {
- obj.options.oncreate(el, div);
- }
-
- setBorder();
-
- return div;
- };
-
- obj.remove = function (index) {
- return obj.deleteElement(index);
- };
-
- obj.nextNumber = function () {
- var num = 0;
- for (var i = 0; i < obj.headers.children.length; i++) {
- var tmp = obj.headers.children[i].innerText.match(/[0-9].*/);
- if (tmp > num) {
- num = parseInt(tmp);
- }
- }
- if (!num) {
- num = 1;
- } else {
- num++;
- }
-
- return num;
- };
-
- obj.deleteElement = function (index) {
- if (!obj.headers.children[index]) {
- return false;
- } else {
- obj.headers.removeChild(obj.headers.children[index]);
- obj.content.removeChild(obj.content.children[index]);
- }
-
- obj.open(0);
-
- if (typeof obj.options.ondelete == "function") {
- obj.options.ondelete(el, index);
- }
- };
-
- obj.appendElement = function (title, cb) {
- if (!title) {
- var title = prompt("Title?", "");
- }
-
- if (title) {
- // Add content
- var div = document.createElement("div");
- obj.content.appendChild(div);
-
- // Add headers
- var h = document.createElement("div");
- h.innerHTML = title;
- h.content = div;
- obj.headers.insertBefore(h, obj.headers.lastChild);
-
- // Sortable
- if (obj.options.allowChangePosition) {
- h.setAttribute("draggable", "true");
- }
- // Open new tab
- obj.selectIndex(h);
-
- // Callback
- if (typeof cb == "function") {
- cb(div, h);
- }
-
- // Return element
- return div;
- }
- };
-
- obj.getActive = function () {
- for (var i = 0; i < obj.headers.children.length; i++) {
- if (obj.headers.children[i].classList.contains("jtabs-selected")) {
- return i;
- }
- }
- return 0;
- };
-
- obj.updateContent = function (position, newContent) {
- if (typeof newContent !== "string") {
- var contentItem = newContent;
- } else {
- var contentItem = document.createElement("div");
- contentItem.innerHTML = newContent;
- }
-
- if (obj.content.children[position].classList.contains("jtabs-selected")) {
- newContent.classList.add("jtabs-selected");
- }
-
- obj.content.replaceChild(newContent, obj.content.children[position]);
-
- setBorder();
- };
-
- obj.updatePosition = function (f, t) {
- // Ondrop update position of content
- if (f > t) {
- obj.content.insertBefore(
- obj.content.children[f],
- obj.content.children[t]
- );
- } else {
- obj.content.insertBefore(
- obj.content.children[f],
- obj.content.children[t].nextSibling
- );
- }
-
- // Open destination tab
- obj.open(t);
-
- // Call event
- if (typeof obj.options.onchangeposition == "function") {
- obj.options.onchangeposition(obj.headers, f, t);
- }
- };
-
- obj.move = function (f, t) {
- if (f > t) {
- obj.headers.insertBefore(
- obj.headers.children[f],
- obj.headers.children[t]
- );
- } else {
- obj.headers.insertBefore(
- obj.headers.children[f],
- obj.headers.children[t].nextSibling
- );
- }
-
- obj.updatePosition(f, t);
- };
-
- obj.setBorder = setBorder;
-
- obj.init = function () {
- el.innerHTML = "";
-
- // Make sure the component is blank
- obj.headers = document.createElement("div");
- obj.content = document.createElement("div");
- obj.headers.classList.add("jtabs-headers");
- obj.content.classList.add("jtabs-content");
-
- if (obj.options.palette) {
- el.classList.add("jtabs-modern");
- } else {
- el.classList.remove("jtabs-modern");
- }
-
- // Padding
- if (obj.options.padding) {
- obj.content.style.padding = parseInt(obj.options.padding) + "px";
- }
-
- // Header
- var header = document.createElement("div");
- header.className = "jtabs-headers-container";
- header.appendChild(obj.headers);
- if (obj.options.maxWidth) {
- header.style.maxWidth = parseInt(obj.options.maxWidth) + "px";
- }
-
- // Controls
- var controls = document.createElement("div");
- controls.className = "jtabs-controls";
- controls.setAttribute("draggable", "false");
- header.appendChild(controls);
-
- // Append DOM elements
- if (obj.options.position == "bottom") {
- el.appendChild(obj.content);
- el.appendChild(header);
- } else {
- el.appendChild(header);
- el.appendChild(obj.content);
- }
-
- // New button
- if (obj.options.allowCreate == true) {
- var add = document.createElement("div");
- add.className = "jtabs-add";
- add.onclick = function () {
- obj.create();
- };
- controls.appendChild(add);
- }
-
- prev = document.createElement("div");
- prev.className = "jtabs-prev";
- prev.onclick = function () {
- updateControls(obj.headers.scrollLeft - obj.headers.offsetWidth);
- };
- controls.appendChild(prev);
-
- next = document.createElement("div");
- next.className = "jtabs-next";
- next.onclick = function () {
- updateControls(obj.headers.scrollLeft + obj.headers.offsetWidth);
- };
- controls.appendChild(next);
-
- // Data
- for (var i = 0; i < obj.options.data.length; i++) {
- // Title
- if (obj.options.data[i].titleElement) {
- var headerItem = obj.options.data[i].titleElement;
- } else {
- var headerItem = document.createElement("div");
- }
- // Icon
- if (obj.options.data[i].icon) {
- var iconContainer = document.createElement("div");
- var icon = document.createElement("i");
- icon.classList.add("material-icons");
- icon.innerHTML = obj.options.data[i].icon;
- iconContainer.appendChild(icon);
- headerItem.appendChild(iconContainer);
- }
- // Title
- if (obj.options.data[i].title) {
- var title = document.createTextNode(obj.options.data[i].title);
- headerItem.appendChild(title);
- }
- // Width
- if (obj.options.data[i].width) {
- headerItem.style.width = obj.options.data[i].width;
- }
- // Content
- if (obj.options.data[i].contentElement) {
- var contentItem = obj.options.data[i].contentElement;
- } else {
- var contentItem = document.createElement("div");
- contentItem.innerHTML = obj.options.data[i].content;
- }
- obj.headers.appendChild(headerItem);
- obj.content.appendChild(contentItem);
- }
-
- // Animation
- border = document.createElement("div");
- border.className = "jtabs-border";
- obj.headers.appendChild(border);
-
- if (obj.options.animation) {
- el.classList.add("jtabs-animation");
- }
-
- // Events
- obj.headers.addEventListener("click", function (e) {
- if (e.target.parentNode.classList.contains("jtabs-headers")) {
- var target = e.target;
- } else {
- if (e.target.tagName == "I") {
- var target = e.target.parentNode.parentNode;
- } else {
- var target = e.target.parentNode;
- }
- }
-
- var index = obj.selectIndex(target);
-
- if (typeof obj.options.onclick == "function") {
- obj.options.onclick(
- el,
- obj,
- index,
- obj.headers.children[index],
- obj.content.children[index]
- );
- }
- });
-
- obj.headers.addEventListener("contextmenu", function (e) {
- obj.selectIndex(e.target);
- });
-
- if (obj.headers.children.length) {
- // Open first tab
- obj.open(0);
- }
-
- // Update controls
- updateControls(0);
-
- if (obj.options.allowChangePosition == true) {
- jSuites.sorting(obj.headers, {
- direction: 1,
- ondrop: function (a, b, c) {
- obj.updatePosition(b, c);
- },
- });
- }
-
- if (typeof obj.options.onload == "function") {
- obj.options.onload(el, obj);
- }
- };
-
- // Loading existing nodes as the data
- if (el.children[0] && el.children[0].children.length) {
- // Create from existing elements
- for (var i = 0; i < el.children[0].children.length; i++) {
- var item =
- obj.options.data && obj.options.data[i] ? obj.options.data[i] : {};
-
- if (el.children[1] && el.children[1].children[i]) {
- item.titleElement = el.children[0].children[i];
- item.contentElement = el.children[1].children[i];
- } else {
- item.contentElement = el.children[0].children[i];
- }
-
- obj.options.data[i] = item;
- }
- }
-
- // Remote controller flag
- var loadingRemoteData = false;
-
- // Create from data
- if (obj.options.data) {
- // Append children
- for (var i = 0; i < obj.options.data.length; i++) {
- if (obj.options.data[i].url) {
- jSuites.ajax({
- url: obj.options.data[i].url,
- type: "GET",
- dataType: "text/html",
- index: i,
- success: function (result) {
- obj.options.data[this.index].content = result;
- },
- complete: function () {
- obj.init();
- },
- });
-
- // Flag loading
- loadingRemoteData = true;
- }
- }
- }
-
- if (!loadingRemoteData) {
- obj.init();
- }
-
- el.tabs = obj;
-
- return obj;
- };
-
- jSuites.tags = function (el, options) {
- // Redefine configuration
- if (el.tags) {
- return el.tags.setOptions(options, true);
- }
-
- var obj = { type: "tags" };
- obj.options = {};
-
- // Limit
- var limit = function () {
- return obj.options.limit && el.children.length >= obj.options.limit
- ? true
- : false;
- };
-
- // Search helpers
- var search = null;
- var searchContainer = null;
-
- obj.setOptions = function (options, reset) {
- /**
- * @typedef {Object} defaults
- * @property {(string|Array)} value - Initial value of the compontent
- * @property {number} limit - Max number of tags inside the element
- * @property {string} search - The URL for suggestions
- * @property {string} placeholder - The default instruction text on the element
- * @property {validation} validation - Method to validate the tags
- * @property {requestCallback} onbeforechange - Method to be execute before any changes on the element
- * @property {requestCallback} onchange - Method to be execute after any changes on the element
- * @property {requestCallback} onfocus - Method to be execute when on focus
- * @property {requestCallback} onblur - Method to be execute when on blur
- * @property {requestCallback} onload - Method to be execute when the element is loaded
- */
- var defaults = {
- value: "",
- limit: null,
- limitMessage: null,
- search: null,
- placeholder: null,
- validation: null,
- onbeforepaste: null,
- onbeforechange: null,
- onlimit: null,
- onchange: null,
- onfocus: null,
- onblur: null,
- onload: null,
- colors: null,
- };
-
- // Loop through though the default configuration
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- if (typeof obj.options[property] == "undefined" || reset === true) {
- obj.options[property] = defaults[property];
- }
- }
- }
-
- // Placeholder
- if (obj.options.placeholder) {
- el.setAttribute("data-placeholder", obj.options.placeholder);
- } else {
- el.removeAttribute("data-placeholder");
- }
- el.placeholder = obj.options.placeholder;
-
- // Update value
- obj.setValue(obj.options.value);
-
- // Validate items
- filter();
-
- // Create search box
- if (obj.options.search) {
- if (!searchContainer) {
- searchContainer = document.createElement("div");
- el.parentNode.insertBefore(searchContainer, el.nextSibling);
-
- // Create container
- search = jSuites.search(searchContainer, {
- data: obj.options.search,
- onselect: function (a, b, c) {
- obj.selectIndex(b, c);
- },
- });
- }
- } else {
- if (searchContainer) {
- search = null;
- searchContainer.remove();
- searchContainer = null;
- }
- }
-
- return obj;
- };
-
- /**
- * Add a new tag to the element
- * @param {(?string|Array)} value - The value of the new element
- */
- obj.add = function (value, focus) {
- if (typeof obj.options.onbeforechange == "function") {
- var ret = obj.options.onbeforechange(el, obj, obj.options.value, value);
- if (ret === false) {
- return false;
- } else {
- if (ret != null) {
- value = ret;
- }
- }
- }
-
- // Make sure search is closed
- if (search) {
- search.close();
- }
-
- if (limit()) {
- if (typeof obj.options.onlimit == "function") {
- obj.options.onlimit(obj, obj.options.limit);
- } else if (obj.options.limitMessage) {
- alert(obj.options.limitMessage + " " + obj.options.limit);
- }
- } else {
- // Get node
- var node = jSuites.getNode();
-
- if (
- node &&
- node.parentNode &&
- node.parentNode.classList.contains("jtags") &&
- node.nextSibling &&
- !(node.nextSibling.innerText && node.nextSibling.innerText.trim())
- ) {
- div = node.nextSibling;
- } else {
- // Remove not used last item
- if (el.lastChild) {
- if (!el.lastChild.innerText.trim()) {
- el.removeChild(el.lastChild);
- }
- }
-
- // Mix argument string or array
- if (!value || typeof value == "string") {
- var div = createElement(value, value, node);
- } else {
- for (var i = 0; i <= value.length; i++) {
- if (!limit()) {
- if (!value[i] || typeof value[i] == "string") {
- var t = value[i] || "";
- var v = null;
- } else {
- var t = value[i].text;
- var v = value[i].value;
- }
-
- // Add element
- var div = createElement(t, v);
- }
- }
- }
-
- // Change
- change();
- }
-
- // Place caret
- if (focus) {
- setFocus(div);
- }
- }
- };
-
- obj.setLimit = function (limit) {
- obj.options.limit = limit;
- var n = el.children.length - limit;
- while (el.children.length > limit) {
- el.removeChild(el.lastChild);
- }
- };
-
- // Remove a item node
- obj.remove = function (node) {
- // Remove node
- node.parentNode.removeChild(node);
- // Make sure element is not blank
- if (!el.children.length) {
- obj.add("", true);
- } else {
- change();
- }
- };
-
- /**
- * Get all tags in the element
- * @return {Array} data - All tags as an array
- */
- obj.getData = function () {
- var data = [];
- for (var i = 0; i < el.children.length; i++) {
- // Get value
- var text = el.children[i].innerText.replace("\n", "");
- // Get id
- var value = el.children[i].getAttribute("data-value");
- if (!value) {
- value = text;
- }
- // Item
- if (text || value) {
- data.push({ text: text, value: value });
- }
- }
- return data;
- };
-
- /**
- * Get the value of one tag. Null for all tags
- * @param {?number} index - Tag index number. Null for all tags.
- * @return {string} value - All tags separated by comma
- */
- obj.getValue = function (index) {
- var value = null;
-
- if (index != null) {
- // Get one individual value
- value = el.children[index].getAttribute("data-value");
- if (!value) {
- value = el.children[index].innerText.replace("\n", "");
- }
- } else {
- // Get all
- var data = [];
- for (var i = 0; i < el.children.length; i++) {
- value = el.children[i].innerText.replace("\n", "");
- if (value) {
- data.push(obj.getValue(i));
- }
- }
- value = data.join(",");
- }
-
- return value;
- };
-
- /**
- * Set the value of the element based on a string separeted by (,|;|\r\n)
- * @param {mixed} value - A string or array object with values
- */
- obj.setValue = function (mixed) {
- if (!mixed) {
- obj.reset();
- } else {
- if (el.value != mixed) {
- if (Array.isArray(mixed)) {
- obj.add(mixed);
- } else {
- // Remove whitespaces
- var text = ("" + mixed).trim();
- // Tags
- var data = extractTags(text);
- // Reset
- el.innerHTML = "";
- // Add tags to the element
- obj.add(data);
- }
- }
- }
- };
-
- /**
- * Reset the data from the element
- */
- obj.reset = function () {
- // Empty class
- el.classList.add("jtags-empty");
- // Empty element
- el.innerHTML = "";
- // Execute changes
- change();
- };
-
- /**
- * Verify if all tags in the element are valid
- * @return {boolean}
- */
- obj.isValid = function () {
- var test = 0;
- for (var i = 0; i < el.children.length; i++) {
- if (el.children[i].classList.contains("jtags_error")) {
- test++;
- }
- }
- return test == 0 ? true : false;
- };
-
- /**
- * Add one element from the suggestions to the element
- * @param {object} item - Node element in the suggestions container
- */
- obj.selectIndex = function (text, value) {
- var node = jSuites.getNode();
- if (node) {
- // Append text to the caret
- node.innerText = text;
- // Set node id
- if (value) {
- node.setAttribute("data-value", value);
- }
- // Remove any error
- node.classList.remove("jtags_error");
- if (!limit()) {
- // Add new item
- obj.add("", true);
- }
- }
- };
-
- /**
- * Search for suggestions
- * @param {object} node - Target node for any suggestions
- */
- obj.search = function (node) {
- // Search for
- var terms = node.innerText;
- };
-
- // Destroy tags element
- obj.destroy = function () {
- // Bind events
- el.removeEventListener("mouseup", tagsMouseUp);
- el.removeEventListener("keydown", tagsKeyDown);
- el.removeEventListener("keyup", tagsKeyUp);
- el.removeEventListener("paste", tagsPaste);
- el.removeEventListener("focus", tagsFocus);
- el.removeEventListener("blur", tagsBlur);
-
- // Remove element
- el.parentNode.removeChild(el);
- };
-
- var setFocus = function (node) {
- if (el.children.length > 1) {
- var range = document.createRange();
- var sel = window.getSelection();
- if (!node) {
- var node = el.childNodes[el.childNodes.length - 1];
- }
- range.setStart(node, node.length);
- range.collapse(true);
- sel.removeAllRanges();
- sel.addRange(range);
- el.scrollLeft = el.scrollWidth;
- }
- };
-
- var createElement = function (label, value, node) {
- var div = document.createElement("div");
- div.innerHTML = label ? label : "";
- if (value) {
- div.setAttribute("data-value", value);
- }
-
- if (node && node.parentNode.classList.contains("jtags")) {
- el.insertBefore(div, node.nextSibling);
- } else {
- el.appendChild(div);
- }
-
- return div;
- };
-
- var change = function () {
- // Value
- var value = obj.getValue();
-
- if (value != obj.options.value) {
- obj.options.value = value;
- if (typeof obj.options.onchange == "function") {
- obj.options.onchange(el, obj, obj.options.value);
- }
-
- // Lemonade JS
- if (el.value != obj.options.value) {
- el.value = obj.options.value;
- if (typeof el.oninput == "function") {
- el.oninput({
- type: "input",
- target: el,
- value: el.value,
- });
- }
- }
- }
-
- filter();
- };
-
- /**
- * Filter tags
- */
- var filter = function () {
- for (var i = 0; i < el.children.length; i++) {
- // Create label design
- if (!obj.getValue(i)) {
- el.children[i].classList.remove("jtags_label");
- } else {
- el.children[i].classList.add("jtags_label");
-
- // Validation in place
- if (typeof obj.options.validation == "function") {
- if (obj.getValue(i)) {
- if (
- !obj.options.validation(
- el.children[i],
- el.children[i].innerText,
- el.children[i].getAttribute("data-value")
- )
- ) {
- el.children[i].classList.add("jtags_error");
- } else {
- el.children[i].classList.remove("jtags_error");
- }
- } else {
- el.children[i].classList.remove("jtags_error");
- }
- } else {
- el.children[i].classList.remove("jtags_error");
- }
- }
- }
-
- isEmpty();
- };
-
- var isEmpty = function () {
- // Can't be empty
- if (!el.innerText.trim()) {
- el.innerHTML = "";
- el.classList.add("jtags-empty");
- } else {
- el.classList.remove("jtags-empty");
- }
- };
-
- /**
- * Extract tags from a string
- * @param {string} text - Raw string
- * @return {Array} data - Array with extracted tags
- */
- var extractTags = function (text) {
- /** @type {Array} */
- var data = [];
-
- /** @type {string} */
- var word = "";
-
- // Remove whitespaces
- text = text.trim();
-
- if (text) {
- for (var i = 0; i < text.length; i++) {
- if (text[i] == "," || text[i] == ";" || text[i] == "\n") {
- if (word) {
- data.push(word.trim());
- word = "";
- }
- } else {
- word += text[i];
- }
- }
-
- if (word) {
- data.push(word);
- }
- }
-
- return data;
- };
-
- /** @type {number} */
- var anchorOffset = 0;
-
- /**
- * Processing event keydown on the element
- * @param e {object}
- */
- var tagsKeyDown = function (e) {
- // Anchoroffset
- anchorOffset = window.getSelection().anchorOffset;
-
- // Verify if is empty
- isEmpty();
-
- // Comma
- if (e.key === "Tab" || e.key === ";" || e.key === ",") {
- var n = window.getSelection().anchorOffset;
- if (n > 1) {
- if (limit()) {
- if (typeof obj.options.onlimit == "function") {
- obj.options.onlimit(obj, obj.options.limit);
- }
- } else {
- obj.add("", true);
- }
- }
- e.preventDefault();
- } else if (e.key == "Enter") {
- if (!search || !search.isOpened()) {
- var n = window.getSelection().anchorOffset;
- if (n > 1) {
- if (!limit()) {
- obj.add("", true);
- }
- }
- e.preventDefault();
- }
- } else if (e.key == "Backspace") {
- // Back space - do not let last item to be removed
- if (el.children.length == 1 && window.getSelection().anchorOffset < 1) {
- e.preventDefault();
- }
- }
-
- // Search events
- if (search) {
- search.keydown(e);
- }
- };
-
- /**
- * Processing event keyup on the element
- * @param e {object}
- */
- var tagsKeyUp = function (e) {
- if (e.which == 39) {
- // Right arrow
- var n = window.getSelection().anchorOffset;
- if (n > 1 && n == anchorOffset) {
- obj.add("", true);
- }
- } else if (e.which == 13 || e.which == 38 || e.which == 40) {
- e.preventDefault();
- } else {
- if (search) {
- search.keyup(e);
- }
- }
-
- filter();
- };
-
- /**
- * Processing event paste on the element
- * @param e {object}
- */
- var tagsPaste = function (e) {
- if (e.clipboardData || e.originalEvent.clipboardData) {
- var text = (e.originalEvent || e).clipboardData.getData("text/plain");
- } else if (window.clipboardData) {
- var text = window.clipboardData.getData("Text");
- }
-
- var data = extractTags(text);
-
- if (typeof obj.options.onbeforepaste == "function") {
- var ret = obj.options.onbeforepaste(el, obj, data);
- if (ret === false) {
- e.preventDefault();
- return false;
- } else {
- if (ret) {
- data = ret;
- }
- }
- }
-
- if (data.length > 1) {
- obj.add(data, true);
- e.preventDefault();
- } else if (data[0]) {
- document.execCommand("insertText", false, data[0]);
- e.preventDefault();
- }
- };
-
- /**
- * Processing event mouseup on the element
- * @param e {object}
- */
- var tagsMouseUp = function (e) {
- if (
- e.target.parentNode &&
- e.target.parentNode.classList.contains("jtags")
- ) {
- if (
- e.target.classList.contains("jtags_label") ||
- e.target.classList.contains("jtags_error")
- ) {
- var rect = e.target.getBoundingClientRect();
- if (rect.width - (e.clientX - rect.left) < 16) {
- obj.remove(e.target);
- }
- }
- }
-
- // Set focus in the last item
- if (e.target == el) {
- setFocus();
- }
- };
-
- var tagsFocus = function () {
- if (!el.classList.contains("jtags-focus")) {
- if (!el.children.length || obj.getValue(el.children.length - 1)) {
- if (!limit()) {
- createElement("");
- }
- }
-
- if (typeof obj.options.onfocus == "function") {
- obj.options.onfocus(el, obj, obj.getValue());
- }
-
- el.classList.add("jtags-focus");
- }
- };
-
- var tagsBlur = function () {
- if (el.classList.contains("jtags-focus")) {
- if (search) {
- search.close();
- }
-
- for (var i = 0; i < el.children.length - 1; i++) {
- // Create label design
- if (!obj.getValue(i)) {
- el.removeChild(el.children[i]);
- }
- }
-
- change();
-
- el.classList.remove("jtags-focus");
-
- if (typeof obj.options.onblur == "function") {
- obj.options.onblur(el, obj, obj.getValue());
- }
- }
- };
-
- var init = function () {
- // Bind events
- if ("touchend" in document.documentElement === true) {
- el.addEventListener("touchend", tagsMouseUp);
- } else {
- el.addEventListener("mouseup", tagsMouseUp);
- }
-
- el.addEventListener("keydown", tagsKeyDown);
- el.addEventListener("keyup", tagsKeyUp);
- el.addEventListener("paste", tagsPaste);
- el.addEventListener("focus", tagsFocus);
- el.addEventListener("blur", tagsBlur);
-
- // Editable
- el.setAttribute("contenteditable", true);
-
- // Prepare container
- el.classList.add("jtags");
-
- // Initial options
- obj.setOptions(options);
-
- if (typeof obj.options.onload == "function") {
- obj.options.onload(el, obj);
- }
-
- // Change methods
- el.change = obj.setValue;
-
- // Global generic value handler
- el.val = function (val) {
- if (val === undefined) {
- return obj.getValue();
- } else {
- obj.setValue(val);
- }
- };
-
- el.tags = obj;
- };
-
- init();
-
- return obj;
- };
-
- jSuites.toolbar = function (el, options) {
- // New instance
- var obj = { type: "toolbar" };
- obj.options = {};
-
- // Default configuration
- var defaults = {
- app: null,
- container: false,
- badge: false,
- title: false,
- responsive: false,
- maxWidth: null,
- bottom: true,
- items: [],
- };
-
- // Loop through our object
- for (var property in defaults) {
- if (options && options.hasOwnProperty(property)) {
- obj.options[property] = options[property];
- } else {
- obj.options[property] = defaults[property];
- }
- }
-
- if (!el && options.app && options.app.el) {
- el = document.createElement("div");
- options.app.el.appendChild(el);
- }
-
- // Arrow
- var toolbarArrow = document.createElement("div");
- toolbarArrow.classList.add("jtoolbar-item");
- toolbarArrow.classList.add("jtoolbar-arrow");
-
- var toolbarFloating = document.createElement("div");
- toolbarFloating.classList.add("jtoolbar-floating");
- toolbarArrow.appendChild(toolbarFloating);
-
- obj.selectItem = function (element) {
- var elements = toolbarContent.children;
- for (var i = 0; i < elements.length; i++) {
- if (element != elements[i]) {
- elements[i].classList.remove("jtoolbar-selected");
- }
- }
- element.classList.add("jtoolbar-selected");
- };
-
- obj.hide = function () {
- jSuites.animation.slideBottom(el, 0, function () {
- el.style.display = "none";
- });
- };
-
- obj.show = function () {
- el.style.display = "";
- jSuites.animation.slideBottom(el, 1);
- };
-
- obj.get = function () {
- return el;
- };
-
- obj.setBadge = function (index, value) {
- toolbarContent.children[index].children[1].firstChild.innerHTML = value;
- };
-
- obj.destroy = function () {
- toolbar.remove();
- el.innerHTML = "";
- };
-
- obj.update = function (a, b) {
- for (var i = 0; i < toolbarContent.children.length; i++) {
- // Toolbar element
- var toolbarItem = toolbarContent.children[i];
- // State management
- if (typeof toolbarItem.updateState == "function") {
- toolbarItem.updateState(el, obj, toolbarItem, a, b);
- }
- }
- for (var i = 0; i < toolbarFloating.children.length; i++) {
- // Toolbar element
- var toolbarItem = toolbarFloating.children[i];
- // State management
- if (typeof toolbarItem.updateState == "function") {
- toolbarItem.updateState(el, obj, toolbarItem, a, b);
- }
- }
- };
-
- obj.create = function (items) {
- // Reset anything in the toolbar
- toolbarContent.innerHTML = "";
- // Create elements in the toolbar
- for (var i = 0; i < items.length; i++) {
- var toolbarItem = document.createElement("div");
- toolbarItem.classList.add("jtoolbar-item");
-
- if (items[i].width) {
- toolbarItem.style.width = parseInt(items[i].width) + "px";
- }
-
- if (items[i].k) {
- toolbarItem.k = items[i].k;
- }
-
- if (items[i].tooltip) {
- toolbarItem.setAttribute("title", items[i].tooltip);
- }
-
- // Id
- if (items[i].id) {
- toolbarItem.setAttribute("id", items[i].id);
- }
-
- // Selected
- if (items[i].updateState) {
- toolbarItem.updateState = items[i].updateState;
- }
-
- if (items[i].active) {
- toolbarItem.classList.add("jtoolbar-active");
- }
-
- if (items[i].type == "select" || items[i].type == "dropdown") {
- jSuites.picker(toolbarItem, items[i]);
- } else if (items[i].type == "divisor") {
- toolbarItem.classList.add("jtoolbar-divisor");
- } else if (items[i].type == "label") {
- toolbarItem.classList.add("jtoolbar-label");
- toolbarItem.innerHTML = items[i].content;
- } else {
- // Material icons
- var toolbarIcon = document.createElement("i");
- if (typeof items[i].class === "undefined") {
- toolbarIcon.classList.add("material-icons");
- } else {
- var c = items[i].class.split(" ");
- for (var j = 0; j < c.length; j++) {
- toolbarIcon.classList.add(c[j]);
- }
- }
- toolbarIcon.innerHTML = items[i].content ? items[i].content : "";
- toolbarItem.appendChild(toolbarIcon);
-
- // Badge options
- if (obj.options.badge == true) {
- var toolbarBadge = document.createElement("div");
- toolbarBadge.classList.add("jbadge");
- var toolbarBadgeContent = document.createElement("div");
- toolbarBadgeContent.innerHTML = items[i].badge
- ? items[i].badge
- : "";
- toolbarBadge.appendChild(toolbarBadgeContent);
- toolbarItem.appendChild(toolbarBadge);
- }
-
- // Title
- if (items[i].title) {
- if (obj.options.title == true) {
- var toolbarTitle = document.createElement("span");
- toolbarTitle.innerHTML = items[i].title;
- toolbarItem.appendChild(toolbarTitle);
- } else {
- toolbarItem.setAttribute("title", items[i].title);
- }
- }
-
- if (obj.options.app && items[i].route) {
- // Route
- toolbarItem.route = items[i].route;
- // Onclick for route
- toolbarItem.onclick = function () {
- obj.options.app.pages(this.route);
- };
- // Create pages
- obj.options.app.pages(items[i].route, {
- toolbarItem: toolbarItem,
- closed: true,
- });
- }
- }
-
- if (items[i].onclick) {
- toolbarItem.onclick = items[i].onclick.bind(
- items[i],
- el,
- obj,
- toolbarItem
- );
- }
-
- toolbarContent.appendChild(toolbarItem);
- }
-
- // Fits to the page
- setTimeout(function () {
- obj.refresh();
- }, 0);
- };
-
- obj.open = function () {
- toolbarArrow.classList.add("jtoolbar-arrow-selected");
-
- var rectElement = el.getBoundingClientRect();
- var rect = toolbarFloating.getBoundingClientRect();
- if (rect.bottom > window.innerHeight || obj.options.bottom) {
- toolbarFloating.style.bottom = "0";
- } else {
- toolbarFloating.style.removeProperty("bottom");
- }
-
- toolbarFloating.style.right = "0";
-
- toolbarArrow.children[0].focus();
- // Start tracking
- jSuites.tracking(obj, true);
- };
-
- obj.close = function () {
- toolbarArrow.classList.remove("jtoolbar-arrow-selected");
- // End tracking
- jSuites.tracking(obj, false);
- };
-
- obj.refresh = function () {
- if (obj.options.responsive == true) {
- // Width of the c
- var rect = el.parentNode.getBoundingClientRect();
- if (!obj.options.maxWidth) {
- obj.options.maxWidth = rect.width;
- }
- // Available parent space
- var available = parseInt(obj.options.maxWidth);
- // Remove arrow
- if (toolbarArrow.parentNode) {
- toolbarArrow.parentNode.removeChild(toolbarArrow);
- }
- // Move all items to the toolbar
- while (toolbarFloating.firstChild) {
- toolbarContent.appendChild(toolbarFloating.firstChild);
- }
- // Toolbar is larger than the parent, move elements to the floating element
- if (available < toolbarContent.offsetWidth) {
- // Give space to the floating element
- available -= 50;
- // Move to the floating option
- while (
- toolbarContent.lastChild &&
- available < toolbarContent.offsetWidth
- ) {
- toolbarFloating.insertBefore(
- toolbarContent.lastChild,
- toolbarFloating.firstChild
- );
- }
- }
- // Show arrow
- if (toolbarFloating.children.length > 0) {
- toolbarContent.appendChild(toolbarArrow);
- }
- }
- };
-
- obj.setReadonly = function (state) {
- state = state ? "add" : "remove";
- el.classList[state]("jtoolbar-readonly");
- };
-
- el.onclick = function (e) {
- var element = jSuites.findElement(e.target, "jtoolbar-item");
- if (element) {
- obj.selectItem(element);
- }
-
- if (e.target.classList.contains("jtoolbar-arrow")) {
- obj.open();
- }
- };
-
- window.addEventListener("resize", function () {
- obj.refresh();
- });
-
- // Toolbar
- el.classList.add("jtoolbar");
- // Reset content
- el.innerHTML = "";
- // Container
- if (obj.options.container == true) {
- el.classList.add("jtoolbar-container");
- }
- // Content
- var toolbarContent = document.createElement("div");
- el.appendChild(toolbarContent);
- // Special toolbar for mobile applications
- if (obj.options.app) {
- el.classList.add("jtoolbar-mobile");
- }
- // Create toolbar
- obj.create(obj.options.items);
- // Shortcut
- el.toolbar = obj;
-
- return obj;
- };
-
- jSuites.validations = (function () {
- /**
- * Options: Object,
- * Properties:
- * Constraint,
- * Reference,
- * Value
- */
-
- var isNumeric = function (num) {
- return !isNaN(num) && num !== null && num !== "";
- };
-
- var numberCriterias = {
- between: function (value, range) {
- return value >= range[0] && value <= range[1];
- },
- "not between": function (value, range) {
- return value < range[0] || value > range[1];
- },
- "<": function (value, range) {
- return value < range[0];
- },
- "<=": function (value, range) {
- return value <= range[0];
- },
- ">": function (value, range) {
- return value > range[0];
- },
- ">=": function (value, range) {
- return value >= range[0];
- },
- "=": function (value, range) {
- return value == range[0];
- },
- "!=": function (value, range) {
- return value != range[0];
- },
- };
-
- var dateCriterias = {
- "valid date": function () {
- return true;
- },
- "=": function (value, range) {
- return value === range[0];
- },
- "<": function (value, range) {
- return value < range[0];
- },
- "<=": function (value, range) {
- return value <= range[0];
- },
- ">": function (value, range) {
- return value > range[0];
- },
- ">=": function (value, range) {
- return value >= range[0];
- },
- between: function (value, range) {
- return value >= range[0] && value <= range[1];
- },
- "not between": function (value, range) {
- return value < range[0] || value > range[1];
- },
- };
-
- var textCriterias = {
- contains: function (value, range) {
- return value.includes(range[0]);
- },
- "not contains": function (value, range) {
- return !value.includes(range[0]);
- },
- "begins with": function (value, range) {
- return value.startsWith(range[0]);
- },
- "ends with": function (value, range) {
- return value.endsWith(range[0]);
- },
- "=": function (value, range) {
- return value === range[0];
- },
- "valid email": function (value) {
- var pattern = new RegExp(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
-
- return pattern.test(value);
- },
- "valid url": function (value) {
- var pattern = new RegExp(
- /(((https?:\/\/)|(www\.))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]+)/gi
- );
-
- return pattern.test(value);
- },
- };
-
- // Component router
- var component = function (value, options) {
- if (typeof component[options.type] === "function") {
- if (options.allowBlank && value === "") {
- return true;
- }
-
- return component[options.type](value, options);
- }
- return null;
- };
-
- component.url = function () {
- var pattern = new RegExp(
- /(((https?:\/\/)|(www\.))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]+)/gi
- );
- return pattern.test(data) ? true : false;
- };
-
- component.email = function (data) {
- var pattern = new RegExp(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
- return data && pattern.test(data) ? true : false;
- };
-
- component.required = function (data) {
- return data.trim() ? true : false;
- };
-
- component.exist = function (data, options) {
- return !!data.toString();
- };
-
- component["not exist"] = function (data, options) {
- return !data.toString();
- };
-
- component.number = function (data, options) {
- if (!isNumeric(data)) {
- return false;
- }
-
- if (!options || !options.criteria) {
- return true;
- }
-
- if (!numberCriterias[options.criteria]) {
- return false;
- }
-
- var values = options.value.map(function (num) {
- return parseFloat(num);
- });
-
- return numberCriterias[options.criteria](data, values);
- };
-
- component.login = function (data) {
- var pattern = new RegExp(/^[a-zA-Z0-9\_\-\.\s+]+$/);
- return data && pattern.test(data) ? true : false;
- };
-
- component.list = function (data, options) {
- var dataType = typeof data;
- if (dataType !== "string" && dataType !== "number") {
- return false;
- }
- if (typeof options.value[0] === "string") {
- var list = options.value[0].split(",");
- } else {
- var list = options.value[0];
- }
-
- var validOption = list.findIndex(function name(item) {
- return item == data;
- });
-
- return validOption > -1;
- };
-
- component.date = function (data, options) {
- if (new Date(data) == "Invalid Date") {
- return false;
- }
-
- if (!options || !options.criteria) {
- return true;
- }
-
- if (!dateCriterias[options.criteria]) {
- return false;
- }
-
- var values = options.value.map(function (date) {
- return new Date(date).getTime();
- });
-
- return dateCriterias[options.criteria](new Date(data).getTime(), values);
- };
-
- component.text = function (data, options) {
- if (typeof data !== "string") {
- return false;
- }
-
- if (!options || !options.criteria) {
- return true;
- }
-
- if (!textCriterias[options.criteria]) {
- return false;
- }
-
- return textCriterias[options.criteria](data, options.value);
- };
-
- component.textLength = function (data, options) {
- data = data.toString();
-
- return component.number(data.length, options);
- };
-
- return component;
- })();
-
- return jSuites;
-});
-
/**
* Jspreadsheet v4.10.1
*
diff --git a/assets/jsuites.js b/assets/jsuites.js
new file mode 100644
index 0000000..09fadc6
--- /dev/null
+++ b/assets/jsuites.js
@@ -0,0 +1,13310 @@
+/**
+ * (c) jSuites Javascript Web Components
+ *
+ * Website: https://jsuites.net
+ * Description: Create amazing web based applications.
+ *
+ * MIT License
+ *
+ */
+(function (global, factory) {
+ typeof exports === "object" && typeof module !== "undefined"
+ ? (module.exports = factory())
+ : typeof define === "function" && define.amd
+ ? define(factory)
+ : (global.jSuites = factory());
+})(this, function () {
+ "use strict";
+
+ var jSuites = {};
+
+ var Version = "4.14.3";
+
+ var Events = function () {
+ document.jsuitesComponents = [];
+
+ var find = function (DOMElement, component) {
+ if (
+ DOMElement[component.type] &&
+ DOMElement[component.type] == component
+ ) {
+ return true;
+ }
+ if (DOMElement.component && DOMElement.component == component) {
+ return true;
+ }
+ if (DOMElement.parentNode) {
+ return find(DOMElement.parentNode, component);
+ }
+ return false;
+ };
+
+ var isOpened = function (e) {
+ if (document.jsuitesComponents && document.jsuitesComponents.length > 0) {
+ for (var i = 0; i < document.jsuitesComponents.length; i++) {
+ if (
+ document.jsuitesComponents[i] &&
+ !find(e, document.jsuitesComponents[i])
+ ) {
+ document.jsuitesComponents[i].close();
+ }
+ }
+ }
+ };
+
+ // Width of the border
+ var cornerSize = 15;
+
+ // Current element
+ var element = null;
+
+ // Controllers
+ var editorAction = false;
+
+ // Event state
+ var state = {
+ x: null,
+ y: null,
+ };
+
+ // Tooltip element
+ var tooltip = document.createElement("div");
+ tooltip.classList.add("jtooltip");
+
+ // Events
+ var mouseDown = function (e) {
+ // Check if this is the floating
+ var item = jSuites.findElement(e.target, "jpanel");
+ // Jfloating found
+ if (item && !item.classList.contains("readonly")) {
+ // Add focus to the chart container
+ item.focus();
+ // Keep the tracking information
+ var rect = e.target.getBoundingClientRect();
+ editorAction = {
+ e: item,
+ x: e.clientX,
+ y: e.clientY,
+ w: rect.width,
+ h: rect.height,
+ d: item.style.cursor,
+ resizing: item.style.cursor ? true : false,
+ actioned: false,
+ };
+
+ // Make sure width and height styling is OK
+ if (!item.style.width) {
+ item.style.width = rect.width + "px";
+ }
+
+ if (!item.style.height) {
+ item.style.height = rect.height + "px";
+ }
+
+ // Remove any selection from the page
+ var s = window.getSelection();
+ if (s.rangeCount) {
+ for (var i = 0; i < s.rangeCount; i++) {
+ s.removeRange(s.getRangeAt(i));
+ }
+ }
+
+ e.preventDefault();
+ e.stopPropagation();
+ } else {
+ // No floating action found
+ editorAction = false;
+ }
+
+ // Verify current components tracking
+ if (e.changedTouches && e.changedTouches[0]) {
+ var x = e.changedTouches[0].clientX;
+ var y = e.changedTouches[0].clientY;
+ } else {
+ var x = e.clientX;
+ var y = e.clientY;
+ }
+
+ // Which component I am clicking
+ var path = e.path || (e.composedPath && e.composedPath());
+
+ // If path available get the first element in the chain
+ if (path) {
+ element = path[0];
+ } else {
+ // Try to guess using the coordinates
+ if (e.target && e.target.shadowRoot) {
+ var d = e.target.shadowRoot;
+ } else {
+ var d = document;
+ }
+ // Get the first target element
+ element = d.elementFromPoint(x, y);
+ }
+
+ isOpened(element);
+ };
+
+ var mouseUp = function (e) {
+ if (editorAction && editorAction.e) {
+ if (typeof editorAction.e.refresh == "function" && state.actioned) {
+ editorAction.e.refresh();
+ }
+ editorAction.e.style.cursor = "";
+ }
+
+ // Reset
+ state = {
+ x: null,
+ y: null,
+ };
+
+ editorAction = false;
+ };
+
+ var mouseMove = function (e) {
+ if (editorAction) {
+ var x = e.clientX || e.pageX;
+ var y = e.clientY || e.pageY;
+
+ // Action on going
+ if (!editorAction.resizing) {
+ if (state.x == null && state.y == null) {
+ state.x = x;
+ state.y = y;
+ }
+
+ var dx = x - state.x;
+ var dy = y - state.y;
+ var top = editorAction.e.offsetTop + dy;
+ var left = editorAction.e.offsetLeft + dx;
+
+ // Update position
+ editorAction.e.style.top = top + "px";
+ editorAction.e.style.left = left + "px";
+ editorAction.e.style.cursor = "move";
+
+ state.x = x;
+ state.y = y;
+
+ // Update element
+ if (typeof editorAction.e.refresh == "function") {
+ state.actioned = true;
+ editorAction.e.refresh("position", top, left);
+ }
+ } else {
+ var width = null;
+ var height = null;
+
+ if (
+ editorAction.d == "e-resize" ||
+ editorAction.d == "ne-resize" ||
+ editorAction.d == "se-resize"
+ ) {
+ // Update width
+ width = editorAction.w + (x - editorAction.x);
+ editorAction.e.style.width = width + "px";
+
+ // Update Height
+ if (e.shiftKey) {
+ var newHeight =
+ (x - editorAction.x) * (editorAction.h / editorAction.w);
+ height = editorAction.h + newHeight;
+ editorAction.e.style.height = height + "px";
+ } else {
+ var newHeight = false;
+ }
+ }
+
+ if (!newHeight) {
+ if (
+ editorAction.d == "s-resize" ||
+ editorAction.d == "se-resize" ||
+ editorAction.d == "sw-resize"
+ ) {
+ height = editorAction.h + (y - editorAction.y);
+ editorAction.e.style.height = height + "px";
+ }
+ }
+
+ // Update element
+ if (typeof editorAction.e.refresh == "function") {
+ state.actioned = true;
+ editorAction.e.refresh("dimensions", width, height);
+ }
+ }
+ } else {
+ // Resizing action
+ var item = jSuites.findElement(e.target, "jpanel");
+ // Found eligible component
+ if (item) {
+ if (item.getAttribute("tabindex")) {
+ var rect = item.getBoundingClientRect();
+ if (e.clientY - rect.top < cornerSize) {
+ if (rect.width - (e.clientX - rect.left) < cornerSize) {
+ item.style.cursor = "ne-resize";
+ } else if (e.clientX - rect.left < cornerSize) {
+ item.style.cursor = "nw-resize";
+ } else {
+ item.style.cursor = "n-resize";
+ }
+ } else if (rect.height - (e.clientY - rect.top) < cornerSize) {
+ if (rect.width - (e.clientX - rect.left) < cornerSize) {
+ item.style.cursor = "se-resize";
+ } else if (e.clientX - rect.left < cornerSize) {
+ item.style.cursor = "sw-resize";
+ } else {
+ item.style.cursor = "s-resize";
+ }
+ } else if (rect.width - (e.clientX - rect.left) < cornerSize) {
+ item.style.cursor = "e-resize";
+ } else if (e.clientX - rect.left < cornerSize) {
+ item.style.cursor = "w-resize";
+ } else {
+ item.style.cursor = "";
+ }
+ }
+ }
+ }
+ };
+
+ var mouseOver = function (e) {
+ var message = e.target.getAttribute("data-tooltip");
+ if (message) {
+ // Instructions
+ tooltip.innerText = message;
+
+ // Position
+ if (e.changedTouches && e.changedTouches[0]) {
+ var x = e.changedTouches[0].clientX;
+ var y = e.changedTouches[0].clientY;
+ } else {
+ var x = e.clientX;
+ var y = e.clientY;
+ }
+
+ tooltip.style.top = y + "px";
+ tooltip.style.left = x + "px";
+ document.body.appendChild(tooltip);
+ } else if (tooltip.innerText) {
+ tooltip.innerText = "";
+ document.body.removeChild(tooltip);
+ }
+ };
+
+ var dblClick = function (e) {
+ var item = jSuites.findElement(e.target, "jpanel");
+ if (item && typeof item.dblclick == "function") {
+ // Create edition
+ item.dblclick(e);
+ }
+ };
+
+ var contextMenu = function (e) {
+ var item = document.activeElement;
+ if (item && typeof item.contextmenu == "function") {
+ // Create edition
+ item.contextmenu(e);
+
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ } else {
+ // Search for possible context menus
+ item = jSuites.findElement(e.target, function (o) {
+ return o.tagName && o.getAttribute("aria-contextmenu-id");
+ });
+
+ if (item) {
+ var o = document.querySelector("#" + item);
+ if (!o) {
+ console.error("JSUITES: contextmenu id not found: " + item);
+ } else {
+ o.contextmenu.open(e);
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ }
+ }
+ }
+ };
+
+ var keyDown = function (e) {
+ var item = document.activeElement;
+ if (item) {
+ if (e.key == "Delete" && typeof item.delete == "function") {
+ item.delete();
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ }
+ }
+
+ if (document.jsuitesComponents && document.jsuitesComponents.length) {
+ if (
+ (item =
+ document.jsuitesComponents[document.jsuitesComponents.length - 1])
+ ) {
+ if (e.key == "Escape" && typeof item.close == "function") {
+ item.close();
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ }
+ }
+ }
+ };
+
+ document.addEventListener("mouseup", mouseUp);
+ document.addEventListener("mousedown", mouseDown);
+ document.addEventListener("mousemove", mouseMove);
+ document.addEventListener("mouseover", mouseOver);
+ document.addEventListener("dblclick", dblClick);
+ document.addEventListener("keydown", keyDown);
+ document.addEventListener("contextmenu", contextMenu);
+ };
+
+ /**
+ * Global jsuites event
+ */
+ if (typeof document !== "undefined" && !document.jsuitesComponents) {
+ Events();
+ }
+
+ jSuites.version = Version;
+
+ jSuites.setExtensions = function (o) {
+ if (typeof o == "object") {
+ var k = Object.keys(o);
+ for (var i = 0; i < k.length; i++) {
+ jSuites[k[i]] = o[k[i]];
+ }
+ }
+ };
+
+ jSuites.tracking = function (component, state) {
+ if (state == true) {
+ document.jsuitesComponents = document.jsuitesComponents.filter(function (
+ v
+ ) {
+ return v !== null;
+ });
+
+ // Start after all events
+ setTimeout(function () {
+ document.jsuitesComponents.push(component);
+ }, 0);
+ } else {
+ var index = document.jsuitesComponents.indexOf(component);
+ if (index >= 0) {
+ document.jsuitesComponents.splice(index, 1);
+ }
+ }
+ };
+
+ /**
+ * Get or set a property from a JSON from a string.
+ */
+ jSuites.path = function (str, val) {
+ str = str.split(".");
+ if (str.length) {
+ var o = this;
+ var p = null;
+ while (str.length > 1) {
+ // Get the property
+ p = str.shift();
+ // Check if the property exists
+ if (o.hasOwnProperty(p)) {
+ o = o[p];
+ } else {
+ // Property does not exists
+ if (val === undefined) {
+ return undefined;
+ } else {
+ // Create the property
+ o[p] = {};
+ // Next property
+ o = o[p];
+ }
+ }
+ }
+ // Get the property
+ p = str.shift();
+ // Set or get the value
+ if (val !== undefined) {
+ o[p] = val;
+ // Success
+ return true;
+ } else {
+ // Return the value
+ if (o) {
+ return o[p];
+ }
+ }
+ }
+ // Something went wrong
+ return false;
+ };
+
+ // Update dictionary
+ jSuites.setDictionary = function (d) {
+ if (!document.dictionary) {
+ document.dictionary = {};
+ }
+ // Replace the key into the dictionary and append the new ones
+ var k = Object.keys(d);
+ for (var i = 0; i < k.length; i++) {
+ document.dictionary[k[i]] = d[k[i]];
+ }
+
+ // Translations
+ var t = null;
+ for (var i = 0; i < jSuites.calendar.weekdays.length; i++) {
+ t = jSuites.translate(jSuites.calendar.weekdays[i]);
+ if (jSuites.calendar.weekdays[i]) {
+ jSuites.calendar.weekdays[i] = t;
+ jSuites.calendar.weekdaysShort[i] = t.substr(0, 3);
+ }
+ }
+ for (var i = 0; i < jSuites.calendar.months.length; i++) {
+ t = jSuites.translate(jSuites.calendar.months[i]);
+ if (t) {
+ jSuites.calendar.months[i] = t;
+ jSuites.calendar.monthsShort[i] = t.substr(0, 3);
+ }
+ }
+ };
+
+ // Translate
+ jSuites.translate = function (t) {
+ if (document.dictionary) {
+ return document.dictionary[t] || t;
+ } else {
+ return t;
+ }
+ };
+
+ jSuites.ajax = function (options, complete) {
+ if (Array.isArray(options)) {
+ // Create multiple request controller
+ var multiple = {
+ instance: [],
+ complete: complete,
+ };
+
+ if (options.length > 0) {
+ for (var i = 0; i < options.length; i++) {
+ options[i].multiple = multiple;
+ multiple.instance.push(jSuites.ajax(options[i]));
+ }
+ }
+
+ return multiple;
+ }
+
+ if (!options.data) {
+ options.data = {};
+ }
+
+ if (options.type) {
+ options.method = options.type;
+ }
+
+ // Default method
+ if (!options.method) {
+ options.method = "GET";
+ }
+
+ // Default type
+ if (!options.dataType) {
+ options.dataType = "json";
+ }
+
+ if (options.data) {
+ // Parse object to variables format
+ var parseData = function (value, key) {
+ var vars = [];
+ if (value) {
+ var keys = Object.keys(value);
+ if (keys.length) {
+ for (var i = 0; i < keys.length; i++) {
+ if (key) {
+ var k = key + "[" + keys[i] + "]";
+ } else {
+ var k = keys[i];
+ }
+
+ if (value[k] instanceof FileList) {
+ vars[k] = value[keys[i]];
+ } else if (
+ value[keys[i]] === null ||
+ value[keys[i]] === undefined
+ ) {
+ vars[k] = "";
+ } else if (typeof value[keys[i]] == "object") {
+ var r = parseData(value[keys[i]], k);
+ var o = Object.keys(r);
+ for (var j = 0; j < o.length; j++) {
+ vars[o[j]] = r[o[j]];
+ }
+ } else {
+ vars[k] = value[keys[i]];
+ }
+ }
+ }
+ }
+
+ return vars;
+ };
+
+ var d = parseData(options.data);
+ var k = Object.keys(d);
+
+ // Data form
+ if (options.method == "GET") {
+ if (k.length) {
+ var data = [];
+ for (var i = 0; i < k.length; i++) {
+ data.push(k[i] + "=" + encodeURIComponent(d[k[i]]));
+ }
+
+ if (options.url.indexOf("?") < 0) {
+ options.url += "?";
+ }
+ options.url += data.join("&");
+ }
+ } else {
+ var data = new FormData();
+ for (var i = 0; i < k.length; i++) {
+ if (d[k[i]] instanceof FileList) {
+ if (d[k[i]].length) {
+ for (var j = 0; j < d[k[i]].length; j++) {
+ data.append(k[i], d[k[i]][j], d[k[i]][j].name);
+ }
+ }
+ } else {
+ data.append(k[i], d[k[i]]);
+ }
+ }
+ }
+ }
+
+ var httpRequest = new XMLHttpRequest();
+ httpRequest.open(options.method, options.url, true);
+ httpRequest.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+ // Content type
+ if (options.contentType) {
+ httpRequest.setRequestHeader("Content-Type", options.contentType);
+ }
+
+ // Headers
+ if (options.method == "POST") {
+ httpRequest.setRequestHeader("Accept", "application/json");
+ } else {
+ if (options.dataType == "blob") {
+ httpRequest.responseType = "blob";
+ } else {
+ if (!options.contentType) {
+ if (options.dataType == "json") {
+ httpRequest.setRequestHeader("Content-Type", "text/json");
+ } else if (options.dataType == "html") {
+ httpRequest.setRequestHeader("Content-Type", "text/html");
+ }
+ }
+ }
+ }
+
+ // No cache
+ if (options.cache != true) {
+ httpRequest.setRequestHeader("pragma", "no-cache");
+ httpRequest.setRequestHeader("cache-control", "no-cache");
+ }
+
+ // Authentication
+ if (options.withCredentials == true) {
+ httpRequest.withCredentials = true;
+ }
+
+ // Before send
+ if (typeof options.beforeSend == "function") {
+ options.beforeSend(httpRequest);
+ }
+
+ // Before send
+ if (typeof jSuites.ajax.beforeSend == "function") {
+ jSuites.ajax.beforeSend(httpRequest);
+ }
+
+ if (document.ajax && typeof document.ajax.beforeSend == "function") {
+ document.ajax.beforeSend(httpRequest);
+ }
+
+ httpRequest.onload = function () {
+ if (httpRequest.status === 200) {
+ if (options.dataType == "json") {
+ try {
+ var result = JSON.parse(httpRequest.responseText);
+
+ if (options.success && typeof options.success == "function") {
+ options.success(result);
+ }
+ } catch (err) {
+ if (options.error && typeof options.error == "function") {
+ options.error(err, result);
+ }
+ }
+ } else {
+ if (options.dataType == "blob") {
+ var result = httpRequest.response;
+ } else {
+ var result = httpRequest.responseText;
+ }
+
+ if (options.success && typeof options.success == "function") {
+ options.success(result);
+ }
+ }
+ } else {
+ if (options.error && typeof options.error == "function") {
+ options.error(httpRequest.responseText, httpRequest.status);
+ }
+ }
+
+ // Global queue
+ if (jSuites.ajax.queue && jSuites.ajax.queue.length > 0) {
+ jSuites.ajax.send(jSuites.ajax.queue.shift());
+ }
+
+ // Global complete method
+ if (jSuites.ajax.requests && jSuites.ajax.requests.length) {
+ // Get index of this request in the container
+ var index = jSuites.ajax.requests.indexOf(httpRequest);
+ // Remove from the ajax requests container
+ jSuites.ajax.requests.splice(index, 1);
+ // Deprected: Last one?
+ if (!jSuites.ajax.requests.length) {
+ // Object event
+ if (options.complete && typeof options.complete == "function") {
+ options.complete(result);
+ }
+ }
+ // Group requests
+ if (options.group) {
+ if (
+ jSuites.ajax.oncomplete &&
+ typeof jSuites.ajax.oncomplete[options.group] == "function"
+ ) {
+ if (!jSuites.ajax.pending(options.group)) {
+ jSuites.ajax.oncomplete[options.group]();
+ jSuites.ajax.oncomplete[options.group] = null;
+ }
+ }
+ }
+ // Multiple requests controller
+ if (options.multiple && options.multiple.instance) {
+ // Get index of this request in the container
+ var index = options.multiple.instance.indexOf(httpRequest);
+ // Remove from the ajax requests container
+ options.multiple.instance.splice(index, 1);
+ // If this is the last one call method complete
+ if (!options.multiple.instance.length) {
+ if (
+ options.multiple.complete &&
+ typeof options.multiple.complete == "function"
+ ) {
+ options.multiple.complete(result);
+ }
+ }
+ }
+ }
+ };
+
+ // Keep the options
+ httpRequest.options = options;
+ // Data
+ httpRequest.data = data;
+
+ // Queue
+ if (options.queue == true && jSuites.ajax.requests.length > 0) {
+ jSuites.ajax.queue.push(httpRequest);
+ } else {
+ jSuites.ajax.send(httpRequest);
+ }
+
+ return httpRequest;
+ };
+
+ jSuites.ajax.send = function (httpRequest) {
+ if (httpRequest.data) {
+ if (Array.isArray(httpRequest.data)) {
+ httpRequest.send(httpRequest.data.join("&"));
+ } else {
+ httpRequest.send(httpRequest.data);
+ }
+ } else {
+ httpRequest.send();
+ }
+
+ jSuites.ajax.requests.push(httpRequest);
+ };
+
+ jSuites.ajax.exists = function (url, __callback) {
+ var http = new XMLHttpRequest();
+ http.open("HEAD", url, false);
+ http.send();
+ if (http.status) {
+ __callback(http.status);
+ }
+ };
+
+ jSuites.ajax.pending = function (group) {
+ var n = 0;
+ var o = jSuites.ajax.requests;
+ if (o && o.length) {
+ for (var i = 0; i < o.length; i++) {
+ if (!group || group == o[i].options.group) {
+ n++;
+ }
+ }
+ }
+ return n;
+ };
+
+ jSuites.ajax.oncomplete = {};
+ jSuites.ajax.requests = [];
+ jSuites.ajax.queue = [];
+
+ jSuites.alert = function (message) {
+ if (jSuites.getWindowWidth() < 800 && jSuites.dialog) {
+ jSuites.dialog.open({
+ title: "Alert",
+ message: message,
+ });
+ } else {
+ alert(message);
+ }
+ };
+
+ jSuites.animation = {};
+
+ jSuites.animation.slideLeft = function (element, direction, done) {
+ if (direction == true) {
+ element.classList.add("slide-left-in");
+ setTimeout(function () {
+ element.classList.remove("slide-left-in");
+ if (typeof done == "function") {
+ done();
+ }
+ }, 400);
+ } else {
+ element.classList.add("slide-left-out");
+ setTimeout(function () {
+ element.classList.remove("slide-left-out");
+ if (typeof done == "function") {
+ done();
+ }
+ }, 400);
+ }
+ };
+
+ jSuites.animation.slideRight = function (element, direction, done) {
+ if (direction == true) {
+ element.classList.add("slide-right-in");
+ setTimeout(function () {
+ element.classList.remove("slide-right-in");
+ if (typeof done == "function") {
+ done();
+ }
+ }, 400);
+ } else {
+ element.classList.add("slide-right-out");
+ setTimeout(function () {
+ element.classList.remove("slide-right-out");
+ if (typeof done == "function") {
+ done();
+ }
+ }, 400);
+ }
+ };
+
+ jSuites.animation.slideTop = function (element, direction, done) {
+ if (direction == true) {
+ element.classList.add("slide-top-in");
+ setTimeout(function () {
+ element.classList.remove("slide-top-in");
+ if (typeof done == "function") {
+ done();
+ }
+ }, 400);
+ } else {
+ element.classList.add("slide-top-out");
+ setTimeout(function () {
+ element.classList.remove("slide-top-out");
+ if (typeof done == "function") {
+ done();
+ }
+ }, 400);
+ }
+ };
+
+ jSuites.animation.slideBottom = function (element, direction, done) {
+ if (direction == true) {
+ element.classList.add("slide-bottom-in");
+ setTimeout(function () {
+ element.classList.remove("slide-bottom-in");
+ if (typeof done == "function") {
+ done();
+ }
+ }, 400);
+ } else {
+ element.classList.add("slide-bottom-out");
+ setTimeout(function () {
+ element.classList.remove("slide-bottom-out");
+ if (typeof done == "function") {
+ done();
+ }
+ }, 100);
+ }
+ };
+
+ jSuites.animation.fadeIn = function (element, done) {
+ element.style.display = "";
+ element.classList.add("fade-in");
+ setTimeout(function () {
+ element.classList.remove("fade-in");
+ if (typeof done == "function") {
+ done();
+ }
+ }, 2000);
+ };
+
+ jSuites.animation.fadeOut = function (element, done) {
+ element.classList.add("fade-out");
+ setTimeout(function () {
+ element.style.display = "none";
+ element.classList.remove("fade-out");
+ if (typeof done == "function") {
+ done();
+ }
+ }, 1000);
+ };
+
+ jSuites.calendar = function (el, options) {
+ // Already created, update options
+ if (el.calendar) {
+ return el.calendar.setOptions(options, true);
+ }
+
+ // New instance
+ var obj = { type: "calendar" };
+ obj.options = {};
+
+ // Date
+ obj.date = null;
+
+ /**
+ * Update options
+ */
+ obj.setOptions = function (options, reset) {
+ // Default configuration
+ var defaults = {
+ // Render type: [ default | year-month-picker ]
+ type: "default",
+ // Restrictions
+ validRange: null,
+ // Starting weekday - 0 for sunday, 6 for saturday
+ startingDay: null,
+ // Date format
+ format: "DD/MM/YYYY",
+ // Allow keyboard date entry
+ readonly: true,
+ // Today is default
+ today: false,
+ // Show timepicker
+ time: false,
+ // Show the reset button
+ resetButton: true,
+ // Placeholder
+ placeholder: "",
+ // Translations can be done here
+ months: jSuites.calendar.monthsShort,
+ monthsFull: jSuites.calendar.months,
+ weekdays: jSuites.calendar.weekdays,
+ textDone: jSuites.translate("Done"),
+ textReset: jSuites.translate("Reset"),
+ textUpdate: jSuites.translate("Update"),
+ // Value
+ value: null,
+ // Fullscreen (this is automatic set for screensize < 800)
+ fullscreen: false,
+ // Create the calendar closed as default
+ opened: false,
+ // Events
+ onopen: null,
+ onclose: null,
+ onchange: null,
+ onupdate: null,
+ // Internal mode controller
+ mode: null,
+ position: null,
+ // Data type
+ dataType: null,
+ };
+
+ // Loop through our object
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ if (typeof obj.options[property] == "undefined" || reset === true) {
+ obj.options[property] = defaults[property];
+ }
+ }
+ }
+
+ // Reset button
+ if (obj.options.resetButton == false) {
+ calendarReset.style.display = "none";
+ } else {
+ calendarReset.style.display = "";
+ }
+
+ // Readonly
+ if (obj.options.readonly) {
+ el.setAttribute("readonly", "readonly");
+ } else {
+ el.removeAttribute("readonly");
+ }
+
+ // Placeholder
+ if (obj.options.placeholder) {
+ el.setAttribute("placeholder", obj.options.placeholder);
+ } else {
+ el.removeAttribute("placeholder");
+ }
+
+ if (jSuites.isNumeric(obj.options.value) && obj.options.value > 0) {
+ obj.options.value = jSuites.calendar.numToDate(obj.options.value);
+ // Data type numberic
+ obj.options.dataType = "numeric";
+ }
+
+ // Texts
+ calendarReset.innerHTML = obj.options.textReset;
+ calendarConfirm.innerHTML = obj.options.textDone;
+ calendarControlsUpdateButton.innerHTML = obj.options.textUpdate;
+
+ // Define mask
+ el.setAttribute("data-mask", obj.options.format.toLowerCase());
+
+ // Value
+ if (!obj.options.value && obj.options.today) {
+ var value = jSuites.calendar.now();
+ } else {
+ var value = obj.options.value;
+ }
+
+ // Set internal date
+ if (value) {
+ // Force the update
+ obj.options.value = null;
+ // New value
+ obj.setValue(value);
+ }
+
+ return obj;
+ };
+
+ /**
+ * Open the calendar
+ */
+ obj.open = function (value) {
+ if (!calendar.classList.contains("jcalendar-focus")) {
+ if (!calendar.classList.contains("jcalendar-inline")) {
+ // Current
+ jSuites.calendar.current = obj;
+ // Start tracking
+ jSuites.tracking(obj, true);
+ // Create the days
+ obj.getDays();
+ // Render months
+ if (obj.options.type == "year-month-picker") {
+ obj.getMonths();
+ }
+ // Get time
+ if (obj.options.time) {
+ calendarSelectHour.value = obj.date[3];
+ calendarSelectMin.value = obj.date[4];
+ }
+
+ // Show calendar
+ calendar.classList.add("jcalendar-focus");
+
+ // Get the position of the corner helper
+ if (jSuites.getWindowWidth() < 800 || obj.options.fullscreen) {
+ calendar.classList.add("jcalendar-fullsize");
+ // Animation
+ jSuites.animation.slideBottom(calendarContent, 1);
+ } else {
+ calendar.classList.remove("jcalendar-fullsize");
+
+ var rect = el.getBoundingClientRect();
+ var rectContent = calendarContent.getBoundingClientRect();
+
+ if (obj.options.position) {
+ calendarContainer.style.position = "fixed";
+ if (window.innerHeight < rect.bottom + rectContent.height) {
+ calendarContainer.style.top =
+ rect.top - (rectContent.height + 2) + "px";
+ } else {
+ calendarContainer.style.top = rect.top + rect.height + 2 + "px";
+ }
+ calendarContainer.style.left = rect.left + "px";
+ } else {
+ if (window.innerHeight < rect.bottom + rectContent.height) {
+ var d = -1 * (rect.height + rectContent.height + 2);
+ if (d + rect.top < 0) {
+ d = -1 * (rect.top + rect.height);
+ }
+ calendarContainer.style.top = d + "px";
+ } else {
+ calendarContainer.style.top = 2 + "px";
+ }
+
+ if (window.innerWidth < rect.left + rectContent.width) {
+ var d =
+ window.innerWidth - (rect.left + rectContent.width + 20);
+ calendarContainer.style.left = d + "px";
+ } else {
+ calendarContainer.style.left = "0px";
+ }
+ }
+ }
+
+ // Events
+ if (typeof obj.options.onopen == "function") {
+ obj.options.onopen(el);
+ }
+ }
+ }
+ };
+
+ obj.close = function (ignoreEvents, update) {
+ if (calendar.classList.contains("jcalendar-focus")) {
+ if (update !== false) {
+ var element = calendar.querySelector(".jcalendar-selected");
+
+ if (typeof update == "string") {
+ var value = update;
+ } else if (
+ !element ||
+ element.classList.contains("jcalendar-disabled")
+ ) {
+ var value = obj.options.value;
+ } else {
+ var value = obj.getValue();
+ }
+
+ obj.setValue(value);
+ }
+
+ // Events
+ if (!ignoreEvents && typeof obj.options.onclose == "function") {
+ obj.options.onclose(el);
+ }
+ // Hide
+ calendar.classList.remove("jcalendar-focus");
+ // Stop tracking
+ jSuites.tracking(obj, false);
+ // Current
+ jSuites.calendar.current = null;
+ }
+
+ return obj.options.value;
+ };
+
+ obj.prev = function () {
+ // Check if the visualization is the days picker or years picker
+ if (obj.options.mode == "years") {
+ obj.date[0] = obj.date[0] - 12;
+
+ // Update picker table of days
+ obj.getYears();
+ } else if (obj.options.mode == "months") {
+ obj.date[0] = parseInt(obj.date[0]) - 1;
+ // Update picker table of months
+ obj.getMonths();
+ } else {
+ // Go to the previous month
+ if (obj.date[1] < 2) {
+ obj.date[0] = obj.date[0] - 1;
+ obj.date[1] = 12;
+ } else {
+ obj.date[1] = obj.date[1] - 1;
+ }
+
+ // Update picker table of days
+ obj.getDays();
+ }
+ };
+
+ obj.next = function () {
+ // Check if the visualization is the days picker or years picker
+ if (obj.options.mode == "years") {
+ obj.date[0] = parseInt(obj.date[0]) + 12;
+
+ // Update picker table of days
+ obj.getYears();
+ } else if (obj.options.mode == "months") {
+ obj.date[0] = parseInt(obj.date[0]) + 1;
+ // Update picker table of months
+ obj.getMonths();
+ } else {
+ // Go to the previous month
+ if (obj.date[1] > 11) {
+ obj.date[0] = parseInt(obj.date[0]) + 1;
+ obj.date[1] = 1;
+ } else {
+ obj.date[1] = parseInt(obj.date[1]) + 1;
+ }
+
+ // Update picker table of days
+ obj.getDays();
+ }
+ };
+
+ /**
+ * Set today
+ */
+ obj.setToday = function () {
+ // Today
+ var value = new Date().toISOString().substr(0, 10);
+ // Change value
+ obj.setValue(value);
+ // Value
+ return value;
+ };
+
+ obj.setValue = function (val) {
+ if (!val) {
+ val = "" + val;
+ }
+ // Values
+ var newValue = val;
+ var oldValue = obj.options.value;
+
+ if (oldValue != newValue) {
+ // Set label
+ if (!newValue) {
+ obj.date = null;
+ var val = "";
+ } else {
+ var value = obj.setLabel(newValue, obj.options);
+ var date = newValue.split(" ");
+ if (!date[1]) {
+ date[1] = "00:00:00";
+ }
+ var time = date[1].split(":");
+ var date = date[0].split("-");
+ var y = parseInt(date[0]);
+ var m = parseInt(date[1]);
+ var d = parseInt(date[2]);
+ var h = parseInt(time[0]);
+ var i = parseInt(time[1]);
+ obj.date = [y, m, d, h, i, 0];
+ var val = obj.setLabel(newValue, obj.options);
+ }
+
+ // New value
+ obj.options.value = newValue;
+
+ if (typeof obj.options.onchange == "function") {
+ obj.options.onchange(el, newValue, oldValue);
+ }
+
+ // Lemonade JS
+ if (el.value != val) {
+ el.value = val;
+ if (typeof el.oninput == "function") {
+ el.oninput({
+ type: "input",
+ target: el,
+ value: el.value,
+ });
+ }
+ }
+ }
+
+ obj.getDays();
+ };
+
+ obj.getValue = function () {
+ if (obj.date) {
+ if (obj.options.time) {
+ return (
+ jSuites.two(obj.date[0]) +
+ "-" +
+ jSuites.two(obj.date[1]) +
+ "-" +
+ jSuites.two(obj.date[2]) +
+ " " +
+ jSuites.two(obj.date[3]) +
+ ":" +
+ jSuites.two(obj.date[4]) +
+ ":" +
+ jSuites.two(0)
+ );
+ } else {
+ return (
+ jSuites.two(obj.date[0]) +
+ "-" +
+ jSuites.two(obj.date[1]) +
+ "-" +
+ jSuites.two(obj.date[2]) +
+ " " +
+ jSuites.two(0) +
+ ":" +
+ jSuites.two(0) +
+ ":" +
+ jSuites.two(0)
+ );
+ }
+ } else {
+ return "";
+ }
+ };
+
+ /**
+ * Calendar
+ */
+ obj.update = function (element, v) {
+ if (element.classList.contains("jcalendar-disabled")) {
+ // Do nothing
+ } else {
+ var elements = calendar.querySelector(".jcalendar-selected");
+ if (elements) {
+ elements.classList.remove("jcalendar-selected");
+ }
+ element.classList.add("jcalendar-selected");
+
+ if (element.classList.contains("jcalendar-set-month")) {
+ obj.date[1] = v;
+ obj.date[2] = 1; // first day of the month
+ } else {
+ obj.date[2] = element.innerText;
+ }
+
+ if (!obj.options.time) {
+ obj.close();
+ } else {
+ obj.date[3] = calendarSelectHour.value;
+ obj.date[4] = calendarSelectMin.value;
+ }
+ }
+
+ // Update
+ updateActions();
+ };
+
+ /**
+ * Set to blank
+ */
+ obj.reset = function () {
+ // Close calendar
+ obj.setValue("");
+ obj.date = null;
+ obj.close(false, false);
+ };
+
+ /**
+ * Get calendar days
+ */
+ obj.getDays = function () {
+ // Mode
+ obj.options.mode = "days";
+
+ // Setting current values in case of NULLs
+ var date = new Date();
+
+ // Current selection
+ var year =
+ obj.date && jSuites.isNumeric(obj.date[0])
+ ? obj.date[0]
+ : parseInt(date.getFullYear());
+ var month =
+ obj.date && jSuites.isNumeric(obj.date[1])
+ ? obj.date[1]
+ : parseInt(date.getMonth()) + 1;
+ var day =
+ obj.date && jSuites.isNumeric(obj.date[2])
+ ? obj.date[2]
+ : parseInt(date.getDate());
+ var hour =
+ obj.date && jSuites.isNumeric(obj.date[3])
+ ? obj.date[3]
+ : parseInt(date.getHours());
+ var min =
+ obj.date && jSuites.isNumeric(obj.date[4])
+ ? obj.date[4]
+ : parseInt(date.getMinutes());
+
+ // Selection container
+ obj.date = [year, month, day, hour, min, 0];
+
+ // Update title
+ calendarLabelYear.innerHTML = year;
+ calendarLabelMonth.innerHTML = obj.options.months[month - 1];
+
+ // Current month and Year
+ var isCurrentMonthAndYear =
+ date.getMonth() == month - 1 && date.getFullYear() == year
+ ? true
+ : false;
+ var currentDay = date.getDate();
+
+ // Number of days in the month
+ var date = new Date(year, month, 0, 0, 0);
+ var numberOfDays = date.getDate();
+
+ // First day
+ var date = new Date(year, month - 1, 0, 0, 0);
+ var firstDay = date.getDay() + 1;
+
+ // Index value
+ var index = obj.options.startingDay || 0;
+
+ // First of day relative to the starting calendar weekday
+ firstDay = firstDay - index;
+
+ // Reset table
+ calendarBody.innerHTML = "";
+
+ // Weekdays Row
+ var row = document.createElement("tr");
+ row.setAttribute("align", "center");
+ calendarBody.appendChild(row);
+
+ // Create weekdays row
+ for (var i = 0; i < 7; i++) {
+ var cell = document.createElement("td");
+ cell.classList.add("jcalendar-weekday");
+ cell.innerHTML = obj.options.weekdays[index].substr(0, 1);
+ row.appendChild(cell);
+ // Next week day
+ index++;
+ // Restart index
+ if (index > 6) {
+ index = 0;
+ }
+ }
+
+ // Index of days
+ var index = 0;
+ var d = 0;
+
+ // Calendar table
+ for (var j = 0; j < 6; j++) {
+ // Reset cells container
+ var row = document.createElement("tr");
+ row.setAttribute("align", "center");
+ // Data control
+ var emptyRow = true;
+ // Create cells
+ for (var i = 0; i < 7; i++) {
+ // Create cell
+ var cell = document.createElement("td");
+ cell.classList.add("jcalendar-set-day");
+
+ if (index >= firstDay && index < firstDay + numberOfDays) {
+ // Day cell
+ d++;
+ cell.innerHTML = d;
+
+ // Selected
+ if (d == day) {
+ cell.classList.add("jcalendar-selected");
+ }
+
+ // Current selection day is today
+ if (isCurrentMonthAndYear && currentDay == d) {
+ cell.style.fontWeight = "bold";
+ }
+
+ // Current selection day
+ var current = jSuites.calendar.now(
+ new Date(year, month - 1, d),
+ true
+ );
+
+ // Available ranges
+ if (obj.options.validRange) {
+ if (
+ !obj.options.validRange[0] ||
+ current >= obj.options.validRange[0]
+ ) {
+ var test1 = true;
+ } else {
+ var test1 = false;
+ }
+
+ if (
+ !obj.options.validRange[1] ||
+ current <= obj.options.validRange[1]
+ ) {
+ var test2 = true;
+ } else {
+ var test2 = false;
+ }
+
+ if (!(test1 && test2)) {
+ cell.classList.add("jcalendar-disabled");
+ }
+ }
+
+ // Control
+ emptyRow = false;
+ }
+ // Day cell
+ row.appendChild(cell);
+ // Index
+ index++;
+ }
+
+ // Add cell to the calendar body
+ if (emptyRow == false) {
+ calendarBody.appendChild(row);
+ }
+ }
+
+ // Show time controls
+ if (obj.options.time) {
+ calendarControlsTime.style.display = "";
+ } else {
+ calendarControlsTime.style.display = "none";
+ }
+
+ // Update
+ updateActions();
+ };
+
+ obj.getMonths = function () {
+ // Mode
+ obj.options.mode = "months";
+
+ // Loading month labels
+ var months = obj.options.months;
+
+ // Value
+ var value = obj.options.value;
+
+ // Current date
+ var date = new Date();
+ var currentYear = parseInt(date.getFullYear());
+ var currentMonth = parseInt(date.getMonth()) + 1;
+ var selectedYear =
+ obj.date && jSuites.isNumeric(obj.date[0]) ? obj.date[0] : currentYear;
+ var selectedMonth =
+ obj.date && jSuites.isNumeric(obj.date[1]) ? obj.date[1] : currentMonth;
+
+ // Update title
+ calendarLabelYear.innerHTML = obj.date[0];
+ calendarLabelMonth.innerHTML = months[selectedMonth - 1];
+
+ // Table
+ var table = document.createElement("table");
+ table.setAttribute("width", "100%");
+
+ // Row
+ var row = null;
+
+ // Calendar table
+ for (var i = 0; i < 12; i++) {
+ if (!(i % 4)) {
+ // Reset cells container
+ var row = document.createElement("tr");
+ row.setAttribute("align", "center");
+ table.appendChild(row);
+ }
+
+ // Create cell
+ var cell = document.createElement("td");
+ cell.classList.add("jcalendar-set-month");
+ cell.setAttribute("data-value", i + 1);
+ cell.innerText = months[i];
+
+ if (obj.options.validRange) {
+ var current = selectedYear + "-" + jSuites.two(i + 1);
+ if (
+ !obj.options.validRange[0] ||
+ current >= obj.options.validRange[0].substr(0, 7)
+ ) {
+ var test1 = true;
+ } else {
+ var test1 = false;
+ }
+
+ if (
+ !obj.options.validRange[1] ||
+ current <= obj.options.validRange[1].substr(0, 7)
+ ) {
+ var test2 = true;
+ } else {
+ var test2 = false;
+ }
+
+ if (!(test1 && test2)) {
+ cell.classList.add("jcalendar-disabled");
+ }
+ }
+
+ if (i + 1 == selectedMonth) {
+ cell.classList.add("jcalendar-selected");
+ }
+
+ if (currentYear == selectedYear && i + 1 == currentMonth) {
+ cell.style.fontWeight = "bold";
+ }
+
+ row.appendChild(cell);
+ }
+
+ calendarBody.innerHTML = ' |
';
+ calendarBody.children[0].children[0].appendChild(table);
+
+ // Update
+ updateActions();
+ };
+
+ obj.getYears = function () {
+ // Mode
+ obj.options.mode = "years";
+
+ // Current date
+ var date = new Date();
+ var currentYear = date.getFullYear();
+ var selectedYear =
+ obj.date && jSuites.isNumeric(obj.date[0])
+ ? obj.date[0]
+ : parseInt(date.getFullYear());
+
+ // Array of years
+ var y = [];
+ for (var i = 0; i < 25; i++) {
+ y[i] = parseInt(obj.date[0]) + (i - 12);
+ }
+
+ // Assembling the year tables
+ var table = document.createElement("table");
+ table.setAttribute("width", "100%");
+
+ for (var i = 0; i < 25; i++) {
+ if (!(i % 5)) {
+ // Reset cells container
+ var row = document.createElement("tr");
+ row.setAttribute("align", "center");
+ table.appendChild(row);
+ }
+
+ // Create cell
+ var cell = document.createElement("td");
+ cell.classList.add("jcalendar-set-year");
+ cell.innerText = y[i];
+
+ if (selectedYear == y[i]) {
+ cell.classList.add("jcalendar-selected");
+ }
+
+ if (currentYear == y[i]) {
+ cell.style.fontWeight = "bold";
+ }
+
+ row.appendChild(cell);
+ }
+
+ calendarBody.innerHTML = ' |
';
+ calendarBody.firstChild.firstChild.appendChild(table);
+
+ // Update
+ updateActions();
+ };
+
+ obj.setLabel = function (value, mixed) {
+ return jSuites.calendar.getDateString(value, mixed);
+ };
+
+ obj.fromFormatted = function (value, format) {
+ return jSuites.calendar.extractDateFromString(value, format);
+ };
+
+ var mouseUpControls = function (e) {
+ var element = jSuites.findElement(e.target, "jcalendar-container");
+ if (element) {
+ var action = e.target.className;
+
+ // Object id
+ if (action == "jcalendar-prev") {
+ obj.prev();
+ } else if (action == "jcalendar-next") {
+ obj.next();
+ } else if (action == "jcalendar-month") {
+ obj.getMonths();
+ } else if (action == "jcalendar-year") {
+ obj.getYears();
+ } else if (action == "jcalendar-set-year") {
+ obj.date[0] = e.target.innerText;
+ if (obj.options.type == "year-month-picker") {
+ obj.getMonths();
+ } else {
+ obj.getDays();
+ }
+ } else if (e.target.classList.contains("jcalendar-set-month")) {
+ var month = parseInt(e.target.getAttribute("data-value"));
+ if (obj.options.type == "year-month-picker") {
+ obj.update(e.target, month);
+ } else {
+ obj.date[1] = month;
+ obj.getDays();
+ }
+ } else if (
+ action == "jcalendar-confirm" ||
+ action == "jcalendar-update" ||
+ action == "jcalendar-close"
+ ) {
+ obj.close();
+ } else if (action == "jcalendar-backdrop") {
+ obj.close(false, false);
+ } else if (action == "jcalendar-reset") {
+ obj.reset();
+ } else if (
+ e.target.classList.contains("jcalendar-set-day") &&
+ e.target.innerText
+ ) {
+ obj.update(e.target);
+ }
+ } else {
+ obj.close();
+ }
+ };
+
+ var keyUpControls = function (e) {
+ if (e.target.value && e.target.value.length > 3) {
+ var test = jSuites.calendar.extractDateFromString(
+ e.target.value,
+ obj.options.format
+ );
+ if (test) {
+ obj.setValue(test);
+ }
+ }
+ };
+
+ // Update actions button
+ var updateActions = function () {
+ var currentDay = calendar.querySelector(".jcalendar-selected");
+
+ if (currentDay && currentDay.classList.contains("jcalendar-disabled")) {
+ calendarControlsUpdateButton.setAttribute("disabled", "disabled");
+ calendarSelectHour.setAttribute("disabled", "disabled");
+ calendarSelectMin.setAttribute("disabled", "disabled");
+ } else {
+ calendarControlsUpdateButton.removeAttribute("disabled");
+ calendarSelectHour.removeAttribute("disabled");
+ calendarSelectMin.removeAttribute("disabled");
+ }
+
+ // Event
+ if (typeof obj.options.onupdate == "function") {
+ obj.options.onupdate(el, obj.getValue());
+ }
+ };
+
+ var calendar = null;
+ var calendarReset = null;
+ var calendarConfirm = null;
+ var calendarContainer = null;
+ var calendarContent = null;
+ var calendarLabelYear = null;
+ var calendarLabelMonth = null;
+ var calendarTable = null;
+ var calendarBody = null;
+
+ var calendarControls = null;
+ var calendarControlsTime = null;
+ var calendarControlsUpdate = null;
+ var calendarControlsUpdateButton = null;
+ var calendarSelectHour = null;
+ var calendarSelectMin = null;
+
+ var init = function () {
+ // Get value from initial element if that is an input
+ if (el.tagName == "INPUT" && el.value) {
+ options.value = el.value;
+ }
+
+ // Calendar DOM elements
+ calendarReset = document.createElement("div");
+ calendarReset.className = "jcalendar-reset";
+
+ calendarConfirm = document.createElement("div");
+ calendarConfirm.className = "jcalendar-confirm";
+
+ calendarControls = document.createElement("div");
+ calendarControls.className = "jcalendar-controls";
+ calendarControls.style.borderBottom = "1px solid #ddd";
+ calendarControls.appendChild(calendarReset);
+ calendarControls.appendChild(calendarConfirm);
+
+ calendarContainer = document.createElement("div");
+ calendarContainer.className = "jcalendar-container";
+
+ calendarContent = document.createElement("div");
+ calendarContent.className = "jcalendar-content";
+ calendarContainer.appendChild(calendarContent);
+
+ // Main element
+ if (el.tagName == "DIV") {
+ calendar = el;
+ calendar.classList.add("jcalendar-inline");
+ } else {
+ // Add controls to the screen
+ calendarContent.appendChild(calendarControls);
+
+ calendar = document.createElement("div");
+ calendar.className = "jcalendar";
+ }
+ calendar.classList.add("jcalendar-container");
+ calendar.appendChild(calendarContainer);
+
+ // Table container
+ var calendarTableContainer = document.createElement("div");
+ calendarTableContainer.className = "jcalendar-table";
+ calendarContent.appendChild(calendarTableContainer);
+
+ // Previous button
+ var calendarHeaderPrev = document.createElement("td");
+ calendarHeaderPrev.setAttribute("colspan", "2");
+ calendarHeaderPrev.className = "jcalendar-prev";
+
+ // Header with year and month
+ calendarLabelYear = document.createElement("span");
+ calendarLabelYear.className = "jcalendar-year";
+ calendarLabelMonth = document.createElement("span");
+ calendarLabelMonth.className = "jcalendar-month";
+
+ var calendarHeaderTitle = document.createElement("td");
+ calendarHeaderTitle.className = "jcalendar-header";
+ calendarHeaderTitle.setAttribute("colspan", "3");
+ calendarHeaderTitle.appendChild(calendarLabelMonth);
+ calendarHeaderTitle.appendChild(calendarLabelYear);
+
+ var calendarHeaderNext = document.createElement("td");
+ calendarHeaderNext.setAttribute("colspan", "2");
+ calendarHeaderNext.className = "jcalendar-next";
+
+ var calendarHeader = document.createElement("thead");
+ var calendarHeaderRow = document.createElement("tr");
+ calendarHeaderRow.appendChild(calendarHeaderPrev);
+ calendarHeaderRow.appendChild(calendarHeaderTitle);
+ calendarHeaderRow.appendChild(calendarHeaderNext);
+ calendarHeader.appendChild(calendarHeaderRow);
+
+ calendarTable = document.createElement("table");
+ calendarBody = document.createElement("tbody");
+ calendarTable.setAttribute("cellpadding", "0");
+ calendarTable.setAttribute("cellspacing", "0");
+ calendarTable.appendChild(calendarHeader);
+ calendarTable.appendChild(calendarBody);
+ calendarTableContainer.appendChild(calendarTable);
+
+ calendarSelectHour = document.createElement("select");
+ calendarSelectHour.className = "jcalendar-select";
+ calendarSelectHour.onchange = function () {
+ obj.date[3] = this.value;
+
+ // Event
+ if (typeof obj.options.onupdate == "function") {
+ obj.options.onupdate(el, obj.getValue());
+ }
+ };
+
+ for (var i = 0; i < 24; i++) {
+ var element = document.createElement("option");
+ element.value = i;
+ element.innerHTML = jSuites.two(i);
+ calendarSelectHour.appendChild(element);
+ }
+
+ calendarSelectMin = document.createElement("select");
+ calendarSelectMin.className = "jcalendar-select";
+ calendarSelectMin.onchange = function () {
+ obj.date[4] = this.value;
+
+ // Event
+ if (typeof obj.options.onupdate == "function") {
+ obj.options.onupdate(el, obj.getValue());
+ }
+ };
+
+ for (var i = 0; i < 60; i++) {
+ var element = document.createElement("option");
+ element.value = i;
+ element.innerHTML = jSuites.two(i);
+ calendarSelectMin.appendChild(element);
+ }
+
+ // Footer controls
+ var calendarControlsFooter = document.createElement("div");
+ calendarControlsFooter.className = "jcalendar-controls";
+
+ calendarControlsTime = document.createElement("div");
+ calendarControlsTime.className = "jcalendar-time";
+ calendarControlsTime.style.maxWidth = "140px";
+ calendarControlsTime.appendChild(calendarSelectHour);
+ calendarControlsTime.appendChild(calendarSelectMin);
+
+ calendarControlsUpdateButton = document.createElement("button");
+ calendarControlsUpdateButton.setAttribute("type", "button");
+ calendarControlsUpdateButton.className = "jcalendar-update";
+
+ calendarControlsUpdate = document.createElement("div");
+ calendarControlsUpdate.style.flexGrow = "10";
+ calendarControlsUpdate.appendChild(calendarControlsUpdateButton);
+ calendarControlsFooter.appendChild(calendarControlsTime);
+
+ // Only show the update button for input elements
+ if (el.tagName == "INPUT") {
+ calendarControlsFooter.appendChild(calendarControlsUpdate);
+ }
+
+ calendarContent.appendChild(calendarControlsFooter);
+
+ var calendarBackdrop = document.createElement("div");
+ calendarBackdrop.className = "jcalendar-backdrop";
+ calendar.appendChild(calendarBackdrop);
+
+ // Handle events
+ el.addEventListener("keyup", keyUpControls);
+
+ // Add global events
+ calendar.addEventListener("swipeleft", function (e) {
+ jSuites.animation.slideLeft(calendarTable, 0, function () {
+ obj.next();
+ jSuites.animation.slideRight(calendarTable, 1);
+ });
+ e.preventDefault();
+ e.stopPropagation();
+ });
+
+ calendar.addEventListener("swiperight", function (e) {
+ jSuites.animation.slideRight(calendarTable, 0, function () {
+ obj.prev();
+ jSuites.animation.slideLeft(calendarTable, 1);
+ });
+ e.preventDefault();
+ e.stopPropagation();
+ });
+
+ el.onmouseup = function () {
+ obj.open();
+ };
+
+ if ("ontouchend" in document.documentElement === true) {
+ calendar.addEventListener("touchend", mouseUpControls);
+ } else {
+ calendar.addEventListener("mouseup", mouseUpControls);
+ }
+
+ // Global controls
+ if (!jSuites.calendar.hasEvents) {
+ // Execute only one time
+ jSuites.calendar.hasEvents = true;
+ // Enter and Esc
+ document.addEventListener("keydown", jSuites.calendar.keydown);
+ }
+
+ // Set configuration
+ obj.setOptions(options);
+
+ // Append element to the DOM
+ if (el.tagName == "INPUT") {
+ el.parentNode.insertBefore(calendar, el.nextSibling);
+ // Add properties
+ el.setAttribute("autocomplete", "off");
+ // Element
+ el.classList.add("jcalendar-input");
+ // Value
+ el.value = obj.setLabel(obj.getValue(), obj.options);
+ } else {
+ // Get days
+ obj.getDays();
+ // Hour
+ if (obj.options.time) {
+ calendarSelectHour.value = obj.date[3];
+ calendarSelectMin.value = obj.date[4];
+ }
+ }
+
+ // Default opened
+ if (obj.options.opened == true) {
+ obj.open();
+ }
+
+ // Change method
+ el.change = obj.setValue;
+
+ // Global generic value handler
+ el.val = function (val) {
+ if (val === undefined) {
+ return obj.getValue();
+ } else {
+ obj.setValue(val);
+ }
+ };
+
+ // Keep object available from the node
+ el.calendar = calendar.calendar = obj;
+ };
+
+ init();
+
+ return obj;
+ };
+
+ jSuites.calendar.keydown = function (e) {
+ var calendar = null;
+ if ((calendar = jSuites.calendar.current)) {
+ if (e.which == 13) {
+ // ENTER
+ calendar.close(false, true);
+ } else if (e.which == 27) {
+ // ESC
+ calendar.close(false, false);
+ }
+ }
+ };
+
+ jSuites.calendar.prettify = function (d, texts) {
+ if (!texts) {
+ var texts = {
+ justNow: "Just now",
+ xMinutesAgo: "{0}m ago",
+ xHoursAgo: "{0}h ago",
+ xDaysAgo: "{0}d ago",
+ xWeeksAgo: "{0}w ago",
+ xMonthsAgo: "{0} mon ago",
+ xYearsAgo: "{0}y ago",
+ };
+ }
+
+ var d1 = new Date();
+ var d2 = new Date(d);
+ var total = parseInt((d1 - d2) / 1000 / 60);
+
+ String.prototype.format = function (o) {
+ return this.replace("{0}", o);
+ };
+
+ if (total == 0) {
+ var text = texts.justNow;
+ } else if (total < 90) {
+ var text = texts.xMinutesAgo.format(total);
+ } else if (total < 1440) {
+ // One day
+ var text = texts.xHoursAgo.format(Math.round(total / 60));
+ } else if (total < 20160) {
+ // 14 days
+ var text = texts.xDaysAgo.format(Math.round(total / 1440));
+ } else if (total < 43200) {
+ // 30 days
+ var text = texts.xWeeksAgo.format(Math.round(total / 10080));
+ } else if (total < 1036800) {
+ // 24 months
+ var text = texts.xMonthsAgo.format(Math.round(total / 43200));
+ } else {
+ // 24 months+
+ var text = texts.xYearsAgo.format(Math.round(total / 525600));
+ }
+
+ return text;
+ };
+
+ jSuites.calendar.prettifyAll = function () {
+ var elements = document.querySelectorAll(".prettydate");
+ for (var i = 0; i < elements.length; i++) {
+ if (elements[i].getAttribute("data-date")) {
+ elements[i].innerHTML = jSuites.calendar.prettify(
+ elements[i].getAttribute("data-date")
+ );
+ } else {
+ if (elements[i].innerHTML) {
+ elements[i].setAttribute("title", elements[i].innerHTML);
+ elements[i].setAttribute("data-date", elements[i].innerHTML);
+ elements[i].innerHTML = jSuites.calendar.prettify(
+ elements[i].innerHTML
+ );
+ }
+ }
+ }
+ };
+
+ jSuites.calendar.now = function (date, dateOnly) {
+ if (Array.isArray(date)) {
+ var y = date[0];
+ var m = date[1];
+ var d = date[2];
+ var h = date[3];
+ var i = date[4];
+ var s = date[5];
+ } else {
+ if (!date) {
+ var date = new Date();
+ }
+ var y = date.getFullYear();
+ var m = date.getMonth() + 1;
+ var d = date.getDate();
+ var h = date.getHours();
+ var i = date.getMinutes();
+ var s = date.getSeconds();
+ }
+
+ if (dateOnly == true) {
+ return jSuites.two(y) + "-" + jSuites.two(m) + "-" + jSuites.two(d);
+ } else {
+ return (
+ jSuites.two(y) +
+ "-" +
+ jSuites.two(m) +
+ "-" +
+ jSuites.two(d) +
+ " " +
+ jSuites.two(h) +
+ ":" +
+ jSuites.two(i) +
+ ":" +
+ jSuites.two(s)
+ );
+ }
+ };
+
+ jSuites.calendar.toArray = function (value) {
+ var date = value.split(value.indexOf("T") !== -1 ? "T" : " ");
+ var time = date[1];
+ var date = date[0].split("-");
+ var y = parseInt(date[0]);
+ var m = parseInt(date[1]);
+ var d = parseInt(date[2]);
+
+ if (time) {
+ var time = time.split(":");
+ var h = parseInt(time[0]);
+ var i = parseInt(time[1]);
+ } else {
+ var h = 0;
+ var i = 0;
+ }
+ return [y, m, d, h, i, 0];
+ };
+
+ // Helper to extract date from a string
+ jSuites.calendar.extractDateFromString = function (date, format) {
+ if (date > 0 && Number(date) == date) {
+ var d = new Date(Math.round((date - 25569) * 86400 * 1000));
+ return (
+ d.getFullYear() +
+ "-" +
+ jSuites.two(d.getMonth()) +
+ "-" +
+ jSuites.two(d.getDate()) +
+ " 00:00:00"
+ );
+ }
+
+ var o = jSuites.mask(date, { mask: format }, true);
+ if (o.date[0] && o.date[1]) {
+ if (!o.date[2]) {
+ o.date[2] = 1;
+ }
+
+ return (
+ o.date[0] +
+ "-" +
+ jSuites.two(o.date[1]) +
+ "-" +
+ jSuites.two(o.date[2]) +
+ " " +
+ jSuites.two(o.date[3]) +
+ ":" +
+ jSuites.two(o.date[4]) +
+ ":" +
+ jSuites.two(o.date[5])
+ );
+ }
+ return "";
+ };
+
+ var excelInitialTime = Date.UTC(1900, 0, 0);
+ var excelLeapYearBug = Date.UTC(1900, 1, 29);
+ var millisecondsPerDay = 86400000;
+
+ /**
+ * Date to number
+ */
+ jSuites.calendar.dateToNum = function (jsDate) {
+ if (typeof jsDate === "string") {
+ jsDate = new Date(jsDate + " GMT+0");
+ }
+ var jsDateInMilliseconds = jsDate.getTime();
+
+ if (jsDateInMilliseconds >= excelLeapYearBug) {
+ jsDateInMilliseconds += millisecondsPerDay;
+ }
+
+ jsDateInMilliseconds -= excelInitialTime;
+
+ return jsDateInMilliseconds / millisecondsPerDay;
+ };
+
+ /**
+ * Number to date
+ */
+ // !IMPORTANT!
+ // Excel incorrectly considers 1900 to be a leap year
+ jSuites.calendar.numToDate = function (excelSerialNumber) {
+ var jsDateInMilliseconds =
+ excelInitialTime + excelSerialNumber * millisecondsPerDay;
+
+ if (jsDateInMilliseconds >= excelLeapYearBug) {
+ jsDateInMilliseconds -= millisecondsPerDay;
+ }
+
+ const d = new Date(jsDateInMilliseconds);
+
+ var date = [
+ d.getUTCFullYear(),
+ d.getUTCMonth() + 1,
+ d.getUTCDate(),
+ d.getUTCHours(),
+ d.getUTCMinutes(),
+ d.getUTCSeconds(),
+ ];
+
+ return jSuites.calendar.now(date);
+ };
+
+ // Helper to convert date into string
+ jSuites.calendar.getDateString = function (value, options) {
+ if (!options) {
+ var options = {};
+ }
+
+ // Labels
+ if (options && typeof options == "object") {
+ var format = options.format;
+ } else {
+ var format = options;
+ }
+
+ if (!format) {
+ format = "YYYY-MM-DD";
+ }
+
+ // Convert to number of hours
+ if (typeof value == "number" && format.indexOf("[h]") >= 0) {
+ var result = parseFloat(24 * Number(value));
+ if (format.indexOf("mm") >= 0) {
+ var h = ("" + result).split(".");
+ if (h[1]) {
+ var d = 60 * parseFloat("0." + h[1]);
+ d = parseFloat(d.toFixed(2));
+ } else {
+ var d = 0;
+ }
+ result = parseInt(h[0]) + ":" + jSuites.two(d);
+ }
+ return result;
+ }
+
+ // Date instance
+ if (value instanceof Date) {
+ value = jSuites.calendar.now(value);
+ } else if (value && jSuites.isNumeric(value)) {
+ value = jSuites.calendar.numToDate(value);
+ }
+
+ // Tokens
+ var tokens = [
+ "DAY",
+ "WD",
+ "DDDD",
+ "DDD",
+ "DD",
+ "D",
+ "Q",
+ "HH24",
+ "HH12",
+ "HH",
+ "H",
+ "AM/PM",
+ "MI",
+ "SS",
+ "MS",
+ "YYYY",
+ "YYY",
+ "YY",
+ "Y",
+ "MONTH",
+ "MON",
+ "MMMMM",
+ "MMMM",
+ "MMM",
+ "MM",
+ "M",
+ ".",
+ ];
+
+ // Expression to extract all tokens from the string
+ var e = new RegExp(tokens.join("|"), "gi");
+ // Extract
+ var t = format.match(e);
+
+ // Compatibility with excel
+ for (var i = 0; i < t.length; i++) {
+ if (t[i].toUpperCase() == "MM") {
+ // Not a month, correct to minutes
+ if (t[i - 1] && t[i - 1].toUpperCase().indexOf("H") >= 0) {
+ t[i] = "mi";
+ } else if (t[i - 2] && t[i - 2].toUpperCase().indexOf("H") >= 0) {
+ t[i] = "mi";
+ } else if (t[i + 1] && t[i + 1].toUpperCase().indexOf("S") >= 0) {
+ t[i] = "mi";
+ } else if (t[i + 2] && t[i + 2].toUpperCase().indexOf("S") >= 0) {
+ t[i] = "mi";
+ }
+ }
+ }
+
+ // Object
+ var o = {
+ tokens: t,
+ };
+
+ // Value
+ if (value) {
+ var d = "" + value;
+ var splitStr = d.indexOf("T") !== -1 ? "T" : " ";
+ d = d.split(splitStr);
+
+ var h = 0;
+ var m = 0;
+ var s = 0;
+
+ if (d[1]) {
+ h = d[1].split(":");
+ m = h[1] ? h[1] : 0;
+ s = h[2] ? h[2] : 0;
+ h = h[0] ? h[0] : 0;
+ }
+
+ d = d[0].split("-");
+
+ if (
+ d[0] &&
+ d[1] &&
+ d[2] &&
+ d[0] > 0 &&
+ d[1] > 0 &&
+ d[1] < 13 &&
+ d[2] > 0 &&
+ d[2] < 32
+ ) {
+ // Data
+ o.data = [d[0], d[1], d[2], h, m, s];
+
+ // Value
+ o.value = [];
+
+ // Calendar instance
+ var calendar = new Date(
+ o.data[0],
+ o.data[1] - 1,
+ o.data[2],
+ o.data[3],
+ o.data[4],
+ o.data[5]
+ );
+
+ // Get method
+ var get = function (i) {
+ // Token
+ var t = this.tokens[i];
+ // Case token
+ var s = t.toUpperCase();
+ var v = null;
+
+ if (s === "YYYY") {
+ v = this.data[0];
+ } else if (s === "YYY") {
+ v = this.data[0].substring(1, 4);
+ } else if (s === "YY") {
+ v = this.data[0].substring(2, 4);
+ } else if (s === "Y") {
+ v = this.data[0].substring(3, 4);
+ } else if (t === "MON") {
+ v = jSuites.calendar.months[calendar.getMonth()]
+ .substr(0, 3)
+ .toUpperCase();
+ } else if (t === "mon") {
+ v = jSuites.calendar.months[calendar.getMonth()]
+ .substr(0, 3)
+ .toLowerCase();
+ } else if (t === "MONTH") {
+ v = jSuites.calendar.months[calendar.getMonth()].toUpperCase();
+ } else if (t === "month") {
+ v = jSuites.calendar.months[calendar.getMonth()].toLowerCase();
+ } else if (s === "MMMMM") {
+ v = jSuites.calendar.months[calendar.getMonth()].substr(0, 1);
+ } else if (s === "MMMM" || t === "Month") {
+ v = jSuites.calendar.months[calendar.getMonth()];
+ } else if (s === "MMM" || t == "Mon") {
+ v = jSuites.calendar.months[calendar.getMonth()].substr(0, 3);
+ } else if (s === "MM") {
+ v = jSuites.two(this.data[1]);
+ } else if (s === "M") {
+ v = calendar.getMonth() + 1;
+ } else if (t === "DAY") {
+ v = jSuites.calendar.weekdays[calendar.getDay()].toUpperCase();
+ } else if (t === "day") {
+ v = jSuites.calendar.weekdays[calendar.getDay()].toLowerCase();
+ } else if (s === "DDDD" || t == "Day") {
+ v = jSuites.calendar.weekdays[calendar.getDay()];
+ } else if (s === "DDD") {
+ v = jSuites.calendar.weekdays[calendar.getDay()].substr(0, 3);
+ } else if (s === "DD") {
+ v = jSuites.two(this.data[2]);
+ } else if (s === "D") {
+ v = this.data[2];
+ } else if (s === "Q") {
+ v = Math.floor((calendar.getMonth() + 3) / 3);
+ } else if (s === "HH24" || s === "HH") {
+ v = jSuites.two(this.data[3]);
+ } else if (s === "HH12") {
+ if (this.data[3] > 12) {
+ v = jSuites.two(this.data[3] - 12);
+ } else {
+ v = jSuites.two(this.data[3]);
+ }
+ } else if (s === "H") {
+ v = this.data[3];
+ } else if (s === "MI") {
+ v = jSuites.two(this.data[4]);
+ } else if (s === "SS") {
+ v = jSuites.two(this.data[5]);
+ } else if (s === "MS") {
+ v = calendar.getMilliseconds();
+ } else if (s === "AM/PM") {
+ if (this.data[3] >= 12) {
+ v = "PM";
+ } else {
+ v = "AM";
+ }
+ } else if (s === "WD") {
+ v = jSuites.calendar.weekdays[calendar.getDay()];
+ }
+
+ if (v === null) {
+ this.value[i] = this.tokens[i];
+ } else {
+ this.value[i] = v;
+ }
+ };
+
+ for (var i = 0; i < o.tokens.length; i++) {
+ get.call(o, i);
+ }
+ // Put pieces together
+ value = o.value.join("");
+ } else {
+ value = "";
+ }
+ }
+
+ return value;
+ };
+
+ // Jsuites calendar labels
+ jSuites.calendar.weekdays = [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+ ];
+ jSuites.calendar.months = [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December",
+ ];
+ jSuites.calendar.weekdaysShort = [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat",
+ ];
+ jSuites.calendar.monthsShort = [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec",
+ ];
+
+ jSuites.color = function (el, options) {
+ // Already created, update options
+ if (el.color) {
+ return el.color.setOptions(options, true);
+ }
+
+ // New instance
+ var obj = { type: "color" };
+ obj.options = {};
+
+ var container = null;
+ var backdrop = null;
+ var content = null;
+ var resetButton = null;
+ var closeButton = null;
+ var tabs = null;
+ var jsuitesTabs = null;
+
+ /**
+ * Update options
+ */
+ obj.setOptions = function (options, reset) {
+ /**
+ * @typedef {Object} defaults
+ * @property {(string|Array)} value - Initial value of the compontent
+ * @property {string} placeholder - The default instruction text on the element
+ * @property {requestCallback} onchange - Method to be execute after any changes on the element
+ * @property {requestCallback} onclose - Method to be execute when the element is closed
+ * @property {string} doneLabel - Label for button done
+ * @property {string} resetLabel - Label for button reset
+ * @property {string} resetValue - Value for button reset
+ * @property {Bool} showResetButton - Active or note for button reset - default false
+ */
+ var defaults = {
+ placeholder: "",
+ value: null,
+ onopen: null,
+ onclose: null,
+ onchange: null,
+ closeOnChange: true,
+ palette: null,
+ position: null,
+ doneLabel: "Done",
+ resetLabel: "Reset",
+ fullscreen: false,
+ opened: false,
+ };
+
+ if (!options) {
+ options = {};
+ }
+
+ if (options && !options.palette) {
+ // Default pallete
+ options.palette = jSuites.palette();
+ }
+
+ // Loop through our object
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ if (typeof obj.options[property] == "undefined" || reset === true) {
+ obj.options[property] = defaults[property];
+ }
+ }
+ }
+
+ // Update the text of the controls, if they have already been created
+ if (resetButton) {
+ resetButton.innerHTML = obj.options.resetLabel;
+ }
+ if (closeButton) {
+ closeButton.innerHTML = obj.options.doneLabel;
+ }
+
+ // Update the pallete
+ if (obj.options.palette && jsuitesTabs) {
+ jsuitesTabs.updateContent(0, table());
+ }
+
+ // Value
+ if (typeof obj.options.value === "string") {
+ el.value = obj.options.value;
+ if (el.tagName === "INPUT") {
+ el.style.color = el.value;
+ el.style.backgroundColor = el.value;
+ }
+ }
+
+ // Placeholder
+ if (obj.options.placeholder) {
+ el.setAttribute("placeholder", obj.options.placeholder);
+ } else {
+ if (el.getAttribute("placeholder")) {
+ el.removeAttribute("placeholder");
+ }
+ }
+
+ return obj;
+ };
+
+ obj.select = function (color) {
+ // Remove current selected mark
+ var selected = container.querySelector(".jcolor-selected");
+ if (selected) {
+ selected.classList.remove("jcolor-selected");
+ }
+
+ // Mark cell as selected
+ if (obj.values[color]) {
+ obj.values[color].classList.add("jcolor-selected");
+ }
+
+ obj.options.value = color;
+ };
+
+ /**
+ * Open color pallete
+ */
+ obj.open = function () {
+ if (!container.classList.contains("jcolor-focus")) {
+ // Start tracking
+ jSuites.tracking(obj, true);
+
+ // Show color picker
+ container.classList.add("jcolor-focus");
+
+ // Select current color
+ if (obj.options.value) {
+ obj.select(obj.options.value);
+ }
+
+ // Reset margin
+ content.style.marginTop = "";
+ content.style.marginLeft = "";
+
+ var rectContent = content.getBoundingClientRect();
+ var availableWidth = jSuites.getWindowWidth();
+ var availableHeight = jSuites.getWindowHeight();
+
+ if (availableWidth < 800 || obj.options.fullscreen == true) {
+ content.classList.add("jcolor-fullscreen");
+ jSuites.animation.slideBottom(content, 1);
+ backdrop.style.display = "block";
+ } else {
+ if (content.classList.contains("jcolor-fullscreen")) {
+ content.classList.remove("jcolor-fullscreen");
+ backdrop.style.display = "";
+ }
+
+ if (obj.options.position) {
+ content.style.position = "fixed";
+ } else {
+ content.style.position = "";
+ }
+
+ if (rectContent.left + rectContent.width > availableWidth) {
+ content.style.marginLeft =
+ -1 *
+ (rectContent.left + rectContent.width - (availableWidth - 20)) +
+ "px";
+ }
+ if (rectContent.top + rectContent.height > availableHeight) {
+ content.style.marginTop =
+ -1 *
+ (rectContent.top +
+ rectContent.height -
+ (availableHeight - 20)) +
+ "px";
+ }
+ }
+
+ if (typeof obj.options.onopen == "function") {
+ obj.options.onopen(el);
+ }
+
+ jsuitesTabs.setBorder(jsuitesTabs.getActive());
+
+ // Update sliders
+ if (obj.options.value) {
+ var rgb = HexToRgb(obj.options.value);
+
+ rgbInputs.forEach(function (rgbInput, index) {
+ rgbInput.value = rgb[index];
+ rgbInput.dispatchEvent(new Event("input"));
+ });
+ }
+ }
+ };
+
+ /**
+ * Close color pallete
+ */
+ obj.close = function (ignoreEvents) {
+ if (container.classList.contains("jcolor-focus")) {
+ // Remove focus
+ container.classList.remove("jcolor-focus");
+ // Make sure backdrop is hidden
+ backdrop.style.display = "";
+ // Call related events
+ if (!ignoreEvents && typeof obj.options.onclose == "function") {
+ obj.options.onclose(el);
+ }
+ // Stop the object
+ jSuites.tracking(obj, false);
+ }
+
+ return obj.options.value;
+ };
+
+ /**
+ * Set value
+ */
+ obj.setValue = function (color) {
+ if (!color) {
+ color = "";
+ }
+
+ if (color != obj.options.value) {
+ obj.options.value = color;
+ slidersResult = color;
+
+ // Remove current selecded mark
+ obj.select(color);
+
+ // Onchange
+ if (typeof obj.options.onchange == "function") {
+ obj.options.onchange(el, color);
+ }
+
+ // Changes
+ if (el.value != obj.options.value) {
+ // Set input value
+ el.value = obj.options.value;
+ if (el.tagName === "INPUT") {
+ el.style.color = el.value;
+ el.style.backgroundColor = el.value;
+ }
+
+ // Element onchange native
+ if (typeof el.oninput == "function") {
+ el.oninput({
+ type: "input",
+ target: el,
+ value: el.value,
+ });
+ }
+ }
+
+ if (obj.options.closeOnChange == true) {
+ obj.close();
+ }
+ }
+ };
+
+ /**
+ * Get value
+ */
+ obj.getValue = function () {
+ return obj.options.value;
+ };
+
+ var backdropClickControl = false;
+
+ // Converts a number in decimal to hexadecimal
+ var decToHex = function (num) {
+ var hex = num.toString(16);
+ return hex.length === 1 ? "0" + hex : hex;
+ };
+
+ // Converts a color in rgb to hexadecimal
+ var rgbToHex = function (r, g, b) {
+ return "#" + decToHex(r) + decToHex(g) + decToHex(b);
+ };
+
+ // Converts a number in hexadecimal to decimal
+ var hexToDec = function (hex) {
+ return parseInt("0x" + hex);
+ };
+
+ // Converts a color in hexadecimal to rgb
+ var HexToRgb = function (hex) {
+ return [
+ hexToDec(hex.substr(1, 2)),
+ hexToDec(hex.substr(3, 2)),
+ hexToDec(hex.substr(5, 2)),
+ ];
+ };
+
+ var table = function () {
+ // Content of the first tab
+ var tableContainer = document.createElement("div");
+ tableContainer.className = "jcolor-grid";
+
+ // Cells
+ obj.values = [];
+
+ // Table pallete
+ var t = document.createElement("table");
+ t.setAttribute("cellpadding", "7");
+ t.setAttribute("cellspacing", "0");
+
+ for (var j = 0; j < obj.options.palette.length; j++) {
+ var tr = document.createElement("tr");
+ for (var i = 0; i < obj.options.palette[j].length; i++) {
+ var td = document.createElement("td");
+ var color = obj.options.palette[j][i];
+ if (color.length < 7 && color.substr(0, 1) !== "#") {
+ color = "#" + color;
+ }
+ td.style.backgroundColor = color;
+ td.setAttribute("data-value", color);
+ td.innerHTML = "";
+ tr.appendChild(td);
+
+ // Selected color
+ if (obj.options.value == color) {
+ td.classList.add("jcolor-selected");
+ }
+
+ // Possible values
+ obj.values[color] = td;
+ }
+ t.appendChild(tr);
+ }
+
+ // Append to the table
+ tableContainer.appendChild(t);
+
+ return tableContainer;
+ };
+
+ // Canvas where the image will be rendered
+ var canvas = document.createElement("canvas");
+ canvas.width = 200;
+ canvas.height = 160;
+ var context = canvas.getContext("2d");
+
+ var resizeCanvas = function () {
+ // Specifications necessary to correctly obtain colors later in certain positions
+ var m = tabs.firstChild.getBoundingClientRect();
+ canvas.width = m.width - 14;
+ gradient();
+ };
+
+ var gradient = function () {
+ var g = context.createLinearGradient(0, 0, canvas.width, 0);
+ // Create color gradient
+ g.addColorStop(0, "rgb(255,0,0)");
+ g.addColorStop(0.15, "rgb(255,0,255)");
+ g.addColorStop(0.33, "rgb(0,0,255)");
+ g.addColorStop(0.49, "rgb(0,255,255)");
+ g.addColorStop(0.67, "rgb(0,255,0)");
+ g.addColorStop(0.84, "rgb(255,255,0)");
+ g.addColorStop(1, "rgb(255,0,0)");
+ context.fillStyle = g;
+ context.fillRect(0, 0, canvas.width, canvas.height);
+ g = context.createLinearGradient(0, 0, 0, canvas.height);
+ g.addColorStop(0, "rgba(255,255,255,1)");
+ g.addColorStop(0.5, "rgba(255,255,255,0)");
+ g.addColorStop(0.5, "rgba(0,0,0,0)");
+ g.addColorStop(1, "rgba(0,0,0,1)");
+ context.fillStyle = g;
+ context.fillRect(0, 0, canvas.width, canvas.height);
+ };
+
+ var hsl = function () {
+ var element = document.createElement("div");
+ element.className = "jcolor-hsl";
+
+ var point = document.createElement("div");
+ point.className = "jcolor-point";
+
+ var div = document.createElement("div");
+ div.appendChild(canvas);
+ div.appendChild(point);
+ element.appendChild(div);
+
+ // Moves the marquee point to the specified position
+ var update = function (buttons, x, y) {
+ if (buttons === 1) {
+ var rect = element.getBoundingClientRect();
+ var left = x - rect.left;
+ var top = y - rect.top;
+ if (left < 0) {
+ left = 0;
+ }
+ if (top < 0) {
+ top = 0;
+ }
+ if (left > rect.width) {
+ left = rect.width;
+ }
+ if (top > rect.height) {
+ top = rect.height;
+ }
+ point.style.left = left + "px";
+ point.style.top = top + "px";
+ var pixel = context.getImageData(left, top, 1, 1).data;
+ slidersResult = rgbToHex(pixel[0], pixel[1], pixel[2]);
+ }
+ };
+
+ // Applies the point's motion function to the div that contains it
+ element.addEventListener("mousedown", function (e) {
+ update(e.buttons, e.clientX, e.clientY);
+ });
+
+ element.addEventListener("mousemove", function (e) {
+ update(e.buttons, e.clientX, e.clientY);
+ });
+
+ element.addEventListener("touchmove", function (e) {
+ update(1, e.changedTouches[0].clientX, e.changedTouches[0].clientY);
+ });
+
+ return element;
+ };
+
+ var slidersResult = "";
+
+ var rgbInputs = [];
+
+ var changeInputColors = function () {
+ if (slidersResult !== "") {
+ for (var j = 0; j < rgbInputs.length; j++) {
+ var currentColor = HexToRgb(slidersResult);
+
+ currentColor[j] = 0;
+
+ var newGradient = "linear-gradient(90deg, rgb(";
+ newGradient += currentColor.join(", ");
+ newGradient += "), rgb(";
+
+ currentColor[j] = 255;
+
+ newGradient += currentColor.join(", ");
+ newGradient += "))";
+
+ rgbInputs[j].style.backgroundImage = newGradient;
+ }
+ }
+ };
+
+ var sliders = function () {
+ // Content of the third tab
+ var slidersElement = document.createElement("div");
+ slidersElement.className = "jcolor-sliders";
+
+ var slidersBody = document.createElement("div");
+
+ // Creates a range-type input with the specified name
+ var createSliderInput = function (name) {
+ var inputContainer = document.createElement("div");
+ inputContainer.className = "jcolor-sliders-input-container";
+
+ var label = document.createElement("label");
+ label.innerText = name;
+
+ var subContainer = document.createElement("div");
+ subContainer.className = "jcolor-sliders-input-subcontainer";
+
+ var input = document.createElement("input");
+ input.type = "range";
+ input.min = 0;
+ input.max = 255;
+ input.value = 0;
+
+ inputContainer.appendChild(label);
+ subContainer.appendChild(input);
+
+ var value = document.createElement("div");
+ value.innerText = input.value;
+
+ input.addEventListener("input", function () {
+ value.innerText = input.value;
+ });
+
+ subContainer.appendChild(value);
+ inputContainer.appendChild(subContainer);
+
+ slidersBody.appendChild(inputContainer);
+
+ return input;
+ };
+
+ // Creates red, green and blue inputs
+ rgbInputs = [
+ createSliderInput("Red"),
+ createSliderInput("Green"),
+ createSliderInput("Blue"),
+ ];
+
+ slidersElement.appendChild(slidersBody);
+
+ // Element that prints the current color
+ var slidersResultColor = document.createElement("div");
+ slidersResultColor.className = "jcolor-sliders-final-color";
+
+ var resultElement = document.createElement("div");
+ resultElement.style.visibility = "hidden";
+ resultElement.innerText = "a";
+ slidersResultColor.appendChild(resultElement);
+
+ // Update the element that prints the current color
+ var updateResult = function () {
+ var resultColor = rgbToHex(
+ parseInt(rgbInputs[0].value),
+ parseInt(rgbInputs[1].value),
+ parseInt(rgbInputs[2].value)
+ );
+
+ resultElement.innerText = resultColor;
+ resultElement.style.color = resultColor;
+ resultElement.style.removeProperty("visibility");
+
+ slidersResult = resultColor;
+ };
+
+ // Apply the update function to color inputs
+ rgbInputs.forEach(function (rgbInput) {
+ rgbInput.addEventListener("input", function () {
+ updateResult();
+ changeInputColors();
+ });
+ });
+
+ slidersElement.appendChild(slidersResultColor);
+
+ return slidersElement;
+ };
+
+ var init = function () {
+ // Initial options
+ obj.setOptions(options);
+
+ // Add a proper input tag when the element is an input
+ if (el.tagName == "INPUT") {
+ el.classList.add("jcolor-input");
+ el.readOnly = true;
+ }
+
+ // Table container
+ container = document.createElement("div");
+ container.className = "jcolor";
+
+ // Table container
+ backdrop = document.createElement("div");
+ backdrop.className = "jcolor-backdrop";
+ container.appendChild(backdrop);
+
+ // Content
+ content = document.createElement("div");
+ content.className = "jcolor-content";
+
+ // Controls
+ var controls = document.createElement("div");
+ controls.className = "jcolor-controls";
+ content.appendChild(controls);
+
+ // Reset button
+ resetButton = document.createElement("div");
+ resetButton.className = "jcolor-reset";
+ resetButton.innerHTML = obj.options.resetLabel;
+ controls.appendChild(resetButton);
+
+ // Close button
+ closeButton = document.createElement("div");
+ closeButton.className = "jcolor-close";
+ closeButton.innerHTML = obj.options.doneLabel;
+ controls.appendChild(closeButton);
+
+ // Element that will be used to create the tabs
+ tabs = document.createElement("div");
+ content.appendChild(tabs);
+
+ // Starts the jSuites tabs component
+ jsuitesTabs = jSuites.tabs(tabs, {
+ animation: true,
+ data: [
+ {
+ title: "Grid",
+ contentElement: table(),
+ },
+ {
+ title: "Spectrum",
+ contentElement: hsl(),
+ },
+ {
+ title: "Sliders",
+ contentElement: sliders(),
+ },
+ ],
+ onchange: function (element, instance, index) {
+ if (index === 1) {
+ resizeCanvas();
+ } else {
+ var color = slidersResult !== "" ? slidersResult : obj.getValue();
+
+ if (index === 2 && color) {
+ var rgb = HexToRgb(color);
+
+ rgbInputs.forEach(function (rgbInput, index) {
+ rgbInput.value = rgb[index];
+ rgbInput.dispatchEvent(new Event("input"));
+ });
+ }
+ }
+ },
+ palette: "modern",
+ });
+
+ container.appendChild(content);
+
+ // Insert picker after the element
+ if (el.tagName == "INPUT") {
+ el.parentNode.insertBefore(container, el.nextSibling);
+ } else {
+ el.appendChild(container);
+ }
+
+ container.addEventListener("click", function (e) {
+ if (e.target.tagName == "TD") {
+ var value = e.target.getAttribute("data-value");
+ if (value) {
+ obj.setValue(value);
+ }
+ } else if (e.target.classList.contains("jcolor-reset")) {
+ obj.setValue("");
+ obj.close();
+ } else if (e.target.classList.contains("jcolor-close")) {
+ if (jsuitesTabs.getActive() > 0) {
+ obj.setValue(slidersResult);
+ }
+ obj.close();
+ } else if (e.target.classList.contains("jcolor-backdrop")) {
+ obj.close();
+ } else {
+ obj.open();
+ }
+ });
+
+ /**
+ * If element is focus open the picker
+ */
+ el.addEventListener("mouseup", function (e) {
+ obj.open();
+ });
+
+ // If the picker is open on the spectrum tab, it changes the canvas size when the window size is changed
+ window.addEventListener("resize", function () {
+ if (
+ container.classList.contains("jcolor-focus") &&
+ jsuitesTabs.getActive() == 1
+ ) {
+ resizeCanvas();
+ }
+ });
+
+ // Default opened
+ if (obj.options.opened == true) {
+ obj.open();
+ }
+
+ // Change
+ el.change = obj.setValue;
+
+ // Global generic value handler
+ el.val = function (val) {
+ if (val === undefined) {
+ return obj.getValue();
+ } else {
+ obj.setValue(val);
+ }
+ };
+
+ // Keep object available from the node
+ el.color = obj;
+
+ // Container shortcut
+ container.color = obj;
+ };
+
+ obj.toHex = function (rgb) {
+ var hex = function (x) {
+ return ("0" + parseInt(x).toString(16)).slice(-2);
+ };
+ if (/^#[0-9A-F]{6}$/i.test(rgb)) {
+ return rgb;
+ } else {
+ rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
+ return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
+ }
+ };
+
+ init();
+
+ return obj;
+ };
+
+ jSuites.contextmenu = function (el, options) {
+ // New instance
+ var obj = { type: "contextmenu" };
+ obj.options = {};
+
+ // Default configuration
+ var defaults = {
+ items: null,
+ onclick: null,
+ };
+
+ // Loop through our object
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ obj.options[property] = defaults[property];
+ }
+ }
+
+ // Class definition
+ el.classList.add("jcontextmenu");
+
+ /**
+ * Open contextmenu
+ */
+ obj.open = function (e, items) {
+ if (items) {
+ // Update content
+ obj.options.items = items;
+ // Create items
+ obj.create(items);
+ }
+
+ // Close current contextmenu
+ if (jSuites.contextmenu.current) {
+ jSuites.contextmenu.current.close();
+ }
+
+ // Add to the opened components monitor
+ jSuites.tracking(obj, true);
+
+ // Show context menu
+ el.classList.add("jcontextmenu-focus");
+
+ // Current
+ jSuites.contextmenu.current = obj;
+
+ // Coordinates
+ if (
+ (obj.options.items && obj.options.items.length > 0) ||
+ el.children.length
+ ) {
+ if (e.target) {
+ if (e.changedTouches && e.changedTouches[0]) {
+ x = e.changedTouches[0].clientX;
+ y = e.changedTouches[0].clientY;
+ } else {
+ var x = e.clientX;
+ var y = e.clientY;
+ }
+ } else {
+ var x = e.x;
+ var y = e.y;
+ }
+
+ var rect = el.getBoundingClientRect();
+
+ if (window.innerHeight < y + rect.height) {
+ var h = y - rect.height;
+ if (h < 0) {
+ h = 0;
+ }
+ el.style.top = h + "px";
+ } else {
+ el.style.top = y + "px";
+ }
+
+ if (window.innerWidth < x + rect.width) {
+ if (x - rect.width > 0) {
+ el.style.left = x - rect.width + "px";
+ } else {
+ el.style.left = "10px";
+ }
+ } else {
+ el.style.left = x + "px";
+ }
+ }
+ };
+
+ obj.isOpened = function () {
+ return el.classList.contains("jcontextmenu-focus") ? true : false;
+ };
+
+ /**
+ * Close menu
+ */
+ obj.close = function () {
+ if (el.classList.contains("jcontextmenu-focus")) {
+ el.classList.remove("jcontextmenu-focus");
+ }
+ jSuites.tracking(obj, false);
+ };
+
+ /**
+ * Create items based on the declared objectd
+ * @param {object} items - List of object
+ */
+ obj.create = function (items) {
+ // Update content
+ el.innerHTML = "";
+
+ // Add header contextmenu
+ var itemHeader = createHeader();
+ el.appendChild(itemHeader);
+
+ // Append items
+ for (var i = 0; i < items.length; i++) {
+ var itemContainer = createItemElement(items[i]);
+ el.appendChild(itemContainer);
+ }
+ };
+
+ /**
+ * createHeader for context menu
+ * @private
+ * @returns {HTMLElement}
+ */
+ function createHeader() {
+ var header = document.createElement("div");
+ header.classList.add("header");
+ header.addEventListener("click", function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ });
+ var title = document.createElement("a");
+ title.classList.add("title");
+ title.innerHTML = jSuites.translate("Menu");
+
+ header.appendChild(title);
+
+ var closeButton = document.createElement("a");
+ closeButton.classList.add("close");
+ closeButton.innerHTML = jSuites.translate("close");
+ closeButton.addEventListener("click", function (e) {
+ obj.close();
+ });
+
+ header.appendChild(closeButton);
+
+ return header;
+ }
+
+ /**
+ * Private function for create a new Item element
+ * @param {type} item
+ * @returns {jsuitesL#15.jSuites.contextmenu.createItemElement.itemContainer}
+ */
+ function createItemElement(item) {
+ if (item.type && (item.type == "line" || item.type == "divisor")) {
+ var itemContainer = document.createElement("hr");
+ } else {
+ var itemContainer = document.createElement("div");
+ var itemText = document.createElement("a");
+ itemText.innerHTML = item.title;
+
+ if (item.tooltip) {
+ itemContainer.setAttribute("title", item.tooltip);
+ }
+
+ if (item.icon) {
+ itemContainer.setAttribute("data-icon", item.icon);
+ }
+
+ if (item.id) {
+ itemContainer.id = item.id;
+ }
+
+ if (item.disabled) {
+ itemContainer.className = "jcontextmenu-disabled";
+ } else if (item.onclick) {
+ itemContainer.method = item.onclick;
+ itemContainer.addEventListener("mousedown", function (e) {
+ e.preventDefault();
+ });
+ itemContainer.addEventListener("mouseup", function (e) {
+ // Execute method
+ this.method(this, e);
+ });
+ }
+ itemContainer.appendChild(itemText);
+
+ if (item.submenu) {
+ var itemIconSubmenu = document.createElement("span");
+ itemIconSubmenu.innerHTML = "►";
+ itemContainer.appendChild(itemIconSubmenu);
+ itemContainer.classList.add("jcontexthassubmenu");
+ var el_submenu = document.createElement("div");
+ // Class definition
+ el_submenu.classList.add("jcontextmenu");
+ // Focusable
+ el_submenu.setAttribute("tabindex", "900");
+
+ // Append items
+ var submenu = item.submenu;
+ for (var i = 0; i < submenu.length; i++) {
+ var itemContainerSubMenu = createItemElement(submenu[i]);
+ el_submenu.appendChild(itemContainerSubMenu);
+ }
+
+ itemContainer.appendChild(el_submenu);
+ } else if (item.shortcut) {
+ var itemShortCut = document.createElement("span");
+ itemShortCut.innerHTML = item.shortcut;
+ itemContainer.appendChild(itemShortCut);
+ }
+ }
+ return itemContainer;
+ }
+
+ if (typeof obj.options.onclick == "function") {
+ el.addEventListener("click", function (e) {
+ obj.options.onclick(obj, e);
+ });
+ }
+
+ // Create items
+ if (obj.options.items) {
+ obj.create(obj.options.items);
+ }
+
+ window.addEventListener("mousewheel", function () {
+ obj.close();
+ });
+
+ el.contextmenu = obj;
+
+ return obj;
+ };
+
+ jSuites.dropdown = function (el, options) {
+ // Already created, update options
+ if (el.dropdown) {
+ return el.dropdown.setOptions(options, true);
+ }
+
+ // New instance
+ var obj = { type: "dropdown" };
+ obj.options = {};
+
+ // Success
+ var success = function (data, val) {
+ // Set data
+ if (data && data.length) {
+ // Sort
+ if (obj.options.sortResults !== false) {
+ if (typeof obj.options.sortResults == "function") {
+ data.sort(obj.options.sortResults);
+ } else {
+ data.sort(sortData);
+ }
+ }
+
+ obj.setData(data);
+ }
+
+ // Onload method
+ if (typeof obj.options.onload == "function") {
+ obj.options.onload(el, obj, data, val);
+ }
+
+ // Set value
+ if (val) {
+ applyValue(val);
+ }
+
+ // Component value
+ if (val === undefined || val === null) {
+ obj.options.value = "";
+ }
+ el.value = obj.options.value;
+
+ // Open dropdown
+ if (obj.options.opened == true) {
+ obj.open();
+ }
+ };
+
+ // Default sort
+ var sortData = function (itemA, itemB) {
+ var testA, testB;
+ if (typeof itemA == "string") {
+ testA = itemA;
+ } else {
+ if (itemA.text) {
+ testA = itemA.text;
+ } else if (itemA.name) {
+ testA = itemA.name;
+ }
+ }
+
+ if (typeof itemB == "string") {
+ testB = itemB;
+ } else {
+ if (itemB.text) {
+ testB = itemB.text;
+ } else if (itemB.name) {
+ testB = itemB.name;
+ }
+ }
+
+ if (typeof testA == "string" || typeof testB == "string") {
+ if (typeof testA != "string") {
+ testA = "" + testA;
+ }
+ if (typeof testB != "string") {
+ testB = "" + testB;
+ }
+ return testA.localeCompare(testB);
+ } else {
+ return testA - testB;
+ }
+ };
+
+ /**
+ * Reset the options for the dropdown
+ */
+ var resetValue = function () {
+ // Reset value container
+ obj.value = {};
+ // Remove selected
+ for (var i = 0; i < obj.items.length; i++) {
+ if (obj.items[i].selected == true) {
+ if (obj.items[i].element) {
+ obj.items[i].element.classList.remove("jdropdown-selected");
+ }
+ obj.items[i].selected = null;
+ }
+ }
+ // Reset options
+ obj.options.value = "";
+ };
+
+ /**
+ * Apply values to the dropdown
+ */
+ var applyValue = function (values) {
+ // Reset the current values
+ resetValue();
+
+ // Read values
+ if (values !== null) {
+ if (!values) {
+ if (typeof obj.value[""] !== "undefined") {
+ obj.value[""] = "";
+ }
+ } else {
+ if (!Array.isArray(values)) {
+ values = ("" + values).split(";");
+ }
+ for (var i = 0; i < values.length; i++) {
+ obj.value[values[i]] = "";
+ }
+ }
+ }
+
+ // Update the DOM
+ for (var i = 0; i < obj.items.length; i++) {
+ if (typeof obj.value[Value(i)] !== "undefined") {
+ if (obj.items[i].element) {
+ obj.items[i].element.classList.add("jdropdown-selected");
+ }
+ obj.items[i].selected = true;
+
+ // Keep label
+ obj.value[Value(i)] = Text(i);
+ }
+ }
+
+ // Global value
+ obj.options.value = Object.keys(obj.value).join(";");
+
+ // Update labels
+ obj.header.value = obj.getText();
+ };
+
+ // Get the value of one item
+ var Value = function (k, v) {
+ // Legacy purposes
+ if (!obj.options.format) {
+ var property = "value";
+ } else {
+ var property = "id";
+ }
+
+ if (obj.items[k]) {
+ if (v !== undefined) {
+ return (obj.items[k].data[property] = v);
+ } else {
+ return obj.items[k].data[property];
+ }
+ }
+
+ return "";
+ };
+
+ // Get the label of one item
+ var Text = function (k, v) {
+ // Legacy purposes
+ if (!obj.options.format) {
+ var property = "text";
+ } else {
+ var property = "name";
+ }
+
+ if (obj.items[k]) {
+ if (v !== undefined) {
+ return (obj.items[k].data[property] = v);
+ } else {
+ return obj.items[k].data[property];
+ }
+ }
+
+ return "";
+ };
+
+ var getValue = function () {
+ return Object.keys(obj.value);
+ };
+
+ var getText = function () {
+ var data = [];
+ var k = Object.keys(obj.value);
+ for (var i = 0; i < k.length; i++) {
+ data.push(obj.value[k[i]]);
+ }
+ return data;
+ };
+
+ obj.setOptions = function (options, reset) {
+ if (!options) {
+ options = {};
+ }
+
+ // Default configuration
+ var defaults = {
+ url: null,
+ data: [],
+ format: 0,
+ multiple: false,
+ autocomplete: false,
+ remoteSearch: false,
+ lazyLoading: false,
+ type: null,
+ width: null,
+ maxWidth: null,
+ opened: false,
+ value: null,
+ placeholder: "",
+ newOptions: false,
+ position: false,
+ onchange: null,
+ onload: null,
+ onopen: null,
+ onclose: null,
+ onfocus: null,
+ onblur: null,
+ oninsert: null,
+ onbeforeinsert: null,
+ sortResults: false,
+ autofocus: false,
+ };
+
+ // Loop through our object
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ if (typeof obj.options[property] == "undefined" || reset === true) {
+ obj.options[property] = defaults[property];
+ }
+ }
+ }
+
+ // Force autocomplete search
+ if (
+ obj.options.remoteSearch == true ||
+ obj.options.type === "searchbar"
+ ) {
+ obj.options.autocomplete = true;
+ }
+
+ // New options
+ if (obj.options.newOptions == true) {
+ obj.header.classList.add("jdropdown-add");
+ } else {
+ obj.header.classList.remove("jdropdown-add");
+ }
+
+ // Autocomplete
+ if (obj.options.autocomplete == true) {
+ obj.header.removeAttribute("readonly");
+ } else {
+ obj.header.setAttribute("readonly", "readonly");
+ }
+
+ // Place holder
+ if (obj.options.placeholder) {
+ obj.header.setAttribute("placeholder", obj.options.placeholder);
+ } else {
+ obj.header.removeAttribute("placeholder");
+ }
+
+ // Remove specific dropdown typing to add again
+ el.classList.remove("jdropdown-searchbar");
+ el.classList.remove("jdropdown-picker");
+ el.classList.remove("jdropdown-list");
+
+ if (obj.options.type == "searchbar") {
+ el.classList.add("jdropdown-searchbar");
+ } else if (obj.options.type == "list") {
+ el.classList.add("jdropdown-list");
+ } else if (obj.options.type == "picker") {
+ el.classList.add("jdropdown-picker");
+ } else {
+ if (jSuites.getWindowWidth() < 800) {
+ if (obj.options.autocomplete) {
+ el.classList.add("jdropdown-searchbar");
+ obj.options.type = "searchbar";
+ } else {
+ el.classList.add("jdropdown-picker");
+ obj.options.type = "picker";
+ }
+ } else {
+ if (obj.options.width) {
+ el.style.width = obj.options.width;
+ el.style.minWidth = obj.options.width;
+ } else {
+ el.style.removeProperty("width");
+ el.style.removeProperty("min-width");
+ }
+
+ el.classList.add("jdropdown-default");
+ obj.options.type = "default";
+ }
+ }
+
+ // Close button
+ if (obj.options.type == "searchbar") {
+ containerHeader.appendChild(closeButton);
+ } else {
+ container.insertBefore(closeButton, container.firstChild);
+ }
+
+ // Load the content
+ if (obj.options.url && !options.data) {
+ jSuites.ajax({
+ url: obj.options.url,
+ method: "GET",
+ dataType: "json",
+ success: function (data) {
+ if (data) {
+ success(data, obj.options.value);
+ }
+ },
+ });
+ } else {
+ success(obj.options.data, obj.options.value);
+ }
+
+ // Return the instance
+ return obj;
+ };
+
+ // Helpers
+ var containerHeader = null;
+ var container = null;
+ var content = null;
+ var closeButton = null;
+ var resetButton = null;
+ var backdrop = null;
+
+ var keyTimer = null;
+
+ /**
+ * Init dropdown
+ */
+ var init = function () {
+ // Do not accept null
+ if (!options) {
+ options = {};
+ }
+
+ // If the element is a SELECT tag, create a configuration object
+ if (el.tagName == "SELECT") {
+ var ret = jSuites.dropdown.extractFromDom(el, options);
+ el = ret.el;
+ options = ret.options;
+ }
+
+ // Place holder
+ if (!options.placeholder && el.getAttribute("placeholder")) {
+ options.placeholder = el.getAttribute("placeholder");
+ }
+
+ // Value container
+ obj.value = {};
+ // Containers
+ obj.items = [];
+ obj.groups = [];
+ // Search options
+ obj.search = "";
+ obj.results = null;
+
+ // Create dropdown
+ el.classList.add("jdropdown");
+
+ // Header container
+ containerHeader = document.createElement("div");
+ containerHeader.className = "jdropdown-container-header";
+
+ // Header
+ obj.header = document.createElement("input");
+ obj.header.className = "jdropdown-header";
+ obj.header.type = "text";
+ obj.header.setAttribute("autocomplete", "off");
+ obj.header.onfocus = function () {
+ if (typeof obj.options.onfocus == "function") {
+ obj.options.onfocus(el);
+ }
+ };
+
+ obj.header.onblur = function () {
+ if (typeof obj.options.onblur == "function") {
+ obj.options.onblur(el);
+ }
+ };
+
+ obj.header.onkeyup = function (e) {
+ if (obj.options.autocomplete == true && !keyTimer) {
+ if (obj.search != obj.header.value.trim()) {
+ keyTimer = setTimeout(function () {
+ obj.find(obj.header.value.trim());
+ keyTimer = null;
+ }, 400);
+ }
+
+ if (!el.classList.contains("jdropdown-focus")) {
+ obj.open();
+ }
+ } else {
+ if (!obj.options.autocomplete) {
+ obj.next(e.key);
+ }
+ }
+ };
+
+ // Global controls
+ if (!jSuites.dropdown.hasEvents) {
+ // Execute only one time
+ jSuites.dropdown.hasEvents = true;
+ // Enter and Esc
+ document.addEventListener("keydown", jSuites.dropdown.keydown);
+ }
+
+ // Container
+ container = document.createElement("div");
+ container.className = "jdropdown-container";
+
+ // Dropdown content
+ content = document.createElement("div");
+ content.className = "jdropdown-content";
+
+ // Close button
+ closeButton = document.createElement("div");
+ closeButton.className = "jdropdown-close";
+ closeButton.innerHTML = "Done";
+
+ // Reset button
+ resetButton = document.createElement("div");
+ resetButton.className = "jdropdown-reset";
+ resetButton.innerHTML = "x";
+ resetButton.onclick = function () {
+ obj.reset();
+ obj.close();
+ };
+
+ // Create backdrop
+ backdrop = document.createElement("div");
+ backdrop.className = "jdropdown-backdrop";
+
+ // Append elements
+ containerHeader.appendChild(obj.header);
+
+ container.appendChild(content);
+ el.appendChild(containerHeader);
+ el.appendChild(container);
+ el.appendChild(backdrop);
+
+ // Set the otiptions
+ obj.setOptions(options);
+
+ if ("ontouchsend" in document.documentElement === true) {
+ el.addEventListener("touchsend", jSuites.dropdown.mouseup);
+ } else {
+ el.addEventListener("mouseup", jSuites.dropdown.mouseup);
+ }
+
+ // Lazyloading
+ if (obj.options.lazyLoading == true) {
+ jSuites.lazyLoading(content, {
+ loadUp: obj.loadUp,
+ loadDown: obj.loadDown,
+ });
+ }
+
+ content.onwheel = function (e) {
+ e.stopPropagation();
+ };
+
+ // Change method
+ el.change = obj.setValue;
+
+ // Global generic value handler
+ el.val = function (val) {
+ if (val === undefined) {
+ return obj.getValue(obj.options.multiple ? true : false);
+ } else {
+ obj.setValue(val);
+ }
+ };
+
+ // Keep object available from the node
+ el.dropdown = obj;
+ };
+
+ /**
+ * Get the current remote source of data URL
+ */
+ obj.getUrl = function () {
+ return obj.options.url;
+ };
+
+ /**
+ * Set the new data from a remote source
+ * @param {string} url - url from the remote source
+ * @param {function} callback - callback when the data is loaded
+ */
+ obj.setUrl = function (url, callback) {
+ obj.options.url = url;
+
+ jSuites.ajax({
+ url: obj.options.url,
+ method: "GET",
+ dataType: "json",
+ success: function (data) {
+ obj.setData(data);
+ // Callback
+ if (typeof callback == "function") {
+ callback(obj);
+ }
+ },
+ });
+ };
+
+ /**
+ * Set ID for one item
+ */
+ obj.setId = function (item, v) {
+ // Legacy purposes
+ if (!obj.options.format) {
+ var property = "value";
+ } else {
+ var property = "id";
+ }
+
+ if (typeof item == "object") {
+ item[property] = v;
+ } else {
+ obj.items[item].data[property] = v;
+ }
+ };
+
+ /**
+ * Add a new item
+ * @param {string} title - title of the new item
+ * @param {string} id - value/id of the new item
+ */
+ obj.add = function (title, id) {
+ if (!title) {
+ var current = obj.options.autocomplete == true ? obj.header.value : "";
+ var title = prompt(jSuites.translate("Add A New Option"), current);
+ if (!title) {
+ return false;
+ }
+ }
+
+ // Id
+ if (!id) {
+ id = jSuites.guid();
+ }
+
+ // Create new item
+ if (!obj.options.format) {
+ var item = {
+ value: id,
+ text: title,
+ };
+ } else {
+ var item = {
+ id: id,
+ name: title,
+ };
+ }
+
+ // Callback
+ if (typeof obj.options.onbeforeinsert == "function") {
+ var ret = obj.options.onbeforeinsert(obj, item);
+ if (ret === false) {
+ return false;
+ } else if (ret) {
+ item = ret;
+ }
+ }
+
+ // Add item to the main list
+ obj.options.data.push(item);
+
+ // Create DOM
+ var newItem = obj.createItem(item);
+
+ // Append DOM to the list
+ content.appendChild(newItem.element);
+
+ // Callback
+ if (typeof obj.options.oninsert == "function") {
+ obj.options.oninsert(obj, item, newItem);
+ }
+
+ // Show content
+ if (content.style.display == "none") {
+ content.style.display = "";
+ }
+
+ // Search?
+ if (obj.results) {
+ obj.results.push(newItem);
+ }
+
+ return item;
+ };
+
+ /**
+ * Create a new item
+ */
+ obj.createItem = function (data, group, groupName) {
+ // Keep the correct source of data
+ if (!obj.options.format) {
+ if (!data.value && data.id !== undefined) {
+ data.value = data.id;
+ //delete data.id;
+ }
+ if (!data.text && data.name !== undefined) {
+ data.text = data.name;
+ //delete data.name;
+ }
+ } else {
+ if (!data.id && data.value !== undefined) {
+ data.id = data.value;
+ //delete data.value;
+ }
+ if (!data.name && data.text !== undefined) {
+ data.name = data.text;
+ //delete data.text;
+ }
+ }
+
+ // Create item
+ var item = {};
+ item.element = document.createElement("div");
+ item.element.className = "jdropdown-item";
+ item.element.indexValue = obj.items.length;
+ item.data = data;
+
+ // Groupd DOM
+ if (group) {
+ item.group = group;
+ }
+
+ // Id
+ if (data.id) {
+ item.element.setAttribute("id", data.id);
+ }
+
+ // Disabled
+ if (data.disabled == true) {
+ item.element.setAttribute("data-disabled", true);
+ }
+
+ // Tooltip
+ if (data.tooltip) {
+ item.element.setAttribute("title", data.tooltip);
+ }
+
+ // Image
+ if (data.image) {
+ var image = document.createElement("img");
+ image.className = "jdropdown-image";
+ image.src = data.image;
+ if (!data.title) {
+ image.classList.add("jdropdown-image-small");
+ }
+ item.element.appendChild(image);
+ } else if (data.icon) {
+ var icon = document.createElement("span");
+ icon.className = "jdropdown-icon material-icons";
+ icon.innerText = data.icon;
+ if (!data.title) {
+ icon.classList.add("jdropdown-icon-small");
+ }
+ if (data.color) {
+ icon.style.color = data.color;
+ }
+ item.element.appendChild(icon);
+ } else if (data.color) {
+ var color = document.createElement("div");
+ color.className = "jdropdown-color";
+ color.style.backgroundColor = data.color;
+ item.element.appendChild(color);
+ }
+
+ // Set content
+ if (!obj.options.format) {
+ var text = data.text;
+ } else {
+ var text = data.name;
+ }
+
+ var node = document.createElement("div");
+ node.className = "jdropdown-description";
+ node.innerHTML = text || " ";
+
+ // Title
+ if (data.title) {
+ var title = document.createElement("div");
+ title.className = "jdropdown-title";
+ title.innerText = data.title;
+ node.appendChild(title);
+ }
+
+ // Set content
+ if (!obj.options.format) {
+ var val = data.value;
+ } else {
+ var val = data.id;
+ }
+
+ // Value
+ if (obj.value[val]) {
+ item.element.classList.add("jdropdown-selected");
+ item.selected = true;
+ }
+
+ // Keep DOM accessible
+ obj.items.push(item);
+
+ // Add node to item
+ item.element.appendChild(node);
+
+ return item;
+ };
+
+ obj.appendData = function (data) {
+ // Create elements
+ if (data.length) {
+ // Helpers
+ var items = [];
+ var groups = [];
+
+ // Prepare data
+ for (var i = 0; i < data.length; i++) {
+ // Process groups
+ if (data[i].group) {
+ if (!groups[data[i].group]) {
+ groups[data[i].group] = [];
+ }
+ groups[data[i].group].push(i);
+ } else {
+ items.push(i);
+ }
+ }
+
+ // Number of items counter
+ var counter = 0;
+
+ // Groups
+ var groupNames = Object.keys(groups);
+
+ // Append groups in case exists
+ if (groupNames.length > 0) {
+ for (var i = 0; i < groupNames.length; i++) {
+ // Group container
+ var group = document.createElement("div");
+ group.className = "jdropdown-group";
+ // Group name
+ var groupName = document.createElement("div");
+ groupName.className = "jdropdown-group-name";
+ groupName.innerHTML = groupNames[i];
+ // Group arrow
+ var groupArrow = document.createElement("i");
+ groupArrow.className =
+ "jdropdown-group-arrow jdropdown-group-arrow-down";
+ groupName.appendChild(groupArrow);
+ // Group items
+ var groupContent = document.createElement("div");
+ groupContent.className = "jdropdown-group-items";
+ for (var j = 0; j < groups[groupNames[i]].length; j++) {
+ var item = obj.createItem(
+ data[groups[groupNames[i]][j]],
+ group,
+ groupNames[i]
+ );
+
+ if (obj.options.lazyLoading == false || counter < 200) {
+ groupContent.appendChild(item.element);
+ counter++;
+ }
+ }
+ // Group itens
+ group.appendChild(groupName);
+ group.appendChild(groupContent);
+ // Keep group DOM
+ obj.groups.push(group);
+ // Only add to the screen if children on the group
+ if (groupContent.children.length > 0) {
+ // Add DOM to the content
+ content.appendChild(group);
+ }
+ }
+ }
+
+ if (items.length) {
+ for (var i = 0; i < items.length; i++) {
+ var item = obj.createItem(data[items[i]]);
+ if (obj.options.lazyLoading == false || counter < 200) {
+ content.appendChild(item.element);
+ counter++;
+ }
+ }
+ }
+ }
+ };
+
+ obj.setData = function (data) {
+ // Reset current value
+ resetValue();
+
+ // Make sure the content container is blank
+ content.innerHTML = "";
+
+ // Reset
+ obj.header.value = "";
+
+ // Reset items and values
+ obj.items = [];
+
+ // Prepare data
+ if (data && data.length) {
+ for (var i = 0; i < data.length; i++) {
+ // Compatibility
+ if (typeof data[i] != "object") {
+ // Correct format
+ if (!obj.options.format) {
+ data[i] = {
+ value: data[i],
+ text: data[i],
+ };
+ } else {
+ data[i] = {
+ id: data[i],
+ name: data[i],
+ };
+ }
+ }
+ }
+
+ // Append data
+ obj.appendData(data);
+
+ // Update data
+ obj.options.data = data;
+ } else {
+ // Update data
+ obj.options.data = [];
+ }
+
+ obj.close();
+ };
+
+ obj.getData = function () {
+ return obj.options.data;
+ };
+
+ /**
+ * Get position of the item
+ */
+ obj.getPosition = function (val) {
+ for (var i = 0; i < obj.items.length; i++) {
+ if (Value(i) == val) {
+ return i;
+ }
+ }
+ return false;
+ };
+
+ /**
+ * Get dropdown current text
+ */
+ obj.getText = function (asArray) {
+ // Get value
+ var v = getText();
+ // Return value
+ if (asArray) {
+ return v;
+ } else {
+ return v.join("; ");
+ }
+ };
+
+ /**
+ * Get dropdown current value
+ */
+ obj.getValue = function (asArray) {
+ // Get value
+ var v = getValue();
+ // Return value
+ if (asArray) {
+ return v;
+ } else {
+ return v.join(";");
+ }
+ };
+
+ /**
+ * Change event
+ */
+ var change = function (oldValue) {
+ // Lemonade JS
+ if (el.value != obj.options.value) {
+ el.value = obj.options.value;
+ if (typeof el.oninput == "function") {
+ el.oninput({
+ type: "input",
+ target: el,
+ value: el.value,
+ });
+ }
+ }
+
+ // Events
+ if (typeof obj.options.onchange == "function") {
+ obj.options.onchange(el, obj, oldValue, obj.options.value);
+ }
+ };
+
+ /**
+ * Set value
+ */
+ obj.setValue = function (newValue) {
+ // Current value
+ var oldValue = obj.getValue();
+ // New value
+ if (Array.isArray(newValue)) {
+ newValue = newValue.join(";");
+ }
+
+ if (oldValue !== newValue) {
+ // Set value
+ applyValue(newValue);
+
+ // Change
+ change(oldValue);
+ }
+ };
+
+ obj.resetSelected = function () {
+ obj.setValue(null);
+ };
+
+ obj.selectIndex = function (index, force) {
+ // Make sure is a number
+ var index = parseInt(index);
+
+ // Only select those existing elements
+ if (
+ obj.items &&
+ obj.items[index] &&
+ (force === true || obj.items[index].data.disabled !== true)
+ ) {
+ // Reset cursor to a new position
+ obj.setCursor(index, false);
+
+ // Behaviour
+ if (!obj.options.multiple) {
+ // Update value
+ if (obj.items[index].selected) {
+ obj.setValue(null);
+ } else {
+ obj.setValue(Value(index));
+ }
+
+ // Close component
+ obj.close();
+ } else {
+ // Old value
+ var oldValue = obj.options.value;
+
+ // Toggle option
+ if (obj.items[index].selected) {
+ obj.items[index].element.classList.remove("jdropdown-selected");
+ obj.items[index].selected = false;
+
+ delete obj.value[Value(index)];
+ } else {
+ // Select element
+ obj.items[index].element.classList.add("jdropdown-selected");
+ obj.items[index].selected = true;
+
+ // Set value
+ obj.value[Value(index)] = Text(index);
+ }
+
+ // Global value
+ obj.options.value = Object.keys(obj.value).join(";");
+
+ // Update labels for multiple dropdown
+ if (obj.options.autocomplete == false) {
+ obj.header.value = getText().join("; ");
+ }
+
+ // Events
+ change(oldValue);
+ }
+ }
+ };
+
+ obj.selectItem = function (item) {
+ obj.selectIndex(item.indexValue);
+ };
+
+ var exists = function (k, result) {
+ for (var j = 0; j < result.length; j++) {
+ if (!obj.options.format) {
+ if (result[j].value == k) {
+ return true;
+ }
+ } else {
+ if (result[j].id == k) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ obj.find = function (str) {
+ if (obj.search == str.trim()) {
+ return false;
+ }
+
+ // Search term
+ obj.search = str;
+
+ // Reset index
+ obj.setCursor();
+
+ // Remove nodes from all groups
+ if (obj.groups.length) {
+ for (var i = 0; i < obj.groups.length; i++) {
+ obj.groups[i].lastChild.innerHTML = "";
+ }
+ }
+
+ // Remove all nodes
+ content.innerHTML = "";
+
+ // Remove current items in the remote search
+ if (obj.options.remoteSearch == true) {
+ // Reset results
+ obj.results = null;
+ // URL
+ var url =
+ obj.options.url +
+ (obj.options.url.indexOf("?") > 0 ? "&" : "?") +
+ "q=" +
+ str;
+ // Remote search
+ jSuites.ajax({
+ url: url,
+ method: "GET",
+ dataType: "json",
+ success: function (result) {
+ // Reset items
+ obj.items = [];
+
+ // Add the current selected items to the results in case they are not there
+ var current = Object.keys(obj.value);
+ if (current.length) {
+ for (var i = 0; i < current.length; i++) {
+ if (!exists(current[i], result)) {
+ if (!obj.options.format) {
+ result.unshift({
+ value: current[i],
+ text: obj.value[current[i]],
+ });
+ } else {
+ result.unshift({
+ id: current[i],
+ name: obj.value[current[i]],
+ });
+ }
+ }
+ }
+ }
+ // Append data
+ obj.appendData(result);
+ // Show or hide results
+ if (!result.length) {
+ content.style.display = "none";
+ } else {
+ content.style.display = "";
+ }
+ },
+ });
+ } else {
+ // Search terms
+ str = new RegExp(str, "gi");
+
+ // Reset search
+ var results = [];
+
+ // Append options
+ for (var i = 0; i < obj.items.length; i++) {
+ // Item label
+ var label = Text(i);
+ // Item title
+ var title = obj.items[i].data.title || "";
+ // Group name
+ var groupName = obj.items[i].data.group || "";
+ // Synonym
+ var synonym = obj.items[i].data.synonym || "";
+ if (synonym) {
+ synonym = synonym.join(" ");
+ }
+
+ if (
+ str == null ||
+ obj.items[i].selected == true ||
+ label.match(str) ||
+ title.match(str) ||
+ groupName.match(str) ||
+ synonym.match(str)
+ ) {
+ results.push(obj.items[i]);
+ }
+ }
+
+ if (!results.length) {
+ content.style.display = "none";
+
+ // Results
+ obj.results = null;
+ } else {
+ content.style.display = "";
+
+ // Results
+ obj.results = results;
+
+ // Show 200 items at once
+ var number = results.length || 0;
+
+ // Lazyloading
+ if (obj.options.lazyLoading == true && number > 200) {
+ number = 200;
+ }
+
+ for (var i = 0; i < number; i++) {
+ if (obj.results[i].group) {
+ if (!obj.results[i].group.parentNode) {
+ content.appendChild(obj.results[i].group);
+ }
+ obj.results[i].group.lastChild.appendChild(
+ obj.results[i].element
+ );
+ } else {
+ content.appendChild(obj.results[i].element);
+ }
+ }
+ }
+ }
+
+ // Auto focus
+ if (obj.options.autofocus == true) {
+ obj.first();
+ }
+ };
+
+ obj.open = function () {
+ // Focus
+ if (!el.classList.contains("jdropdown-focus")) {
+ // Current dropdown
+ jSuites.dropdown.current = obj;
+
+ // Start tracking
+ jSuites.tracking(obj, true);
+
+ // Add focus
+ el.classList.add("jdropdown-focus");
+
+ // Animation
+ if (jSuites.getWindowWidth() < 800) {
+ if (obj.options.type == null || obj.options.type == "picker") {
+ jSuites.animation.slideBottom(container, 1);
+ }
+ }
+
+ // Filter
+ if (obj.options.autocomplete == true) {
+ obj.header.value = obj.search;
+ obj.header.focus();
+ }
+
+ // Set cursor for the first or first selected element
+ var k = getValue();
+ if (k[0]) {
+ var cursor = obj.getPosition(k[0]);
+ if (cursor !== false) {
+ obj.setCursor(cursor);
+ }
+ }
+
+ // Container Size
+ if (!obj.options.type || obj.options.type == "default") {
+ var rect = el.getBoundingClientRect();
+ var rectContainer = container.getBoundingClientRect();
+
+ if (obj.options.position) {
+ container.style.position = "fixed";
+ if (window.innerHeight < rect.bottom + rectContainer.height) {
+ container.style.top = "";
+ container.style.bottom = window.innerHeight - rect.top + 1 + "px";
+ } else {
+ container.style.top = rect.bottom + "px";
+ container.style.bottom = "";
+ }
+ container.style.left = rect.left + "px";
+ } else {
+ if (window.innerHeight < rect.bottom + rectContainer.height) {
+ container.style.top = "";
+ container.style.bottom = rect.height + 1 + "px";
+ } else {
+ container.style.top = "";
+ container.style.bottom = "";
+ }
+ }
+
+ container.style.minWidth = rect.width + "px";
+
+ if (obj.options.maxWidth) {
+ container.style.maxWidth = obj.options.maxWidth;
+ }
+
+ if (!obj.items.length && obj.options.autocomplete == true) {
+ content.style.display = "none";
+ } else {
+ content.style.display = "";
+ }
+ }
+ }
+
+ // Events
+ if (typeof obj.options.onopen == "function") {
+ obj.options.onopen(el);
+ }
+ };
+
+ obj.close = function (ignoreEvents) {
+ if (el.classList.contains("jdropdown-focus")) {
+ // Update labels
+ obj.header.value = obj.getText();
+ // Remove cursor
+ obj.setCursor();
+ // Events
+ if (!ignoreEvents && typeof obj.options.onclose == "function") {
+ obj.options.onclose(el);
+ }
+ // Blur
+ if (obj.header.blur) {
+ obj.header.blur();
+ }
+ // Remove focus
+ el.classList.remove("jdropdown-focus");
+ // Start tracking
+ jSuites.tracking(obj, false);
+ // Current dropdown
+ jSuites.dropdown.current = null;
+ }
+
+ return obj.getValue();
+ };
+
+ /**
+ * Set cursor
+ */
+ obj.setCursor = function (index, setPosition) {
+ // Remove current cursor
+ if (obj.currentIndex != null) {
+ // Remove visual cursor
+ if (obj.items && obj.items[obj.currentIndex]) {
+ obj.items[obj.currentIndex].element.classList.remove(
+ "jdropdown-cursor"
+ );
+ }
+ }
+
+ if (index == undefined) {
+ obj.currentIndex = null;
+ } else {
+ index = parseInt(index);
+
+ // Cursor only for visible items
+ if (obj.items[index].element.parentNode) {
+ obj.items[index].element.classList.add("jdropdown-cursor");
+ obj.currentIndex = index;
+
+ // Update scroll to the cursor element
+ if (setPosition !== false && obj.items[obj.currentIndex].element) {
+ var container = content.scrollTop;
+ var element = obj.items[obj.currentIndex].element;
+ content.scrollTop =
+ element.offsetTop - element.scrollTop + element.clientTop - 95;
+ }
+ }
+ }
+ };
+
+ // Compatibility
+ obj.resetCursor = obj.setCursor;
+ obj.updateCursor = obj.setCursor;
+
+ /**
+ * Reset cursor and selected items
+ */
+ obj.reset = function () {
+ // Reset cursor
+ obj.setCursor();
+
+ // Reset selected
+ obj.setValue(null);
+ };
+
+ /**
+ * First available item
+ */
+ obj.first = function () {
+ if (obj.options.lazyLoading === true) {
+ obj.loadFirst();
+ }
+
+ var items = content.querySelectorAll(".jdropdown-item");
+ if (items.length) {
+ var newIndex = items[0].indexValue;
+ obj.setCursor(newIndex);
+ }
+ };
+
+ /**
+ * Last available item
+ */
+ obj.last = function () {
+ if (obj.options.lazyLoading === true) {
+ obj.loadLast();
+ }
+
+ var items = content.querySelectorAll(".jdropdown-item");
+ if (items.length) {
+ var newIndex = items[items.length - 1].indexValue;
+ obj.setCursor(newIndex);
+ }
+ };
+
+ obj.next = function (letter) {
+ var newIndex = null;
+
+ if (letter) {
+ if (letter.length == 1) {
+ // Current index
+ var current = obj.currentIndex || -1;
+ // Letter
+ letter = letter.toLowerCase();
+
+ var e = null;
+ var l = null;
+ var items = content.querySelectorAll(".jdropdown-item");
+ if (items.length) {
+ for (var i = 0; i < items.length; i++) {
+ if (items[i].indexValue > current) {
+ if ((e = obj.items[items[i].indexValue])) {
+ if ((l = e.element.innerText[0])) {
+ l = l.toLowerCase();
+ if (letter == l) {
+ newIndex = items[i].indexValue;
+ break;
+ }
+ }
+ }
+ }
+ }
+ obj.setCursor(newIndex);
+ }
+ }
+ } else {
+ if (obj.currentIndex == undefined || obj.currentIndex == null) {
+ obj.first();
+ } else {
+ var element = obj.items[obj.currentIndex].element;
+
+ var next = element.nextElementSibling;
+ if (next) {
+ if (next.classList.contains("jdropdown-group")) {
+ next = next.lastChild.firstChild;
+ }
+ newIndex = next.indexValue;
+ } else {
+ if (
+ element.parentNode.classList.contains("jdropdown-group-items")
+ ) {
+ if ((next = element.parentNode.parentNode.nextElementSibling)) {
+ if (next.classList.contains("jdropdown-group")) {
+ next = next.lastChild.firstChild;
+ } else if (next.classList.contains("jdropdown-item")) {
+ newIndex = next.indexValue;
+ } else {
+ next = null;
+ }
+ }
+
+ if (next) {
+ newIndex = next.indexValue;
+ }
+ }
+ }
+
+ if (newIndex !== null) {
+ obj.setCursor(newIndex);
+ }
+ }
+ }
+ };
+
+ obj.prev = function () {
+ var newIndex = null;
+
+ if (obj.currentIndex === null) {
+ obj.first();
+ } else {
+ var element = obj.items[obj.currentIndex].element;
+
+ var prev = element.previousElementSibling;
+ if (prev) {
+ if (prev.classList.contains("jdropdown-group")) {
+ prev = prev.lastChild.lastChild;
+ }
+ newIndex = prev.indexValue;
+ } else {
+ if (element.parentNode.classList.contains("jdropdown-group-items")) {
+ if ((prev = element.parentNode.parentNode.previousElementSibling)) {
+ if (prev.classList.contains("jdropdown-group")) {
+ prev = prev.lastChild.lastChild;
+ } else if (prev.classList.contains("jdropdown-item")) {
+ newIndex = prev.indexValue;
+ } else {
+ prev = null;
+ }
+ }
+
+ if (prev) {
+ newIndex = prev.indexValue;
+ }
+ }
+ }
+ }
+
+ if (newIndex !== null) {
+ obj.setCursor(newIndex);
+ }
+ };
+
+ obj.loadFirst = function () {
+ // Search
+ if (obj.results) {
+ var results = obj.results;
+ } else {
+ var results = obj.items;
+ }
+
+ // Show 200 items at once
+ var number = results.length || 0;
+
+ // Lazyloading
+ if (obj.options.lazyLoading == true && number > 200) {
+ number = 200;
+ }
+
+ // Reset container
+ content.innerHTML = "";
+
+ // First 200 items
+ for (var i = 0; i < number; i++) {
+ if (results[i].group) {
+ if (!results[i].group.parentNode) {
+ content.appendChild(results[i].group);
+ }
+ results[i].group.lastChild.appendChild(results[i].element);
+ } else {
+ content.appendChild(results[i].element);
+ }
+ }
+
+ // Scroll go to the begin
+ content.scrollTop = 0;
+ };
+
+ obj.loadLast = function () {
+ // Search
+ if (obj.results) {
+ var results = obj.results;
+ } else {
+ var results = obj.items;
+ }
+
+ // Show first page
+ var number = results.length;
+
+ // Max 200 items
+ if (number > 200) {
+ number = number - 200;
+
+ // Reset container
+ content.innerHTML = "";
+
+ // First 200 items
+ for (var i = number; i < results.length; i++) {
+ if (results[i].group) {
+ if (!results[i].group.parentNode) {
+ content.appendChild(results[i].group);
+ }
+ results[i].group.lastChild.appendChild(results[i].element);
+ } else {
+ content.appendChild(results[i].element);
+ }
+ }
+
+ // Scroll go to the begin
+ content.scrollTop = content.scrollHeight;
+ }
+ };
+
+ obj.loadUp = function () {
+ var test = false;
+
+ // Search
+ if (obj.results) {
+ var results = obj.results;
+ } else {
+ var results = obj.items;
+ }
+
+ var items = content.querySelectorAll(".jdropdown-item");
+ var fistItem = items[0].indexValue;
+ fistItem = obj.items[fistItem];
+ var index = results.indexOf(fistItem) - 1;
+
+ if (index > 0) {
+ var number = 0;
+
+ while (index > 0 && results[index] && number < 200) {
+ if (results[index].group) {
+ if (!results[index].group.parentNode) {
+ content.insertBefore(results[index].group, content.firstChild);
+ }
+ results[index].group.lastChild.insertBefore(
+ results[index].element,
+ results[index].group.lastChild.firstChild
+ );
+ } else {
+ content.insertBefore(results[index].element, content.firstChild);
+ }
+
+ index--;
+ number++;
+ }
+
+ // New item added
+ test = true;
+ }
+
+ return test;
+ };
+
+ obj.loadDown = function () {
+ var test = false;
+
+ // Search
+ if (obj.results) {
+ var results = obj.results;
+ } else {
+ var results = obj.items;
+ }
+
+ var items = content.querySelectorAll(".jdropdown-item");
+ var lastItem = items[items.length - 1].indexValue;
+ lastItem = obj.items[lastItem];
+ var index = results.indexOf(lastItem) + 1;
+
+ if (index < results.length) {
+ var number = 0;
+ while (index < results.length && results[index] && number < 200) {
+ if (results[index].group) {
+ if (!results[index].group.parentNode) {
+ content.appendChild(results[index].group);
+ }
+ results[index].group.lastChild.appendChild(results[index].element);
+ } else {
+ content.appendChild(results[index].element);
+ }
+
+ index++;
+ number++;
+ }
+
+ // New item added
+ test = true;
+ }
+
+ return test;
+ };
+
+ init();
+
+ return obj;
+ };
+
+ jSuites.dropdown.keydown = function (e) {
+ var dropdown = null;
+ if ((dropdown = jSuites.dropdown.current)) {
+ if (e.which == 13 || e.which == 9) {
+ // enter or tab
+ if (
+ dropdown.header.value &&
+ dropdown.currentIndex == null &&
+ dropdown.options.newOptions
+ ) {
+ // if they typed something in, but it matched nothing, and newOptions are allowed, start that flow
+ dropdown.add();
+ } else {
+ // Quick Select/Filter
+ if (
+ dropdown.currentIndex == null &&
+ dropdown.options.autocomplete == true &&
+ dropdown.header.value != ""
+ ) {
+ dropdown.find(dropdown.header.value);
+ }
+ dropdown.selectIndex(dropdown.currentIndex);
+ }
+ } else if (e.which == 38) {
+ // up arrow
+ if (dropdown.currentIndex == null) {
+ dropdown.first();
+ } else if (dropdown.currentIndex > 0) {
+ dropdown.prev();
+ }
+ e.preventDefault();
+ } else if (e.which == 40) {
+ // down arrow
+ if (dropdown.currentIndex == null) {
+ dropdown.first();
+ } else if (dropdown.currentIndex + 1 < dropdown.items.length) {
+ dropdown.next();
+ }
+ e.preventDefault();
+ } else if (e.which == 36) {
+ dropdown.first();
+ if (!e.target.classList.contains("jdropdown-header")) {
+ e.preventDefault();
+ }
+ } else if (e.which == 35) {
+ dropdown.last();
+ if (!e.target.classList.contains("jdropdown-header")) {
+ e.preventDefault();
+ }
+ } else if (e.which == 27) {
+ dropdown.close();
+ } else if (e.which == 33) {
+ // page up
+ if (dropdown.currentIndex == null) {
+ dropdown.first();
+ } else if (dropdown.currentIndex > 0) {
+ for (var i = 0; i < 7; i++) {
+ dropdown.prev();
+ }
+ }
+ e.preventDefault();
+ } else if (e.which == 34) {
+ // page down
+ if (dropdown.currentIndex == null) {
+ dropdown.first();
+ } else if (dropdown.currentIndex + 1 < dropdown.items.length) {
+ for (var i = 0; i < 7; i++) {
+ dropdown.next();
+ }
+ }
+ e.preventDefault();
+ }
+ }
+ };
+
+ jSuites.dropdown.mouseup = function (e) {
+ var element = jSuites.findElement(e.target, "jdropdown");
+ if (element) {
+ var dropdown = element.dropdown;
+ if (e.target.classList.contains("jdropdown-header")) {
+ if (
+ element.classList.contains("jdropdown-focus") &&
+ element.classList.contains("jdropdown-default")
+ ) {
+ var rect = element.getBoundingClientRect();
+
+ if (e.changedTouches && e.changedTouches[0]) {
+ var x = e.changedTouches[0].clientX;
+ var y = e.changedTouches[0].clientY;
+ } else {
+ var x = e.clientX;
+ var y = e.clientY;
+ }
+
+ if (rect.width - (x - rect.left) < 30) {
+ if (e.target.classList.contains("jdropdown-add")) {
+ dropdown.add();
+ } else {
+ dropdown.close();
+ }
+ } else {
+ if (dropdown.options.autocomplete == false) {
+ dropdown.close();
+ }
+ }
+ } else {
+ dropdown.open();
+ }
+ } else if (e.target.classList.contains("jdropdown-group-name")) {
+ var items = e.target.nextSibling.children;
+ if (e.target.nextSibling.style.display != "none") {
+ for (var i = 0; i < items.length; i++) {
+ if (items[i].style.display != "none") {
+ dropdown.selectItem(items[i]);
+ }
+ }
+ }
+ } else if (e.target.classList.contains("jdropdown-group-arrow")) {
+ if (e.target.classList.contains("jdropdown-group-arrow-down")) {
+ e.target.classList.remove("jdropdown-group-arrow-down");
+ e.target.classList.add("jdropdown-group-arrow-up");
+ e.target.parentNode.nextSibling.style.display = "none";
+ } else {
+ e.target.classList.remove("jdropdown-group-arrow-up");
+ e.target.classList.add("jdropdown-group-arrow-down");
+ e.target.parentNode.nextSibling.style.display = "";
+ }
+ } else if (e.target.classList.contains("jdropdown-item")) {
+ dropdown.selectItem(e.target);
+ } else if (e.target.classList.contains("jdropdown-image")) {
+ dropdown.selectItem(e.target.parentNode);
+ } else if (e.target.classList.contains("jdropdown-description")) {
+ dropdown.selectItem(e.target.parentNode);
+ } else if (e.target.classList.contains("jdropdown-title")) {
+ dropdown.selectItem(e.target.parentNode.parentNode);
+ } else if (
+ e.target.classList.contains("jdropdown-close") ||
+ e.target.classList.contains("jdropdown-backdrop")
+ ) {
+ dropdown.close();
+ }
+ }
+ };
+
+ jSuites.dropdown.extractFromDom = function (el, options) {
+ // Keep reference
+ var select = el;
+ if (!options) {
+ options = {};
+ }
+ // Prepare configuration
+ if (
+ el.getAttribute("multiple") &&
+ (!options || options.multiple == undefined)
+ ) {
+ options.multiple = true;
+ }
+ if (
+ el.getAttribute("placeholder") &&
+ (!options || options.placeholder == undefined)
+ ) {
+ options.placeholder = el.getAttribute("placeholder");
+ }
+ if (
+ el.getAttribute("data-autocomplete") &&
+ (!options || options.autocomplete == undefined)
+ ) {
+ options.autocomplete = true;
+ }
+ if (!options || options.width == undefined) {
+ options.width = el.offsetWidth;
+ }
+ if (el.value && (!options || options.value == undefined)) {
+ options.value = el.value;
+ }
+ if (!options || options.data == undefined) {
+ options.data = [];
+ for (var j = 0; j < el.children.length; j++) {
+ if (el.children[j].tagName == "OPTGROUP") {
+ for (var i = 0; i < el.children[j].children.length; i++) {
+ options.data.push({
+ value: el.children[j].children[i].value,
+ text: el.children[j].children[i].innerHTML,
+ group: el.children[j].getAttribute("label"),
+ });
+ }
+ } else {
+ options.data.push({
+ value: el.children[j].value,
+ text: el.children[j].innerHTML,
+ });
+ }
+ }
+ }
+ if (!options || options.onchange == undefined) {
+ options.onchange = function (a, b, c, d) {
+ if (options.multiple == true) {
+ if (obj.items[b].classList.contains("jdropdown-selected")) {
+ select.options[b].setAttribute("selected", "selected");
+ } else {
+ select.options[b].removeAttribute("selected");
+ }
+ } else {
+ select.value = d;
+ }
+ };
+ }
+ // Create DIV
+ var div = document.createElement("div");
+ el.parentNode.insertBefore(div, el);
+ el.style.display = "none";
+ el = div;
+
+ return { el: el, options: options };
+ };
+
+ jSuites.editor = function (el, options) {
+ // New instance
+ var obj = { type: "editor" };
+ obj.options = {};
+
+ // Default configuration
+ var defaults = {
+ // Initial HTML content
+ value: null,
+ // Initial snippet
+ snippet: null,
+ // Add toolbar
+ toolbar: null,
+ // Website parser is to read websites and images from cross domain
+ remoteParser: null,
+ // Placeholder
+ placeholder: null,
+ // Parse URL
+ parseURL: false,
+ filterPaste: true,
+ // Accept drop files
+ dropZone: false,
+ dropAsSnippet: false,
+ acceptImages: false,
+ acceptFiles: false,
+ maxFileSize: 5000000,
+ allowImageResize: true,
+ // Style
+ border: true,
+ padding: true,
+ maxHeight: null,
+ height: null,
+ focus: false,
+ // Events
+ onclick: null,
+ onfocus: null,
+ onblur: null,
+ onload: null,
+ onkeyup: null,
+ onkeydown: null,
+ onchange: null,
+ userSearch: null,
+ };
+
+ // Loop through our object
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ obj.options[property] = defaults[property];
+ }
+ }
+
+ // Private controllers
+ var imageResize = 0;
+ var editorTimer = null;
+ var editorAction = null;
+ var files = [];
+
+ // Make sure element is empty
+ el.innerHTML = "";
+
+ // Keep the reference for the container
+ obj.el = el;
+
+ if (typeof obj.options.onclick == "function") {
+ el.onclick = function (e) {
+ obj.options.onclick(el, obj, e);
+ };
+ }
+
+ // Prepare container
+ el.classList.add("jeditor-container");
+
+ // Padding
+ if (obj.options.padding == true) {
+ el.classList.add("jeditor-padding");
+ }
+
+ // Border
+ if (obj.options.border == false) {
+ el.style.border = "0px";
+ }
+
+ // Snippet
+ var snippet = document.createElement("div");
+ snippet.className = "jsnippet";
+ snippet.setAttribute("contenteditable", false);
+
+ // Toolbar
+ var toolbar = document.createElement("div");
+ toolbar.className = "jeditor-toolbar";
+
+ // Create editor
+ var editor = document.createElement("div");
+ editor.setAttribute("contenteditable", true);
+ editor.setAttribute("spellcheck", false);
+ editor.className = "jeditor";
+
+ // Placeholder
+ if (obj.options.placeholder) {
+ editor.setAttribute("data-placeholder", obj.options.placeholder);
+ }
+
+ // Max height
+ if (obj.options.maxHeight || obj.options.height) {
+ editor.style.overflowY = "auto";
+
+ if (obj.options.maxHeight) {
+ editor.style.maxHeight = obj.options.maxHeight;
+ }
+ if (obj.options.height) {
+ editor.style.height = obj.options.height;
+ }
+ }
+
+ // Set editor initial value
+ if (obj.options.value) {
+ var value = obj.options.value;
+ } else {
+ var value = el.innerHTML ? el.innerHTML : "";
+ }
+
+ if (!value) {
+ var value = "";
+ }
+
+ /**
+ * Onchange event controllers
+ */
+ var change = function (e) {
+ if (typeof obj.options.onchange == "function") {
+ obj.options.onchange(el, obj, e);
+ }
+
+ // Update value
+ obj.options.value = obj.getData();
+
+ // Lemonade JS
+ if (el.value != obj.options.value) {
+ el.value = obj.options.value;
+ if (typeof el.oninput == "function") {
+ el.oninput({
+ type: "input",
+ target: el,
+ value: el.value,
+ });
+ }
+ }
+ };
+
+ // Create node
+ var createUserSearchNode = function () {
+ // Get coordinates from caret
+ var sel = window.getSelection
+ ? window.getSelection()
+ : document.selection;
+ var range = sel.getRangeAt(0);
+ range.deleteContents();
+ // Append text node
+ var input = document.createElement("a");
+ input.innerText = "@";
+ input.searchable = true;
+ range.insertNode(input);
+ var node = range.getBoundingClientRect();
+ range.collapse(false);
+ // Position
+ userSearch.style.position = "fixed";
+ userSearch.style.top = node.top + node.height + 10 + "px";
+ userSearch.style.left = node.left + 2 + "px";
+ };
+
+ /**
+ * Extract images from a HTML string
+ */
+ var extractImageFromHtml = function (html) {
+ // Create temp element
+ var div = document.createElement("div");
+ div.innerHTML = html;
+
+ // Extract images
+ var img = div.querySelectorAll("img");
+
+ if (img.length) {
+ for (var i = 0; i < img.length; i++) {
+ obj.addImage(img[i].src);
+ }
+ }
+ };
+
+ /**
+ * Insert node at caret
+ */
+ var insertNodeAtCaret = function (newNode) {
+ var sel, range;
+
+ if (window.getSelection) {
+ sel = window.getSelection();
+ if (sel.rangeCount) {
+ range = sel.getRangeAt(0);
+ var selectedText = range.toString();
+ range.deleteContents();
+ range.insertNode(newNode);
+ // move the cursor after element
+ range.setStartAfter(newNode);
+ range.setEndAfter(newNode);
+ sel.removeAllRanges();
+ sel.addRange(range);
+ }
+ }
+ };
+
+ var updateTotalImages = function () {
+ var o = null;
+ if ((o = snippet.children[0])) {
+ // Make sure is a grid
+ if (!o.classList.contains("jslider-grid")) {
+ o.classList.add("jslider-grid");
+ }
+ // Quantify of images
+ var number = o.children.length;
+ // Set the configuration of the grid
+ o.setAttribute("data-number", number > 4 ? 4 : number);
+ // Total of images inside the grid
+ if (number > 4) {
+ o.setAttribute("data-total", number - 4);
+ } else {
+ o.removeAttribute("data-total");
+ }
+ }
+ };
+
+ /**
+ * Append image to the snippet
+ */
+ var appendImage = function (image) {
+ if (!snippet.innerHTML) {
+ appendElement({});
+ }
+ snippet.children[0].appendChild(image);
+ updateTotalImages();
+ };
+
+ /**
+ * Append snippet
+ * @Param object data
+ */
+ var appendElement = function (data) {
+ // Reset snippet
+ snippet.innerHTML = "";
+
+ // Attributes
+ var a = ["image", "title", "description", "host", "url"];
+
+ for (var i = 0; i < a.length; i++) {
+ var div = document.createElement("div");
+ div.className = "jsnippet-" + a[i];
+ div.setAttribute("data-k", a[i]);
+ snippet.appendChild(div);
+ if (data[a[i]]) {
+ if (a[i] == "image") {
+ if (!Array.isArray(data.image)) {
+ data.image = [data.image];
+ }
+ for (var j = 0; j < data.image.length; j++) {
+ var img = document.createElement("img");
+ img.src = data.image[j];
+ div.appendChild(img);
+ }
+ } else {
+ div.innerHTML = data[a[i]];
+ }
+ }
+ }
+
+ editor.appendChild(document.createElement("br"));
+ editor.appendChild(snippet);
+ };
+
+ var verifyEditor = function () {
+ clearTimeout(editorTimer);
+ editorTimer = setTimeout(function () {
+ var snippet = editor.querySelector(".jsnippet");
+ if (!snippet) {
+ var html = editor.innerHTML.replace(/\n/g, " ");
+ var container = document.createElement("div");
+ container.innerHTML = html;
+ var text = container.innerText;
+ var url = jSuites.editor.detectUrl(text);
+
+ if (url) {
+ if (
+ url[0].substr(-3) == "jpg" ||
+ url[0].substr(-3) == "png" ||
+ url[0].substr(-3) == "gif"
+ ) {
+ obj.addImage(url[0], true);
+ } else {
+ var id = jSuites.editor.youtubeParser(url[0]);
+ obj.parseWebsite(url[0], id);
+ }
+ }
+ }
+ }, 1000);
+ };
+
+ obj.parseContent = function () {
+ verifyEditor();
+ };
+
+ obj.parseWebsite = function (url, youtubeId) {
+ if (!obj.options.remoteParser) {
+ console.log("The remoteParser is not defined");
+ } else {
+ // Youtube definitions
+ if (youtubeId) {
+ var url = "https://www.youtube.com/watch?v=" + youtubeId;
+ }
+
+ var p = {
+ title: "",
+ description: "",
+ image: "",
+ host: url.split("/")[2],
+ url: url,
+ };
+
+ jSuites.ajax({
+ url: obj.options.remoteParser + encodeURI(url.trim()),
+ method: "GET",
+ dataType: "json",
+ success: function (result) {
+ // Get title
+ if (result.title) {
+ p.title = result.title;
+ }
+ // Description
+ if (result.description) {
+ p.description = result.description;
+ }
+ // Host
+ if (result.host) {
+ p.host = result.host;
+ }
+ // Url
+ if (result.url) {
+ p.url = result.url;
+ }
+ // Append snippet
+ appendElement(p);
+ // Add image
+ if (result.image) {
+ obj.addImage(result.image, true);
+ } else if (result["og:image"]) {
+ obj.addImage(result["og:image"], true);
+ }
+ },
+ });
+ }
+ };
+
+ /**
+ * Set editor value
+ */
+ obj.setData = function (o) {
+ if (typeof o == "object") {
+ editor.innerHTML = o.content;
+ } else {
+ editor.innerHTML = o;
+ }
+
+ if (obj.options.focus) {
+ jSuites.editor.setCursor(editor, true);
+ }
+
+ // Reset files container
+ files = [];
+ };
+
+ obj.getFiles = function () {
+ var f = editor.querySelectorAll(".jfile");
+ var d = [];
+ for (var i = 0; i < f.length; i++) {
+ if (files[f[i].src]) {
+ d.push(files[f[i].src]);
+ }
+ }
+ return d;
+ };
+
+ obj.getText = function () {
+ return editor.innerText;
+ };
+
+ /**
+ * Get editor data
+ */
+ obj.getData = function (json) {
+ if (!json) {
+ var data = editor.innerHTML;
+ } else {
+ var data = {
+ content: "",
+ };
+
+ // Get snippet
+ if (snippet.innerHTML) {
+ var index = 0;
+ data.snippet = {};
+ for (var i = 0; i < snippet.children.length; i++) {
+ // Get key from element
+ var key = snippet.children[i].getAttribute("data-k");
+ if (key) {
+ if (key == "image") {
+ if (!data.snippet.image) {
+ data.snippet.image = [];
+ }
+ // Get all images
+ for (var j = 0; j < snippet.children[i].children.length; j++) {
+ data.snippet.image.push(
+ snippet.children[i].children[j].getAttribute("src")
+ );
+ }
+ } else {
+ data.snippet[key] = snippet.children[i].innerHTML;
+ }
+ }
+ }
+ }
+
+ // Get files
+ var f = Object.keys(files);
+ if (f.length) {
+ data.files = [];
+ for (var i = 0; i < f.length; i++) {
+ data.files.push(files[f[i]]);
+ }
+ }
+
+ // Users
+ if (userSearch) {
+ // Get tag users
+ var tagged = editor.querySelectorAll("a[data-user]");
+ if (tagged.length) {
+ data.users = [];
+ for (var i = 0; i < tagged.length; i++) {
+ var userId = tagged[i].getAttribute("data-user");
+ if (userId) {
+ data.users.push(userId);
+ }
+ }
+ data.users = data.users.join(",");
+ }
+ }
+
+ // Get content
+ var d = document.createElement("div");
+ d.innerHTML = editor.innerHTML;
+ var s = d.querySelector(".jsnippet");
+ if (s) {
+ s.remove();
+ }
+
+ var text = d.innerHTML;
+ text = text.replace(/
/g, "\n");
+ text = text.replace(/<\/div>/g, "\n");
+ text = text.replace(/<(?:.|\n)*?>/gm, "");
+ data.content = text.trim();
+ }
+
+ return data;
+ };
+
+ // Reset
+ obj.reset = function () {
+ editor.innerHTML = "";
+ snippet.innerHTML = "";
+ files = [];
+ };
+
+ obj.addPdf = function (data) {
+ if (data.result.substr(0, 4) != "data") {
+ console.error("Invalid source");
+ } else {
+ var canvas = document.createElement("canvas");
+ canvas.width = 60;
+ canvas.height = 60;
+
+ var img = new Image();
+ var ctx = canvas.getContext("2d");
+ ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
+
+ canvas.toBlob(function (blob) {
+ var newImage = document.createElement("img");
+ newImage.src = window.URL.createObjectURL(blob);
+ newImage.title = data.name;
+ newImage.className = "jfile pdf";
+
+ files[newImage.src] = {
+ file: newImage.src,
+ extension: "pdf",
+ content: data.result,
+ };
+
+ insertNodeAtCaret(newImage);
+ });
+ }
+ };
+
+ obj.addImage = function (src, asSnippet) {
+ if (!src) {
+ src = "";
+ }
+
+ if (src.substr(0, 4) != "data" && !obj.options.remoteParser) {
+ console.error("remoteParser not defined in your initialization");
+ } else {
+ // This is to process cross domain images
+ if (src.substr(0, 4) == "data") {
+ var extension = src.split(";");
+ extension = extension[0].split("/");
+ extension = extension[1];
+ } else {
+ var extension = src.substr(src.lastIndexOf(".") + 1);
+ // Work for cross browsers
+ src = obj.options.remoteParser + src;
+ }
+
+ var img = new Image();
+
+ img.onload = function onload() {
+ var canvas = document.createElement("canvas");
+ canvas.width = img.width;
+ canvas.height = img.height;
+
+ var ctx = canvas.getContext("2d");
+ ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
+
+ canvas.toBlob(function (blob) {
+ var newImage = document.createElement("img");
+ newImage.src = window.URL.createObjectURL(blob);
+ newImage.classList.add("jfile");
+ newImage.setAttribute("tabindex", "900");
+ files[newImage.src] = {
+ file: newImage.src,
+ extension: extension,
+ content: canvas.toDataURL(),
+ };
+
+ if (obj.options.dropAsSnippet || asSnippet) {
+ appendImage(newImage);
+ // Just to understand the attachment is part of a snippet
+ files[newImage.src].snippet = true;
+ } else {
+ insertNodeAtCaret(newImage);
+ }
+
+ change();
+ });
+ };
+
+ img.src = src;
+ }
+ };
+
+ obj.addFile = function (files) {
+ var reader = [];
+
+ for (var i = 0; i < files.length; i++) {
+ if (files[i].size > obj.options.maxFileSize) {
+ alert("The file is too big");
+ } else {
+ // Only PDF or Images
+ var type = files[i].type.split("/");
+
+ if (type[0] == "image") {
+ type = 1;
+ } else if (type[1] == "pdf") {
+ type = 2;
+ } else {
+ type = 0;
+ }
+
+ if (type) {
+ // Create file
+ reader[i] = new FileReader();
+ reader[i].index = i;
+ reader[i].type = type;
+ reader[i].name = files[i].name;
+ reader[i].date = files[i].lastModified;
+ reader[i].size = files[i].size;
+ reader[i].addEventListener(
+ "load",
+ function (data) {
+ // Get result
+ if (data.target.type == 2) {
+ if (obj.options.acceptFiles == true) {
+ obj.addPdf(data.target);
+ }
+ } else {
+ obj.addImage(data.target.result);
+ }
+ },
+ false
+ );
+
+ reader[i].readAsDataURL(files[i]);
+ } else {
+ alert("The extension is not allowed");
+ }
+ }
+ }
+ };
+
+ // Destroy
+ obj.destroy = function () {
+ editor.removeEventListener("mouseup", editorMouseUp);
+ editor.removeEventListener("mousedown", editorMouseDown);
+ editor.removeEventListener("mousemove", editorMouseMove);
+ editor.removeEventListener("keyup", editorKeyUp);
+ editor.removeEventListener("keydown", editorKeyDown);
+ editor.removeEventListener("dragstart", editorDragStart);
+ editor.removeEventListener("dragenter", editorDragEnter);
+ editor.removeEventListener("dragover", editorDragOver);
+ editor.removeEventListener("drop", editorDrop);
+ editor.removeEventListener("paste", editorPaste);
+ editor.removeEventListener("blur", editorBlur);
+ editor.removeEventListener("focus", editorFocus);
+
+ el.editor = null;
+ el.classList.remove("jeditor-container");
+
+ toolbar.remove();
+ snippet.remove();
+ editor.remove();
+ };
+
+ var isLetter = function (str) {
+ var regex =
+ /([\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]+)/g;
+ return str.match(regex) ? 1 : 0;
+ };
+
+ // Event handlers
+ var editorMouseUp = function (e) {
+ if (editorAction && editorAction.e) {
+ editorAction.e.classList.remove("resizing");
+ }
+
+ editorAction = false;
+ };
+
+ var editorMouseDown = function (e) {
+ var close = function (snippet) {
+ var rect = snippet.getBoundingClientRect();
+ if (
+ rect.width - (e.clientX - rect.left) < 40 &&
+ e.clientY - rect.top < 40
+ ) {
+ snippet.innerHTML = "";
+ snippet.remove();
+ }
+ };
+
+ if (e.target.tagName == "IMG") {
+ if (e.target.style.cursor) {
+ var rect = e.target.getBoundingClientRect();
+ editorAction = {
+ e: e.target,
+ x: e.clientX,
+ y: e.clientY,
+ w: rect.width,
+ h: rect.height,
+ d: e.target.style.cursor,
+ };
+
+ if (!e.target.width) {
+ e.target.width = rect.width + "px";
+ }
+
+ if (!e.target.height) {
+ e.target.height = rect.height + "px";
+ }
+
+ var s = window.getSelection();
+ if (s.rangeCount) {
+ for (var i = 0; i < s.rangeCount; i++) {
+ s.removeRange(s.getRangeAt(i));
+ }
+ }
+
+ e.target.classList.add("resizing");
+ } else {
+ editorAction = true;
+ }
+ } else {
+ if (e.target.classList.contains("jsnippet")) {
+ close(e.target);
+ } else if (e.target.parentNode.classList.contains("jsnippet")) {
+ close(e.target.parentNode);
+ }
+
+ editorAction = true;
+ }
+ };
+
+ var editorMouseMove = function (e) {
+ if (
+ e.target.tagName == "IMG" &&
+ !e.target.parentNode.classList.contains("jsnippet-image") &&
+ obj.options.allowImageResize == true
+ ) {
+ if (e.target.getAttribute("tabindex")) {
+ var rect = e.target.getBoundingClientRect();
+ if (e.clientY - rect.top < 5) {
+ if (rect.width - (e.clientX - rect.left) < 5) {
+ e.target.style.cursor = "ne-resize";
+ } else if (e.clientX - rect.left < 5) {
+ e.target.style.cursor = "nw-resize";
+ } else {
+ e.target.style.cursor = "n-resize";
+ }
+ } else if (rect.height - (e.clientY - rect.top) < 5) {
+ if (rect.width - (e.clientX - rect.left) < 5) {
+ e.target.style.cursor = "se-resize";
+ } else if (e.clientX - rect.left < 5) {
+ e.target.style.cursor = "sw-resize";
+ } else {
+ e.target.style.cursor = "s-resize";
+ }
+ } else if (rect.width - (e.clientX - rect.left) < 5) {
+ e.target.style.cursor = "e-resize";
+ } else if (e.clientX - rect.left < 5) {
+ e.target.style.cursor = "w-resize";
+ } else {
+ e.target.style.cursor = "";
+ }
+ }
+ }
+
+ // Move
+ if (e.which == 1 && editorAction && editorAction.d) {
+ if (
+ editorAction.d == "e-resize" ||
+ editorAction.d == "ne-resize" ||
+ editorAction.d == "se-resize"
+ ) {
+ editorAction.e.width = editorAction.w + (e.clientX - editorAction.x);
+
+ if (e.shiftKey) {
+ var newHeight =
+ (e.clientX - editorAction.x) * (editorAction.h / editorAction.w);
+ editorAction.e.height = editorAction.h + newHeight;
+ } else {
+ var newHeight = null;
+ }
+ }
+
+ if (!newHeight) {
+ if (
+ editorAction.d == "s-resize" ||
+ editorAction.d == "se-resize" ||
+ editorAction.d == "sw-resize"
+ ) {
+ if (!e.shiftKey) {
+ editorAction.e.height =
+ editorAction.h + (e.clientY - editorAction.y);
+ }
+ }
+ }
+ }
+ };
+
+ var editorKeyUp = function (e) {
+ if (!editor.innerHTML) {
+ editor.innerHTML = "
";
+ }
+
+ if (userSearch) {
+ var t = jSuites.getNode();
+ if (t) {
+ if (t.searchable === true) {
+ if (t.innerText && t.innerText.substr(0, 1) == "@") {
+ userSearchInstance(t.innerText.substr(1));
+ }
+ } else if (t.searchable === false) {
+ if (t.innerText !== t.getAttribute("data-label")) {
+ t.searchable = true;
+ t.removeAttribute("href");
+ }
+ }
+ }
+ }
+
+ if (typeof obj.options.onkeyup == "function") {
+ obj.options.onkeyup(el, obj, e);
+ }
+ };
+
+ var editorKeyDown = function (e) {
+ // Check for URL
+ if (obj.options.parseURL == true) {
+ verifyEditor();
+ }
+
+ if (userSearch) {
+ if (e.key == "@") {
+ createUserSearchNode(editor);
+ e.preventDefault();
+ } else {
+ if (userSearchInstance.isOpened()) {
+ userSearchInstance.keydown(e);
+ }
+ }
+ }
+
+ if (typeof obj.options.onkeydown == "function") {
+ obj.options.onkeydown(el, obj, e);
+ }
+
+ if (e.key == "Delete") {
+ if (
+ e.target.tagName == "IMG" &&
+ e.target.parentNode.classList.contains("jsnippet-image")
+ ) {
+ e.target.remove();
+ updateTotalImages();
+ }
+ }
+ };
+
+ // Elements to be removed
+ var remove = [
+ HTMLUnknownElement,
+ HTMLAudioElement,
+ HTMLEmbedElement,
+ HTMLIFrameElement,
+ HTMLTextAreaElement,
+ HTMLInputElement,
+ HTMLScriptElement,
+ ];
+
+ // Valid properties
+ var validProperty = [
+ "width",
+ "height",
+ "align",
+ "border",
+ "src",
+ "tabindex",
+ ];
+
+ // Valid CSS attributes
+ var validStyle = [
+ "color",
+ "font-weight",
+ "font-size",
+ "background",
+ "background-color",
+ "margin",
+ ];
+
+ var parse = function (element) {
+ // Remove attributes
+ if (element.attributes && element.attributes.length) {
+ var image = null;
+ var style = null;
+ // Process style attribute
+ var elementStyle = element.getAttribute("style");
+ if (elementStyle) {
+ style = [];
+ var t = elementStyle.split(";");
+ for (var j = 0; j < t.length; j++) {
+ var v = t[j].trim().split(":");
+ if (validStyle.indexOf(v[0].trim()) >= 0) {
+ var k = v.shift();
+ var v = v.join(":");
+ style.push(k + ":" + v);
+ }
+ }
+ }
+ // Process image
+ if (element.tagName.toUpperCase() == "IMG") {
+ if (!obj.options.acceptImages || !element.src) {
+ element.parentNode.removeChild(element);
+ } else {
+ // Check if is data
+ element.setAttribute("tabindex", "900");
+ // Check attributes for persistance
+ obj.addImage(element.src);
+ }
+ }
+ // Remove attributes
+ var attr = [];
+ var numAttributes = element.attributes.length - 1;
+ if (numAttributes > 0) {
+ for (var i = numAttributes; i >= 0; i--) {
+ attr.push(element.attributes[i].name);
+ }
+ attr.forEach(function (v) {
+ if (validProperty.indexOf(v) == -1) {
+ element.removeAttribute(v);
+ }
+ });
+ }
+ element.style = "";
+ // Add valid style
+ if (style && style.length) {
+ element.setAttribute("style", style.join(";"));
+ }
+ }
+ // Parse children
+ if (element.children.length) {
+ for (var i = 0; i < element.children.length; i++) {
+ parse(element.children[i]);
+ }
+ }
+
+ if (remove.indexOf(element.constructor) >= 0) {
+ element.remove();
+ }
+ };
+
+ var filter = function (data) {
+ if (data) {
+ data = data.replace(new RegExp("", "gsi"), "");
+ }
+ var parser = new DOMParser();
+ var d = parser.parseFromString(data, "text/html");
+ parse(d);
+ var span = document.createElement("span");
+ span.innerHTML = d.firstChild.innerHTML;
+ return span;
+ };
+
+ var editorPaste = function (e) {
+ if (obj.options.filterPaste == true) {
+ if (e.clipboardData || e.originalEvent.clipboardData) {
+ var html = (e.originalEvent || e).clipboardData.getData("text/html");
+ var text = (e.originalEvent || e).clipboardData.getData("text/plain");
+ var file = (e.originalEvent || e).clipboardData.files;
+ } else if (window.clipboardData) {
+ var html = window.clipboardData.getData("Html");
+ var text = window.clipboardData.getData("Text");
+ var file = window.clipboardData.files;
+ }
+
+ if (file.length) {
+ // Paste a image from the clipboard
+ obj.addFile(file);
+ } else {
+ if (!html) {
+ html = text.split("\r\n");
+ if (!e.target.innerText) {
+ html.map(function (v) {
+ var d = document.createElement("div");
+ d.innerText = v;
+ editor.appendChild(d);
+ });
+ } else {
+ html = html.map(function (v) {
+ return "" + v + "
";
+ });
+ document.execCommand("insertHtml", false, html.join(""));
+ }
+ } else {
+ var d = filter(html);
+ // Paste to the editor
+ //insertNodeAtCaret(d);
+ document.execCommand("insertHtml", false, d.innerHTML);
+ }
+ }
+
+ e.preventDefault();
+ }
+ };
+
+ var editorDragStart = function (e) {
+ if (editorAction && editorAction.e) {
+ e.preventDefault();
+ }
+ };
+
+ var editorDragEnter = function (e) {
+ if (editorAction || obj.options.dropZone == false) {
+ // Do nothing
+ } else {
+ el.classList.add("jeditor-dragging");
+ e.preventDefault();
+ }
+ };
+
+ var editorDragOver = function (e) {
+ if (editorAction || obj.options.dropZone == false) {
+ // Do nothing
+ } else {
+ if (editorTimer) {
+ clearTimeout(editorTimer);
+ }
+
+ editorTimer = setTimeout(function () {
+ el.classList.remove("jeditor-dragging");
+ }, 100);
+ e.preventDefault();
+ }
+ };
+
+ var editorDrop = function (e) {
+ if (editorAction || obj.options.dropZone == false) {
+ // Do nothing
+ } else {
+ // Position caret on the drop
+ var range = null;
+ if (document.caretRangeFromPoint) {
+ range = document.caretRangeFromPoint(e.clientX, e.clientY);
+ } else if (e.rangeParent) {
+ range = document.createRange();
+ range.setStart(e.rangeParent, e.rangeOffset);
+ }
+ var sel = window.getSelection();
+ sel.removeAllRanges();
+ sel.addRange(range);
+ sel.anchorNode.parentNode.focus();
+
+ var html = (e.originalEvent || e).dataTransfer.getData("text/html");
+ var text = (e.originalEvent || e).dataTransfer.getData("text/plain");
+ var file = (e.originalEvent || e).dataTransfer.files;
+
+ if (file.length) {
+ obj.addFile(file);
+ } else if (text) {
+ extractImageFromHtml(html);
+ }
+
+ el.classList.remove("jeditor-dragging");
+ e.preventDefault();
+ }
+ };
+
+ var editorBlur = function (e) {
+ if (userSearch && userSearchInstance.isOpened()) {
+ userSearchInstance.close();
+ }
+
+ // Blur
+ if (typeof obj.options.onblur == "function") {
+ obj.options.onblur(el, obj, e);
+ }
+
+ change(e);
+ };
+
+ var editorFocus = function (e) {
+ // Focus
+ if (typeof obj.options.onfocus == "function") {
+ obj.options.onfocus(el, obj, e);
+ }
+ };
+
+ editor.addEventListener("mouseup", editorMouseUp);
+ editor.addEventListener("mousedown", editorMouseDown);
+ editor.addEventListener("mousemove", editorMouseMove);
+ editor.addEventListener("keyup", editorKeyUp);
+ editor.addEventListener("keydown", editorKeyDown);
+ editor.addEventListener("dragstart", editorDragStart);
+ editor.addEventListener("dragenter", editorDragEnter);
+ editor.addEventListener("dragover", editorDragOver);
+ editor.addEventListener("drop", editorDrop);
+ editor.addEventListener("paste", editorPaste);
+ editor.addEventListener("focus", editorFocus);
+ editor.addEventListener("blur", editorBlur);
+
+ // Onload
+ if (typeof obj.options.onload == "function") {
+ obj.options.onload(el, obj, editor);
+ }
+
+ // Set value to the editor
+ editor.innerHTML = value;
+
+ // Append editor to the containre
+ el.appendChild(editor);
+
+ // Snippet
+ if (obj.options.snippet) {
+ appendElement(obj.options.snippet);
+ }
+
+ // Default toolbar
+ if (obj.options.toolbar == null) {
+ obj.options.toolbar = jSuites.editor.getDefaultToolbar();
+ }
+
+ // Add toolbar
+ if (obj.options.toolbar) {
+ // Append to the DOM
+ el.appendChild(toolbar);
+ // Create toolbar
+ jSuites.toolbar(toolbar, {
+ container: true,
+ responsive: true,
+ items: obj.options.toolbar,
+ });
+ }
+
+ // Add user search
+ var userSearch = null;
+ var userSearchInstance = null;
+ if (obj.options.userSearch) {
+ userSearch = document.createElement("div");
+ el.appendChild(userSearch);
+
+ // Component
+ userSearchInstance = jSuites.search(userSearch, {
+ data: obj.options.userSearch,
+ placeholder: jSuites.translate("Type the name a user"),
+ onselect: function (a, b, c, d) {
+ if (userSearchInstance.isOpened()) {
+ var t = jSuites.getNode();
+ if (
+ t &&
+ t.searchable == true &&
+ t.innerText.trim() &&
+ t.innerText.substr(1)
+ ) {
+ t.innerText = "@" + c;
+ t.href = "/" + c;
+ t.setAttribute("data-user", d);
+ t.setAttribute("data-label", t.innerText);
+ t.searchable = false;
+ jSuites.focus(t);
+ }
+ }
+ },
+ });
+ }
+
+ // Focus to the editor
+ if (obj.options.focus) {
+ jSuites.editor.setCursor(
+ editor,
+ obj.options.focus == "initial" ? true : false
+ );
+ }
+
+ // Change method
+ el.change = obj.setData;
+
+ // Global generic value handler
+ el.val = function (val) {
+ if (val === undefined) {
+ // Data type
+ var o = el.getAttribute("data-html") === "true" ? false : true;
+ return obj.getData(o);
+ } else {
+ obj.setData(val);
+ }
+ };
+
+ el.editor = obj;
+
+ return obj;
+ };
+
+ jSuites.editor.setCursor = function (element, first) {
+ element.focus();
+ document.execCommand("selectAll");
+ var sel = window.getSelection();
+ var range = sel.getRangeAt(0);
+ if (first == true) {
+ var node = range.startContainer;
+ var size = 0;
+ } else {
+ var node = range.endContainer;
+ var size = node.length;
+ }
+ range.setStart(node, size);
+ range.setEnd(node, size);
+ sel.removeAllRanges();
+ sel.addRange(range);
+ };
+
+ jSuites.editor.getDomain = function (url) {
+ return url
+ .replace("http://", "")
+ .replace("https://", "")
+ .replace("www.", "")
+ .split(/[/?#]/)[0]
+ .split(/:/g)[0];
+ };
+
+ jSuites.editor.detectUrl = function (text) {
+ var expression =
+ /(((https?:\/\/)|(www\.))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]+)/gi;
+ var links = text.match(expression);
+
+ if (links) {
+ if (links[0].substr(0, 3) == "www") {
+ links[0] = "http://" + links[0];
+ }
+ }
+
+ return links;
+ };
+
+ jSuites.editor.youtubeParser = function (url) {
+ var regExp =
+ /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
+ var match = url.match(regExp);
+
+ return match && match[7].length == 11 ? match[7] : false;
+ };
+
+ jSuites.editor.getDefaultToolbar = function () {
+ return [
+ {
+ content: "undo",
+ onclick: function () {
+ document.execCommand("undo");
+ },
+ },
+ {
+ content: "redo",
+ onclick: function () {
+ document.execCommand("redo");
+ },
+ },
+ {
+ type: "divisor",
+ },
+ {
+ content: "format_bold",
+ onclick: function (a, b, c) {
+ document.execCommand("bold");
+
+ if (document.queryCommandState("bold")) {
+ c.classList.add("selected");
+ } else {
+ c.classList.remove("selected");
+ }
+ },
+ },
+ {
+ content: "format_italic",
+ onclick: function (a, b, c) {
+ document.execCommand("italic");
+
+ if (document.queryCommandState("italic")) {
+ c.classList.add("selected");
+ } else {
+ c.classList.remove("selected");
+ }
+ },
+ },
+ {
+ content: "format_underline",
+ onclick: function (a, b, c) {
+ document.execCommand("underline");
+
+ if (document.queryCommandState("underline")) {
+ c.classList.add("selected");
+ } else {
+ c.classList.remove("selected");
+ }
+ },
+ },
+ {
+ type: "divisor",
+ },
+ {
+ content: "format_list_bulleted",
+ onclick: function (a, b, c) {
+ document.execCommand("insertUnorderedList");
+
+ if (document.queryCommandState("insertUnorderedList")) {
+ c.classList.add("selected");
+ } else {
+ c.classList.remove("selected");
+ }
+ },
+ },
+ {
+ content: "format_list_numbered",
+ onclick: function (a, b, c) {
+ document.execCommand("insertOrderedList");
+
+ if (document.queryCommandState("insertOrderedList")) {
+ c.classList.add("selected");
+ } else {
+ c.classList.remove("selected");
+ }
+ },
+ },
+ {
+ content: "format_indent_increase",
+ onclick: function (a, b, c) {
+ document.execCommand("indent", true, null);
+
+ if (document.queryCommandState("indent")) {
+ c.classList.add("selected");
+ } else {
+ c.classList.remove("selected");
+ }
+ },
+ },
+ {
+ content: "format_indent_decrease",
+ onclick: function () {
+ document.execCommand("outdent");
+
+ if (document.queryCommandState("outdent")) {
+ this.classList.add("selected");
+ } else {
+ this.classList.remove("selected");
+ }
+ },
+ } /*,
+ {
+ icon: ['format_align_left', 'format_align_right', 'format_align_center'],
+ onclick: function() {
+ document.execCommand('justifyCenter');
+
+ if (document.queryCommandState("justifyCenter")) {
+ this.classList.add('selected');
+ } else {
+ this.classList.remove('selected');
+ }
+ }
+ }
+ {
+ type:'select',
+ items: ['Verdana','Arial','Courier New'],
+ onchange: function() {
+ }
+ },
+ {
+ type:'select',
+ items: ['10px','12px','14px','16px','18px','20px','22px'],
+ onchange: function() {
+ }
+ },
+ {
+ icon:'format_align_left',
+ onclick: function() {
+ document.execCommand('JustifyLeft');
+
+ if (document.queryCommandState("JustifyLeft")) {
+ this.classList.add('selected');
+ } else {
+ this.classList.remove('selected');
+ }
+ }
+ },
+ {
+ icon:'format_align_center',
+ onclick: function() {
+ document.execCommand('justifyCenter');
+
+ if (document.queryCommandState("justifyCenter")) {
+ this.classList.add('selected');
+ } else {
+ this.classList.remove('selected');
+ }
+ }
+ },
+ {
+ icon:'format_align_right',
+ onclick: function() {
+ document.execCommand('justifyRight');
+
+ if (document.queryCommandState("justifyRight")) {
+ this.classList.add('selected');
+ } else {
+ this.classList.remove('selected');
+ }
+ }
+ },
+ {
+ icon:'format_align_justify',
+ onclick: function() {
+ document.execCommand('justifyFull');
+
+ if (document.queryCommandState("justifyFull")) {
+ this.classList.add('selected');
+ } else {
+ this.classList.remove('selected');
+ }
+ }
+ },
+ {
+ icon:'format_list_bulleted',
+ onclick: function() {
+ document.execCommand('insertUnorderedList');
+
+ if (document.queryCommandState("insertUnorderedList")) {
+ this.classList.add('selected');
+ } else {
+ this.classList.remove('selected');
+ }
+ }
+ }*/,
+ ];
+ };
+
+ jSuites.form = function (el, options) {
+ var obj = {};
+ obj.options = {};
+
+ // Default configuration
+ var defaults = {
+ url: null,
+ message: "Are you sure? There are unsaved information in your form",
+ ignore: false,
+ currentHash: null,
+ submitButton: null,
+ validations: null,
+ onbeforeload: null,
+ onload: null,
+ onbeforesave: null,
+ onsave: null,
+ onbeforeremove: null,
+ onremove: null,
+ onerror: function (el, message) {
+ jSuites.alert(message);
+ },
+ };
+
+ // Loop through our object
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ obj.options[property] = defaults[property];
+ }
+ }
+
+ // Validations
+ if (!obj.options.validations) {
+ obj.options.validations = {};
+ }
+
+ // Submit Button
+ if (!obj.options.submitButton) {
+ obj.options.submitButton = el.querySelector("input[type=submit]");
+ }
+
+ if (obj.options.submitButton && obj.options.url) {
+ obj.options.submitButton.onclick = function () {
+ obj.save();
+ };
+ }
+
+ if (!obj.options.validations.email) {
+ obj.options.validations.email = jSuites.validations.email;
+ }
+
+ if (!obj.options.validations.length) {
+ obj.options.validations.length = jSuites.validations.length;
+ }
+
+ if (!obj.options.validations.required) {
+ obj.options.validations.required = jSuites.validations.required;
+ }
+
+ obj.setUrl = function (url) {
+ obj.options.url = url;
+ };
+
+ obj.load = function () {
+ jSuites.ajax({
+ url: obj.options.url,
+ method: "GET",
+ dataType: "json",
+ queue: true,
+ success: function (data) {
+ // Overwrite values from the backend
+ if (typeof obj.options.onbeforeload == "function") {
+ var ret = obj.options.onbeforeload(el, data);
+ if (ret) {
+ data = ret;
+ }
+ }
+ // Apply values to the form
+ jSuites.form.setElements(el, data);
+ // Onload methods
+ if (typeof obj.options.onload == "function") {
+ obj.options.onload(el, data);
+ }
+ },
+ });
+ };
+
+ obj.save = function () {
+ var test = obj.validate();
+
+ if (test) {
+ obj.options.onerror(el, test);
+ } else {
+ var data = jSuites.form.getElements(el, true);
+
+ if (typeof obj.options.onbeforesave == "function") {
+ var data = obj.options.onbeforesave(el, data);
+
+ if (data === false) {
+ return;
+ }
+ }
+
+ jSuites.ajax({
+ url: obj.options.url,
+ method: "POST",
+ dataType: "json",
+ data: data,
+ success: function (result) {
+ if (typeof obj.options.onsave == "function") {
+ obj.options.onsave(el, data, result);
+ }
+ },
+ });
+ }
+ };
+
+ obj.remove = function () {
+ if (typeof obj.options.onbeforeremove == "function") {
+ var ret = obj.options.onbeforeremove(el, obj);
+ if (ret === false) {
+ return false;
+ }
+ }
+
+ jSuites.ajax({
+ url: obj.options.url,
+ method: "DELETE",
+ dataType: "json",
+ success: function (result) {
+ if (typeof obj.options.onremove == "function") {
+ obj.options.onremove(el, obj, result);
+ }
+
+ obj.reset();
+ },
+ });
+ };
+
+ var addError = function (element) {
+ // Add error in the element
+ element.classList.add("error");
+ // Submit button
+ if (obj.options.submitButton) {
+ obj.options.submitButton.setAttribute("disabled", true);
+ }
+ // Return error message
+ var error =
+ element.getAttribute("data-error") || "There is an error in the form";
+ element.setAttribute("title", error);
+ return error;
+ };
+
+ var delError = function (element) {
+ var error = false;
+ // Remove class from this element
+ element.classList.remove("error");
+ element.removeAttribute("title");
+ // Get elements in the form
+ var elements = el.querySelectorAll("input, select, textarea, div[name]");
+ // Run all elements
+ for (var i = 0; i < elements.length; i++) {
+ if (elements[i].getAttribute("data-validation")) {
+ if (elements[i].classList.contains("error")) {
+ error = true;
+ }
+ }
+ }
+
+ if (obj.options.submitButton) {
+ if (error) {
+ obj.options.submitButton.setAttribute("disabled", true);
+ } else {
+ obj.options.submitButton.removeAttribute("disabled");
+ }
+ }
+ };
+
+ obj.validateElement = function (element) {
+ // Test results
+ var test = false;
+ // Value
+ var value = jSuites.form.getValue(element);
+ // Validation
+ var validation = element.getAttribute("data-validation");
+ // Parse
+ if (
+ typeof obj.options.validations[validation] == "function" &&
+ !obj.options.validations[validation](value, element)
+ ) {
+ // Not passed in the test
+ test = addError(element);
+ } else {
+ if (element.classList.contains("error")) {
+ delError(element);
+ }
+ }
+
+ return test;
+ };
+
+ obj.reset = function () {
+ // Get elements in the form
+ var name = null;
+ var elements = el.querySelectorAll("input, select, textarea, div[name]");
+ // Run all elements
+ for (var i = 0; i < elements.length; i++) {
+ if ((name = elements[i].getAttribute("name"))) {
+ if (elements[i].type == "checkbox" || elements[i].type == "radio") {
+ elements[i].checked = false;
+ } else {
+ if (typeof elements[i].val == "function") {
+ elements[i].val("");
+ } else {
+ elements[i].value = "";
+ }
+ }
+ }
+ }
+ };
+
+ // Run form validation
+ obj.validate = function () {
+ var test = [];
+ // Get elements in the form
+ var elements = el.querySelectorAll("input, select, textarea, div[name]");
+ // Run all elements
+ for (var i = 0; i < elements.length; i++) {
+ // Required
+ if (elements[i].getAttribute("data-validation")) {
+ var res = obj.validateElement(elements[i]);
+ if (res) {
+ test.push(res);
+ }
+ }
+ }
+ if (test.length > 0) {
+ return test.join("
");
+ } else {
+ return false;
+ }
+ };
+
+ // Check the form
+ obj.getError = function () {
+ // Validation
+ return obj.validation() ? true : false;
+ };
+
+ // Return the form hash
+ obj.setHash = function () {
+ return obj.getHash(jSuites.form.getElements(el));
+ };
+
+ // Get the form hash
+ obj.getHash = function (str) {
+ var hash = 0,
+ i,
+ chr;
+
+ if (str.length === 0) {
+ return hash;
+ } else {
+ for (i = 0; i < str.length; i++) {
+ chr = str.charCodeAt(i);
+ hash = (hash << 5) - hash + chr;
+ hash |= 0;
+ }
+ }
+
+ return hash;
+ };
+
+ // Is there any change in the form since start tracking?
+ obj.isChanged = function () {
+ var hash = obj.setHash();
+ return obj.options.currentHash != hash;
+ };
+
+ // Restart tracking
+ obj.resetTracker = function () {
+ obj.options.currentHash = obj.setHash();
+ obj.options.ignore = false;
+ };
+
+ // Ignore flag
+ obj.setIgnore = function (ignoreFlag) {
+ obj.options.ignore = ignoreFlag ? true : false;
+ };
+
+ // Start tracking in one second
+ setTimeout(function () {
+ obj.options.currentHash = obj.setHash();
+ }, 1000);
+
+ // Validations
+ el.addEventListener("keyup", function (e) {
+ if (e.target.getAttribute("data-validation")) {
+ obj.validateElement(e.target);
+ }
+ });
+
+ // Alert
+ if (!jSuites.form.hasEvents) {
+ window.addEventListener("beforeunload", function (e) {
+ if (obj.isChanged() && obj.options.ignore == false) {
+ var confirmationMessage = obj.options.message
+ ? obj.options.message
+ : "o/";
+
+ if (confirmationMessage) {
+ if (typeof e == "undefined") {
+ e = window.event;
+ }
+
+ if (e) {
+ e.returnValue = confirmationMessage;
+ }
+
+ return confirmationMessage;
+ } else {
+ return void 0;
+ }
+ }
+ });
+
+ jSuites.form.hasEvents = true;
+ }
+
+ el.form = obj;
+
+ return obj;
+ };
+
+ // Get value from one element
+ jSuites.form.getValue = function (element) {
+ var value = null;
+ if (element.type == "checkbox") {
+ if (element.checked == true) {
+ value = element.value || true;
+ }
+ } else if (element.type == "radio") {
+ if (element.checked == true) {
+ value = element.value;
+ }
+ } else if (element.type == "file") {
+ value = element.files;
+ } else if (element.tagName == "select" && element.multiple == true) {
+ value = [];
+ var options = element.querySelectorAll("options[selected]");
+ for (var j = 0; j < options.length; j++) {
+ value.push(options[j].value);
+ }
+ } else if (typeof element.val == "function") {
+ value = element.val();
+ } else {
+ value = element.value || "";
+ }
+
+ return value;
+ };
+
+ // Get form elements
+ jSuites.form.getElements = function (el, asArray) {
+ var data = {};
+ var name = null;
+ var elements = el.querySelectorAll("input, select, textarea, div[name]");
+
+ for (var i = 0; i < elements.length; i++) {
+ if ((name = elements[i].getAttribute("name"))) {
+ data[name] = jSuites.form.getValue(elements[i]) || "";
+ }
+ }
+
+ return asArray == true ? data : JSON.stringify(data);
+ };
+
+ //Get form elements
+ jSuites.form.setElements = function (el, data) {
+ var name = null;
+ var value = null;
+ var elements = el.querySelectorAll("input, select, textarea, div[name]");
+ for (var i = 0; i < elements.length; i++) {
+ // Attributes
+ var type = elements[i].getAttribute("type");
+ if ((name = elements[i].getAttribute("name"))) {
+ // Transform variable names in pathname
+ name = name.replace(new RegExp(/\[(.*?)\]/gi), ".$1");
+ value = null;
+ // Seach for the data in the path
+ if (name.match(/\./)) {
+ var tmp = jSuites.path.call(data, name) || "";
+ if (typeof tmp !== "undefined") {
+ value = tmp;
+ }
+ } else {
+ if (typeof data[name] !== "undefined") {
+ value = data[name];
+ }
+ }
+ // Set the values
+ if (value !== null) {
+ if (type == "checkbox" || type == "radio") {
+ elements[i].checked = value ? true : false;
+ } else if (type == "file") {
+ // Do nothing
+ } else {
+ if (typeof elements[i].val == "function") {
+ elements[i].val(value);
+ } else {
+ elements[i].value = value;
+ }
+ }
+ }
+ }
+ }
+ };
+
+ // Legacy
+ jSuites.tracker = jSuites.form;
+
+ jSuites.focus = function (el) {
+ if (el.innerText.length) {
+ var range = document.createRange();
+ var sel = window.getSelection();
+ var node = el.childNodes[el.childNodes.length - 1];
+ range.setStart(node, node.length);
+ range.collapse(true);
+ sel.removeAllRanges();
+ sel.addRange(range);
+ el.scrollLeft = el.scrollWidth;
+ }
+ };
+
+ jSuites.isNumeric = function (num) {
+ if (typeof num === "string") {
+ num = num.trim();
+ }
+ return !isNaN(num) && num !== null && num !== "";
+ };
+
+ jSuites.guid = function () {
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
+ /[xy]/g,
+ function (c) {
+ var r = (Math.random() * 16) | 0,
+ v = c == "x" ? r : (r & 0x3) | 0x8;
+ return v.toString(16);
+ }
+ );
+ };
+
+ jSuites.getNode = function () {
+ var node = document.getSelection().anchorNode;
+ if (node) {
+ return node.nodeType == 3 ? node.parentNode : node;
+ } else {
+ return null;
+ }
+ };
+ /**
+ * Generate hash from a string
+ */
+ jSuites.hash = function (str) {
+ var hash = 0,
+ i,
+ chr;
+
+ if (str.length === 0) {
+ return hash;
+ } else {
+ for (i = 0; i < str.length; i++) {
+ chr = str.charCodeAt(i);
+ if (chr > 32) {
+ hash = (hash << 5) - hash + chr;
+ hash |= 0;
+ }
+ }
+ }
+ return hash;
+ };
+
+ /**
+ * Generate a random color
+ */
+ jSuites.randomColor = function (h) {
+ var lum = -0.25;
+ var hex = String(
+ "#" + Math.random().toString(16).slice(2, 8).toUpperCase()
+ ).replace(/[^0-9a-f]/gi, "");
+ if (hex.length < 6) {
+ hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
+ }
+ var rgb = [],
+ c,
+ i;
+ for (i = 0; i < 3; i++) {
+ c = parseInt(hex.substr(i * 2, 2), 16);
+ c = Math.round(Math.min(Math.max(0, c + c * lum), 255)).toString(16);
+ rgb.push(("00" + c).substr(c.length));
+ }
+
+ // Return hex
+ if (h == true) {
+ return (
+ "#" +
+ jSuites.two(rgb[0].toString(16)) +
+ jSuites.two(rgb[1].toString(16)) +
+ jSuites.two(rgb[2].toString(16))
+ );
+ }
+
+ return rgb;
+ };
+
+ jSuites.getWindowWidth = function () {
+ var w = window,
+ d = document,
+ e = d.documentElement,
+ g = d.getElementsByTagName("body")[0],
+ x = w.innerWidth || e.clientWidth || g.clientWidth;
+ return x;
+ };
+
+ jSuites.getWindowHeight = function () {
+ var w = window,
+ d = document,
+ e = d.documentElement,
+ g = d.getElementsByTagName("body")[0],
+ y = w.innerHeight || e.clientHeight || g.clientHeight;
+ return y;
+ };
+
+ jSuites.getPosition = function (e) {
+ if (e.changedTouches && e.changedTouches[0]) {
+ var x = e.changedTouches[0].pageX;
+ var y = e.changedTouches[0].pageY;
+ } else {
+ var x = window.Event
+ ? e.pageX
+ : e.clientX +
+ (document.documentElement.scrollLeft
+ ? document.documentElement.scrollLeft
+ : document.body.scrollLeft);
+ var y = window.Event
+ ? e.pageY
+ : e.clientY +
+ (document.documentElement.scrollTop
+ ? document.documentElement.scrollTop
+ : document.body.scrollTop);
+ }
+
+ return [x, y];
+ };
+
+ jSuites.click = function (el) {
+ if (el.click) {
+ el.click();
+ } else {
+ var evt = new MouseEvent("click", {
+ bubbles: true,
+ cancelable: true,
+ view: window,
+ });
+ el.dispatchEvent(evt);
+ }
+ };
+
+ jSuites.findElement = function (element, condition) {
+ var foundElement = false;
+
+ function path(element) {
+ if (element && !foundElement) {
+ if (typeof condition == "function") {
+ foundElement = condition(element);
+ } else if (typeof condition == "string") {
+ if (element.classList && element.classList.contains(condition)) {
+ foundElement = element;
+ }
+ }
+ }
+
+ if (element.parentNode && !foundElement) {
+ path(element.parentNode);
+ }
+ }
+
+ path(element);
+
+ return foundElement;
+ };
+
+ // Two digits
+ jSuites.two = function (value) {
+ value = "" + value;
+ if (value.length == 1) {
+ value = "0" + value;
+ }
+ return value;
+ };
+
+ jSuites.sha512 = function (str) {
+ function int64(msint_32, lsint_32) {
+ this.highOrder = msint_32;
+ this.lowOrder = lsint_32;
+ }
+
+ var H = [
+ new int64(0x6a09e667, 0xf3bcc908),
+ new int64(0xbb67ae85, 0x84caa73b),
+ new int64(0x3c6ef372, 0xfe94f82b),
+ new int64(0xa54ff53a, 0x5f1d36f1),
+ new int64(0x510e527f, 0xade682d1),
+ new int64(0x9b05688c, 0x2b3e6c1f),
+ new int64(0x1f83d9ab, 0xfb41bd6b),
+ new int64(0x5be0cd19, 0x137e2179),
+ ];
+
+ var K = [
+ new int64(0x428a2f98, 0xd728ae22),
+ new int64(0x71374491, 0x23ef65cd),
+ new int64(0xb5c0fbcf, 0xec4d3b2f),
+ new int64(0xe9b5dba5, 0x8189dbbc),
+ new int64(0x3956c25b, 0xf348b538),
+ new int64(0x59f111f1, 0xb605d019),
+ new int64(0x923f82a4, 0xaf194f9b),
+ new int64(0xab1c5ed5, 0xda6d8118),
+ new int64(0xd807aa98, 0xa3030242),
+ new int64(0x12835b01, 0x45706fbe),
+ new int64(0x243185be, 0x4ee4b28c),
+ new int64(0x550c7dc3, 0xd5ffb4e2),
+ new int64(0x72be5d74, 0xf27b896f),
+ new int64(0x80deb1fe, 0x3b1696b1),
+ new int64(0x9bdc06a7, 0x25c71235),
+ new int64(0xc19bf174, 0xcf692694),
+ new int64(0xe49b69c1, 0x9ef14ad2),
+ new int64(0xefbe4786, 0x384f25e3),
+ new int64(0x0fc19dc6, 0x8b8cd5b5),
+ new int64(0x240ca1cc, 0x77ac9c65),
+ new int64(0x2de92c6f, 0x592b0275),
+ new int64(0x4a7484aa, 0x6ea6e483),
+ new int64(0x5cb0a9dc, 0xbd41fbd4),
+ new int64(0x76f988da, 0x831153b5),
+ new int64(0x983e5152, 0xee66dfab),
+ new int64(0xa831c66d, 0x2db43210),
+ new int64(0xb00327c8, 0x98fb213f),
+ new int64(0xbf597fc7, 0xbeef0ee4),
+ new int64(0xc6e00bf3, 0x3da88fc2),
+ new int64(0xd5a79147, 0x930aa725),
+ new int64(0x06ca6351, 0xe003826f),
+ new int64(0x14292967, 0x0a0e6e70),
+ new int64(0x27b70a85, 0x46d22ffc),
+ new int64(0x2e1b2138, 0x5c26c926),
+ new int64(0x4d2c6dfc, 0x5ac42aed),
+ new int64(0x53380d13, 0x9d95b3df),
+ new int64(0x650a7354, 0x8baf63de),
+ new int64(0x766a0abb, 0x3c77b2a8),
+ new int64(0x81c2c92e, 0x47edaee6),
+ new int64(0x92722c85, 0x1482353b),
+ new int64(0xa2bfe8a1, 0x4cf10364),
+ new int64(0xa81a664b, 0xbc423001),
+ new int64(0xc24b8b70, 0xd0f89791),
+ new int64(0xc76c51a3, 0x0654be30),
+ new int64(0xd192e819, 0xd6ef5218),
+ new int64(0xd6990624, 0x5565a910),
+ new int64(0xf40e3585, 0x5771202a),
+ new int64(0x106aa070, 0x32bbd1b8),
+ new int64(0x19a4c116, 0xb8d2d0c8),
+ new int64(0x1e376c08, 0x5141ab53),
+ new int64(0x2748774c, 0xdf8eeb99),
+ new int64(0x34b0bcb5, 0xe19b48a8),
+ new int64(0x391c0cb3, 0xc5c95a63),
+ new int64(0x4ed8aa4a, 0xe3418acb),
+ new int64(0x5b9cca4f, 0x7763e373),
+ new int64(0x682e6ff3, 0xd6b2b8a3),
+ new int64(0x748f82ee, 0x5defb2fc),
+ new int64(0x78a5636f, 0x43172f60),
+ new int64(0x84c87814, 0xa1f0ab72),
+ new int64(0x8cc70208, 0x1a6439ec),
+ new int64(0x90befffa, 0x23631e28),
+ new int64(0xa4506ceb, 0xde82bde9),
+ new int64(0xbef9a3f7, 0xb2c67915),
+ new int64(0xc67178f2, 0xe372532b),
+ new int64(0xca273ece, 0xea26619c),
+ new int64(0xd186b8c7, 0x21c0c207),
+ new int64(0xeada7dd6, 0xcde0eb1e),
+ new int64(0xf57d4f7f, 0xee6ed178),
+ new int64(0x06f067aa, 0x72176fba),
+ new int64(0x0a637dc5, 0xa2c898a6),
+ new int64(0x113f9804, 0xbef90dae),
+ new int64(0x1b710b35, 0x131c471b),
+ new int64(0x28db77f5, 0x23047d84),
+ new int64(0x32caab7b, 0x40c72493),
+ new int64(0x3c9ebe0a, 0x15c9bebc),
+ new int64(0x431d67c4, 0x9c100d4c),
+ new int64(0x4cc5d4be, 0xcb3e42b6),
+ new int64(0x597f299c, 0xfc657e2a),
+ new int64(0x5fcb6fab, 0x3ad6faec),
+ new int64(0x6c44198c, 0x4a475817),
+ ];
+
+ var W = new Array(64);
+ var a, b, c, d, e, f, g, h, i, j;
+ var T1, T2;
+ var charsize = 8;
+
+ function utf8_encode(str) {
+ return unescape(encodeURIComponent(str));
+ }
+
+ function str2binb(str) {
+ var bin = [];
+ var mask = (1 << charsize) - 1;
+ var len = str.length * charsize;
+
+ for (var i = 0; i < len; i += charsize) {
+ bin[i >> 5] |=
+ (str.charCodeAt(i / charsize) & mask) << (32 - charsize - (i % 32));
+ }
+
+ return bin;
+ }
+
+ function binb2hex(binarray) {
+ var hex_tab = "0123456789abcdef";
+ var str = "";
+ var length = binarray.length * 4;
+ var srcByte;
+
+ for (var i = 0; i < length; i += 1) {
+ srcByte = binarray[i >> 2] >> ((3 - (i % 4)) * 8);
+ str +=
+ hex_tab.charAt((srcByte >> 4) & 0xf) + hex_tab.charAt(srcByte & 0xf);
+ }
+
+ return str;
+ }
+
+ function safe_add_2(x, y) {
+ var lsw, msw, lowOrder, highOrder;
+
+ lsw = (x.lowOrder & 0xffff) + (y.lowOrder & 0xffff);
+ msw = (x.lowOrder >>> 16) + (y.lowOrder >>> 16) + (lsw >>> 16);
+ lowOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
+
+ lsw = (x.highOrder & 0xffff) + (y.highOrder & 0xffff) + (msw >>> 16);
+ msw = (x.highOrder >>> 16) + (y.highOrder >>> 16) + (lsw >>> 16);
+ highOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
+
+ return new int64(highOrder, lowOrder);
+ }
+
+ function safe_add_4(a, b, c, d) {
+ var lsw, msw, lowOrder, highOrder;
+
+ lsw =
+ (a.lowOrder & 0xffff) +
+ (b.lowOrder & 0xffff) +
+ (c.lowOrder & 0xffff) +
+ (d.lowOrder & 0xffff);
+ msw =
+ (a.lowOrder >>> 16) +
+ (b.lowOrder >>> 16) +
+ (c.lowOrder >>> 16) +
+ (d.lowOrder >>> 16) +
+ (lsw >>> 16);
+ lowOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
+
+ lsw =
+ (a.highOrder & 0xffff) +
+ (b.highOrder & 0xffff) +
+ (c.highOrder & 0xffff) +
+ (d.highOrder & 0xffff) +
+ (msw >>> 16);
+ msw =
+ (a.highOrder >>> 16) +
+ (b.highOrder >>> 16) +
+ (c.highOrder >>> 16) +
+ (d.highOrder >>> 16) +
+ (lsw >>> 16);
+ highOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
+
+ return new int64(highOrder, lowOrder);
+ }
+
+ function safe_add_5(a, b, c, d, e) {
+ var lsw, msw, lowOrder, highOrder;
+
+ lsw =
+ (a.lowOrder & 0xffff) +
+ (b.lowOrder & 0xffff) +
+ (c.lowOrder & 0xffff) +
+ (d.lowOrder & 0xffff) +
+ (e.lowOrder & 0xffff);
+ msw =
+ (a.lowOrder >>> 16) +
+ (b.lowOrder >>> 16) +
+ (c.lowOrder >>> 16) +
+ (d.lowOrder >>> 16) +
+ (e.lowOrder >>> 16) +
+ (lsw >>> 16);
+ lowOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
+
+ lsw =
+ (a.highOrder & 0xffff) +
+ (b.highOrder & 0xffff) +
+ (c.highOrder & 0xffff) +
+ (d.highOrder & 0xffff) +
+ (e.highOrder & 0xffff) +
+ (msw >>> 16);
+ msw =
+ (a.highOrder >>> 16) +
+ (b.highOrder >>> 16) +
+ (c.highOrder >>> 16) +
+ (d.highOrder >>> 16) +
+ (e.highOrder >>> 16) +
+ (lsw >>> 16);
+ highOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
+
+ return new int64(highOrder, lowOrder);
+ }
+
+ function maj(x, y, z) {
+ return new int64(
+ (x.highOrder & y.highOrder) ^
+ (x.highOrder & z.highOrder) ^
+ (y.highOrder & z.highOrder),
+ (x.lowOrder & y.lowOrder) ^
+ (x.lowOrder & z.lowOrder) ^
+ (y.lowOrder & z.lowOrder)
+ );
+ }
+
+ function ch(x, y, z) {
+ return new int64(
+ (x.highOrder & y.highOrder) ^ (~x.highOrder & z.highOrder),
+ (x.lowOrder & y.lowOrder) ^ (~x.lowOrder & z.lowOrder)
+ );
+ }
+
+ function rotr(x, n) {
+ if (n <= 32) {
+ return new int64(
+ (x.highOrder >>> n) | (x.lowOrder << (32 - n)),
+ (x.lowOrder >>> n) | (x.highOrder << (32 - n))
+ );
+ } else {
+ return new int64(
+ (x.lowOrder >>> n) | (x.highOrder << (32 - n)),
+ (x.highOrder >>> n) | (x.lowOrder << (32 - n))
+ );
+ }
+ }
+
+ function sigma0(x) {
+ var rotr28 = rotr(x, 28);
+ var rotr34 = rotr(x, 34);
+ var rotr39 = rotr(x, 39);
+
+ return new int64(
+ rotr28.highOrder ^ rotr34.highOrder ^ rotr39.highOrder,
+ rotr28.lowOrder ^ rotr34.lowOrder ^ rotr39.lowOrder
+ );
+ }
+
+ function sigma1(x) {
+ var rotr14 = rotr(x, 14);
+ var rotr18 = rotr(x, 18);
+ var rotr41 = rotr(x, 41);
+
+ return new int64(
+ rotr14.highOrder ^ rotr18.highOrder ^ rotr41.highOrder,
+ rotr14.lowOrder ^ rotr18.lowOrder ^ rotr41.lowOrder
+ );
+ }
+
+ function gamma0(x) {
+ var rotr1 = rotr(x, 1),
+ rotr8 = rotr(x, 8),
+ shr7 = shr(x, 7);
+
+ return new int64(
+ rotr1.highOrder ^ rotr8.highOrder ^ shr7.highOrder,
+ rotr1.lowOrder ^ rotr8.lowOrder ^ shr7.lowOrder
+ );
+ }
+
+ function gamma1(x) {
+ var rotr19 = rotr(x, 19);
+ var rotr61 = rotr(x, 61);
+ var shr6 = shr(x, 6);
+
+ return new int64(
+ rotr19.highOrder ^ rotr61.highOrder ^ shr6.highOrder,
+ rotr19.lowOrder ^ rotr61.lowOrder ^ shr6.lowOrder
+ );
+ }
+
+ function shr(x, n) {
+ if (n <= 32) {
+ return new int64(
+ x.highOrder >>> n,
+ (x.lowOrder >>> n) | (x.highOrder << (32 - n))
+ );
+ } else {
+ return new int64(0, x.highOrder << (32 - n));
+ }
+ }
+
+ var str = utf8_encode(str);
+ var strlen = str.length * charsize;
+ str = str2binb(str);
+
+ str[strlen >> 5] |= 0x80 << (24 - (strlen % 32));
+ str[(((strlen + 128) >> 10) << 5) + 31] = strlen;
+
+ for (var i = 0; i < str.length; i += 32) {
+ a = H[0];
+ b = H[1];
+ c = H[2];
+ d = H[3];
+ e = H[4];
+ f = H[5];
+ g = H[6];
+ h = H[7];
+
+ for (var j = 0; j < 80; j++) {
+ if (j < 16) {
+ W[j] = new int64(str[j * 2 + i], str[j * 2 + i + 1]);
+ } else {
+ W[j] = safe_add_4(
+ gamma1(W[j - 2]),
+ W[j - 7],
+ gamma0(W[j - 15]),
+ W[j - 16]
+ );
+ }
+
+ T1 = safe_add_5(h, sigma1(e), ch(e, f, g), K[j], W[j]);
+ T2 = safe_add_2(sigma0(a), maj(a, b, c));
+ h = g;
+ g = f;
+ f = e;
+ e = safe_add_2(d, T1);
+ d = c;
+ c = b;
+ b = a;
+ a = safe_add_2(T1, T2);
+ }
+
+ H[0] = safe_add_2(a, H[0]);
+ H[1] = safe_add_2(b, H[1]);
+ H[2] = safe_add_2(c, H[2]);
+ H[3] = safe_add_2(d, H[3]);
+ H[4] = safe_add_2(e, H[4]);
+ H[5] = safe_add_2(f, H[5]);
+ H[6] = safe_add_2(g, H[6]);
+ H[7] = safe_add_2(h, H[7]);
+ }
+
+ var binarray = [];
+ for (var i = 0; i < H.length; i++) {
+ binarray.push(H[i].highOrder);
+ binarray.push(H[i].lowOrder);
+ }
+
+ return binb2hex(binarray);
+ };
+
+ if (!jSuites.login) {
+ jSuites.login = {};
+ jSuites.login.sha512 = jSuites.sha512;
+ }
+
+ jSuites.image = jSuites.upload = function (el, options) {
+ var obj = {};
+ obj.options = {};
+
+ // Default configuration
+ var defaults = {
+ type: "image",
+ extension: "*",
+ input: false,
+ minWidth: false,
+ maxWidth: null,
+ maxHeight: null,
+ maxJpegSizeBytes: null, // For example, 350Kb would be 350000
+ onchange: null,
+ multiple: false,
+ remoteParser: null,
+ text: {
+ extensionNotAllowed: "The extension is not allowed",
+ },
+ };
+
+ // Loop through our object
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ obj.options[property] = defaults[property];
+ }
+ }
+
+ // Multiple
+ if (obj.options.multiple == true) {
+ el.setAttribute("data-multiple", true);
+ }
+
+ // Container
+ el.content = [];
+
+ // Upload icon
+ el.classList.add("jupload");
+
+ if (obj.options.input == true) {
+ el.classList.add("input");
+ }
+
+ obj.add = function (data) {
+ // Reset container for single files
+ if (obj.options.multiple == false) {
+ el.content = [];
+ el.innerText = "";
+ }
+
+ // Append to the element
+ if (obj.options.type == "image") {
+ var img = document.createElement("img");
+ img.setAttribute("src", data.file);
+ img.setAttribute("tabindex", -1);
+ if (!el.getAttribute("name")) {
+ img.className = "jfile";
+ img.content = data;
+ }
+ el.appendChild(img);
+ } else {
+ if (data.name) {
+ var name = data.name;
+ } else {
+ var name = data.file;
+ }
+ var div = document.createElement("div");
+ div.innerText = name || obj.options.type;
+ div.classList.add("jupload-item");
+ div.setAttribute("tabindex", -1);
+ el.appendChild(div);
+ }
+
+ if (data.content) {
+ data.file = jSuites.guid();
+ }
+
+ // Push content
+ el.content.push(data);
+
+ // Onchange
+ if (typeof obj.options.onchange == "function") {
+ obj.options.onchange(el, data);
+ }
+ };
+
+ obj.addFromFile = function (file) {
+ var type = file.type.split("/");
+ if (type[0] == obj.options.type) {
+ var readFile = new FileReader();
+ readFile.addEventListener("load", function (v) {
+ var data = {
+ file: v.srcElement.result,
+ extension: file.name.substr(file.name.lastIndexOf(".") + 1),
+ name: file.name,
+ size: file.size,
+ lastmodified: file.lastModified,
+ content: v.srcElement.result,
+ };
+
+ obj.add(data);
+ });
+
+ readFile.readAsDataURL(file);
+ } else {
+ alert(obj.options.text.extensionNotAllowed);
+ }
+ };
+
+ obj.addFromUrl = function (src) {
+ if (src.substr(0, 4) != "data" && !obj.options.remoteParser) {
+ console.error("remoteParser not defined in your initialization");
+ } else {
+ // This is to process cross domain images
+ if (src.substr(0, 4) == "data") {
+ var extension = src.split(";");
+ extension = extension[0].split("/");
+ var type = extension[0].replace("data:", "");
+ if (type == obj.options.type) {
+ var data = {
+ file: src,
+ name: "",
+ extension: extension[1],
+ content: src,
+ };
+ obj.add(data);
+ } else {
+ alert(obj.options.text.extensionNotAllowed);
+ }
+ } else {
+ var extension = src.substr(src.lastIndexOf(".") + 1);
+ // Work for cross browsers
+ src = obj.options.remoteParser + src;
+ // Get remove content
+ jSuites.ajax({
+ url: src,
+ type: "GET",
+ dataType: "blob",
+ success: function (data) {
+ //add(extension[0].replace('data:',''), data);
+ },
+ });
+ }
+ }
+ };
+
+ var getDataURL = function (canvas, type) {
+ var compression = 0.92;
+ var lastContentLength = null;
+ var content = canvas.toDataURL(type, compression);
+ while (
+ obj.options.maxJpegSizeBytes &&
+ type === "image/jpeg" &&
+ content.length > obj.options.maxJpegSizeBytes &&
+ content.length !== lastContentLength
+ ) {
+ // Apply the compression
+ compression *= 0.9;
+ lastContentLength = content.length;
+ content = canvas.toDataURL(type, compression);
+ }
+ return content;
+ };
+
+ var mime = obj.options.type + "/" + obj.options.extension;
+ var input = document.createElement("input");
+ input.type = "file";
+ input.setAttribute("accept", mime);
+ input.onchange = function () {
+ for (var i = 0; i < this.files.length; i++) {
+ obj.addFromFile(this.files[i]);
+ }
+ };
+
+ // Allow multiple files
+ if (obj.options.multiple == true) {
+ input.setAttribute("multiple", true);
+ }
+
+ var current = null;
+
+ el.addEventListener("click", function (e) {
+ current = null;
+ if (!el.children.length || e.target === el) {
+ jSuites.click(input);
+ } else {
+ if (e.target.parentNode == el) {
+ current = e.target;
+ }
+ }
+ });
+
+ el.addEventListener("dblclick", function (e) {
+ jSuites.click(input);
+ });
+
+ el.addEventListener("dragenter", function (e) {
+ el.style.border = "1px dashed #000";
+ });
+
+ el.addEventListener("dragleave", function (e) {
+ el.style.border = "1px solid #eee";
+ });
+
+ el.addEventListener("dragstop", function (e) {
+ el.style.border = "1px solid #eee";
+ });
+
+ el.addEventListener("dragover", function (e) {
+ e.preventDefault();
+ });
+
+ el.addEventListener("keydown", function (e) {
+ if (current && e.which == 46) {
+ var index = Array.prototype.indexOf.call(el.children, current);
+ if (index >= 0) {
+ el.content.splice(index, 1);
+ current.remove();
+ current = null;
+ }
+ }
+ });
+
+ el.addEventListener("drop", function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ var html = (e.originalEvent || e).dataTransfer.getData("text/html");
+ var file = (e.originalEvent || e).dataTransfer.files;
+
+ if (file.length) {
+ for (var i = 0; i < e.dataTransfer.files.length; i++) {
+ obj.addFromFile(e.dataTransfer.files[i]);
+ }
+ } else if (html) {
+ if (obj.options.multiple == false) {
+ el.innerText = "";
+ }
+
+ // Create temp element
+ var div = document.createElement("div");
+ div.innerHTML = html;
+
+ // Extract images
+ var img = div.querySelectorAll("img");
+
+ if (img.length) {
+ for (var i = 0; i < img.length; i++) {
+ obj.addFromUrl(img[i].src);
+ }
+ }
+ }
+
+ el.style.border = "1px solid #eee";
+
+ return false;
+ });
+
+ el.val = function (val) {
+ if (val === undefined) {
+ return el.content && el.content.length ? el.content : null;
+ } else {
+ // Reset
+ el.innerText = "";
+ el.content = [];
+
+ if (val) {
+ if (Array.isArray(val)) {
+ for (var i = 0; i < val.length; i++) {
+ if (typeof val[i] == "string") {
+ obj.add({ file: val[i] });
+ } else {
+ obj.add(val[i]);
+ }
+ }
+ } else if (typeof val == "string") {
+ obj.add({ file: val });
+ }
+ }
+ }
+ };
+
+ el.upload = el.image = obj;
+
+ return obj;
+ };
+
+ jSuites.image.create = function (data) {
+ var img = document.createElement("img");
+ img.setAttribute("src", data.file);
+ img.className = "jfile";
+ img.setAttribute("tabindex", -1);
+ img.content = data;
+
+ return img;
+ };
+
+ jSuites.lazyLoading = function (el, options) {
+ var obj = {};
+
+ // Mandatory options
+ if (!options.loadUp || typeof options.loadUp != "function") {
+ options.loadUp = function () {
+ return false;
+ };
+ }
+ if (!options.loadDown || typeof options.loadDown != "function") {
+ options.loadDown = function () {
+ return false;
+ };
+ }
+ // Timer ms
+ if (!options.timer) {
+ options.timer = 100;
+ }
+
+ // Timer
+ var timeControlLoading = null;
+
+ // Controls
+ var scrollControls = function (e) {
+ if (timeControlLoading == null) {
+ var event = false;
+ var scrollTop = el.scrollTop;
+ if (el.scrollTop + el.clientHeight * 2 >= el.scrollHeight) {
+ if (options.loadDown()) {
+ if (scrollTop == el.scrollTop) {
+ el.scrollTop = el.scrollTop - el.clientHeight;
+ }
+ event = true;
+ }
+ } else if (el.scrollTop <= el.clientHeight) {
+ if (options.loadUp()) {
+ if (scrollTop == el.scrollTop) {
+ el.scrollTop = el.scrollTop + el.clientHeight;
+ }
+ event = true;
+ }
+ }
+
+ timeControlLoading = setTimeout(function () {
+ timeControlLoading = null;
+ }, options.timer);
+
+ if (event) {
+ if (typeof options.onupdate == "function") {
+ options.onupdate();
+ }
+ }
+ }
+ };
+
+ // Onscroll
+ el.onscroll = function (e) {
+ scrollControls(e);
+ };
+
+ el.onwheel = function (e) {
+ scrollControls(e);
+ };
+
+ return obj;
+ };
+
+ jSuites.loading = (function () {
+ var obj = {};
+
+ var loading = null;
+
+ obj.show = function () {
+ if (!loading) {
+ loading = document.createElement("div");
+ loading.className = "jloading";
+ }
+ document.body.appendChild(loading);
+ };
+
+ obj.hide = function () {
+ if (loading && loading.parentNode) {
+ document.body.removeChild(loading);
+ }
+ };
+
+ return obj;
+ })();
+
+ jSuites.mask = (function () {
+ // Currency
+ var tokens = {
+ // Text
+ text: ["@"],
+ // Currency tokens
+ currency: ["#(.{1})##0?(.{1}0+)?( ?;(.*)?)?", "#"],
+ // Percentage
+ percentage: ["0{1}(.{1}0+)?%"],
+ // Number
+ numeric: ["0{1}(.{1}0+)?"],
+ // Data tokens
+ datetime: [
+ "YYYY",
+ "YYY",
+ "YY",
+ "MMMMM",
+ "MMMM",
+ "MMM",
+ "MM",
+ "DDDDD",
+ "DDDD",
+ "DDD",
+ "DD",
+ "DY",
+ "DAY",
+ "WD",
+ "D",
+ "Q",
+ "HH24",
+ "HH12",
+ "HH",
+ "\\[H\\]",
+ "H",
+ "AM/PM",
+ "PM",
+ "AM",
+ "MI",
+ "SS",
+ "MS",
+ "MONTH",
+ "MON",
+ "Y",
+ "M",
+ ],
+ // Other
+ general: ["A", "0", "[0-9a-zA-Z$]+", "."],
+ };
+
+ var getDate = function () {
+ if (this.mask.toLowerCase().indexOf("[h]") !== -1) {
+ var m = 0;
+ if (this.date[4]) {
+ m = parseFloat(this.date[4] / 60);
+ }
+ var v = parseInt(this.date[3]) + m;
+ v /= 24;
+ } else if (
+ !(this.date[0] && this.date[1] && this.date[2]) &&
+ (this.date[3] || this.date[4])
+ ) {
+ v =
+ jSuites.two(this.date[3]) +
+ ":" +
+ jSuites.two(this.date[4]) +
+ ":" +
+ jSuites.two(this.date[5]);
+ } else {
+ if (this.date[0] && this.date[1] && !this.date[2]) {
+ this.date[2] = 1;
+ }
+ v =
+ jSuites.two(this.date[0]) +
+ "-" +
+ jSuites.two(this.date[1]) +
+ "-" +
+ jSuites.two(this.date[2]);
+
+ if (this.date[3] || this.date[4] || this.date[5]) {
+ v +=
+ " " +
+ jSuites.two(this.date[3]) +
+ ":" +
+ jSuites.two(this.date[4]) +
+ ":" +
+ jSuites.two(this.date[5]);
+ }
+ }
+
+ return v;
+ };
+
+ var isBlank = function (v) {
+ return v === null || v === "" || v === undefined ? true : false;
+ };
+
+ var isFormula = function (value) {
+ return ("" + value).chartAt(0) == "=";
+ };
+
+ var isNumeric = function (t) {
+ return t === "currency" || t === "percentage" || t === "numeric"
+ ? true
+ : false;
+ };
+ /**
+ * Get the decimal defined in the mask configuration
+ */
+ var getDecimal = function (v) {
+ if (v && Number(v) == v) {
+ return ".";
+ } else {
+ if (this.options.decimal) {
+ return this.options.decimal;
+ } else {
+ if (this.locale) {
+ var t = Intl.NumberFormat(this.locale).format(1.1);
+ return (this.options.decimal = t[1]);
+ } else {
+ if (!v) {
+ v = this.mask;
+ }
+ var e = new RegExp("0{1}(.{1})0+", "ig");
+ var t = e.exec(v);
+ if (t && t[1] && t[1].length == 1) {
+ // Save decimal
+ this.options.decimal = t[1];
+ // Return decimal
+ return t[1];
+ } else {
+ // Did not find any decimal last resort the default
+ var e = new RegExp("#{1}(.{1})#+", "ig");
+ var t = e.exec(v);
+ if (t && t[1] && t[1].length == 1) {
+ if (t[1] === ",") {
+ this.options.decimal = ".";
+ } else {
+ this.options.decimal = ",";
+ }
+ } else {
+ this.options.decimal = "1.1".toLocaleString().substring(1, 2);
+ }
+ }
+ }
+ }
+ }
+
+ if (this.options.decimal) {
+ return this.options.decimal;
+ } else {
+ return null;
+ }
+ };
+
+ var ParseValue = function (v, decimal) {
+ if (v == "") {
+ return "";
+ }
+
+ // Get decimal
+ if (!decimal) {
+ decimal = getDecimal.call(this);
+ }
+
+ // New value
+ v = ("" + v).split(decimal);
+
+ // Signal
+ var signal = v[0].match(/[-]+/g);
+ if (signal && signal.length) {
+ signal = true;
+ } else {
+ signal = false;
+ }
+
+ v[0] = v[0].match(/[0-9]+/g);
+
+ if (v[0]) {
+ if (signal) {
+ v[0].unshift("-");
+ }
+ v[0] = v[0].join("");
+ } else {
+ if (signal) {
+ v[0] = "-";
+ }
+ }
+
+ if (v[0] || v[1]) {
+ if (v[1] !== undefined) {
+ v[1] = v[1].match(/[0-9]+/g);
+ if (v[1]) {
+ v[1] = v[1].join("");
+ } else {
+ v[1] = "";
+ }
+ }
+ } else {
+ return "";
+ }
+ return v;
+ };
+
+ var FormatValue = function (v, event) {
+ if (v == "") {
+ return "";
+ }
+ // Get decimal
+ var d = getDecimal.call(this);
+ // Convert value
+ var o = this.options;
+ // Parse value
+ v = ParseValue.call(this, v);
+ if (v == "") {
+ return "";
+ }
+ // Temporary value
+ if (v[0]) {
+ var t = parseFloat(v[0] + ".1");
+ if (o.style == "percent") {
+ t /= 100;
+ }
+ } else {
+ var t = null;
+ }
+
+ if (
+ (v[0] == "-" || v[0] == "-00") &&
+ !v[1] &&
+ event &&
+ event.inputType == "deleteContentBackward"
+ ) {
+ return "";
+ }
+
+ var n = new Intl.NumberFormat(this.locale, o).format(t);
+ n = n.split(d);
+ if (typeof n[1] !== "undefined") {
+ var s = n[1].replace(/[0-9]*/g, "");
+ if (s) {
+ n[2] = s;
+ }
+ }
+
+ if (v[1] !== undefined) {
+ n[1] = d + v[1];
+ } else {
+ n[1] = "";
+ }
+
+ return n.join("");
+ };
+
+ var Format = function (e, event) {
+ var v = Value.call(e);
+ if (!v) {
+ return;
+ }
+
+ // Get decimal
+ var d = getDecimal.call(this);
+ var n = FormatValue.call(this, v, event);
+ var t = n.length - v.length;
+ var index = Caret.call(e) + t;
+ // Set value and update caret
+ Value.call(e, n, index, true);
+ };
+
+ var Extract = function (v) {
+ // Keep the raw value
+ var current = ParseValue.call(this, v);
+ if (current) {
+ // Negative values
+ if (current[0] === "-") {
+ current[0] = "-0";
+ }
+ return parseFloat(current.join("."));
+ }
+ return null;
+ };
+
+ /**
+ * Caret getter and setter methods
+ */
+ var Caret = function (index, adjustNumeric) {
+ if (index === undefined) {
+ if (this.tagName == "DIV") {
+ var pos = 0;
+ var s = window.getSelection();
+ if (s) {
+ if (s.rangeCount !== 0) {
+ var r = s.getRangeAt(0);
+ var p = r.cloneRange();
+ p.selectNodeContents(this);
+ p.setEnd(r.endContainer, r.endOffset);
+ pos = p.toString().length;
+ }
+ }
+ return pos;
+ } else {
+ return this.selectionStart;
+ }
+ } else {
+ // Get the current value
+ var n = Value.call(this);
+
+ // Review the position
+ if (adjustNumeric) {
+ var p = null;
+ for (var i = 0; i < n.length; i++) {
+ if (n[i].match(/[\-0-9]/g) || n[i] == "." || n[i] == ",") {
+ p = i;
+ }
+ }
+
+ // If the string has no numbers
+ if (p === null) {
+ p = n.indexOf(" ");
+ }
+
+ if (index >= p) {
+ index = p + 1;
+ }
+ }
+
+ // Do not update caret
+ if (index > n.length) {
+ index = n.length;
+ }
+
+ if (index) {
+ // Set caret
+ if (this.tagName == "DIV") {
+ var s = window.getSelection();
+ var r = document.createRange();
+
+ if (this.childNodes[0]) {
+ r.setStart(this.childNodes[0], index);
+ s.removeAllRanges();
+ s.addRange(r);
+ }
+ } else {
+ this.selectionStart = index;
+ this.selectionEnd = index;
+ }
+ }
+ }
+ };
+
+ /**
+ * Value getter and setter method
+ */
+ var Value = function (v, updateCaret, adjustNumeric) {
+ if (this.tagName == "DIV") {
+ if (v === undefined) {
+ var v = this.innerText;
+ if (this.value && this.value.length > v.length) {
+ v = this.value;
+ }
+ return v;
+ } else {
+ if (this.innerText !== v) {
+ this.innerText = v;
+
+ if (updateCaret) {
+ Caret.call(this, updateCaret, adjustNumeric);
+ }
+ }
+ }
+ } else {
+ if (v === undefined) {
+ return this.value;
+ } else {
+ if (this.value !== v) {
+ this.value = v;
+ if (updateCaret) {
+ Caret.call(this, updateCaret, adjustNumeric);
+ }
+ }
+ }
+ }
+ };
+
+ // Labels
+ var weekDaysFull = jSuites.calendar.weekdays;
+ var weekDays = jSuites.calendar.weekdaysShort;
+ var monthsFull = jSuites.calendar.months;
+ var months = jSuites.calendar.monthsShort;
+
+ var parser = {
+ YEAR: function (v, s) {
+ var y = "" + new Date().getFullYear();
+
+ if (typeof this.values[this.index] === "undefined") {
+ this.values[this.index] = "";
+ }
+ if (parseInt(v) >= 0 && parseInt(v) <= 10) {
+ if (this.values[this.index].length < s) {
+ this.values[this.index] += v;
+ }
+ }
+ if (this.values[this.index].length == s) {
+ if (s == 2) {
+ var y = y.substr(0, 2) + this.values[this.index];
+ } else if (s == 3) {
+ var y = y.substr(0, 1) + this.values[this.index];
+ } else if (s == 4) {
+ var y = this.values[this.index];
+ }
+ this.date[0] = y;
+ this.index++;
+ }
+ },
+ YYYY: function (v) {
+ parser.YEAR.call(this, v, 4);
+ },
+ YYY: function (v) {
+ parser.YEAR.call(this, v, 3);
+ },
+ YY: function (v) {
+ parser.YEAR.call(this, v, 2);
+ },
+ FIND: function (v, a) {
+ if (isBlank(this.values[this.index])) {
+ this.values[this.index] = "";
+ }
+ var pos = 0;
+ var count = 0;
+ var value = (this.values[this.index] + v).toLowerCase();
+ for (var i = 0; i < a.length; i++) {
+ if (a[i].toLowerCase().indexOf(value) == 0) {
+ pos = i;
+ count++;
+ }
+ }
+ if (count > 1) {
+ this.values[this.index] += v;
+ } else if (count == 1) {
+ // Jump number of chars
+ var t = a[pos].length - this.values[this.index].length - 1;
+ this.position += t;
+
+ this.values[this.index] = a[pos];
+ this.index++;
+ return pos;
+ }
+ },
+ MMM: function (v) {
+ var ret = parser.FIND.call(this, v, months);
+ if (ret !== undefined) {
+ this.date[1] = ret + 1;
+ }
+ },
+ MMMM: function (v) {
+ var ret = parser.FIND.call(this, v, monthsFull);
+ if (ret !== undefined) {
+ this.date[1] = ret + 1;
+ }
+ },
+ MMMMM: function (v) {
+ if (isBlank(this.values[this.index])) {
+ this.values[this.index] = "";
+ }
+ var pos = 0;
+ var count = 0;
+ var value = (this.values[this.index] + v).toLowerCase();
+ for (var i = 0; i < monthsFull.length; i++) {
+ if (monthsFull[i][0].toLowerCase().indexOf(value) == 0) {
+ this.values[this.index] = monthsFull[i][0];
+ this.date[1] = i + 1;
+ this.index++;
+ break;
+ }
+ }
+ },
+ MM: function (v) {
+ if (isBlank(this.values[this.index])) {
+ if (parseInt(v) > 1 && parseInt(v) < 10) {
+ this.date[1] = this.values[this.index] = "0" + v;
+ this.index++;
+ } else if (parseInt(v) < 2) {
+ this.values[this.index] = v;
+ }
+ } else {
+ if (this.values[this.index] == 1 && parseInt(v) < 3) {
+ this.date[1] = this.values[this.index] += v;
+ this.index++;
+ } else if (
+ this.values[this.index] == 0 &&
+ parseInt(v) > 0 &&
+ parseInt(v) < 10
+ ) {
+ this.date[1] = this.values[this.index] += v;
+ this.index++;
+ }
+ }
+ },
+ M: function (v) {
+ var test = false;
+ if (parseInt(v) >= 0 && parseInt(v) < 10) {
+ if (isBlank(this.values[this.index])) {
+ this.values[this.index] = v;
+ if (v > 1) {
+ this.date[1] = this.values[this.index];
+ this.index++;
+ }
+ } else {
+ if (this.values[this.index] == 1 && parseInt(v) < 3) {
+ this.date[1] = this.values[this.index] += v;
+ this.index++;
+ } else if (this.values[this.index] == 0 && parseInt(v) > 0) {
+ this.date[1] = this.values[this.index] += v;
+ this.index++;
+ } else {
+ var test = true;
+ }
+ }
+ } else {
+ var test = true;
+ }
+
+ // Re-test
+ if (test == true) {
+ var t = parseInt(this.values[this.index]);
+ if (t > 0 && t < 12) {
+ this.date[2] = this.values[this.index];
+ this.index++;
+ // Repeat the character
+ this.position--;
+ }
+ }
+ },
+ D: function (v) {
+ var test = false;
+ if (parseInt(v) >= 0 && parseInt(v) < 10) {
+ if (isBlank(this.values[this.index])) {
+ this.values[this.index] = v;
+ if (parseInt(v) > 3) {
+ this.date[2] = this.values[this.index];
+ this.index++;
+ }
+ } else {
+ if (this.values[this.index] == 3 && parseInt(v) < 2) {
+ this.date[2] = this.values[this.index] += v;
+ this.index++;
+ } else if (
+ this.values[this.index] == 1 ||
+ this.values[this.index] == 2
+ ) {
+ this.date[2] = this.values[this.index] += v;
+ this.index++;
+ } else if (this.values[this.index] == 0 && parseInt(v) > 0) {
+ this.date[2] = this.values[this.index] += v;
+ this.index++;
+ } else {
+ var test = true;
+ }
+ }
+ } else {
+ var test = true;
+ }
+
+ // Re-test
+ if (test == true) {
+ var t = parseInt(this.values[this.index]);
+ if (t > 0 && t < 32) {
+ this.date[2] = this.values[this.index];
+ this.index++;
+ // Repeat the character
+ this.position--;
+ }
+ }
+ },
+ DD: function (v) {
+ if (isBlank(this.values[this.index])) {
+ if (parseInt(v) > 3 && parseInt(v) < 10) {
+ this.date[2] = this.values[this.index] = "0" + v;
+ this.index++;
+ } else if (parseInt(v) < 10) {
+ this.values[this.index] = v;
+ }
+ } else {
+ if (this.values[this.index] == 3 && parseInt(v) < 2) {
+ this.date[2] = this.values[this.index] += v;
+ this.index++;
+ } else if (
+ (this.values[this.index] == 1 || this.values[this.index] == 2) &&
+ parseInt(v) < 10
+ ) {
+ this.date[2] = this.values[this.index] += v;
+ this.index++;
+ } else if (
+ this.values[this.index] == 0 &&
+ parseInt(v) > 0 &&
+ parseInt(v) < 10
+ ) {
+ this.date[2] = this.values[this.index] += v;
+ this.index++;
+ }
+ }
+ },
+ DDD: function (v) {
+ parser.FIND.call(this, v, weekDays);
+ },
+ DDDD: function (v) {
+ parser.FIND.call(this, v, weekDaysFull);
+ },
+ HH12: function (v, two) {
+ if (isBlank(this.values[this.index])) {
+ if (parseInt(v) > 1 && parseInt(v) < 10) {
+ if (two) {
+ v = 0 + v;
+ }
+ this.date[3] = this.values[this.index] = v;
+ this.index++;
+ } else if (parseInt(v) < 10) {
+ this.values[this.index] = v;
+ }
+ } else {
+ if (this.values[this.index] == 1 && parseInt(v) < 3) {
+ this.date[3] = this.values[this.index] += v;
+ this.index++;
+ } else if (this.values[this.index] < 1 && parseInt(v) < 10) {
+ this.date[3] = this.values[this.index] += v;
+ this.index++;
+ }
+ }
+ },
+ HH24: function (v, two) {
+ var test = false;
+ if (parseInt(v) >= 0 && parseInt(v) < 10) {
+ if (
+ this.values[this.index] == null ||
+ this.values[this.index] == ""
+ ) {
+ if (parseInt(v) > 2 && parseInt(v) < 10) {
+ if (two) {
+ v = 0 + v;
+ }
+ this.date[3] = this.values[this.index] = v;
+ this.index++;
+ } else if (parseInt(v) < 10) {
+ this.values[this.index] = v;
+ }
+ } else {
+ if (this.values[this.index] == 2 && parseInt(v) < 4) {
+ this.date[3] = this.values[this.index] += v;
+ this.index++;
+ } else if (this.values[this.index] < 2 && parseInt(v) < 10) {
+ this.date[3] = this.values[this.index] += v;
+ this.index++;
+ }
+ }
+ }
+ },
+ HH: function (v) {
+ parser["HH24"].call(this, v, 1);
+ },
+ H: function (v) {
+ parser["HH24"].call(this, v, 0);
+ },
+ "\\[H\\]": function (v) {
+ if (this.values[this.index] == undefined) {
+ this.values[this.index] = "";
+ }
+ if (v.match(/[0-9]/g)) {
+ this.date[3] = this.values[this.index] += v;
+ } else {
+ if (this.values[this.index].match(/[0-9]/g)) {
+ this.date[3] = this.values[this.index];
+ this.index++;
+ // Repeat the character
+ this.position--;
+ }
+ }
+ },
+ N60: function (v, i) {
+ if (this.values[this.index] == null || this.values[this.index] == "") {
+ if (parseInt(v) > 5 && parseInt(v) < 10) {
+ this.date[i] = this.values[this.index] = "0" + v;
+ this.index++;
+ } else if (parseInt(v) < 10) {
+ this.values[this.index] = v;
+ }
+ } else {
+ if (parseInt(v) < 10) {
+ this.date[i] = this.values[this.index] += v;
+ this.index++;
+ }
+ }
+ },
+ MI: function (v) {
+ parser.N60.call(this, v, 4);
+ },
+ SS: function (v) {
+ parser.N60.call(this, v, 5);
+ },
+ "AM/PM": function (v) {
+ this.values[this.index] = "";
+ if (v) {
+ if (this.date[3] > 12) {
+ this.values[this.index] = "PM";
+ } else {
+ this.values[this.index] = "AM";
+ }
+ }
+ this.index++;
+ },
+ WD: function (v) {
+ if (typeof this.values[this.index] === "undefined") {
+ this.values[this.index] = "";
+ }
+ if (parseInt(v) >= 0 && parseInt(v) < 7) {
+ this.values[this.index] = v;
+ }
+ if (this.value[this.index].length == 1) {
+ this.index++;
+ }
+ },
+ "0{1}(.{1}0+)?": function (v) {
+ // Get decimal
+ var decimal = getDecimal.call(this);
+ // Negative number
+ var neg = false;
+ // Create if is blank
+ if (isBlank(this.values[this.index])) {
+ this.values[this.index] = "";
+ } else {
+ if (this.values[this.index] == "-") {
+ neg = true;
+ }
+ }
+ var current = ParseValue.call(this, this.values[this.index], decimal);
+ if (current) {
+ this.values[this.index] = current.join(decimal);
+ }
+ // New entry
+ if (parseInt(v) >= 0 && parseInt(v) < 10) {
+ // Replace the zero for a number
+ if (this.values[this.index] == "0" && v > 0) {
+ this.values[this.index] = "";
+ } else if (this.values[this.index] == "-0" && v > 0) {
+ this.values[this.index] = "-";
+ }
+ // Don't add up zeros because does not mean anything here
+ if (
+ (this.values[this.index] != "0" &&
+ this.values[this.index] != "-0") ||
+ v == decimal
+ ) {
+ this.values[this.index] += v;
+ }
+ } else if (decimal && v == decimal) {
+ if (this.values[this.index].indexOf(decimal) == -1) {
+ if (!this.values[this.index]) {
+ this.values[this.index] = "0";
+ }
+ this.values[this.index] += v;
+ }
+ } else if (v == "-") {
+ // Negative signed
+ neg = true;
+ }
+
+ if (neg === true && this.values[this.index][0] !== "-") {
+ this.values[this.index] = "-" + this.values[this.index];
+ }
+ },
+ "0{1}(.{1}0+)?%": function (v) {
+ parser["0{1}(.{1}0+)?"].call(this, v);
+
+ if (this.values[this.index].match(/[\-0-9]/g)) {
+ if (
+ this.values[this.index] &&
+ this.values[this.index].indexOf("%") == -1
+ ) {
+ this.values[this.index] += "%";
+ }
+ } else {
+ this.values[this.index] = "";
+ }
+ },
+ "#(.{1})##0?(.{1}0+)?( ?;(.*)?)?": function (v) {
+ // Parse number
+ parser["0{1}(.{1}0+)?"].call(this, v);
+ // Get decimal
+ var decimal = getDecimal.call(this);
+ // Get separator
+ var separator = this.tokens[this.index].substr(1, 1);
+ // Negative
+ var negative = this.values[this.index][0] === "-" ? true : false;
+ // Current value
+ var current = ParseValue.call(this, this.values[this.index], decimal);
+
+ // Get main and decimal parts
+ if (current !== "") {
+ // Format number
+ var n = current[0].match(/[0-9]/g);
+ if (n) {
+ // Format
+ n = n.join("");
+ var t = [];
+ var s = 0;
+ for (var j = n.length - 1; j >= 0; j--) {
+ t.push(n[j]);
+ s++;
+ if (!(s % 3)) {
+ t.push(separator);
+ }
+ }
+ t = t.reverse();
+ current[0] = t.join("");
+ if (current[0].substr(0, 1) == separator) {
+ current[0] = current[0].substr(1);
+ }
+ } else {
+ current[0] = "";
+ }
+
+ // Value
+ this.values[this.index] = current.join(decimal);
+
+ // Negative
+ if (negative) {
+ this.values[this.index] = "-" + this.values[this.index];
+ }
+ }
+ },
+ 0: function (v) {
+ if (v.match(/[0-9]/g)) {
+ this.values[this.index] = v;
+ this.index++;
+ }
+ },
+ "[0-9a-zA-Z$]+": function (v) {
+ if (isBlank(this.values[this.index])) {
+ this.values[this.index] = "";
+ }
+ var t = this.tokens[this.index];
+ var s = this.values[this.index];
+ var i = s.length;
+
+ if (t[i] == v) {
+ this.values[this.index] += v;
+
+ if (this.values[this.index] == t) {
+ this.index++;
+ }
+ } else {
+ this.values[this.index] = t;
+ this.index++;
+
+ if (v.match(/[\-0-9]/g)) {
+ // Repeat the character
+ this.position--;
+ }
+ }
+ },
+ A: function (v) {
+ if (v.match(/[a-zA-Z]/gi)) {
+ this.values[this.index] = v;
+ this.index++;
+ }
+ },
+ ".": function (v) {
+ parser["[0-9a-zA-Z$]+"].call(this, v);
+ },
+ "@": function (v) {
+ if (isBlank(this.values[this.index])) {
+ this.values[this.index] = "";
+ }
+ this.values[this.index] += v;
+ },
+ };
+
+ /**
+ * Get the tokens in the mask string
+ */
+ var getTokens = function (str) {
+ if (this.type == "general") {
+ var t = [].concat(tokens.general);
+ } else {
+ var t = [].concat(
+ tokens.currency,
+ tokens.datetime,
+ tokens.percentage,
+ tokens.numeric,
+ tokens.text,
+ tokens.general
+ );
+ }
+ // Expression to extract all tokens from the string
+ var e = new RegExp(t.join("|"), "gi");
+ // Extract
+ return str.match(e);
+ };
+
+ /**
+ * Get the method of one given token
+ */
+ var getMethod = function (str) {
+ if (!this.type) {
+ var types = Object.keys(tokens);
+ } else if (this.type == "text") {
+ var types = ["text"];
+ } else if (this.type == "general") {
+ var types = ["general"];
+ } else if (this.type == "datetime") {
+ var types = ["numeric", "datetime", "general"];
+ } else {
+ var types = ["currency", "percentage", "numeric", "general"];
+ }
+
+ // Found
+ for (var i = 0; i < types.length; i++) {
+ var type = types[i];
+ for (var j = 0; j < tokens[type].length; j++) {
+ var e = new RegExp(tokens[type][j], "gi");
+ var r = str.match(e);
+ if (r) {
+ return { type: type, method: tokens[type][j] };
+ }
+ }
+ }
+ };
+
+ /**
+ * Identify each method for each token
+ */
+ var getMethods = function (t) {
+ var result = [];
+ for (var i = 0; i < t.length; i++) {
+ var m = getMethod.call(this, t[i]);
+ if (m) {
+ result.push(m.method);
+ } else {
+ result.push(null);
+ }
+ }
+
+ // Compatibility with excel
+ for (var i = 0; i < result.length; i++) {
+ if (result[i] == "MM") {
+ // Not a month, correct to minutes
+ if (result[i - 1] && result[i - 1].indexOf("H") >= 0) {
+ result[i] = "MI";
+ } else if (result[i - 2] && result[i - 2].indexOf("H") >= 0) {
+ result[i] = "MI";
+ } else if (result[i + 1] && result[i + 1].indexOf("S") >= 0) {
+ result[i] = "MI";
+ } else if (result[i + 2] && result[i + 2].indexOf("S") >= 0) {
+ result[i] = "MI";
+ }
+ }
+ }
+
+ return result;
+ };
+
+ /**
+ * Get the type for one given token
+ */
+ var getType = function (str) {
+ var m = getMethod.call(this, str);
+ if (m) {
+ var type = m.type;
+ }
+
+ if (type) {
+ var numeric = 0;
+ // Make sure the correct type
+ var t = getTokens.call(this, str);
+ for (var i = 0; i < t.length; i++) {
+ m = getMethod.call(this, t[i]);
+ if (m && isNumeric(m.type)) {
+ numeric++;
+ }
+ }
+ if (numeric > 1) {
+ type = "general";
+ }
+ }
+
+ return type;
+ };
+
+ /**
+ * Parse character per character using the detected tokens in the mask
+ */
+ var parse = function () {
+ // Parser method for this position
+ if (typeof parser[this.methods[this.index]] == "function") {
+ parser[this.methods[this.index]].call(this, this.value[this.position]);
+ this.position++;
+ } else {
+ this.values[this.index] = this.tokens[this.index];
+ this.index++;
+ }
+ };
+
+ var isFormula = function (value) {
+ var v = ("" + value)[0];
+ return v == "=" ? true : false;
+ };
+
+ var toPlainString = function (num) {
+ return ("" + +num).replace(
+ /(-?)(\d*)\.?(\d*)e([+-]\d+)/,
+ function (a, b, c, d, e) {
+ return e < 0
+ ? b + "0." + Array(1 - e - c.length).join(0) + c + d
+ : b + c + d + Array(e - d.length + 1).join(0);
+ }
+ );
+ };
+
+ /**
+ * Mask function
+ * @param {mixed|string} JS input or a string to be parsed
+ * @param {object|string} When the first param is a string, the second is the mask or object with the mask options
+ */
+ var obj = function (e, config, returnObject) {
+ // Options
+ var r = null;
+ var t = null;
+ var o = {
+ // Element
+ input: null,
+ // Current value
+ value: null,
+ // Mask options
+ options: {},
+ // New values for each token found
+ values: [],
+ // Token position
+ index: 0,
+ // Character position
+ position: 0,
+ // Date raw values
+ date: [0, 0, 0, 0, 0, 0],
+ // Raw number for the numeric values
+ number: 0,
+ };
+
+ // This is a JavaScript Event
+ if (typeof e == "object") {
+ // Element
+ o.input = e.target;
+ // Current value
+ o.value = Value.call(e.target);
+ // Current caret position
+ o.caret = Caret.call(e.target);
+ // Mask
+ if ((t = e.target.getAttribute("data-mask"))) {
+ o.mask = t;
+ }
+ // Type
+ if ((t = e.target.getAttribute("data-type"))) {
+ o.type = t;
+ }
+ // Options
+ if (e.target.mask) {
+ if (e.target.mask.options) {
+ o.options = e.target.mask.options;
+ }
+ if (e.target.mask.locale) {
+ o.locale = e.target.mask.locale;
+ }
+ } else {
+ // Locale
+ if ((t = e.target.getAttribute("data-locale"))) {
+ o.locale = t;
+ if (o.mask) {
+ o.options.style = o.mask;
+ }
+ }
+ }
+ // Extra configuration
+ if (e.target.attributes && e.target.attributes.length) {
+ for (var i = 0; i < e.target.attributes.length; i++) {
+ var k = e.target.attributes[i].name;
+ var v = e.target.attributes[i].value;
+ if (k.substr(0, 4) == "data") {
+ o.options[k.substr(5)] = v;
+ }
+ }
+ }
+ } else {
+ // Options
+ if (typeof config == "string") {
+ // Mask
+ o.mask = config;
+ } else {
+ // Mask
+ var k = Object.keys(config);
+ for (var i = 0; i < k.length; i++) {
+ o[k[i]] = config[k[i]];
+ }
+ }
+
+ if (typeof e === "number") {
+ // Get decimal
+ getDecimal.call(o, o.mask);
+ // Replace to the correct decimal
+ e = ("" + e).replace(".", o.options.decimal);
+ }
+
+ // Current
+ o.value = e;
+
+ if (o.input) {
+ // Value
+ Value.call(o.input, e);
+ // Focus
+ jSuites.focus(o.input);
+ // Caret
+ o.caret = Caret.call(o.input);
+ }
+ }
+
+ // Mask detected start the process
+ if (!isFormula(o.value) && (o.mask || o.locale)) {
+ // Compatibility fixes
+ if (o.mask) {
+ // Remove []
+ o.mask = o.mask.replace(new RegExp(/\[h]/), "|h|");
+ o.mask = o.mask.replace(new RegExp(/\[.*?\]/), "");
+ o.mask = o.mask.replace(new RegExp(/\|h\|/), "[h]");
+ if (o.mask.indexOf(";") !== -1) {
+ var t = o.mask.split(";");
+ o.mask = t[0];
+ }
+ // Excel mask TODO: Improve
+ if (o.mask.indexOf("##") !== -1) {
+ var d = o.mask.split(";");
+ if (d[0]) {
+ d[0] = d[0].replace("*", "\t");
+ d[0] = d[0].replace(new RegExp(/_-/g), " ");
+ d[0] = d[0].replace(new RegExp(/_/g), "");
+ d[0] = d[0].replace("##0.###", "##0.000");
+ d[0] = d[0].replace("##0.##", "##0.00");
+ d[0] = d[0].replace("##0.#", "##0.0");
+ d[0] = d[0].replace("##0,###", "##0,000");
+ d[0] = d[0].replace("##0,##", "##0,00");
+ d[0] = d[0].replace("##0,#", "##0,0");
+ }
+ o.mask = d[0];
+ }
+ // Get type
+ if (!o.type) {
+ o.type = getType.call(o, o.mask);
+ }
+ // Get tokens
+ o.tokens = getTokens.call(o, o.mask);
+ }
+ // On new input
+ if (
+ typeof e !== "object" ||
+ !e.inputType ||
+ !e.inputType.indexOf("insert") ||
+ !e.inputType.indexOf("delete")
+ ) {
+ // Start transformation
+ if (o.locale) {
+ if (o.input) {
+ Format.call(o, o.input, e);
+ } else {
+ var newValue = FormatValue.call(o, o.value);
+ }
+ } else {
+ // Get tokens
+ o.methods = getMethods.call(o, o.tokens);
+ // Go through all tokes
+ while (
+ o.position < o.value.length &&
+ typeof o.tokens[o.index] !== "undefined"
+ ) {
+ // Get the appropriate parser
+ parse.call(o);
+ }
+
+ // New value
+ var newValue = o.values.join("");
+
+ // Add tokens to the end of string only if string is not empty
+ if (isNumeric(o.type) && newValue !== "") {
+ // Complement things in the end of the mask
+ while (typeof o.tokens[o.index] !== "undefined") {
+ var t = getMethod.call(o, o.tokens[o.index]);
+ if (t && t.type == "general") {
+ o.values[o.index] = o.tokens[o.index];
+ }
+ o.index++;
+ }
+
+ var adjustNumeric = true;
+ } else {
+ var adjustNumeric = false;
+ }
+
+ // New value
+ newValue = o.values.join("");
+
+ // Reset value
+ if (o.input) {
+ t = newValue.length - o.value.length;
+ if (t > 0) {
+ var caret = o.caret + t;
+ } else {
+ var caret = o.caret;
+ }
+ Value.call(o.input, newValue, caret, adjustNumeric);
+ }
+ }
+ }
+
+ // Update raw data
+ if (o.input) {
+ var label = null;
+ if (isNumeric(o.type)) {
+ // Extract the number
+ o.number = Extract.call(o, Value.call(o.input));
+ // Keep the raw data as a property of the tag
+ if (o.type == "percentage") {
+ label = o.number / 100;
+ } else {
+ label = o.number;
+ }
+ } else if (o.type == "datetime") {
+ label = getDate.call(o);
+
+ if (o.date[0] && o.date[1] && o.date[2]) {
+ o.input.setAttribute("data-completed", true);
+ }
+ }
+
+ if (label) {
+ o.input.setAttribute("data-value", label);
+ }
+ }
+
+ if (newValue !== undefined) {
+ if (returnObject) {
+ return o;
+ } else {
+ return newValue;
+ }
+ }
+ }
+ };
+
+ // Get the type of the mask
+ obj.getType = getType;
+
+ // Extract the tokens from a mask
+ obj.prepare = function (str, o) {
+ if (!o) {
+ o = {};
+ }
+ return getTokens.call(o, str);
+ };
+
+ /**
+ * Apply the mask to a element (legacy)
+ */
+ obj.apply = function (e) {
+ var v = Value.call(e.target);
+ if (e.key.length == 1) {
+ v += e.key;
+ }
+ Value.call(e.target, obj(v, e.target.getAttribute("data-mask")));
+ };
+
+ /**
+ * Legacy support
+ */
+ obj.run = function (value, mask, decimal) {
+ return obj(value, { mask: mask, decimal: decimal });
+ };
+
+ /**
+ * Extract number from masked string
+ */
+ obj.extract = function (v, options, returnObject) {
+ if (isBlank(v)) {
+ return v;
+ }
+ if (typeof options != "object") {
+ return value;
+ } else {
+ options = Object.assign({}, options);
+
+ if (!options.options) {
+ options.options = {};
+ }
+ }
+
+ // Compatibility
+ if (!options.mask && options.format) {
+ options.mask = options.format;
+ }
+
+ // Remove []
+ if (options.mask) {
+ if (options.mask.indexOf(";") !== -1) {
+ var t = options.mask.split(";");
+ options.mask = t[0];
+ }
+ options.mask = options.mask.replace(new RegExp(/\[.*?\]/), "");
+ }
+
+ // Get decimal
+ getDecimal.call(options, options.mask);
+
+ var type = null;
+ if (options.type == "percent" || options.options.style == "percent") {
+ type = "percentage";
+ } else if (options.mask) {
+ type = getType.call(options, options.mask);
+ }
+
+ if (type === "general") {
+ var o = obj(v, options, true);
+
+ value = v;
+ } else if (type === "datetime") {
+ if (v instanceof Date) {
+ var t = jSuites.calendar.getDateString(value, options.mask);
+ }
+
+ var o = obj(v, options, true);
+
+ if (jSuites.isNumeric(v)) {
+ value = v;
+ } else {
+ var value = getDate.call(o);
+ var t = jSuites.calendar.now(o.date);
+ value = jSuites.calendar.dateToNum(t);
+ }
+ } else {
+ var value = Extract.call(options, v);
+ // Percentage
+ if (type == "percentage") {
+ value /= 100;
+ }
+ var o = options;
+ }
+
+ o.value = value;
+
+ if (!o.type && type) {
+ o.type = type;
+ }
+
+ if (returnObject) {
+ return o;
+ } else {
+ return value;
+ }
+ };
+
+ /**
+ * Render
+ */
+ obj.render = function (value, options, fullMask) {
+ if (isBlank(value)) {
+ return value;
+ }
+
+ if (typeof options != "object") {
+ return value;
+ } else {
+ options = Object.assign({}, options);
+
+ if (!options.options) {
+ options.options = {};
+ }
+ }
+
+ // Compatibility
+ if (!options.mask && options.format) {
+ options.mask = options.format;
+ }
+
+ // Remove []
+ if (options.mask) {
+ if (options.mask.indexOf(";") !== -1) {
+ var t = options.mask.split(";");
+ options.mask = t[0];
+ }
+ options.mask = options.mask.replace(new RegExp(/\[h]/), "|h|");
+ options.mask = options.mask.replace(new RegExp(/\[.*?\]/), "");
+ options.mask = options.mask.replace(new RegExp(/\|h\|/), "[h]");
+ }
+
+ var type = null;
+ if (options.type == "percent" || options.options.style == "percent") {
+ type = "percentage";
+ } else if (options.mask) {
+ type = getType.call(options, options.mask);
+ } else if (value instanceof Date) {
+ type = "datetime";
+ }
+
+ // Fill with blanks
+ var fillWithBlanks = false;
+
+ if (type == "datetime" || options.type == "calendar") {
+ var t = jSuites.calendar.getDateString(value, options.mask);
+ if (t) {
+ value = t;
+ }
+
+ if (options.mask && fullMask) {
+ fillWithBlanks = true;
+ }
+ } else {
+ // Percentage
+ if (type == "percentage") {
+ value *= 100;
+ }
+ // Number of decimal places
+ if (typeof value === "number") {
+ var t = null;
+ if (options.mask && fullMask) {
+ var d = getDecimal.call(options, options.mask);
+ if (options.mask.indexOf(d) !== -1) {
+ d = options.mask.split(d);
+ d = "" + d[1].match(/[0-9]+/g);
+ d = d.length;
+ t = value.toFixed(d);
+ } else {
+ t = value.toFixed(0);
+ }
+ } else if (options.locale && fullMask) {
+ // Append zeros
+ var d = ("" + value).split(".");
+ if (options.options) {
+ if (typeof d[1] === "undefined") {
+ d[1] = "";
+ }
+ var len = d[1].length;
+ if (options.options.minimumFractionDigits > len) {
+ for (
+ var i = 0;
+ i < options.options.minimumFractionDigits - len;
+ i++
+ ) {
+ d[1] += "0";
+ }
+ }
+ }
+ if (!d[1].length) {
+ t = d[0];
+ } else {
+ t = d.join(".");
+ }
+ var len = d[1].length;
+ if (
+ options.options &&
+ options.options.maximumFractionDigits < len
+ ) {
+ t = parseFloat(t).toFixed(options.options.maximumFractionDigits);
+ }
+ } else {
+ t = toPlainString(value);
+ }
+
+ if (t !== null) {
+ value = t;
+ // Get decimal
+ getDecimal.call(options, options.mask);
+ // Replace to the correct decimal
+ if (options.options.decimal) {
+ value = value.replace(".", options.options.decimal);
+ }
+ }
+ } else {
+ if (options.mask && fullMask) {
+ fillWithBlanks = true;
+ }
+ }
+ }
+
+ if (fillWithBlanks) {
+ var s = options.mask.length - value.length;
+ if (s > 0) {
+ for (var i = 0; i < s; i++) {
+ value += " ";
+ }
+ }
+ }
+
+ value = obj(value, options);
+
+ // Numeric mask, number of zeros
+ if (fullMask && type === "numeric") {
+ var maskZeros = options.mask.match(new RegExp(/^[0]+$/gm));
+ if (maskZeros && maskZeros.length === 1) {
+ var maskLength = maskZeros[0].length;
+ if (maskLength > 3) {
+ value = "" + value;
+ while (value.length < maskLength) {
+ value = "0" + value;
+ }
+ }
+ }
+ }
+
+ return value;
+ };
+
+ obj.set = function (e, m) {
+ if (m) {
+ e.setAttribute("data-mask", m);
+ // Reset the value
+ var event = new Event("input", {
+ bubbles: true,
+ cancelable: true,
+ });
+ e.dispatchEvent(event);
+ }
+ };
+
+ if (typeof document !== "undefined") {
+ document.addEventListener("input", function (e) {
+ if (e.target.getAttribute("data-mask") || e.target.mask) {
+ obj(e);
+ }
+ });
+ }
+
+ return obj;
+ })();
+
+ jSuites.modal = function (el, options) {
+ var obj = {};
+ obj.options = {};
+
+ // Default configuration
+ var defaults = {
+ url: null,
+ onopen: null,
+ onclose: null,
+ closed: false,
+ width: null,
+ height: null,
+ title: null,
+ padding: null,
+ backdrop: true,
+ };
+
+ // Loop through our object
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ obj.options[property] = defaults[property];
+ }
+ }
+
+ // Title
+ if (!obj.options.title && el.getAttribute("title")) {
+ obj.options.title = el.getAttribute("title");
+ }
+
+ var temp = document.createElement("div");
+ while (el.children[0]) {
+ temp.appendChild(el.children[0]);
+ }
+
+ obj.content = document.createElement("div");
+ obj.content.className = "jmodal_content";
+ obj.content.innerHTML = el.innerHTML;
+
+ while (temp.children[0]) {
+ obj.content.appendChild(temp.children[0]);
+ }
+
+ obj.container = document.createElement("div");
+ obj.container.className = "jmodal";
+ obj.container.appendChild(obj.content);
+
+ if (obj.options.padding) {
+ obj.content.style.padding = obj.options.padding;
+ }
+ if (obj.options.width) {
+ obj.container.style.width = obj.options.width;
+ }
+ if (obj.options.height) {
+ obj.container.style.height = obj.options.height;
+ }
+ if (obj.options.title) {
+ obj.container.setAttribute("title", obj.options.title);
+ } else {
+ obj.container.classList.add("no-title");
+ }
+ el.innerHTML = "";
+ el.style.display = "none";
+ el.appendChild(obj.container);
+
+ // Backdrop
+ if (obj.options.backdrop) {
+ var backdrop = document.createElement("div");
+ backdrop.className = "jmodal_backdrop";
+ backdrop.onclick = function () {
+ obj.close();
+ };
+ el.appendChild(backdrop);
+ }
+
+ obj.open = function () {
+ el.style.display = "block";
+ // Fullscreen
+ var rect = obj.container.getBoundingClientRect();
+ if (jSuites.getWindowWidth() < rect.width) {
+ obj.container.style.top = "";
+ obj.container.style.left = "";
+ obj.container.classList.add("jmodal_fullscreen");
+ jSuites.animation.slideBottom(obj.container, 1);
+ } else {
+ if (obj.options.backdrop) {
+ backdrop.style.display = "block";
+ }
+ }
+ // Event
+ if (typeof obj.options.onopen == "function") {
+ obj.options.onopen(el, obj);
+ }
+ };
+
+ obj.resetPosition = function () {
+ obj.container.style.top = "";
+ obj.container.style.left = "";
+ };
+
+ obj.isOpen = function () {
+ return el.style.display != "none" ? true : false;
+ };
+
+ obj.close = function () {
+ if (obj.isOpen()) {
+ el.style.display = "none";
+ if (obj.options.backdrop) {
+ // Backdrop
+ backdrop.style.display = "";
+ }
+ // Remove fullscreen class
+ obj.container.classList.remove("jmodal_fullscreen");
+ // Event
+ if (typeof obj.options.onclose == "function") {
+ obj.options.onclose(el, obj);
+ }
+ }
+ };
+
+ if (!jSuites.modal.hasEvents) {
+ // Position
+ var tracker = null;
+
+ document.addEventListener("keydown", function (e) {
+ if (e.which == 27) {
+ var modals = document.querySelectorAll(".jmodal");
+ for (var i = 0; i < modals.length; i++) {
+ modals[i].parentNode.modal.close();
+ }
+ }
+ });
+
+ document.addEventListener("mouseup", function (e) {
+ var item = jSuites.findElement(e.target, "jmodal");
+ if (item) {
+ // Get target info
+ var rect = item.getBoundingClientRect();
+
+ if (e.changedTouches && e.changedTouches[0]) {
+ var x = e.changedTouches[0].clientX;
+ var y = e.changedTouches[0].clientY;
+ } else {
+ var x = e.clientX;
+ var y = e.clientY;
+ }
+
+ if (rect.width - (x - rect.left) < 50 && y - rect.top < 50) {
+ item.parentNode.modal.close();
+ }
+ }
+
+ if (tracker) {
+ tracker.element.style.cursor = "auto";
+ tracker = null;
+ }
+ });
+
+ document.addEventListener("mousedown", function (e) {
+ var item = jSuites.findElement(e.target, "jmodal");
+ if (item) {
+ // Get target info
+ var rect = item.getBoundingClientRect();
+
+ if (e.changedTouches && e.changedTouches[0]) {
+ var x = e.changedTouches[0].clientX;
+ var y = e.changedTouches[0].clientY;
+ } else {
+ var x = e.clientX;
+ var y = e.clientY;
+ }
+
+ if (rect.width - (x - rect.left) < 50 && y - rect.top < 50) {
+ // Do nothing
+ } else {
+ if (e.target.getAttribute("title") && y - rect.top < 50) {
+ if (document.selection) {
+ document.selection.empty();
+ } else if (window.getSelection) {
+ window.getSelection().removeAllRanges();
+ }
+
+ tracker = {
+ left: rect.left,
+ top: rect.top,
+ x: e.clientX,
+ y: e.clientY,
+ width: rect.width,
+ height: rect.height,
+ element: item,
+ };
+ }
+ }
+ }
+ });
+
+ document.addEventListener("mousemove", function (e) {
+ if (tracker) {
+ e = e || window.event;
+ if (e.buttons) {
+ var mouseButton = e.buttons;
+ } else if (e.button) {
+ var mouseButton = e.button;
+ } else {
+ var mouseButton = e.which;
+ }
+
+ if (mouseButton) {
+ tracker.element.style.top =
+ tracker.top + (e.clientY - tracker.y) + tracker.height / 2 + "px";
+ tracker.element.style.left =
+ tracker.left + (e.clientX - tracker.x) + tracker.width / 2 + "px";
+ tracker.element.style.cursor = "move";
+ } else {
+ tracker.element.style.cursor = "auto";
+ }
+ }
+ });
+
+ jSuites.modal.hasEvents = true;
+ }
+
+ if (obj.options.url) {
+ jSuites.ajax({
+ url: obj.options.url,
+ method: "GET",
+ dataType: "text/html",
+ success: function (data) {
+ obj.content.innerHTML = data;
+
+ if (!obj.options.closed) {
+ obj.open();
+ }
+ },
+ });
+ } else {
+ if (!obj.options.closed) {
+ obj.open();
+ }
+ }
+
+ // Keep object available from the node
+ el.modal = obj;
+
+ return obj;
+ };
+
+ jSuites.notification = function (options) {
+ var obj = {};
+ obj.options = {};
+
+ // Default configuration
+ var defaults = {
+ icon: null,
+ name: "Notification",
+ date: null,
+ error: null,
+ title: null,
+ message: null,
+ timeout: 4000,
+ autoHide: true,
+ closeable: true,
+ };
+
+ // Loop through our object
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ obj.options[property] = defaults[property];
+ }
+ }
+
+ var notification = document.createElement("div");
+ notification.className = "jnotification";
+
+ if (obj.options.error) {
+ notification.classList.add("jnotification-error");
+ }
+
+ var notificationContainer = document.createElement("div");
+ notificationContainer.className = "jnotification-container";
+ notification.appendChild(notificationContainer);
+
+ var notificationHeader = document.createElement("div");
+ notificationHeader.className = "jnotification-header";
+ notificationContainer.appendChild(notificationHeader);
+
+ var notificationImage = document.createElement("div");
+ notificationImage.className = "jnotification-image";
+ notificationHeader.appendChild(notificationImage);
+
+ if (obj.options.icon) {
+ var notificationIcon = document.createElement("img");
+ notificationIcon.src = obj.options.icon;
+ notificationImage.appendChild(notificationIcon);
+ }
+
+ var notificationName = document.createElement("div");
+ notificationName.className = "jnotification-name";
+ notificationName.innerHTML = obj.options.name;
+ notificationHeader.appendChild(notificationName);
+
+ if (obj.options.closeable == true) {
+ var notificationClose = document.createElement("div");
+ notificationClose.className = "jnotification-close";
+ notificationClose.onclick = function () {
+ obj.hide();
+ };
+ notificationHeader.appendChild(notificationClose);
+ }
+
+ var notificationDate = document.createElement("div");
+ notificationDate.className = "jnotification-date";
+ notificationHeader.appendChild(notificationDate);
+
+ var notificationContent = document.createElement("div");
+ notificationContent.className = "jnotification-content";
+ notificationContainer.appendChild(notificationContent);
+
+ if (obj.options.title) {
+ var notificationTitle = document.createElement("div");
+ notificationTitle.className = "jnotification-title";
+ notificationTitle.innerHTML = obj.options.title;
+ notificationContent.appendChild(notificationTitle);
+ }
+
+ var notificationMessage = document.createElement("div");
+ notificationMessage.className = "jnotification-message";
+ notificationMessage.innerHTML = obj.options.message;
+ notificationContent.appendChild(notificationMessage);
+
+ obj.show = function () {
+ document.body.appendChild(notification);
+ if (jSuites.getWindowWidth() > 800) {
+ jSuites.animation.fadeIn(notification);
+ } else {
+ jSuites.animation.slideTop(notification, 1);
+ }
+ };
+
+ obj.hide = function () {
+ if (jSuites.getWindowWidth() > 800) {
+ jSuites.animation.fadeOut(notification, function () {
+ if (notification.parentNode) {
+ notification.parentNode.removeChild(notification);
+ if (notificationTimeout) {
+ clearTimeout(notificationTimeout);
+ }
+ }
+ });
+ } else {
+ jSuites.animation.slideTop(notification, 0, function () {
+ if (notification.parentNode) {
+ notification.parentNode.removeChild(notification);
+ if (notificationTimeout) {
+ clearTimeout(notificationTimeout);
+ }
+ }
+ });
+ }
+ };
+
+ obj.show();
+
+ if (obj.options.autoHide == true) {
+ var notificationTimeout = setTimeout(function () {
+ obj.hide();
+ }, obj.options.timeout);
+ }
+
+ if (jSuites.getWindowWidth() < 800) {
+ notification.addEventListener("swipeup", function (e) {
+ obj.hide();
+ e.preventDefault();
+ e.stopPropagation();
+ });
+ }
+
+ return obj;
+ };
+
+ jSuites.notification.isVisible = function () {
+ var j = document.querySelector(".jnotification");
+ return j && j.parentNode ? true : false;
+ };
+
+ // More palettes https://coolors.co/ or https://gka.github.io/palettes/#/10|s|003790,005647,ffffe0|ffffe0,ff005e,93003a|1|1
+ jSuites.palette = (function () {
+ /**
+ * Available palettes
+ */
+ var palette = {
+ material: [
+ [
+ "#ffebee",
+ "#fce4ec",
+ "#f3e5f5",
+ "#e8eaf6",
+ "#e3f2fd",
+ "#e0f7fa",
+ "#e0f2f1",
+ "#e8f5e9",
+ "#f1f8e9",
+ "#f9fbe7",
+ "#fffde7",
+ "#fff8e1",
+ "#fff3e0",
+ "#fbe9e7",
+ "#efebe9",
+ "#fafafa",
+ "#eceff1",
+ ],
+ [
+ "#ffcdd2",
+ "#f8bbd0",
+ "#e1bee7",
+ "#c5cae9",
+ "#bbdefb",
+ "#b2ebf2",
+ "#b2dfdb",
+ "#c8e6c9",
+ "#dcedc8",
+ "#f0f4c3",
+ "#fff9c4",
+ "#ffecb3",
+ "#ffe0b2",
+ "#ffccbc",
+ "#d7ccc8",
+ "#f5f5f5",
+ "#cfd8dc",
+ ],
+ [
+ "#ef9a9a",
+ "#f48fb1",
+ "#ce93d8",
+ "#9fa8da",
+ "#90caf9",
+ "#80deea",
+ "#80cbc4",
+ "#a5d6a7",
+ "#c5e1a5",
+ "#e6ee9c",
+ "#fff59d",
+ "#ffe082",
+ "#ffcc80",
+ "#ffab91",
+ "#bcaaa4",
+ "#eeeeee",
+ "#b0bec5",
+ ],
+ [
+ "#e57373",
+ "#f06292",
+ "#ba68c8",
+ "#7986cb",
+ "#64b5f6",
+ "#4dd0e1",
+ "#4db6ac",
+ "#81c784",
+ "#aed581",
+ "#dce775",
+ "#fff176",
+ "#ffd54f",
+ "#ffb74d",
+ "#ff8a65",
+ "#a1887f",
+ "#e0e0e0",
+ "#90a4ae",
+ ],
+ [
+ "#ef5350",
+ "#ec407a",
+ "#ab47bc",
+ "#5c6bc0",
+ "#42a5f5",
+ "#26c6da",
+ "#26a69a",
+ "#66bb6a",
+ "#9ccc65",
+ "#d4e157",
+ "#ffee58",
+ "#ffca28",
+ "#ffa726",
+ "#ff7043",
+ "#8d6e63",
+ "#bdbdbd",
+ "#78909c",
+ ],
+ [
+ "#f44336",
+ "#e91e63",
+ "#9c27b0",
+ "#3f51b5",
+ "#2196f3",
+ "#00bcd4",
+ "#009688",
+ "#4caf50",
+ "#8bc34a",
+ "#cddc39",
+ "#ffeb3b",
+ "#ffc107",
+ "#ff9800",
+ "#ff5722",
+ "#795548",
+ "#9e9e9e",
+ "#607d8b",
+ ],
+ [
+ "#e53935",
+ "#d81b60",
+ "#8e24aa",
+ "#3949ab",
+ "#1e88e5",
+ "#00acc1",
+ "#00897b",
+ "#43a047",
+ "#7cb342",
+ "#c0ca33",
+ "#fdd835",
+ "#ffb300",
+ "#fb8c00",
+ "#f4511e",
+ "#6d4c41",
+ "#757575",
+ "#546e7a",
+ ],
+ [
+ "#d32f2f",
+ "#c2185b",
+ "#7b1fa2",
+ "#303f9f",
+ "#1976d2",
+ "#0097a7",
+ "#00796b",
+ "#388e3c",
+ "#689f38",
+ "#afb42b",
+ "#fbc02d",
+ "#ffa000",
+ "#f57c00",
+ "#e64a19",
+ "#5d4037",
+ "#616161",
+ "#455a64",
+ ],
+ [
+ "#c62828",
+ "#ad1457",
+ "#6a1b9a",
+ "#283593",
+ "#1565c0",
+ "#00838f",
+ "#00695c",
+ "#2e7d32",
+ "#558b2f",
+ "#9e9d24",
+ "#f9a825",
+ "#ff8f00",
+ "#ef6c00",
+ "#d84315",
+ "#4e342e",
+ "#424242",
+ "#37474f",
+ ],
+ [
+ "#b71c1c",
+ "#880e4f",
+ "#4a148c",
+ "#1a237e",
+ "#0d47a1",
+ "#006064",
+ "#004d40",
+ "#1b5e20",
+ "#33691e",
+ "#827717",
+ "#f57f17",
+ "#ff6f00",
+ "#e65100",
+ "#bf360c",
+ "#3e2723",
+ "#212121",
+ "#263238",
+ ],
+ ],
+ fire: [
+ [
+ "0b1a6d",
+ "840f38",
+ "b60718",
+ "de030b",
+ "ff0c0c",
+ "fd491c",
+ "fc7521",
+ "faa331",
+ "fbb535",
+ "ffc73a",
+ ],
+ [
+ "071147",
+ "5f0b28",
+ "930513",
+ "be0309",
+ "ef0000",
+ "fa3403",
+ "fb670b",
+ "f9991b",
+ "faad1e",
+ "ffc123",
+ ],
+ [
+ "03071e",
+ "370617",
+ "6a040f",
+ "9d0208",
+ "d00000",
+ "dc2f02",
+ "e85d04",
+ "f48c06",
+ "faa307",
+ "ffba08",
+ ],
+ [
+ "020619",
+ "320615",
+ "61040d",
+ "8c0207",
+ "bc0000",
+ "c82a02",
+ "d05203",
+ "db7f06",
+ "e19405",
+ "efab00",
+ ],
+ [
+ "020515",
+ "2d0513",
+ "58040c",
+ "7f0206",
+ "aa0000",
+ "b62602",
+ "b94903",
+ "c57205",
+ "ca8504",
+ "d89b00",
+ ],
+ ],
+ baby: [
+ [
+ "eddcd2",
+ "fff1e6",
+ "fde2e4",
+ "fad2e1",
+ "c5dedd",
+ "dbe7e4",
+ "f0efeb",
+ "d6e2e9",
+ "bcd4e6",
+ "99c1de",
+ ],
+ [
+ "e1c4b3",
+ "ffd5b5",
+ "fab6ba",
+ "f5a8c4",
+ "aacecd",
+ "bfd5cf",
+ "dbd9d0",
+ "baceda",
+ "9dc0db",
+ "7eb1d5",
+ ],
+ [
+ "daa990",
+ "ffb787",
+ "f88e95",
+ "f282a9",
+ "8fc4c3",
+ "a3c8be",
+ "cec9b3",
+ "9dbcce",
+ "82acd2",
+ "649dcb",
+ ],
+ [
+ "d69070",
+ "ff9c5e",
+ "f66770",
+ "f05f8f",
+ "74bbb9",
+ "87bfae",
+ "c5b993",
+ "83aac3",
+ "699bca",
+ "4d89c2",
+ ],
+ [
+ "c97d5d",
+ "f58443",
+ "eb4d57",
+ "e54a7b",
+ "66a9a7",
+ "78ae9c",
+ "b5a67e",
+ "7599b1",
+ "5c88b7",
+ "4978aa",
+ ],
+ ],
+ chart: [
+ [
+ "#C1D37F",
+ "#4C5454",
+ "#FFD275",
+ "#66586F",
+ "#D05D5B",
+ "#C96480",
+ "#95BF8F",
+ "#6EA240",
+ "#0F0F0E",
+ "#EB8258",
+ "#95A3B3",
+ "#995D81",
+ ],
+ ],
+ };
+
+ /**
+ * Get a pallete
+ */
+ var component = function (o) {
+ // Otherwise get palette value
+ if (palette[o]) {
+ return palette[o];
+ } else {
+ return palette.material;
+ }
+ };
+
+ component.get = function (o) {
+ // Otherwise get palette value
+ if (palette[o]) {
+ return palette[o];
+ } else {
+ return palette;
+ }
+ };
+
+ component.set = function (o, v) {
+ palette[o] = v;
+ };
+
+ return component;
+ })();
+
+ jSuites.picker = function (el, options) {
+ // Already created, update options
+ if (el.picker) {
+ return el.picker.setOptions(options, true);
+ }
+
+ // New instance
+ var obj = { type: "picker" };
+ obj.options = {};
+
+ var dropdownHeader = null;
+ var dropdownContent = null;
+
+ /**
+ * Create the content options
+ */
+ var createContent = function () {
+ dropdownContent.innerHTML = "";
+
+ // Create items
+ var keys = Object.keys(obj.options.data);
+
+ // Go though all options
+ for (var i = 0; i < keys.length; i++) {
+ // Item
+ var dropdownItem = document.createElement("div");
+ dropdownItem.classList.add("jpicker-item");
+ dropdownItem.k = keys[i];
+ dropdownItem.v = obj.options.data[keys[i]];
+ // Label
+ dropdownItem.innerHTML = obj.getLabel(keys[i]);
+ // Append
+ dropdownContent.appendChild(dropdownItem);
+ }
+ };
+
+ /**
+ * Set or reset the options for the picker
+ */
+ obj.setOptions = function (options, reset) {
+ // Default configuration
+ var defaults = {
+ value: 0,
+ data: null,
+ render: null,
+ onchange: null,
+ onselect: null,
+ onopen: null,
+ onclose: null,
+ onload: null,
+ width: null,
+ header: true,
+ right: false,
+ content: false,
+ columns: null,
+ height: null,
+ };
+
+ // Legacy purpose only
+ if (options && options.options) {
+ options.data = options.options;
+ }
+
+ // Loop through the initial configuration
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ if (typeof obj.options[property] == "undefined" || reset === true) {
+ obj.options[property] = defaults[property];
+ }
+ }
+ }
+
+ // Start using the options
+ if (obj.options.header === false) {
+ dropdownHeader.style.display = "none";
+ } else {
+ dropdownHeader.style.display = "";
+ }
+
+ // Width
+ if (obj.options.width) {
+ dropdownHeader.style.width = parseInt(obj.options.width) + "px";
+ } else {
+ dropdownHeader.style.width = "";
+ }
+
+ // Height
+ if (obj.options.height) {
+ dropdownContent.style.maxHeight = obj.options.height + "px";
+ dropdownContent.style.overflow = "scroll";
+ } else {
+ dropdownContent.style.overflow = "";
+ }
+
+ if (obj.options.columns > 0) {
+ dropdownContent.classList.add("jpicker-columns");
+ dropdownContent.style.width = obj.options.width
+ ? obj.options.width
+ : 36 * obj.options.columns + "px";
+ }
+
+ if (isNaN(obj.options.value)) {
+ obj.options.value = "0";
+ }
+
+ // Create list from data
+ createContent();
+
+ // Set value
+ obj.setValue(obj.options.value);
+
+ // Set options all returns the own instance
+ return obj;
+ };
+
+ obj.getValue = function () {
+ return obj.options.value;
+ };
+
+ obj.setValue = function (v) {
+ // Set label
+ obj.setLabel(v);
+
+ // Update value
+ obj.options.value = String(v);
+
+ // Lemonade JS
+ if (el.value != obj.options.value) {
+ el.value = obj.options.value;
+ if (typeof el.oninput == "function") {
+ el.oninput({
+ type: "input",
+ target: el,
+ value: el.value,
+ });
+ }
+ }
+
+ if (dropdownContent.children[v].getAttribute("type") !== "generic") {
+ obj.close();
+ }
+ };
+
+ obj.getLabel = function (v) {
+ var label = obj.options.data[v] || null;
+ if (typeof obj.options.render == "function") {
+ label = obj.options.render(label);
+ }
+ return label;
+ };
+
+ obj.setLabel = function (v) {
+ if (obj.options.content) {
+ var label = '' + obj.options.content + "";
+ } else {
+ var label = obj.getLabel(v);
+ }
+
+ dropdownHeader.innerHTML = label;
+ };
+
+ obj.open = function () {
+ if (!el.classList.contains("jpicker-focus")) {
+ // Start tracking the element
+ jSuites.tracking(obj, true);
+
+ // Open picker
+ el.classList.add("jpicker-focus");
+ el.focus();
+
+ var top = 0;
+ var left = 0;
+
+ dropdownContent.style.marginLeft = "";
+
+ var rectHeader = dropdownHeader.getBoundingClientRect();
+ var rectContent = dropdownContent.getBoundingClientRect();
+
+ if (window.innerHeight < rectHeader.bottom + rectContent.height) {
+ top = -1 * (rectContent.height + 4);
+ } else {
+ top = rectHeader.height + 4;
+ }
+
+ if (obj.options.right === true) {
+ left = -1 * rectContent.width + rectHeader.width;
+ }
+
+ if (rectContent.left + left < 0) {
+ left = left + rectContent.left + 10;
+ }
+ if (rectContent.left + rectContent.width > window.innerWidth) {
+ left =
+ -1 *
+ (10 + rectContent.left + rectContent.width - window.innerWidth);
+ }
+
+ dropdownContent.style.marginTop = parseInt(top) + "px";
+ dropdownContent.style.marginLeft = parseInt(left) + "px";
+
+ //dropdownContent.style.marginTop
+ if (typeof obj.options.onopen == "function") {
+ obj.options.onopen(el, obj);
+ }
+ }
+ };
+
+ obj.close = function () {
+ if (el.classList.contains("jpicker-focus")) {
+ el.classList.remove("jpicker-focus");
+
+ // Start tracking the element
+ jSuites.tracking(obj, false);
+
+ if (typeof obj.options.onclose == "function") {
+ obj.options.onclose(el, obj);
+ }
+ }
+ };
+
+ /**
+ * Create floating picker
+ */
+ var init = function () {
+ // Class
+ el.classList.add("jpicker");
+ el.setAttribute("tabindex", "900");
+ el.onmousedown = function (e) {
+ if (!el.classList.contains("jpicker-focus")) {
+ obj.open();
+ }
+ };
+
+ // Dropdown Header
+ dropdownHeader = document.createElement("div");
+ dropdownHeader.classList.add("jpicker-header");
+
+ // Dropdown content
+ dropdownContent = document.createElement("div");
+ dropdownContent.classList.add("jpicker-content");
+ dropdownContent.onclick = function (e) {
+ var item = jSuites.findElement(e.target, "jpicker-item");
+ if (item) {
+ if (item.parentNode === dropdownContent) {
+ // Update label
+ obj.setValue(item.k);
+ // Call method
+ if (typeof obj.options.onchange == "function") {
+ obj.options.onchange.call(
+ obj,
+ el,
+ obj,
+ item.v,
+ item.v,
+ item.k,
+ e
+ );
+ }
+ }
+ }
+ };
+
+ // Append content and header
+ el.appendChild(dropdownHeader);
+ el.appendChild(dropdownContent);
+
+ // Default value
+ el.value = options.value || 0;
+
+ // Set options
+ obj.setOptions(options);
+
+ if (typeof obj.options.onload == "function") {
+ obj.options.onload(el, obj);
+ }
+
+ // Change
+ el.change = obj.setValue;
+
+ // Global generic value handler
+ el.val = function (val) {
+ if (val === undefined) {
+ return obj.getValue();
+ } else {
+ obj.setValue(val);
+ }
+ };
+
+ // Reference
+ el.picker = obj;
+ };
+
+ init();
+
+ return obj;
+ };
+
+ jSuites.progressbar = function (el, options) {
+ var obj = {};
+ obj.options = {};
+
+ // Default configuration
+ var defaults = {
+ value: 0,
+ onchange: null,
+ width: null,
+ };
+
+ // Loop through the initial configuration
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ obj.options[property] = defaults[property];
+ }
+ }
+
+ // Class
+ el.classList.add("jprogressbar");
+ el.setAttribute("tabindex", 1);
+ el.setAttribute("data-value", obj.options.value);
+
+ var bar = document.createElement("div");
+ bar.style.width = obj.options.value + "%";
+ bar.style.color = "#fff";
+ el.appendChild(bar);
+
+ if (obj.options.width) {
+ el.style.width = obj.options.width;
+ }
+
+ // Set value
+ obj.setValue = function (value) {
+ value = parseInt(value);
+ obj.options.value = value;
+ bar.style.width = value + "%";
+ el.setAttribute("data-value", value + "%");
+
+ if (value < 6) {
+ el.style.color = "#000";
+ } else {
+ el.style.color = "#fff";
+ }
+
+ // Update value
+ obj.options.value = value;
+
+ if (typeof obj.options.onchange == "function") {
+ obj.options.onchange(el, value);
+ }
+
+ // Lemonade JS
+ if (el.value != obj.options.value) {
+ el.value = obj.options.value;
+ if (typeof el.oninput == "function") {
+ el.oninput({
+ type: "input",
+ target: el,
+ value: el.value,
+ });
+ }
+ }
+ };
+
+ obj.getValue = function () {
+ return obj.options.value;
+ };
+
+ var action = function (e) {
+ if (e.which) {
+ // Get target info
+ var rect = el.getBoundingClientRect();
+
+ if (e.changedTouches && e.changedTouches[0]) {
+ var x = e.changedTouches[0].clientX;
+ var y = e.changedTouches[0].clientY;
+ } else {
+ var x = e.clientX;
+ var y = e.clientY;
+ }
+
+ obj.setValue(Math.round(((x - rect.left) / rect.width) * 100));
+ }
+ };
+
+ // Events
+ if ("touchstart" in document.documentElement === true) {
+ el.addEventListener("touchstart", action);
+ el.addEventListener("touchend", action);
+ } else {
+ el.addEventListener("mousedown", action);
+ el.addEventListener("mousemove", action);
+ }
+
+ // Change
+ el.change = obj.setValue;
+
+ // Global generic value handler
+ el.val = function (val) {
+ if (val === undefined) {
+ return obj.getValue();
+ } else {
+ obj.setValue(val);
+ }
+ };
+
+ // Reference
+ el.progressbar = obj;
+
+ return obj;
+ };
+
+ jSuites.rating = function (el, options) {
+ // Already created, update options
+ if (el.rating) {
+ return el.rating.setOptions(options, true);
+ }
+
+ // New instance
+ var obj = {};
+ obj.options = {};
+
+ obj.setOptions = function (options, reset) {
+ // Default configuration
+ var defaults = {
+ number: 5,
+ value: 0,
+ tooltip: ["Very bad", "Bad", "Average", "Good", "Very good"],
+ onchange: null,
+ };
+
+ // Loop through the initial configuration
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ if (typeof obj.options[property] == "undefined" || reset === true) {
+ obj.options[property] = defaults[property];
+ }
+ }
+ }
+
+ // Make sure the container is empty
+ el.innerHTML = "";
+
+ // Add elements
+ for (var i = 0; i < obj.options.number; i++) {
+ var div = document.createElement("div");
+ div.setAttribute("data-index", i + 1);
+ div.setAttribute("title", obj.options.tooltip[i]);
+ el.appendChild(div);
+ }
+
+ // Selected option
+ if (obj.options.value) {
+ for (var i = 0; i < obj.options.number; i++) {
+ if (i < obj.options.value) {
+ el.children[i].classList.add("jrating-selected");
+ }
+ }
+ }
+
+ return obj;
+ };
+
+ // Set value
+ obj.setValue = function (index) {
+ for (var i = 0; i < obj.options.number; i++) {
+ if (i < index) {
+ el.children[i].classList.add("jrating-selected");
+ } else {
+ el.children[i].classList.remove("jrating-over");
+ el.children[i].classList.remove("jrating-selected");
+ }
+ }
+
+ obj.options.value = index;
+
+ if (typeof obj.options.onchange == "function") {
+ obj.options.onchange(el, index);
+ }
+
+ // Lemonade JS
+ if (el.value != obj.options.value) {
+ el.value = obj.options.value;
+ if (typeof el.oninput == "function") {
+ el.oninput({
+ type: "input",
+ target: el,
+ value: el.value,
+ });
+ }
+ }
+ };
+
+ obj.getValue = function () {
+ return obj.options.value;
+ };
+
+ var init = function () {
+ // Start plugin
+ obj.setOptions(options);
+
+ // Class
+ el.classList.add("jrating");
+
+ // Events
+ el.addEventListener("click", function (e) {
+ var index = e.target.getAttribute("data-index");
+ if (index != undefined) {
+ if (index == obj.options.value) {
+ obj.setValue(0);
+ } else {
+ obj.setValue(index);
+ }
+ }
+ });
+
+ el.addEventListener("mouseover", function (e) {
+ var index = e.target.getAttribute("data-index");
+ for (var i = 0; i < obj.options.number; i++) {
+ if (i < index) {
+ el.children[i].classList.add("jrating-over");
+ } else {
+ el.children[i].classList.remove("jrating-over");
+ }
+ }
+ });
+
+ el.addEventListener("mouseout", function (e) {
+ for (var i = 0; i < obj.options.number; i++) {
+ el.children[i].classList.remove("jrating-over");
+ }
+ });
+
+ // Change
+ el.change = obj.setValue;
+
+ // Global generic value handler
+ el.val = function (val) {
+ if (val === undefined) {
+ return obj.getValue();
+ } else {
+ obj.setValue(val);
+ }
+ };
+
+ // Reference
+ el.rating = obj;
+ };
+
+ init();
+
+ return obj;
+ };
+
+ jSuites.search = function (el, options) {
+ if (el.search) {
+ return el.search;
+ }
+
+ var index = null;
+
+ var select = function (e) {
+ if (e.target.classList.contains("jsearch_item")) {
+ var element = e.target;
+ } else {
+ var element = e.target.parentNode;
+ }
+
+ obj.selectIndex(element);
+ e.preventDefault();
+ };
+
+ var createList = function (data) {
+ // Reset container
+ container.innerHTML = "";
+ // Print results
+ if (!data.length) {
+ // Show container
+ el.style.display = "";
+ } else {
+ // Show container
+ el.style.display = "block";
+
+ // Show items (only 10)
+ var len = data.length < 11 ? data.length : 10;
+ for (var i = 0; i < len; i++) {
+ if (typeof data[i] == "string") {
+ var text = data[i];
+ var value = data[i];
+ } else {
+ // Legacy
+ var text = data[i].text;
+ if (!text && data[i].name) {
+ text = data[i].name;
+ }
+ var value = data[i].value;
+ if (!value && data[i].id) {
+ value = data[i].id;
+ }
+ }
+
+ var div = document.createElement("div");
+ div.setAttribute("data-value", value);
+ div.setAttribute("data-text", text);
+ div.className = "jsearch_item";
+
+ if (data[i].id) {
+ div.setAttribute("id", data[i].id);
+ }
+
+ if (obj.options.forceSelect && i == 0) {
+ div.classList.add("selected");
+ }
+ var img = document.createElement("img");
+ if (data[i].image) {
+ img.src = data[i].image;
+ } else {
+ img.style.display = "none";
+ }
+ div.appendChild(img);
+
+ var item = document.createElement("div");
+ item.innerHTML = text;
+ div.appendChild(item);
+
+ // Append item to the container
+ container.appendChild(div);
+ }
+ }
+ };
+
+ var execute = function (str) {
+ if (str != obj.terms) {
+ // New terms
+ obj.terms = str;
+ // New index
+ if (obj.options.forceSelect) {
+ index = 0;
+ } else {
+ index = null;
+ }
+ // Array or remote search
+ if (Array.isArray(obj.options.data)) {
+ var test = function (o) {
+ if (typeof o == "string") {
+ if (("" + o).toLowerCase().search(str.toLowerCase()) >= 0) {
+ return true;
+ }
+ } else {
+ for (var key in o) {
+ var value = o[key];
+ if (("" + value).toLowerCase().search(str.toLowerCase()) >= 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ var results = obj.options.data.filter(function (item) {
+ return test(item);
+ });
+
+ // Show items
+ createList(results);
+ } else {
+ // Get remove results
+ jSuites.ajax({
+ url: obj.options.data + str,
+ method: "GET",
+ dataType: "json",
+ success: function (data) {
+ // Show items
+ createList(data);
+ },
+ });
+ }
+ }
+ };
+
+ // Search timer
+ var timer = null;
+
+ // Search methods
+ var obj = function (str) {
+ if (timer) {
+ clearTimeout(timer);
+ }
+ timer = setTimeout(function () {
+ execute(str);
+ }, 500);
+ };
+ if (options.forceSelect === null) {
+ options.forceSelect = true;
+ }
+ obj.options = {
+ data: options.data || null,
+ input: options.input || null,
+ searchByNode: options.searchByNode || null,
+ onselect: options.onselect || null,
+ forceSelect: options.forceSelect,
+ onbeforesearch: options.onbeforesearch || null,
+ };
+
+ obj.selectIndex = function (item) {
+ var id = item.getAttribute("id");
+ var text = item.getAttribute("data-text");
+ var value = item.getAttribute("data-value");
+ // Onselect
+ if (typeof obj.options.onselect == "function") {
+ obj.options.onselect(obj, text, value, id);
+ }
+ // Close container
+ obj.close();
+ };
+
+ obj.open = function () {
+ el.style.display = "block";
+ };
+
+ obj.close = function () {
+ if (timer) {
+ clearTimeout(timer);
+ }
+ // Current terms
+ obj.terms = "";
+ // Remove results
+ container.innerHTML = "";
+ // Hide
+ el.style.display = "";
+ };
+
+ obj.isOpened = function () {
+ return el.style.display ? true : false;
+ };
+
+ obj.keydown = function (e) {
+ if (obj.isOpened()) {
+ if (e.key == "Enter") {
+ // Enter
+ if (index !== null && container.children[index]) {
+ obj.selectIndex(container.children[index]);
+ e.preventDefault();
+ } else {
+ obj.close();
+ }
+ } else if (e.key === "ArrowUp") {
+ // Up
+ if (index !== null && container.children[0]) {
+ container.children[index].classList.remove("selected");
+ if (!obj.options.forceSelect && index === 0) {
+ index = null;
+ } else {
+ index = Math.max(0, index - 1);
+ container.children[index].classList.add("selected");
+ }
+ }
+ e.preventDefault();
+ } else if (e.key === "ArrowDown") {
+ // Down
+ if (index == null) {
+ index = -1;
+ } else {
+ container.children[index].classList.remove("selected");
+ }
+ if (index < 9 && container.children[index + 1]) {
+ index++;
+ }
+ container.children[index].classList.add("selected");
+ e.preventDefault();
+ }
+ }
+ };
+
+ obj.keyup = function (e) {
+ if (!obj.options.searchByNode) {
+ if (obj.options.input.tagName === "DIV") {
+ var terms = obj.options.input.innerText;
+ } else {
+ var terms = obj.options.input.value;
+ }
+ } else {
+ // Current node
+ var node = jSuites.getNode();
+ if (node) {
+ var terms = node.innerText;
+ }
+ }
+
+ if (typeof obj.options.onbeforesearch == "function") {
+ var ret = obj.options.onbeforesearch(obj, terms);
+ if (ret) {
+ terms = ret;
+ } else {
+ if (ret === false) {
+ // Ignore event
+ return;
+ }
+ }
+ }
+
+ obj(terms);
+ };
+
+ // Add events
+ if (obj.options.input) {
+ obj.options.input.addEventListener("keyup", obj.keyup);
+ obj.options.input.addEventListener("keydown", obj.keydown);
+ }
+
+ // Append element
+ var container = document.createElement("div");
+ container.classList.add("jsearch_container");
+ container.onmousedown = select;
+ el.appendChild(container);
+
+ el.classList.add("jsearch");
+ el.search = obj;
+
+ return obj;
+ };
+
+ jSuites.slider = function (el, options) {
+ var obj = {};
+ obj.options = {};
+ obj.currentImage = null;
+
+ if (options) {
+ obj.options = options;
+ }
+
+ // Focus
+ el.setAttribute("tabindex", "900");
+
+ // Items
+ obj.options.items = [];
+
+ if (!el.classList.contains("jslider")) {
+ el.classList.add("jslider");
+ el.classList.add("unselectable");
+
+ if (obj.options.height) {
+ el.style.minHeight = obj.options.height;
+ }
+ if (obj.options.width) {
+ el.style.width = obj.options.width;
+ }
+ if (obj.options.grid) {
+ el.classList.add("jslider-grid");
+ var number = el.children.length;
+ if (number > 4) {
+ el.setAttribute("data-total", number - 4);
+ }
+ el.setAttribute("data-number", number > 4 ? 4 : number);
+ }
+
+ // Add slider counter
+ var counter = document.createElement("div");
+ counter.classList.add("jslider-counter");
+
+ // Move children inside
+ if (el.children.length > 0) {
+ // Keep children items
+ for (var i = 0; i < el.children.length; i++) {
+ obj.options.items.push(el.children[i]);
+
+ // counter click event
+ var item = document.createElement("div");
+ item.onclick = function () {
+ var index = Array.prototype.slice
+ .call(counter.children)
+ .indexOf(this);
+ obj.show((obj.currentImage = obj.options.items[index]));
+ };
+ counter.appendChild(item);
+ }
+ }
+ // Add caption
+ var caption = document.createElement("div");
+ caption.className = "jslider-caption";
+
+ // Add close buttom
+ var controls = document.createElement("div");
+ var close = document.createElement("div");
+ close.className = "jslider-close";
+ close.innerHTML = "";
+
+ close.onclick = function () {
+ obj.close();
+ };
+ controls.appendChild(caption);
+ controls.appendChild(close);
+ }
+
+ obj.updateCounter = function (index) {
+ for (var i = 0; i < counter.children.length; i++) {
+ if (counter.children[i].classList.contains("jslider-counter-focus")) {
+ counter.children[i].classList.remove("jslider-counter-focus");
+ break;
+ }
+ }
+ counter.children[index].classList.add("jslider-counter-focus");
+ };
+
+ obj.show = function (target) {
+ if (!target) {
+ var target = el.children[0];
+ }
+
+ // Focus element
+ el.classList.add("jslider-focus");
+ el.classList.remove("jslider-grid");
+ el.appendChild(controls);
+ el.appendChild(counter);
+
+ // Update counter
+ var index = obj.options.items.indexOf(target);
+ obj.updateCounter(index);
+
+ // Remove display
+ for (var i = 0; i < el.children.length; i++) {
+ el.children[i].style.display = "";
+ }
+ target.style.display = "block";
+
+ // Is there any previous
+ if (target.previousElementSibling) {
+ el.classList.add("jslider-left");
+ } else {
+ el.classList.remove("jslider-left");
+ }
+
+ // Is there any next
+ if (
+ target.nextElementSibling &&
+ target.nextElementSibling.tagName == "IMG"
+ ) {
+ el.classList.add("jslider-right");
+ } else {
+ el.classList.remove("jslider-right");
+ }
+
+ obj.currentImage = target;
+
+ // Vertical image
+ if (obj.currentImage.offsetHeight > obj.currentImage.offsetWidth) {
+ obj.currentImage.classList.add("jslider-vertical");
+ }
+
+ controls.children[0].innerText = obj.currentImage.getAttribute("title");
+ };
+
+ obj.open = function () {
+ obj.show();
+
+ // Event
+ if (typeof obj.options.onopen == "function") {
+ obj.options.onopen(el);
+ }
+ };
+
+ obj.close = function () {
+ // Remove control classes
+ el.classList.remove("jslider-focus");
+ el.classList.remove("jslider-left");
+ el.classList.remove("jslider-right");
+ // Show as a grid depending on the configuration
+ if (obj.options.grid) {
+ el.classList.add("jslider-grid");
+ }
+ // Remove display
+ for (var i = 0; i < el.children.length; i++) {
+ el.children[i].style.display = "";
+ }
+ // Remove controls from the component
+ counter.remove();
+ controls.remove();
+ // Current image
+ obj.currentImage = null;
+ // Event
+ if (typeof obj.options.onclose == "function") {
+ obj.options.onclose(el);
+ }
+ };
+
+ obj.reset = function () {
+ el.innerHTML = "";
+ };
+
+ obj.next = function () {
+ var nextImage = obj.currentImage.nextElementSibling;
+ if (nextImage && nextImage.tagName === "IMG") {
+ obj.show(obj.currentImage.nextElementSibling);
+ }
+ };
+
+ obj.prev = function () {
+ if (obj.currentImage.previousElementSibling) {
+ obj.show(obj.currentImage.previousElementSibling);
+ }
+ };
+
+ var mouseUp = function (e) {
+ // Open slider
+ if (e.target.tagName == "IMG") {
+ obj.show(e.target);
+ } else if (
+ !e.target.classList.contains("jslider-close") &&
+ !(
+ e.target.parentNode.classList.contains("jslider-counter") ||
+ e.target.classList.contains("jslider-counter")
+ )
+ ) {
+ // Arrow controls
+ var offsetX = e.offsetX || e.changedTouches[0].clientX;
+ if (e.target.clientWidth - offsetX < 40) {
+ // Show next image
+ obj.next();
+ } else if (offsetX < 40) {
+ // Show previous image
+ obj.prev();
+ }
+ }
+ };
+
+ if ("ontouchend" in document.documentElement === true) {
+ el.addEventListener("touchend", mouseUp);
+ } else {
+ el.addEventListener("mouseup", mouseUp);
+ }
+
+ // Add global events
+ el.addEventListener("swipeleft", function (e) {
+ obj.next();
+ e.preventDefault();
+ e.stopPropagation();
+ });
+
+ el.addEventListener("swiperight", function (e) {
+ obj.prev();
+ e.preventDefault();
+ e.stopPropagation();
+ });
+
+ el.addEventListener("keydown", function (e) {
+ if (e.which == 27) {
+ obj.close();
+ }
+ });
+
+ el.slider = obj;
+
+ return obj;
+ };
+
+ jSuites.sorting = function (el, options) {
+ var obj = {};
+ obj.options = {};
+
+ var defaults = {
+ pointer: null,
+ direction: null,
+ ondragstart: null,
+ ondragend: null,
+ ondrop: null,
+ };
+
+ var dragElement = null;
+
+ // Loop through the initial configuration
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ obj.options[property] = defaults[property];
+ }
+ }
+
+ el.classList.add("jsorting");
+
+ el.addEventListener("dragstart", function (e) {
+ var position = Array.prototype.indexOf.call(
+ e.target.parentNode.children,
+ e.target
+ );
+ dragElement = {
+ element: e.target,
+ o: position,
+ d: position,
+ };
+ e.target.style.opacity = "0.25";
+
+ if (typeof obj.options.ondragstart == "function") {
+ obj.options.ondragstart(el, e.target, e);
+ }
+ });
+
+ el.addEventListener("dragover", function (e) {
+ e.preventDefault();
+
+ if (getElement(e.target) && dragElement) {
+ if (
+ e.target.getAttribute("draggable") == "true" &&
+ dragElement.element != e.target
+ ) {
+ if (!obj.options.direction) {
+ var condition = e.target.clientHeight / 2 > e.offsetY;
+ } else {
+ var condition = e.target.clientWidth / 2 > e.offsetX;
+ }
+
+ if (condition) {
+ e.target.parentNode.insertBefore(dragElement.element, e.target);
+ } else {
+ e.target.parentNode.insertBefore(
+ dragElement.element,
+ e.target.nextSibling
+ );
+ }
+
+ dragElement.d = Array.prototype.indexOf.call(
+ e.target.parentNode.children,
+ dragElement.element
+ );
+ }
+ }
+ });
+
+ el.addEventListener("dragleave", function (e) {
+ e.preventDefault();
+ });
+
+ el.addEventListener("dragend", function (e) {
+ e.preventDefault();
+
+ if (dragElement) {
+ if (typeof obj.options.ondragend == "function") {
+ obj.options.ondragend(el, dragElement.element, e);
+ }
+
+ // Cancelled put element to the original position
+ if (dragElement.o < dragElement.d) {
+ e.target.parentNode.insertBefore(
+ dragElement.element,
+ e.target.parentNode.children[dragElement.o]
+ );
+ } else {
+ e.target.parentNode.insertBefore(
+ dragElement.element,
+ e.target.parentNode.children[dragElement.o].nextSibling
+ );
+ }
+
+ dragElement.element.style.opacity = "";
+ dragElement = null;
+ }
+ });
+
+ el.addEventListener("drop", function (e) {
+ e.preventDefault();
+
+ if (dragElement && dragElement.o != dragElement.d) {
+ if (typeof obj.options.ondrop == "function") {
+ obj.options.ondrop(
+ el,
+ dragElement.o,
+ dragElement.d,
+ dragElement.element,
+ e.target,
+ e
+ );
+ }
+ }
+
+ dragElement.element.style.opacity = "";
+ dragElement = null;
+ });
+
+ var getElement = function (element) {
+ var sorting = false;
+
+ function path(element) {
+ if (element.className) {
+ if (element.classList.contains("jsorting")) {
+ sorting = true;
+ }
+ }
+
+ if (!sorting) {
+ path(element.parentNode);
+ }
+ }
+
+ path(element);
+
+ return sorting;
+ };
+
+ for (var i = 0; i < el.children.length; i++) {
+ if (!el.children[i].hasAttribute("draggable")) {
+ el.children[i].setAttribute("draggable", "true");
+ }
+ }
+
+ el.val = function () {
+ var id = null;
+ var data = [];
+ for (var i = 0; i < el.children.length; i++) {
+ if ((id = el.children[i].getAttribute("data-id"))) {
+ data.push(id);
+ }
+ }
+ return data;
+ };
+
+ return el;
+ };
+
+ jSuites.tabs = function (el, options) {
+ var obj = {};
+ obj.options = {};
+
+ // Default configuration
+ var defaults = {
+ data: [],
+ position: null,
+ allowCreate: false,
+ allowChangePosition: false,
+ onclick: null,
+ onload: null,
+ onchange: null,
+ oncreate: null,
+ ondelete: null,
+ onbeforecreate: null,
+ onchangeposition: null,
+ animation: false,
+ hideHeaders: false,
+ padding: null,
+ palette: null,
+ maxWidth: null,
+ };
+
+ // Loop through the initial configuration
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ obj.options[property] = defaults[property];
+ }
+ }
+
+ // Class
+ el.classList.add("jtabs");
+
+ var prev = null;
+ var next = null;
+ var border = null;
+
+ // Helpers
+ var setBorder = function (index) {
+ if (obj.options.animation) {
+ setTimeout(function () {
+ var rect = obj.headers.children[index].getBoundingClientRect();
+
+ if (obj.options.palette == "modern") {
+ border.style.width = rect.width - 4 + "px";
+ border.style.left =
+ obj.headers.children[index].offsetLeft + 2 + "px";
+ } else {
+ border.style.width = rect.width + "px";
+ border.style.left = obj.headers.children[index].offsetLeft + "px";
+ }
+
+ if (obj.options.position == "bottom") {
+ border.style.top = "0px";
+ } else {
+ border.style.bottom = "0px";
+ }
+ }, 150);
+ }
+ };
+
+ var updateControls = function (x) {
+ if (typeof obj.headers.scrollTo == "function") {
+ obj.headers.scrollTo({
+ left: x,
+ behavior: "smooth",
+ });
+ } else {
+ obj.headers.scrollLeft = x;
+ }
+
+ if (x <= 1) {
+ prev.classList.add("disabled");
+ } else {
+ prev.classList.remove("disabled");
+ }
+
+ if (x >= obj.headers.scrollWidth - obj.headers.offsetWidth) {
+ next.classList.add("disabled");
+ } else {
+ next.classList.remove("disabled");
+ }
+
+ if (obj.headers.scrollWidth <= obj.headers.offsetWidth) {
+ prev.style.display = "none";
+ next.style.display = "none";
+ } else {
+ prev.style.display = "";
+ next.style.display = "";
+ }
+ };
+
+ obj.setBorder = setBorder;
+
+ // Set value
+ obj.open = function (index) {
+ var previous = null;
+ for (var i = 0; i < obj.headers.children.length; i++) {
+ if (obj.headers.children[i].classList.contains("jtabs-selected")) {
+ // Current one
+ previous = i;
+ }
+ // Remote selected
+ obj.headers.children[i].classList.remove("jtabs-selected");
+ if (obj.content.children[i]) {
+ obj.content.children[i].classList.remove("jtabs-selected");
+ }
+ }
+
+ obj.headers.children[index].classList.add("jtabs-selected");
+ if (obj.content.children[index]) {
+ obj.content.children[index].classList.add("jtabs-selected");
+ }
+
+ if (previous != index && typeof obj.options.onchange == "function") {
+ if (obj.content.children[index]) {
+ obj.options.onchange(
+ el,
+ obj,
+ index,
+ obj.headers.children[index],
+ obj.content.children[index]
+ );
+ }
+ }
+
+ // Hide
+ if (
+ obj.options.hideHeaders == true &&
+ obj.headers.children.length < 3 &&
+ obj.options.allowCreate == false
+ ) {
+ obj.headers.parentNode.style.display = "none";
+ } else {
+ // Set border
+ setBorder(index);
+
+ obj.headers.parentNode.style.display = "";
+
+ var x1 = obj.headers.children[index].offsetLeft;
+ var x2 = x1 + obj.headers.children[index].offsetWidth;
+ var r1 = obj.headers.scrollLeft;
+ var r2 = r1 + obj.headers.offsetWidth;
+
+ if (!(r1 <= x1 && r2 >= x2)) {
+ // Out of the viewport
+ updateControls(x1 - 1);
+ }
+ }
+ };
+
+ obj.selectIndex = function (a) {
+ var index = Array.prototype.indexOf.call(obj.headers.children, a);
+ if (index >= 0) {
+ obj.open(index);
+ }
+
+ return index;
+ };
+
+ obj.rename = function (i, title) {
+ if (!title) {
+ title = prompt("New title", obj.headers.children[i].innerText);
+ }
+ obj.headers.children[i].innerText = title;
+ obj.open(i);
+ };
+
+ obj.create = function (title, url) {
+ if (typeof obj.options.onbeforecreate == "function") {
+ var ret = obj.options.onbeforecreate(el);
+ if (ret === false) {
+ return false;
+ } else {
+ title = ret;
+ }
+ }
+
+ var div = obj.appendElement(title);
+
+ if (typeof obj.options.oncreate == "function") {
+ obj.options.oncreate(el, div);
+ }
+
+ setBorder();
+
+ return div;
+ };
+
+ obj.remove = function (index) {
+ return obj.deleteElement(index);
+ };
+
+ obj.nextNumber = function () {
+ var num = 0;
+ for (var i = 0; i < obj.headers.children.length; i++) {
+ var tmp = obj.headers.children[i].innerText.match(/[0-9].*/);
+ if (tmp > num) {
+ num = parseInt(tmp);
+ }
+ }
+ if (!num) {
+ num = 1;
+ } else {
+ num++;
+ }
+
+ return num;
+ };
+
+ obj.deleteElement = function (index) {
+ if (!obj.headers.children[index]) {
+ return false;
+ } else {
+ obj.headers.removeChild(obj.headers.children[index]);
+ obj.content.removeChild(obj.content.children[index]);
+ }
+
+ obj.open(0);
+
+ if (typeof obj.options.ondelete == "function") {
+ obj.options.ondelete(el, index);
+ }
+ };
+
+ obj.appendElement = function (title, cb) {
+ if (!title) {
+ var title = prompt("Title?", "");
+ }
+
+ if (title) {
+ // Add content
+ var div = document.createElement("div");
+ obj.content.appendChild(div);
+
+ // Add headers
+ var h = document.createElement("div");
+ h.innerHTML = title;
+ h.content = div;
+ obj.headers.insertBefore(h, obj.headers.lastChild);
+
+ // Sortable
+ if (obj.options.allowChangePosition) {
+ h.setAttribute("draggable", "true");
+ }
+ // Open new tab
+ obj.selectIndex(h);
+
+ // Callback
+ if (typeof cb == "function") {
+ cb(div, h);
+ }
+
+ // Return element
+ return div;
+ }
+ };
+
+ obj.getActive = function () {
+ for (var i = 0; i < obj.headers.children.length; i++) {
+ if (obj.headers.children[i].classList.contains("jtabs-selected")) {
+ return i;
+ }
+ }
+ return 0;
+ };
+
+ obj.updateContent = function (position, newContent) {
+ if (typeof newContent !== "string") {
+ var contentItem = newContent;
+ } else {
+ var contentItem = document.createElement("div");
+ contentItem.innerHTML = newContent;
+ }
+
+ if (obj.content.children[position].classList.contains("jtabs-selected")) {
+ newContent.classList.add("jtabs-selected");
+ }
+
+ obj.content.replaceChild(newContent, obj.content.children[position]);
+
+ setBorder();
+ };
+
+ obj.updatePosition = function (f, t) {
+ // Ondrop update position of content
+ if (f > t) {
+ obj.content.insertBefore(
+ obj.content.children[f],
+ obj.content.children[t]
+ );
+ } else {
+ obj.content.insertBefore(
+ obj.content.children[f],
+ obj.content.children[t].nextSibling
+ );
+ }
+
+ // Open destination tab
+ obj.open(t);
+
+ // Call event
+ if (typeof obj.options.onchangeposition == "function") {
+ obj.options.onchangeposition(obj.headers, f, t);
+ }
+ };
+
+ obj.move = function (f, t) {
+ if (f > t) {
+ obj.headers.insertBefore(
+ obj.headers.children[f],
+ obj.headers.children[t]
+ );
+ } else {
+ obj.headers.insertBefore(
+ obj.headers.children[f],
+ obj.headers.children[t].nextSibling
+ );
+ }
+
+ obj.updatePosition(f, t);
+ };
+
+ obj.setBorder = setBorder;
+
+ obj.init = function () {
+ el.innerHTML = "";
+
+ // Make sure the component is blank
+ obj.headers = document.createElement("div");
+ obj.content = document.createElement("div");
+ obj.headers.classList.add("jtabs-headers");
+ obj.content.classList.add("jtabs-content");
+
+ if (obj.options.palette) {
+ el.classList.add("jtabs-modern");
+ } else {
+ el.classList.remove("jtabs-modern");
+ }
+
+ // Padding
+ if (obj.options.padding) {
+ obj.content.style.padding = parseInt(obj.options.padding) + "px";
+ }
+
+ // Header
+ var header = document.createElement("div");
+ header.className = "jtabs-headers-container";
+ header.appendChild(obj.headers);
+ if (obj.options.maxWidth) {
+ header.style.maxWidth = parseInt(obj.options.maxWidth) + "px";
+ }
+
+ // Controls
+ var controls = document.createElement("div");
+ controls.className = "jtabs-controls";
+ controls.setAttribute("draggable", "false");
+ header.appendChild(controls);
+
+ // Append DOM elements
+ if (obj.options.position == "bottom") {
+ el.appendChild(obj.content);
+ el.appendChild(header);
+ } else {
+ el.appendChild(header);
+ el.appendChild(obj.content);
+ }
+
+ // New button
+ if (obj.options.allowCreate == true) {
+ var add = document.createElement("div");
+ add.className = "jtabs-add";
+ add.onclick = function () {
+ obj.create();
+ };
+ controls.appendChild(add);
+ }
+
+ prev = document.createElement("div");
+ prev.className = "jtabs-prev";
+ prev.onclick = function () {
+ updateControls(obj.headers.scrollLeft - obj.headers.offsetWidth);
+ };
+ controls.appendChild(prev);
+
+ next = document.createElement("div");
+ next.className = "jtabs-next";
+ next.onclick = function () {
+ updateControls(obj.headers.scrollLeft + obj.headers.offsetWidth);
+ };
+ controls.appendChild(next);
+
+ // Data
+ for (var i = 0; i < obj.options.data.length; i++) {
+ // Title
+ if (obj.options.data[i].titleElement) {
+ var headerItem = obj.options.data[i].titleElement;
+ } else {
+ var headerItem = document.createElement("div");
+ }
+ // Icon
+ if (obj.options.data[i].icon) {
+ var iconContainer = document.createElement("div");
+ var icon = document.createElement("i");
+ icon.classList.add("material-icons");
+ icon.innerHTML = obj.options.data[i].icon;
+ iconContainer.appendChild(icon);
+ headerItem.appendChild(iconContainer);
+ }
+ // Title
+ if (obj.options.data[i].title) {
+ var title = document.createTextNode(obj.options.data[i].title);
+ headerItem.appendChild(title);
+ }
+ // Width
+ if (obj.options.data[i].width) {
+ headerItem.style.width = obj.options.data[i].width;
+ }
+ // Content
+ if (obj.options.data[i].contentElement) {
+ var contentItem = obj.options.data[i].contentElement;
+ } else {
+ var contentItem = document.createElement("div");
+ contentItem.innerHTML = obj.options.data[i].content;
+ }
+ obj.headers.appendChild(headerItem);
+ obj.content.appendChild(contentItem);
+ }
+
+ // Animation
+ border = document.createElement("div");
+ border.className = "jtabs-border";
+ obj.headers.appendChild(border);
+
+ if (obj.options.animation) {
+ el.classList.add("jtabs-animation");
+ }
+
+ // Events
+ obj.headers.addEventListener("click", function (e) {
+ if (e.target.parentNode.classList.contains("jtabs-headers")) {
+ var target = e.target;
+ } else {
+ if (e.target.tagName == "I") {
+ var target = e.target.parentNode.parentNode;
+ } else {
+ var target = e.target.parentNode;
+ }
+ }
+
+ var index = obj.selectIndex(target);
+
+ if (typeof obj.options.onclick == "function") {
+ obj.options.onclick(
+ el,
+ obj,
+ index,
+ obj.headers.children[index],
+ obj.content.children[index]
+ );
+ }
+ });
+
+ obj.headers.addEventListener("contextmenu", function (e) {
+ obj.selectIndex(e.target);
+ });
+
+ if (obj.headers.children.length) {
+ // Open first tab
+ obj.open(0);
+ }
+
+ // Update controls
+ updateControls(0);
+
+ if (obj.options.allowChangePosition == true) {
+ jSuites.sorting(obj.headers, {
+ direction: 1,
+ ondrop: function (a, b, c) {
+ obj.updatePosition(b, c);
+ },
+ });
+ }
+
+ if (typeof obj.options.onload == "function") {
+ obj.options.onload(el, obj);
+ }
+ };
+
+ // Loading existing nodes as the data
+ if (el.children[0] && el.children[0].children.length) {
+ // Create from existing elements
+ for (var i = 0; i < el.children[0].children.length; i++) {
+ var item =
+ obj.options.data && obj.options.data[i] ? obj.options.data[i] : {};
+
+ if (el.children[1] && el.children[1].children[i]) {
+ item.titleElement = el.children[0].children[i];
+ item.contentElement = el.children[1].children[i];
+ } else {
+ item.contentElement = el.children[0].children[i];
+ }
+
+ obj.options.data[i] = item;
+ }
+ }
+
+ // Remote controller flag
+ var loadingRemoteData = false;
+
+ // Create from data
+ if (obj.options.data) {
+ // Append children
+ for (var i = 0; i < obj.options.data.length; i++) {
+ if (obj.options.data[i].url) {
+ jSuites.ajax({
+ url: obj.options.data[i].url,
+ type: "GET",
+ dataType: "text/html",
+ index: i,
+ success: function (result) {
+ obj.options.data[this.index].content = result;
+ },
+ complete: function () {
+ obj.init();
+ },
+ });
+
+ // Flag loading
+ loadingRemoteData = true;
+ }
+ }
+ }
+
+ if (!loadingRemoteData) {
+ obj.init();
+ }
+
+ el.tabs = obj;
+
+ return obj;
+ };
+
+ jSuites.tags = function (el, options) {
+ // Redefine configuration
+ if (el.tags) {
+ return el.tags.setOptions(options, true);
+ }
+
+ var obj = { type: "tags" };
+ obj.options = {};
+
+ // Limit
+ var limit = function () {
+ return obj.options.limit && el.children.length >= obj.options.limit
+ ? true
+ : false;
+ };
+
+ // Search helpers
+ var search = null;
+ var searchContainer = null;
+
+ obj.setOptions = function (options, reset) {
+ /**
+ * @typedef {Object} defaults
+ * @property {(string|Array)} value - Initial value of the compontent
+ * @property {number} limit - Max number of tags inside the element
+ * @property {string} search - The URL for suggestions
+ * @property {string} placeholder - The default instruction text on the element
+ * @property {validation} validation - Method to validate the tags
+ * @property {requestCallback} onbeforechange - Method to be execute before any changes on the element
+ * @property {requestCallback} onchange - Method to be execute after any changes on the element
+ * @property {requestCallback} onfocus - Method to be execute when on focus
+ * @property {requestCallback} onblur - Method to be execute when on blur
+ * @property {requestCallback} onload - Method to be execute when the element is loaded
+ */
+ var defaults = {
+ value: "",
+ limit: null,
+ limitMessage: null,
+ search: null,
+ placeholder: null,
+ validation: null,
+ onbeforepaste: null,
+ onbeforechange: null,
+ onlimit: null,
+ onchange: null,
+ onfocus: null,
+ onblur: null,
+ onload: null,
+ colors: null,
+ };
+
+ // Loop through though the default configuration
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ if (typeof obj.options[property] == "undefined" || reset === true) {
+ obj.options[property] = defaults[property];
+ }
+ }
+ }
+
+ // Placeholder
+ if (obj.options.placeholder) {
+ el.setAttribute("data-placeholder", obj.options.placeholder);
+ } else {
+ el.removeAttribute("data-placeholder");
+ }
+ el.placeholder = obj.options.placeholder;
+
+ // Update value
+ obj.setValue(obj.options.value);
+
+ // Validate items
+ filter();
+
+ // Create search box
+ if (obj.options.search) {
+ if (!searchContainer) {
+ searchContainer = document.createElement("div");
+ el.parentNode.insertBefore(searchContainer, el.nextSibling);
+
+ // Create container
+ search = jSuites.search(searchContainer, {
+ data: obj.options.search,
+ onselect: function (a, b, c) {
+ obj.selectIndex(b, c);
+ },
+ });
+ }
+ } else {
+ if (searchContainer) {
+ search = null;
+ searchContainer.remove();
+ searchContainer = null;
+ }
+ }
+
+ return obj;
+ };
+
+ /**
+ * Add a new tag to the element
+ * @param {(?string|Array)} value - The value of the new element
+ */
+ obj.add = function (value, focus) {
+ if (typeof obj.options.onbeforechange == "function") {
+ var ret = obj.options.onbeforechange(el, obj, obj.options.value, value);
+ if (ret === false) {
+ return false;
+ } else {
+ if (ret != null) {
+ value = ret;
+ }
+ }
+ }
+
+ // Make sure search is closed
+ if (search) {
+ search.close();
+ }
+
+ if (limit()) {
+ if (typeof obj.options.onlimit == "function") {
+ obj.options.onlimit(obj, obj.options.limit);
+ } else if (obj.options.limitMessage) {
+ alert(obj.options.limitMessage + " " + obj.options.limit);
+ }
+ } else {
+ // Get node
+ var node = jSuites.getNode();
+
+ if (
+ node &&
+ node.parentNode &&
+ node.parentNode.classList.contains("jtags") &&
+ node.nextSibling &&
+ !(node.nextSibling.innerText && node.nextSibling.innerText.trim())
+ ) {
+ div = node.nextSibling;
+ } else {
+ // Remove not used last item
+ if (el.lastChild) {
+ if (!el.lastChild.innerText.trim()) {
+ el.removeChild(el.lastChild);
+ }
+ }
+
+ // Mix argument string or array
+ if (!value || typeof value == "string") {
+ var div = createElement(value, value, node);
+ } else {
+ for (var i = 0; i <= value.length; i++) {
+ if (!limit()) {
+ if (!value[i] || typeof value[i] == "string") {
+ var t = value[i] || "";
+ var v = null;
+ } else {
+ var t = value[i].text;
+ var v = value[i].value;
+ }
+
+ // Add element
+ var div = createElement(t, v);
+ }
+ }
+ }
+
+ // Change
+ change();
+ }
+
+ // Place caret
+ if (focus) {
+ setFocus(div);
+ }
+ }
+ };
+
+ obj.setLimit = function (limit) {
+ obj.options.limit = limit;
+ var n = el.children.length - limit;
+ while (el.children.length > limit) {
+ el.removeChild(el.lastChild);
+ }
+ };
+
+ // Remove a item node
+ obj.remove = function (node) {
+ // Remove node
+ node.parentNode.removeChild(node);
+ // Make sure element is not blank
+ if (!el.children.length) {
+ obj.add("", true);
+ } else {
+ change();
+ }
+ };
+
+ /**
+ * Get all tags in the element
+ * @return {Array} data - All tags as an array
+ */
+ obj.getData = function () {
+ var data = [];
+ for (var i = 0; i < el.children.length; i++) {
+ // Get value
+ var text = el.children[i].innerText.replace("\n", "");
+ // Get id
+ var value = el.children[i].getAttribute("data-value");
+ if (!value) {
+ value = text;
+ }
+ // Item
+ if (text || value) {
+ data.push({ text: text, value: value });
+ }
+ }
+ return data;
+ };
+
+ /**
+ * Get the value of one tag. Null for all tags
+ * @param {?number} index - Tag index number. Null for all tags.
+ * @return {string} value - All tags separated by comma
+ */
+ obj.getValue = function (index) {
+ var value = null;
+
+ if (index != null) {
+ // Get one individual value
+ value = el.children[index].getAttribute("data-value");
+ if (!value) {
+ value = el.children[index].innerText.replace("\n", "");
+ }
+ } else {
+ // Get all
+ var data = [];
+ for (var i = 0; i < el.children.length; i++) {
+ value = el.children[i].innerText.replace("\n", "");
+ if (value) {
+ data.push(obj.getValue(i));
+ }
+ }
+ value = data.join(",");
+ }
+
+ return value;
+ };
+
+ /**
+ * Set the value of the element based on a string separeted by (,|;|\r\n)
+ * @param {mixed} value - A string or array object with values
+ */
+ obj.setValue = function (mixed) {
+ if (!mixed) {
+ obj.reset();
+ } else {
+ if (el.value != mixed) {
+ if (Array.isArray(mixed)) {
+ obj.add(mixed);
+ } else {
+ // Remove whitespaces
+ var text = ("" + mixed).trim();
+ // Tags
+ var data = extractTags(text);
+ // Reset
+ el.innerHTML = "";
+ // Add tags to the element
+ obj.add(data);
+ }
+ }
+ }
+ };
+
+ /**
+ * Reset the data from the element
+ */
+ obj.reset = function () {
+ // Empty class
+ el.classList.add("jtags-empty");
+ // Empty element
+ el.innerHTML = "";
+ // Execute changes
+ change();
+ };
+
+ /**
+ * Verify if all tags in the element are valid
+ * @return {boolean}
+ */
+ obj.isValid = function () {
+ var test = 0;
+ for (var i = 0; i < el.children.length; i++) {
+ if (el.children[i].classList.contains("jtags_error")) {
+ test++;
+ }
+ }
+ return test == 0 ? true : false;
+ };
+
+ /**
+ * Add one element from the suggestions to the element
+ * @param {object} item - Node element in the suggestions container
+ */
+ obj.selectIndex = function (text, value) {
+ var node = jSuites.getNode();
+ if (node) {
+ // Append text to the caret
+ node.innerText = text;
+ // Set node id
+ if (value) {
+ node.setAttribute("data-value", value);
+ }
+ // Remove any error
+ node.classList.remove("jtags_error");
+ if (!limit()) {
+ // Add new item
+ obj.add("", true);
+ }
+ }
+ };
+
+ /**
+ * Search for suggestions
+ * @param {object} node - Target node for any suggestions
+ */
+ obj.search = function (node) {
+ // Search for
+ var terms = node.innerText;
+ };
+
+ // Destroy tags element
+ obj.destroy = function () {
+ // Bind events
+ el.removeEventListener("mouseup", tagsMouseUp);
+ el.removeEventListener("keydown", tagsKeyDown);
+ el.removeEventListener("keyup", tagsKeyUp);
+ el.removeEventListener("paste", tagsPaste);
+ el.removeEventListener("focus", tagsFocus);
+ el.removeEventListener("blur", tagsBlur);
+
+ // Remove element
+ el.parentNode.removeChild(el);
+ };
+
+ var setFocus = function (node) {
+ if (el.children.length > 1) {
+ var range = document.createRange();
+ var sel = window.getSelection();
+ if (!node) {
+ var node = el.childNodes[el.childNodes.length - 1];
+ }
+ range.setStart(node, node.length);
+ range.collapse(true);
+ sel.removeAllRanges();
+ sel.addRange(range);
+ el.scrollLeft = el.scrollWidth;
+ }
+ };
+
+ var createElement = function (label, value, node) {
+ var div = document.createElement("div");
+ div.innerHTML = label ? label : "";
+ if (value) {
+ div.setAttribute("data-value", value);
+ }
+
+ if (node && node.parentNode.classList.contains("jtags")) {
+ el.insertBefore(div, node.nextSibling);
+ } else {
+ el.appendChild(div);
+ }
+
+ return div;
+ };
+
+ var change = function () {
+ // Value
+ var value = obj.getValue();
+
+ if (value != obj.options.value) {
+ obj.options.value = value;
+ if (typeof obj.options.onchange == "function") {
+ obj.options.onchange(el, obj, obj.options.value);
+ }
+
+ // Lemonade JS
+ if (el.value != obj.options.value) {
+ el.value = obj.options.value;
+ if (typeof el.oninput == "function") {
+ el.oninput({
+ type: "input",
+ target: el,
+ value: el.value,
+ });
+ }
+ }
+ }
+
+ filter();
+ };
+
+ /**
+ * Filter tags
+ */
+ var filter = function () {
+ for (var i = 0; i < el.children.length; i++) {
+ // Create label design
+ if (!obj.getValue(i)) {
+ el.children[i].classList.remove("jtags_label");
+ } else {
+ el.children[i].classList.add("jtags_label");
+
+ // Validation in place
+ if (typeof obj.options.validation == "function") {
+ if (obj.getValue(i)) {
+ if (
+ !obj.options.validation(
+ el.children[i],
+ el.children[i].innerText,
+ el.children[i].getAttribute("data-value")
+ )
+ ) {
+ el.children[i].classList.add("jtags_error");
+ } else {
+ el.children[i].classList.remove("jtags_error");
+ }
+ } else {
+ el.children[i].classList.remove("jtags_error");
+ }
+ } else {
+ el.children[i].classList.remove("jtags_error");
+ }
+ }
+ }
+
+ isEmpty();
+ };
+
+ var isEmpty = function () {
+ // Can't be empty
+ if (!el.innerText.trim()) {
+ el.innerHTML = "";
+ el.classList.add("jtags-empty");
+ } else {
+ el.classList.remove("jtags-empty");
+ }
+ };
+
+ /**
+ * Extract tags from a string
+ * @param {string} text - Raw string
+ * @return {Array} data - Array with extracted tags
+ */
+ var extractTags = function (text) {
+ /** @type {Array} */
+ var data = [];
+
+ /** @type {string} */
+ var word = "";
+
+ // Remove whitespaces
+ text = text.trim();
+
+ if (text) {
+ for (var i = 0; i < text.length; i++) {
+ if (text[i] == "," || text[i] == ";" || text[i] == "\n") {
+ if (word) {
+ data.push(word.trim());
+ word = "";
+ }
+ } else {
+ word += text[i];
+ }
+ }
+
+ if (word) {
+ data.push(word);
+ }
+ }
+
+ return data;
+ };
+
+ /** @type {number} */
+ var anchorOffset = 0;
+
+ /**
+ * Processing event keydown on the element
+ * @param e {object}
+ */
+ var tagsKeyDown = function (e) {
+ // Anchoroffset
+ anchorOffset = window.getSelection().anchorOffset;
+
+ // Verify if is empty
+ isEmpty();
+
+ // Comma
+ if (e.key === "Tab" || e.key === ";" || e.key === ",") {
+ var n = window.getSelection().anchorOffset;
+ if (n > 1) {
+ if (limit()) {
+ if (typeof obj.options.onlimit == "function") {
+ obj.options.onlimit(obj, obj.options.limit);
+ }
+ } else {
+ obj.add("", true);
+ }
+ }
+ e.preventDefault();
+ } else if (e.key == "Enter") {
+ if (!search || !search.isOpened()) {
+ var n = window.getSelection().anchorOffset;
+ if (n > 1) {
+ if (!limit()) {
+ obj.add("", true);
+ }
+ }
+ e.preventDefault();
+ }
+ } else if (e.key == "Backspace") {
+ // Back space - do not let last item to be removed
+ if (el.children.length == 1 && window.getSelection().anchorOffset < 1) {
+ e.preventDefault();
+ }
+ }
+
+ // Search events
+ if (search) {
+ search.keydown(e);
+ }
+ };
+
+ /**
+ * Processing event keyup on the element
+ * @param e {object}
+ */
+ var tagsKeyUp = function (e) {
+ if (e.which == 39) {
+ // Right arrow
+ var n = window.getSelection().anchorOffset;
+ if (n > 1 && n == anchorOffset) {
+ obj.add("", true);
+ }
+ } else if (e.which == 13 || e.which == 38 || e.which == 40) {
+ e.preventDefault();
+ } else {
+ if (search) {
+ search.keyup(e);
+ }
+ }
+
+ filter();
+ };
+
+ /**
+ * Processing event paste on the element
+ * @param e {object}
+ */
+ var tagsPaste = function (e) {
+ if (e.clipboardData || e.originalEvent.clipboardData) {
+ var text = (e.originalEvent || e).clipboardData.getData("text/plain");
+ } else if (window.clipboardData) {
+ var text = window.clipboardData.getData("Text");
+ }
+
+ var data = extractTags(text);
+
+ if (typeof obj.options.onbeforepaste == "function") {
+ var ret = obj.options.onbeforepaste(el, obj, data);
+ if (ret === false) {
+ e.preventDefault();
+ return false;
+ } else {
+ if (ret) {
+ data = ret;
+ }
+ }
+ }
+
+ if (data.length > 1) {
+ obj.add(data, true);
+ e.preventDefault();
+ } else if (data[0]) {
+ document.execCommand("insertText", false, data[0]);
+ e.preventDefault();
+ }
+ };
+
+ /**
+ * Processing event mouseup on the element
+ * @param e {object}
+ */
+ var tagsMouseUp = function (e) {
+ if (
+ e.target.parentNode &&
+ e.target.parentNode.classList.contains("jtags")
+ ) {
+ if (
+ e.target.classList.contains("jtags_label") ||
+ e.target.classList.contains("jtags_error")
+ ) {
+ var rect = e.target.getBoundingClientRect();
+ if (rect.width - (e.clientX - rect.left) < 16) {
+ obj.remove(e.target);
+ }
+ }
+ }
+
+ // Set focus in the last item
+ if (e.target == el) {
+ setFocus();
+ }
+ };
+
+ var tagsFocus = function () {
+ if (!el.classList.contains("jtags-focus")) {
+ if (!el.children.length || obj.getValue(el.children.length - 1)) {
+ if (!limit()) {
+ createElement("");
+ }
+ }
+
+ if (typeof obj.options.onfocus == "function") {
+ obj.options.onfocus(el, obj, obj.getValue());
+ }
+
+ el.classList.add("jtags-focus");
+ }
+ };
+
+ var tagsBlur = function () {
+ if (el.classList.contains("jtags-focus")) {
+ if (search) {
+ search.close();
+ }
+
+ for (var i = 0; i < el.children.length - 1; i++) {
+ // Create label design
+ if (!obj.getValue(i)) {
+ el.removeChild(el.children[i]);
+ }
+ }
+
+ change();
+
+ el.classList.remove("jtags-focus");
+
+ if (typeof obj.options.onblur == "function") {
+ obj.options.onblur(el, obj, obj.getValue());
+ }
+ }
+ };
+
+ var init = function () {
+ // Bind events
+ if ("touchend" in document.documentElement === true) {
+ el.addEventListener("touchend", tagsMouseUp);
+ } else {
+ el.addEventListener("mouseup", tagsMouseUp);
+ }
+
+ el.addEventListener("keydown", tagsKeyDown);
+ el.addEventListener("keyup", tagsKeyUp);
+ el.addEventListener("paste", tagsPaste);
+ el.addEventListener("focus", tagsFocus);
+ el.addEventListener("blur", tagsBlur);
+
+ // Editable
+ el.setAttribute("contenteditable", true);
+
+ // Prepare container
+ el.classList.add("jtags");
+
+ // Initial options
+ obj.setOptions(options);
+
+ if (typeof obj.options.onload == "function") {
+ obj.options.onload(el, obj);
+ }
+
+ // Change methods
+ el.change = obj.setValue;
+
+ // Global generic value handler
+ el.val = function (val) {
+ if (val === undefined) {
+ return obj.getValue();
+ } else {
+ obj.setValue(val);
+ }
+ };
+
+ el.tags = obj;
+ };
+
+ init();
+
+ return obj;
+ };
+
+ jSuites.toolbar = function (el, options) {
+ // New instance
+ var obj = { type: "toolbar" };
+ obj.options = {};
+
+ // Default configuration
+ var defaults = {
+ app: null,
+ container: false,
+ badge: false,
+ title: false,
+ responsive: false,
+ maxWidth: null,
+ bottom: true,
+ items: [],
+ };
+
+ // Loop through our object
+ for (var property in defaults) {
+ if (options && options.hasOwnProperty(property)) {
+ obj.options[property] = options[property];
+ } else {
+ obj.options[property] = defaults[property];
+ }
+ }
+
+ if (!el && options.app && options.app.el) {
+ el = document.createElement("div");
+ options.app.el.appendChild(el);
+ }
+
+ // Arrow
+ var toolbarArrow = document.createElement("div");
+ toolbarArrow.classList.add("jtoolbar-item");
+ toolbarArrow.classList.add("jtoolbar-arrow");
+
+ var toolbarFloating = document.createElement("div");
+ toolbarFloating.classList.add("jtoolbar-floating");
+ toolbarArrow.appendChild(toolbarFloating);
+
+ obj.selectItem = function (element) {
+ var elements = toolbarContent.children;
+ for (var i = 0; i < elements.length; i++) {
+ if (element != elements[i]) {
+ elements[i].classList.remove("jtoolbar-selected");
+ }
+ }
+ element.classList.add("jtoolbar-selected");
+ };
+
+ obj.hide = function () {
+ jSuites.animation.slideBottom(el, 0, function () {
+ el.style.display = "none";
+ });
+ };
+
+ obj.show = function () {
+ el.style.display = "";
+ jSuites.animation.slideBottom(el, 1);
+ };
+
+ obj.get = function () {
+ return el;
+ };
+
+ obj.setBadge = function (index, value) {
+ toolbarContent.children[index].children[1].firstChild.innerHTML = value;
+ };
+
+ obj.destroy = function () {
+ toolbar.remove();
+ el.innerHTML = "";
+ };
+
+ obj.update = function (a, b) {
+ for (var i = 0; i < toolbarContent.children.length; i++) {
+ // Toolbar element
+ var toolbarItem = toolbarContent.children[i];
+ // State management
+ if (typeof toolbarItem.updateState == "function") {
+ toolbarItem.updateState(el, obj, toolbarItem, a, b);
+ }
+ }
+ for (var i = 0; i < toolbarFloating.children.length; i++) {
+ // Toolbar element
+ var toolbarItem = toolbarFloating.children[i];
+ // State management
+ if (typeof toolbarItem.updateState == "function") {
+ toolbarItem.updateState(el, obj, toolbarItem, a, b);
+ }
+ }
+ };
+
+ obj.create = function (items) {
+ // Reset anything in the toolbar
+ toolbarContent.innerHTML = "";
+ // Create elements in the toolbar
+ for (var i = 0; i < items.length; i++) {
+ var toolbarItem = document.createElement("div");
+ toolbarItem.classList.add("jtoolbar-item");
+
+ if (items[i].width) {
+ toolbarItem.style.width = parseInt(items[i].width) + "px";
+ }
+
+ if (items[i].k) {
+ toolbarItem.k = items[i].k;
+ }
+
+ if (items[i].tooltip) {
+ toolbarItem.setAttribute("title", items[i].tooltip);
+ }
+
+ // Id
+ if (items[i].id) {
+ toolbarItem.setAttribute("id", items[i].id);
+ }
+
+ // Selected
+ if (items[i].updateState) {
+ toolbarItem.updateState = items[i].updateState;
+ }
+
+ if (items[i].active) {
+ toolbarItem.classList.add("jtoolbar-active");
+ }
+
+ if (items[i].type == "select" || items[i].type == "dropdown") {
+ jSuites.picker(toolbarItem, items[i]);
+ } else if (items[i].type == "divisor") {
+ toolbarItem.classList.add("jtoolbar-divisor");
+ } else if (items[i].type == "label") {
+ toolbarItem.classList.add("jtoolbar-label");
+ toolbarItem.innerHTML = items[i].content;
+ } else {
+ // Material icons
+ var toolbarIcon = document.createElement("i");
+ if (typeof items[i].class === "undefined") {
+ toolbarIcon.classList.add("material-icons");
+ } else {
+ var c = items[i].class.split(" ");
+ for (var j = 0; j < c.length; j++) {
+ toolbarIcon.classList.add(c[j]);
+ }
+ }
+ toolbarIcon.innerHTML = items[i].content ? items[i].content : "";
+ toolbarItem.appendChild(toolbarIcon);
+
+ // Badge options
+ if (obj.options.badge == true) {
+ var toolbarBadge = document.createElement("div");
+ toolbarBadge.classList.add("jbadge");
+ var toolbarBadgeContent = document.createElement("div");
+ toolbarBadgeContent.innerHTML = items[i].badge
+ ? items[i].badge
+ : "";
+ toolbarBadge.appendChild(toolbarBadgeContent);
+ toolbarItem.appendChild(toolbarBadge);
+ }
+
+ // Title
+ if (items[i].title) {
+ if (obj.options.title == true) {
+ var toolbarTitle = document.createElement("span");
+ toolbarTitle.innerHTML = items[i].title;
+ toolbarItem.appendChild(toolbarTitle);
+ } else {
+ toolbarItem.setAttribute("title", items[i].title);
+ }
+ }
+
+ if (obj.options.app && items[i].route) {
+ // Route
+ toolbarItem.route = items[i].route;
+ // Onclick for route
+ toolbarItem.onclick = function () {
+ obj.options.app.pages(this.route);
+ };
+ // Create pages
+ obj.options.app.pages(items[i].route, {
+ toolbarItem: toolbarItem,
+ closed: true,
+ });
+ }
+ }
+
+ if (items[i].onclick) {
+ toolbarItem.onclick = items[i].onclick.bind(
+ items[i],
+ el,
+ obj,
+ toolbarItem
+ );
+ }
+
+ toolbarContent.appendChild(toolbarItem);
+ }
+
+ // Fits to the page
+ setTimeout(function () {
+ obj.refresh();
+ }, 0);
+ };
+
+ obj.open = function () {
+ toolbarArrow.classList.add("jtoolbar-arrow-selected");
+
+ var rectElement = el.getBoundingClientRect();
+ var rect = toolbarFloating.getBoundingClientRect();
+ if (rect.bottom > window.innerHeight || obj.options.bottom) {
+ toolbarFloating.style.bottom = "0";
+ } else {
+ toolbarFloating.style.removeProperty("bottom");
+ }
+
+ toolbarFloating.style.right = "0";
+
+ toolbarArrow.children[0].focus();
+ // Start tracking
+ jSuites.tracking(obj, true);
+ };
+
+ obj.close = function () {
+ toolbarArrow.classList.remove("jtoolbar-arrow-selected");
+ // End tracking
+ jSuites.tracking(obj, false);
+ };
+
+ obj.refresh = function () {
+ if (obj.options.responsive == true) {
+ // Width of the c
+ var rect = el.parentNode.getBoundingClientRect();
+ if (!obj.options.maxWidth) {
+ obj.options.maxWidth = rect.width;
+ }
+ // Available parent space
+ var available = parseInt(obj.options.maxWidth);
+ // Remove arrow
+ if (toolbarArrow.parentNode) {
+ toolbarArrow.parentNode.removeChild(toolbarArrow);
+ }
+ // Move all items to the toolbar
+ while (toolbarFloating.firstChild) {
+ toolbarContent.appendChild(toolbarFloating.firstChild);
+ }
+ // Toolbar is larger than the parent, move elements to the floating element
+ if (available < toolbarContent.offsetWidth) {
+ // Give space to the floating element
+ available -= 50;
+ // Move to the floating option
+ while (
+ toolbarContent.lastChild &&
+ available < toolbarContent.offsetWidth
+ ) {
+ toolbarFloating.insertBefore(
+ toolbarContent.lastChild,
+ toolbarFloating.firstChild
+ );
+ }
+ }
+ // Show arrow
+ if (toolbarFloating.children.length > 0) {
+ toolbarContent.appendChild(toolbarArrow);
+ }
+ }
+ };
+
+ obj.setReadonly = function (state) {
+ state = state ? "add" : "remove";
+ el.classList[state]("jtoolbar-readonly");
+ };
+
+ el.onclick = function (e) {
+ var element = jSuites.findElement(e.target, "jtoolbar-item");
+ if (element) {
+ obj.selectItem(element);
+ }
+
+ if (e.target.classList.contains("jtoolbar-arrow")) {
+ obj.open();
+ }
+ };
+
+ window.addEventListener("resize", function () {
+ obj.refresh();
+ });
+
+ // Toolbar
+ el.classList.add("jtoolbar");
+ // Reset content
+ el.innerHTML = "";
+ // Container
+ if (obj.options.container == true) {
+ el.classList.add("jtoolbar-container");
+ }
+ // Content
+ var toolbarContent = document.createElement("div");
+ el.appendChild(toolbarContent);
+ // Special toolbar for mobile applications
+ if (obj.options.app) {
+ el.classList.add("jtoolbar-mobile");
+ }
+ // Create toolbar
+ obj.create(obj.options.items);
+ // Shortcut
+ el.toolbar = obj;
+
+ return obj;
+ };
+
+ jSuites.validations = (function () {
+ /**
+ * Options: Object,
+ * Properties:
+ * Constraint,
+ * Reference,
+ * Value
+ */
+
+ var isNumeric = function (num) {
+ return !isNaN(num) && num !== null && num !== "";
+ };
+
+ var numberCriterias = {
+ between: function (value, range) {
+ return value >= range[0] && value <= range[1];
+ },
+ "not between": function (value, range) {
+ return value < range[0] || value > range[1];
+ },
+ "<": function (value, range) {
+ return value < range[0];
+ },
+ "<=": function (value, range) {
+ return value <= range[0];
+ },
+ ">": function (value, range) {
+ return value > range[0];
+ },
+ ">=": function (value, range) {
+ return value >= range[0];
+ },
+ "=": function (value, range) {
+ return value == range[0];
+ },
+ "!=": function (value, range) {
+ return value != range[0];
+ },
+ };
+
+ var dateCriterias = {
+ "valid date": function () {
+ return true;
+ },
+ "=": function (value, range) {
+ return value === range[0];
+ },
+ "<": function (value, range) {
+ return value < range[0];
+ },
+ "<=": function (value, range) {
+ return value <= range[0];
+ },
+ ">": function (value, range) {
+ return value > range[0];
+ },
+ ">=": function (value, range) {
+ return value >= range[0];
+ },
+ between: function (value, range) {
+ return value >= range[0] && value <= range[1];
+ },
+ "not between": function (value, range) {
+ return value < range[0] || value > range[1];
+ },
+ };
+
+ var textCriterias = {
+ contains: function (value, range) {
+ return value.includes(range[0]);
+ },
+ "not contains": function (value, range) {
+ return !value.includes(range[0]);
+ },
+ "begins with": function (value, range) {
+ return value.startsWith(range[0]);
+ },
+ "ends with": function (value, range) {
+ return value.endsWith(range[0]);
+ },
+ "=": function (value, range) {
+ return value === range[0];
+ },
+ "valid email": function (value) {
+ var pattern = new RegExp(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
+
+ return pattern.test(value);
+ },
+ "valid url": function (value) {
+ var pattern = new RegExp(
+ /(((https?:\/\/)|(www\.))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]+)/gi
+ );
+
+ return pattern.test(value);
+ },
+ };
+
+ // Component router
+ var component = function (value, options) {
+ if (typeof component[options.type] === "function") {
+ if (options.allowBlank && value === "") {
+ return true;
+ }
+
+ return component[options.type](value, options);
+ }
+ return null;
+ };
+
+ component.url = function () {
+ var pattern = new RegExp(
+ /(((https?:\/\/)|(www\.))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]+)/gi
+ );
+ return pattern.test(data) ? true : false;
+ };
+
+ component.email = function (data) {
+ var pattern = new RegExp(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
+ return data && pattern.test(data) ? true : false;
+ };
+
+ component.required = function (data) {
+ return data.trim() ? true : false;
+ };
+
+ component.exist = function (data, options) {
+ return !!data.toString();
+ };
+
+ component["not exist"] = function (data, options) {
+ return !data.toString();
+ };
+
+ component.number = function (data, options) {
+ if (!isNumeric(data)) {
+ return false;
+ }
+
+ if (!options || !options.criteria) {
+ return true;
+ }
+
+ if (!numberCriterias[options.criteria]) {
+ return false;
+ }
+
+ var values = options.value.map(function (num) {
+ return parseFloat(num);
+ });
+
+ return numberCriterias[options.criteria](data, values);
+ };
+
+ component.login = function (data) {
+ var pattern = new RegExp(/^[a-zA-Z0-9\_\-\.\s+]+$/);
+ return data && pattern.test(data) ? true : false;
+ };
+
+ component.list = function (data, options) {
+ var dataType = typeof data;
+ if (dataType !== "string" && dataType !== "number") {
+ return false;
+ }
+ if (typeof options.value[0] === "string") {
+ var list = options.value[0].split(",");
+ } else {
+ var list = options.value[0];
+ }
+
+ var validOption = list.findIndex(function name(item) {
+ return item == data;
+ });
+
+ return validOption > -1;
+ };
+
+ component.date = function (data, options) {
+ if (new Date(data) == "Invalid Date") {
+ return false;
+ }
+
+ if (!options || !options.criteria) {
+ return true;
+ }
+
+ if (!dateCriterias[options.criteria]) {
+ return false;
+ }
+
+ var values = options.value.map(function (date) {
+ return new Date(date).getTime();
+ });
+
+ return dateCriterias[options.criteria](new Date(data).getTime(), values);
+ };
+
+ component.text = function (data, options) {
+ if (typeof data !== "string") {
+ return false;
+ }
+
+ if (!options || !options.criteria) {
+ return true;
+ }
+
+ if (!textCriterias[options.criteria]) {
+ return false;
+ }
+
+ return textCriterias[options.criteria](data, options.value);
+ };
+
+ component.textLength = function (data, options) {
+ data = data.toString();
+
+ return component.number(data.length, options);
+ };
+
+ return component;
+ })();
+
+ return jSuites;
+});
diff --git a/javascripts/discourse/components/spreadsheet-editor.js b/javascripts/discourse/components/spreadsheet-editor.js
index 736a1c2..c8bd7ec 100644
--- a/javascripts/discourse/components/spreadsheet-editor.js
+++ b/javascripts/discourse/components/spreadsheet-editor.js
@@ -13,11 +13,17 @@ export default Component.extend({
// ? TODO move to component (read about not allowing Controllers to do DOM manipulation)
this._super(...arguments);
- loadScript(settings.theme_uploads.jspreadsheet).then(() => {
+ this.loadLibraries().then(() => {
this.buildTable(this.tableHtml);
});
},
+ loadLibraries() {
+ return loadScript(settings.theme_uploads.jsuites).then(() => {
+ return loadScript(settings.theme_uploads.jspreadsheet);
+ });
+ },
+
buildTable(table) {
const tableObject = tableToObj(table);
const headings = [];
@@ -41,6 +47,7 @@ export default Component.extend({
const spreadsheetContainer = document.querySelector("#spreadsheet");
+ // eslint-disable-next-line no-undef
this.spreadsheet = jspreadsheet(spreadsheetContainer, {
data: tableData,
columns,