{"version":3,"names":[],"mappings":"","sources":["scripts.bundle.js"],"sourcesContent":["\"use strict\";\r\n/**\r\n * @class KUtil base utilize class that privides helper functions\r\n */\r\n// Polyfill\r\n// matches polyfill\r\nthis.Element && function(ElementPrototype) {\r\n ElementPrototype.matches = ElementPrototype.matches ||\r\n ElementPrototype.matchesSelector ||\r\n ElementPrototype.webkitMatchesSelector ||\r\n ElementPrototype.msMatchesSelector ||\r\n function(selector) {\r\n var node = this,\r\n nodes = (node.parentNode || node.document).querySelectorAll(selector),\r\n i = -1;\r\n while (nodes[++i] && nodes[i] != node);\r\n return !!nodes[i];\r\n }\r\n}(Element.prototype);\r\n\r\n// closest polyfill\r\nthis.Element && function(ElementPrototype) {\r\n ElementPrototype.closest = ElementPrototype.closest ||\r\n function(selector) {\r\n var el = this;\r\n while (el.matches && !el.matches(selector)) el = el.parentNode;\r\n return el.matches ? el : null;\r\n }\r\n}(Element.prototype);\r\n\r\n\r\n// matches polyfill\r\nthis.Element && function(ElementPrototype) {\r\n ElementPrototype.matches = ElementPrototype.matches ||\r\n ElementPrototype.matchesSelector ||\r\n ElementPrototype.webkitMatchesSelector ||\r\n ElementPrototype.msMatchesSelector ||\r\n function(selector) {\r\n var node = this,\r\n nodes = (node.parentNode || node.document).querySelectorAll(selector),\r\n i = -1;\r\n while (nodes[++i] && nodes[i] != node);\r\n return !!nodes[i];\r\n }\r\n}(Element.prototype);\r\n\r\n//\r\n// requestAnimationFrame polyfill by Erik Möller.\r\n// With fixes from Paul Irish and Tino Zijdel\r\n//\r\n// http://paulirish.com/2011/requestanimationframe-for-smart-animating/\r\n// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating\r\n//\r\n// MIT license\r\n//\r\n(function() {\r\n var lastTime = 0;\r\n var vendors = ['webkit', 'moz'];\r\n for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {\r\n window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];\r\n window.cancelAnimationFrame =\r\n window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];\r\n }\r\n\r\n if (!window.requestAnimationFrame)\r\n window.requestAnimationFrame = function(callback) {\r\n var currTime = new Date().getTime();\r\n var timeToCall = Math.max(0, 16 - (currTime - lastTime));\r\n var id = window.setTimeout(function() {\r\n callback(currTime + timeToCall);\r\n }, timeToCall);\r\n lastTime = currTime + timeToCall;\r\n return id;\r\n };\r\n\r\n if (!window.cancelAnimationFrame)\r\n window.cancelAnimationFrame = function(id) {\r\n clearTimeout(id);\r\n };\r\n}());\r\n\r\n// Source: https://github.com/jserz/js_piece/blob/master/DOM/ParentNode/prepend()/prepend().md\r\n(function(arr) {\r\n arr.forEach(function(item) {\r\n if (item.hasOwnProperty('prepend')) {\r\n return;\r\n }\r\n Object.defineProperty(item, 'prepend', {\r\n configurable: true,\r\n enumerable: true,\r\n writable: true,\r\n value: function prepend() {\r\n var argArr = Array.prototype.slice.call(arguments),\r\n docFrag = document.createDocumentFragment();\r\n\r\n argArr.forEach(function(argItem) {\r\n var isNode = argItem instanceof Node;\r\n docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem)));\r\n });\r\n\r\n this.insertBefore(docFrag, this.firstChild);\r\n }\r\n });\r\n });\r\n})([Element.prototype, Document.prototype, DocumentFragment.prototype]);\r\n\r\n// Global variables \r\nwindow.KUtilElementDataStore = {};\r\nwindow.KUtilElementDataStoreID = 0;\r\nwindow.KUtilDelegatedEventHandlers = {};\r\n\r\nvar KUtil = function() {\r\n\r\n var resizeHandlers = [];\r\n\r\n /** @type {object} breakpoints The device width breakpoints **/\r\n var breakpoints = {\r\n sm: 544, // Small screen / phone \r\n md: 768, // Medium screen / tablet \r\n lg: 1024, // Large screen / desktop \r\n xl: 1200 // Extra large screen / wide desktop\r\n };\r\n\r\n /**\r\n * Handle window resize event with some \r\n * delay to attach event handlers upon resize complete \r\n */\r\n var _windowResizeHandler = function() {\r\n var _runResizeHandlers = function() {\r\n // reinitialize other subscribed elements\r\n for (var i = 0; i < resizeHandlers.length; i++) {\r\n var each = resizeHandlers[i];\r\n each.call();\r\n }\r\n };\r\n\r\n var timeout = false; // holder for timeout id\r\n var delay = 250; // delay after event is \"complete\" to run callback\r\n\r\n window.addEventListener('resize', function() {\r\n clearTimeout(timeout);\r\n timeout = setTimeout(function() {\r\n _runResizeHandlers();\r\n }, delay); // wait 50ms until window resize finishes.\r\n });\r\n };\r\n\r\n return {\r\n /**\r\n * Class main initializer.\r\n * @param {object} options.\r\n * @returns null\r\n */\r\n //main function to initiate the theme\r\n init: function(options) {\r\n if (options && options.breakpoints) {\r\n breakpoints = options.breakpoints;\r\n }\r\n\r\n _windowResizeHandler();\r\n },\r\n\r\n /**\r\n * Adds window resize event handler.\r\n * @param {function} callback function.\r\n */\r\n addResizeHandler: function(callback) {\r\n resizeHandlers.push(callback);\r\n },\r\n\r\n /**\r\n * Removes window resize event handler.\r\n * @param {function} callback function.\r\n */\r\n removeResizeHandler: function(callback) {\r\n for (var i = 0; i < resizeHandlers.length; i++) {\r\n if (callback === resizeHandlers[i]) {\r\n delete resizeHandlers[i];\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Trigger window resize handlers.\r\n */\r\n runResizeHandlers: function() {\r\n _runResizeHandlers();\r\n },\r\n\r\n resize: function() {\r\n if (typeof(Event) === 'function') {\r\n // modern browsers\r\n window.dispatchEvent(new Event('resize'));\r\n } else {\r\n // for IE and other old browsers\r\n // causes deprecation warning on modern browsers\r\n var evt = window.document.createEvent('UIEvents'); \r\n evt.initUIEvent('resize', true, false, window, 0); \r\n window.dispatchEvent(evt);\r\n }\r\n },\r\n\r\n /**\r\n * Get GET parameter value from URL.\r\n * @param {string} paramName Parameter name.\r\n * @returns {string} \r\n */\r\n getURLParam: function(paramName) {\r\n var searchString = window.location.search.substring(1),\r\n i, val, params = searchString.split(\"&\");\r\n\r\n for (i = 0; i < params.length; i++) {\r\n val = params[i].split(\"=\");\r\n if (val[0] == paramName) {\r\n return unescape(val[1]);\r\n }\r\n }\r\n\r\n return null;\r\n },\r\n\r\n /**\r\n * Checks whether current device is mobile touch.\r\n * @returns {boolean} \r\n */\r\n isMobileDevice: function() {\r\n return (this.getViewPort().width < this.getBreakpoint('lg') ? true : false);\r\n },\r\n\r\n /**\r\n * Checks whether current device is desktop.\r\n * @returns {boolean} \r\n */\r\n isDesktopDevice: function() {\r\n return KUtil.isMobileDevice() ? false : true;\r\n },\r\n\r\n /**\r\n * Gets browser window viewport size. Ref:\r\n * http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/\r\n * @returns {object} \r\n */\r\n getViewPort: function() {\r\n var e = window,\r\n a = 'inner';\r\n if (!('innerWidth' in window)) {\r\n a = 'client';\r\n e = document.documentElement || document.body;\r\n }\r\n\r\n return {\r\n width: e[a + 'Width'],\r\n height: e[a + 'Height']\r\n };\r\n },\r\n\r\n /**\r\n * Checks whether given device mode is currently activated.\r\n * @param {string} mode Responsive mode name(e.g: desktop,\r\n * desktop-and-tablet, tablet, tablet-and-mobile, mobile)\r\n * @returns {boolean} \r\n */\r\n isInResponsiveRange: function(mode) {\r\n var breakpoint = this.getViewPort().width;\r\n\r\n if (mode == 'general') {\r\n return true;\r\n } else if (mode == 'desktop' && breakpoint >= (this.getBreakpoint('lg') + 1)) {\r\n return true;\r\n } else if (mode == 'tablet' && (breakpoint >= (this.getBreakpoint('md') + 1) && breakpoint < this.getBreakpoint('lg'))) {\r\n return true;\r\n } else if (mode == 'mobile' && breakpoint <= this.getBreakpoint('md')) {\r\n return true;\r\n } else if (mode == 'desktop-and-tablet' && breakpoint >= (this.getBreakpoint('md') + 1)) {\r\n return true;\r\n } else if (mode == 'tablet-and-mobile' && breakpoint <= this.getBreakpoint('lg')) {\r\n return true;\r\n } else if (mode == 'minimal-desktop-and-below' && breakpoint <= this.getBreakpoint('xl')) {\r\n return true;\r\n }\r\n\r\n return false;\r\n },\r\n\r\n /**\r\n * Generates unique ID for give prefix.\r\n * @param {string} prefix Prefix for generated ID\r\n * @returns {boolean} \r\n */\r\n getUniqueID: function(prefix) {\r\n return prefix + Math.floor(Math.random() * (new Date()).getTime());\r\n },\r\n\r\n /**\r\n * Gets window width for give breakpoint mode.\r\n * @param {string} mode Responsive mode name(e.g: xl, lg, md, sm)\r\n * @returns {number} \r\n */\r\n getBreakpoint: function(mode) {\r\n return breakpoints[mode];\r\n },\r\n\r\n /**\r\n * Checks whether object has property matchs given key path.\r\n * @param {object} obj Object contains values paired with given key path\r\n * @param {string} keys Keys path seperated with dots\r\n * @returns {object} \r\n */\r\n isset: function(obj, keys) {\r\n var stone;\r\n\r\n keys = keys || '';\r\n\r\n if (keys.indexOf('[') !== -1) {\r\n throw new Error('Unsupported object path notation.');\r\n }\r\n\r\n keys = keys.split('.');\r\n\r\n do {\r\n if (obj === undefined) {\r\n return false;\r\n }\r\n\r\n stone = keys.shift();\r\n\r\n if (!obj.hasOwnProperty(stone)) {\r\n return false;\r\n }\r\n\r\n obj = obj[stone];\r\n\r\n } while (keys.length);\r\n\r\n return true;\r\n },\r\n\r\n /**\r\n * Gets highest z-index of the given element parents\r\n * @param {object} el jQuery element object\r\n * @returns {number} \r\n */\r\n getHighestZindex: function(el) {\r\n var elem = KUtil.get(el),\r\n position, value;\r\n\r\n while (elem && elem !== document) {\r\n // Ignore z-index if position is set to a value where z-index is ignored by the browser\r\n // This makes behavior of this function consistent across browsers\r\n // WebKit always returns auto if the element is positioned\r\n position = KUtil.css(elem, 'position');\r\n\r\n if (position === \"absolute\" || position === \"relative\" || position === \"fixed\") {\r\n // IE returns 0 when zIndex is not specified\r\n // other browsers return a string\r\n // we ignore the case of nested elements with an explicit value of 0\r\n //
\r\n value = parseInt(KUtil.css(elem, 'z-index'));\r\n\r\n if (!isNaN(value) && value !== 0) {\r\n return value;\r\n }\r\n }\r\n\r\n elem = elem.parentNode;\r\n }\r\n\r\n return null;\r\n },\r\n\r\n /**\r\n * Checks whether the element has any parent with fixed positionfreg\r\n * @param {object} el jQuery element object\r\n * @returns {boolean} \r\n */\r\n hasFixedPositionedParent: function(el) {\r\n while (el && el !== document) {\r\n position = KUtil.css(el, 'position');\r\n\r\n if (position === \"fixed\") {\r\n return true;\r\n }\r\n\r\n el = el.parentNode;\r\n }\r\n\r\n return false;\r\n },\r\n\r\n /**\r\n * Simulates delay\r\n */\r\n sleep: function(milliseconds) {\r\n var start = new Date().getTime();\r\n for (var i = 0; i < 1e7; i++) {\r\n if ((new Date().getTime() - start) > milliseconds) {\r\n break;\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Gets randomly generated integer value within given min and max range\r\n * @param {number} min Range start value\r\n * @param {number} min Range end value\r\n * @returns {number} \r\n */\r\n getRandomInt: function(min, max) {\r\n return Math.floor(Math.random() * (max - min + 1)) + min;\r\n },\r\n\r\n /**\r\n * Checks whether Angular library is included\r\n * @returns {boolean} \r\n */\r\n isAngularVersion: function() {\r\n return window.Zone !== undefined ? true : false;\r\n },\r\n\r\n // jQuery Workarounds\r\n\r\n // Deep extend: $.extend(true, {}, objA, objB);\r\n deepExtend: function(out) {\r\n out = out || {};\r\n\r\n for (var i = 1; i < arguments.length; i++) {\r\n var obj = arguments[i];\r\n\r\n if (!obj)\r\n continue;\r\n\r\n for (var key in obj) {\r\n if (obj.hasOwnProperty(key)) {\r\n if (typeof obj[key] === 'object')\r\n out[key] = KUtil.deepExtend(out[key], obj[key]);\r\n else\r\n out[key] = obj[key];\r\n }\r\n }\r\n }\r\n\r\n return out;\r\n },\r\n\r\n // extend: $.extend({}, objA, objB); \r\n extend: function(out) {\r\n out = out || {};\r\n\r\n for (var i = 1; i < arguments.length; i++) {\r\n if (!arguments[i])\r\n continue;\r\n\r\n for (var key in arguments[i]) {\r\n if (arguments[i].hasOwnProperty(key))\r\n out[key] = arguments[i][key];\r\n }\r\n }\r\n\r\n return out;\r\n },\r\n\r\n get: function(query) {\r\n var el;\r\n\r\n if (query === document) {\r\n return document;\r\n }\r\n\r\n if (!!(query && query.nodeType === 1)) {\r\n return query;\r\n }\r\n\r\n if (el = document.getElementById(query)) {\r\n return el;\r\n } else if (el = document.getElementsByTagName(query)) {\r\n return el[0];\r\n } else if (el = document.getElementsByClassName(query)) {\r\n return el[0];\r\n } else {\r\n return null;\r\n }\r\n },\r\n\r\n getByID: function(query) {\r\n if (!!(query && query.nodeType === 1)) {\r\n return query;\r\n }\r\n\r\n return document.getElementById(query);\r\n },\r\n\r\n getByClass: function(query) {\r\n var el;\r\n \r\n if (el = document.getElementsByClassName(query)) {\r\n return el[0];\r\n } else {\r\n return null;\r\n }\r\n },\r\n\r\n /**\r\n * Checks whether the element has given classes\r\n * @param {object} el jQuery element object\r\n * @param {string} Classes string\r\n * @returns {boolean} \r\n */\r\n hasClasses: function(el, classes) {\r\n if (!el) {\r\n return;\r\n }\r\n\r\n var classesArr = classes.split(\" \");\r\n\r\n for (var i = 0; i < classesArr.length; i++) {\r\n if (KUtil.hasClass(el, KUtil.trim(classesArr[i])) == false) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n },\r\n\r\n hasClass: function(el, className) {\r\n if (!el) {\r\n return;\r\n }\r\n\r\n return el.classList ? el.classList.contains(className) : new RegExp('\\\\b' + className + '\\\\b').test(el.className);\r\n },\r\n\r\n addClass: function(el, className) {\r\n if (!el || typeof className === 'undefined') {\r\n return;\r\n }\r\n\r\n var classNames = className.split(' ');\r\n\r\n if (el.classList) {\r\n for (var i = 0; i < classNames.length; i++) {\r\n if (classNames[i] && classNames[i].length > 0) {\r\n el.classList.add(KUtil.trim(classNames[i]));\r\n }\r\n }\r\n } else if (!KUtil.hasClass(el, className)) {\r\n for (var i = 0; i < classNames.length; i++) {\r\n el.className += ' ' + KUtil.trim(classNames[i]);\r\n }\r\n }\r\n },\r\n\r\n removeClass: function(el, className) {\r\n if (!el || typeof className === 'undefined') {\r\n return;\r\n }\r\n\r\n var classNames = className.split(' ');\r\n\r\n if (el.classList) {\r\n for (var i = 0; i < classNames.length; i++) {\r\n el.classList.remove(KUtil.trim(classNames[i]));\r\n }\r\n } else if (KUtil.hasClass(el, className)) {\r\n for (var i = 0; i < classNames.length; i++) {\r\n el.className = el.className.replace(new RegExp('\\\\b' + KUtil.trim(classNames[i]) + '\\\\b', 'g'), '');\r\n }\r\n }\r\n },\r\n\r\n triggerCustomEvent: function(el, eventName, data) {\r\n if (window.CustomEvent) {\r\n var event = new CustomEvent(eventName, {\r\n detail: data\r\n });\r\n } else {\r\n var event = document.createEvent('CustomEvent');\r\n event.initCustomEvent(eventName, true, true, data);\r\n }\r\n\r\n el.dispatchEvent(event);\r\n },\r\n\r\n triggerEvent: function(node, eventName) {\r\n // Make sure we use the ownerDocument from the provided node to avoid cross-window problems\r\n var doc;\r\n if (node.ownerDocument) {\r\n doc = node.ownerDocument;\r\n } else if (node.nodeType == 9) {\r\n // the node may be the document itself, nodeType 9 = DOCUMENT_NODE\r\n doc = node;\r\n } else {\r\n throw new Error(\"Invalid node passed to fireEvent: \" + node.id);\r\n }\r\n\r\n if (node.dispatchEvent) {\r\n // Gecko-style approach (now the standard) takes more work\r\n var eventClass = \"\";\r\n\r\n // Different events have different event classes.\r\n // If this switch statement can't map an eventName to an eventClass,\r\n // the event firing is going to fail.\r\n switch (eventName) {\r\n case \"click\": // Dispatching of 'click' appears to not work correctly in Safari. Use 'mousedown' or 'mouseup' instead.\r\n case \"mouseenter\":\r\n case \"mouseleave\":\r\n case \"mousedown\":\r\n case \"mouseup\":\r\n eventClass = \"MouseEvents\";\r\n break;\r\n\r\n case \"focus\":\r\n case \"change\":\r\n case \"blur\":\r\n case \"select\":\r\n eventClass = \"HTMLEvents\";\r\n break;\r\n\r\n default:\r\n throw \"fireEvent: Couldn't find an event class for event '\" + eventName + \"'.\";\r\n break;\r\n }\r\n var event = doc.createEvent(eventClass);\r\n\r\n var bubbles = eventName == \"change\" ? false : true;\r\n event.initEvent(eventName, bubbles, true); // All events created as bubbling and cancelable.\r\n\r\n event.synthetic = true; // allow detection of synthetic events\r\n // The second parameter says go ahead with the default action\r\n node.dispatchEvent(event, true);\r\n } else if (node.fireEvent) {\r\n // IE-old school style\r\n var event = doc.createEventObject();\r\n event.synthetic = true; // allow detection of synthetic events\r\n node.fireEvent(\"on\" + eventName, event);\r\n }\r\n },\r\n\r\n index: function( elm ){ \r\n elm = KUtil.get(elm);\r\n var c = elm.parentNode.children, i = 0;\r\n for(; i < c.length; i++ )\r\n if( c[i] == elm ) return i;\r\n },\r\n\r\n trim: function(string) {\r\n return string.trim();\r\n },\r\n\r\n eventTriggered: function(e) {\r\n if (e.currentTarget.dataset.triggered) {\r\n return true;\r\n } else {\r\n e.currentTarget.dataset.triggered = true;\r\n\r\n return false;\r\n }\r\n },\r\n\r\n remove: function(el) {\r\n if (el && el.parentNode) {\r\n el.parentNode.removeChild(el);\r\n }\r\n },\r\n\r\n find: function(parent, query) {\r\n parent = KUtil.get(parent);\r\n if (parent) {\r\n return parent.querySelector(query);\r\n } \r\n },\r\n\r\n findAll: function(parent, query) {\r\n parent = KUtil.get(parent);\r\n if (parent) {\r\n return parent.querySelectorAll(query);\r\n } \r\n },\r\n\r\n insertAfter: function(el, referenceNode) {\r\n return referenceNode.parentNode.insertBefore(el, referenceNode.nextSibling);\r\n },\r\n\r\n parents: function(el, query) {\r\n function collectionHas(a, b) { //helper function (see below)\r\n for (var i = 0, len = a.length; i < len; i++) {\r\n if (a[i] == b) return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n function findParentBySelector(el, selector) {\r\n var all = document.querySelectorAll(selector);\r\n var cur = el.parentNode;\r\n\r\n while (cur && !collectionHas(all, cur)) { //keep going up until you find a match\r\n cur = cur.parentNode; //go up\r\n }\r\n\r\n return cur; //will return null if not found\r\n }\r\n\r\n return findParentBySelector(el, query);\r\n },\r\n\r\n children: function(el, selector, log) {\r\n if (!el || !el.childNodes) {\r\n return;\r\n }\r\n\r\n var result = [],\r\n i = 0,\r\n l = el.childNodes.length;\r\n\r\n for (var i; i < l; ++i) {\r\n if (el.childNodes[i].nodeType == 1 && KUtil.matches(el.childNodes[i], selector, log)) {\r\n result.push(el.childNodes[i]);\r\n }\r\n }\r\n\r\n return result;\r\n },\r\n\r\n child: function(el, selector, log) {\r\n var children = KUtil.children(el, selector, log);\r\n\r\n return children ? children[0] : null;\r\n },\r\n\r\n matches: function(el, selector, log) {\r\n var p = Element.prototype;\r\n var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) {\r\n return [].indexOf.call(document.querySelectorAll(s), this) !== -1;\r\n };\r\n\r\n if (el && el.tagName) {\r\n return f.call(el, selector);\r\n } else {\r\n return false;\r\n }\r\n },\r\n\r\n data: function(element) {\r\n element = KUtil.get(element);\r\n\r\n return {\r\n set: function(name, data) {\r\n if (element === undefined) {\r\n return;\r\n }\r\n\r\n if (element.customDataTag === undefined) {\r\n KUtilElementDataStoreID++;\r\n element.customDataTag = KUtilElementDataStoreID;\r\n }\r\n\r\n if (KUtilElementDataStore[element.customDataTag] === undefined) {\r\n KUtilElementDataStore[element.customDataTag] = {};\r\n }\r\n\r\n KUtilElementDataStore[element.customDataTag][name] = data;\r\n },\r\n\r\n get: function(name) {\r\n if (element === undefined) {\r\n return;\r\n }\r\n\r\n if (element.customDataTag === undefined) { \r\n return null;\r\n }\r\n\r\n return this.has(name) ? KUtilElementDataStore[element.customDataTag][name] : null;\r\n },\r\n\r\n has: function(name) {\r\n if (element === undefined) {\r\n return false;\r\n }\r\n \r\n if (element.customDataTag === undefined) { \r\n return false;\r\n }\r\n\r\n return (KUtilElementDataStore[element.customDataTag] && KUtilElementDataStore[element.customDataTag][name]) ? true : false;\r\n },\r\n\r\n remove: function(name) {\r\n if (element && this.has(name)) {\r\n delete KUtilElementDataStore[element.customDataTag][name];\r\n }\r\n }\r\n };\r\n },\r\n\r\n outerWidth: function(el, margin) {\r\n var width;\r\n\r\n if (margin === true) {\r\n var width = parseFloat(el.offsetWidth);\r\n width += parseFloat(KUtil.css(el, 'margin-left')) + parseFloat(KUtil.css(el, 'margin-right'));\r\n\r\n return parseFloat(width);\r\n } else {\r\n var width = parseFloat(el.offsetWidth);\r\n\r\n return width;\r\n }\r\n },\r\n\r\n offset: function(elem) {\r\n var rect, win;\r\n elem = KUtil.get(elem);\r\n\r\n if ( !elem ) {\r\n return;\r\n }\r\n\r\n // Return zeros for disconnected and hidden (display: none) elements (gh-2310)\r\n // Support: IE <=11 only\r\n // Running getBoundingClientRect on a\r\n // disconnected node in IE throws an error\r\n\r\n if ( !elem.getClientRects().length ) {\r\n return { top: 0, left: 0 };\r\n }\r\n\r\n // Get document-relative position by adding viewport scroll to viewport-relative gBCR\r\n rect = elem.getBoundingClientRect();\r\n win = elem.ownerDocument.defaultView;\r\n\r\n return {\r\n top: rect.top + win.pageYOffset,\r\n left: rect.left + win.pageXOffset\r\n };\r\n },\r\n\r\n height: function(el) {\r\n return KUtil.css(el, 'height');\r\n },\r\n\r\n visible: function(el) {\r\n return !(el.offsetWidth === 0 && el.offsetHeight === 0);\r\n },\r\n\r\n attr: function(el, name, value) {\r\n el = KUtil.get(el);\r\n\r\n if (el == undefined) {\r\n return;\r\n }\r\n\r\n if (value !== undefined) {\r\n el.setAttribute(name, value);\r\n } else {\r\n return el.getAttribute(name);\r\n }\r\n },\r\n\r\n hasAttr: function(el, name) {\r\n el = KUtil.get(el);\r\n\r\n if (el == undefined) {\r\n return;\r\n }\r\n\r\n return el.getAttribute(name) ? true : false;\r\n },\r\n\r\n removeAttr: function(el, name) {\r\n el = KUtil.get(el);\r\n\r\n if (el == undefined) {\r\n return;\r\n }\r\n\r\n el.removeAttribute(name);\r\n },\r\n\r\n animate: function(from, to, duration, update, easing, done) {\r\n /**\r\n * TinyAnimate.easings\r\n * Adapted from jQuery Easing\r\n */\r\n var easings = {};\r\n var easing;\r\n\r\n easings.linear = function(t, b, c, d) {\r\n return c * t / d + b;\r\n };\r\n\r\n easing = easings.linear;\r\n\r\n // Early bail out if called incorrectly\r\n if (typeof from !== 'number' ||\r\n typeof to !== 'number' ||\r\n typeof duration !== 'number' ||\r\n typeof update !== 'function') {\r\n return;\r\n }\r\n\r\n // Create mock done() function if necessary\r\n if (typeof done !== 'function') {\r\n done = function() {};\r\n }\r\n\r\n // Pick implementation (requestAnimationFrame | setTimeout)\r\n var rAF = window.requestAnimationFrame || function(callback) {\r\n window.setTimeout(callback, 1000 / 50);\r\n };\r\n\r\n // Animation loop\r\n var canceled = false;\r\n var change = to - from;\r\n\r\n function loop(timestamp) {\r\n var time = (timestamp || +new Date()) - start;\r\n\r\n if (time >= 0) {\r\n update(easing(time, from, change, duration));\r\n }\r\n if (time >= 0 && time >= duration) {\r\n update(to);\r\n done();\r\n } else {\r\n rAF(loop);\r\n }\r\n }\r\n\r\n update(from);\r\n\r\n // Start animation loop\r\n var start = window.performance && window.performance.now ? window.performance.now() : +new Date();\r\n\r\n rAF(loop);\r\n },\r\n\r\n actualCss: function(el, prop, cache) {\r\n el = KUtil.get(el);\r\n var css = '';\r\n \r\n if (el instanceof HTMLElement === false) {\r\n return;\r\n }\r\n\r\n if (!el.getAttribute('k-hidden-' + prop) || cache === false) {\r\n var value;\r\n\r\n // the element is hidden so:\r\n // making the el block so we can meassure its height but still be hidden\r\n css = el.style.cssText;\r\n el.style.cssText = 'position: absolute; visibility: hidden; display: block;';\r\n\r\n if (prop == 'width') {\r\n value = el.offsetWidth;\r\n } else if (prop == 'height') {\r\n value = el.offsetHeight;\r\n }\r\n\r\n el.style.cssText = css;\r\n\r\n // store it in cache\r\n el.setAttribute('k-hidden-' + prop, value);\r\n\r\n return parseFloat(value);\r\n } else {\r\n // store it in cache\r\n return parseFloat(el.getAttribute('k-hidden-' + prop));\r\n }\r\n },\r\n\r\n actualHeight: function(el, cache) {\r\n return KUtil.actualCss(el, 'height', cache);\r\n },\r\n\r\n actualWidth: function(el, cache) {\r\n return KUtil.actualCss(el, 'width', cache);\r\n },\r\n\r\n getScroll: function(element, method) {\r\n // The passed in `method` value should be 'Top' or 'Left'\r\n method = 'scroll' + method;\r\n return (element == window || element == document) ? (\r\n self[(method == 'scrollTop') ? 'pageYOffset' : 'pageXOffset'] ||\r\n (browserSupportsBoxModel && document.documentElement[method]) ||\r\n document.body[method]\r\n ) : element[method];\r\n },\r\n\r\n css: function(el, styleProp, value) {\r\n el = KUtil.get(el);\r\n\r\n if (!el) {\r\n return;\r\n }\r\n\r\n if (value !== undefined) {\r\n el.style[styleProp] = value;\r\n } else {\r\n var value, defaultView = (el.ownerDocument || document).defaultView;\r\n // W3C standard way:\r\n if (defaultView && defaultView.getComputedStyle) {\r\n // sanitize property name to css notation\r\n // (hyphen separated words eg. font-Size)\r\n styleProp = styleProp.replace(/([A-Z])/g, \"-$1\").toLowerCase();\r\n return defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);\r\n } else if (el.currentStyle) { // IE\r\n // sanitize property name to camelCase\r\n styleProp = styleProp.replace(/\\-(\\w)/g, function(str, letter) {\r\n return letter.toUpperCase();\r\n });\r\n value = el.currentStyle[styleProp];\r\n // convert other units to pixels on IE\r\n if (/^\\d+(em|pt|%|ex)?$/i.test(value)) {\r\n return (function(value) {\r\n var oldLeft = el.style.left,\r\n oldRsLeft = el.runtimeStyle.left;\r\n el.runtimeStyle.left = el.currentStyle.left;\r\n el.style.left = value || 0;\r\n value = el.style.pixelLeft + \"px\";\r\n el.style.left = oldLeft;\r\n el.runtimeStyle.left = oldRsLeft;\r\n return value;\r\n })(value);\r\n }\r\n return value;\r\n }\r\n }\r\n },\r\n\r\n slide: function(el, dir, speed, callback, recalcMaxHeight) {\r\n if (!el || (dir == 'up' && KUtil.visible(el) === false) || (dir == 'down' && KUtil.visible(el) === true)) {\r\n return;\r\n }\r\n\r\n speed = (speed ? speed : 600);\r\n var calcHeight = KUtil.actualHeight(el);\r\n var calcPaddingTop = false;\r\n var calcPaddingBottom = false;\r\n\r\n if (KUtil.css(el, 'padding-top') && KUtil.data(el).has('slide-padding-top') !== true) {\r\n KUtil.data(el).set('slide-padding-top', KUtil.css(el, 'padding-top'));\r\n }\r\n\r\n if (KUtil.css(el, 'padding-bottom') && KUtil.data(el).has('slide-padding-bottom') !== true) {\r\n KUtil.data(el).set('slide-padding-bottom', KUtil.css(el, 'padding-bottom'));\r\n }\r\n\r\n if (KUtil.data(el).has('slide-padding-top')) {\r\n calcPaddingTop = parseInt(KUtil.data(el).get('slide-padding-top'));\r\n }\r\n\r\n if (KUtil.data(el).has('slide-padding-bottom')) {\r\n calcPaddingBottom = parseInt(KUtil.data(el).get('slide-padding-bottom'));\r\n }\r\n\r\n if (dir == 'up') { // up \r\n el.style.cssText = 'display: block; overflow: hidden;';\r\n\r\n if (calcPaddingTop) {\r\n KUtil.animate(0, calcPaddingTop, speed, function(value) {\r\n el.style.paddingTop = (calcPaddingTop - value) + 'px';\r\n }, 'linear');\r\n }\r\n\r\n if (calcPaddingBottom) {\r\n KUtil.animate(0, calcPaddingBottom, speed, function(value) {\r\n el.style.paddingBottom = (calcPaddingBottom - value) + 'px';\r\n }, 'linear');\r\n }\r\n\r\n KUtil.animate(0, calcHeight, speed, function(value) {\r\n el.style.height = (calcHeight - value) + 'px';\r\n }, 'linear', function() {\r\n callback();\r\n el.style.height = '';\r\n el.style.display = 'none';\r\n });\r\n\r\n\r\n } else if (dir == 'down') { // down\r\n el.style.cssText = 'display: block; overflow: hidden;';\r\n\r\n if (calcPaddingTop) {\r\n KUtil.animate(0, calcPaddingTop, speed, function(value) {\r\n el.style.paddingTop = value + 'px';\r\n }, 'linear', function() {\r\n el.style.paddingTop = '';\r\n });\r\n }\r\n\r\n if (calcPaddingBottom) {\r\n KUtil.animate(0, calcPaddingBottom, speed, function(value) {\r\n el.style.paddingBottom = value + 'px';\r\n }, 'linear', function() {\r\n el.style.paddingBottom = '';\r\n });\r\n }\r\n\r\n KUtil.animate(0, calcHeight, speed, function(value) {\r\n el.style.height = value + 'px';\r\n }, 'linear', function() {\r\n callback();\r\n el.style.height = '';\r\n el.style.display = '';\r\n el.style.overflow = '';\r\n });\r\n }\r\n },\r\n\r\n slideUp: function(el, speed, callback) {\r\n KUtil.slide(el, 'up', speed, callback);\r\n },\r\n\r\n slideDown: function(el, speed, callback) {\r\n KUtil.slide(el, 'down', speed, callback);\r\n },\r\n\r\n show: function(el, display) {\r\n el.style.display = (display ? display : 'block');\r\n },\r\n\r\n hide: function(el) {\r\n el.style.display = 'none';\r\n },\r\n\r\n addEvent: function(el, type, handler, one) {\r\n el = KUtil.get(el);\r\n if (typeof el !== 'undefined') {\r\n el.addEventListener(type, handler);\r\n }\r\n },\r\n\r\n removeEvent: function(el, type, handler) {\r\n el = KUtil.get(el);\r\n el.removeEventListener(type, handler);\r\n },\r\n\r\n on: function(element, selector, event, handler) {\r\n if (!selector) {\r\n return;\r\n }\r\n\r\n var eventId = KUtil.getUniqueID('event');\r\n\r\n KUtilDelegatedEventHandlers[eventId] = function(e) {\r\n var targets = element.querySelectorAll(selector);\r\n var target = e.target;\r\n\r\n while (target && target !== element) {\r\n for (var i = 0, j = targets.length; i < j; i++) {\r\n if (target === targets[i]) {\r\n handler.call(target, e);\r\n }\r\n }\r\n\r\n target = target.parentNode;\r\n }\r\n }\r\n\r\n KUtil.addEvent(element, event, KUtilDelegatedEventHandlers[eventId]);\r\n\r\n return eventId;\r\n },\r\n\r\n off: function(element, event, eventId) {\r\n if (!element || !KUtilDelegatedEventHandlers[eventId]) {\r\n return;\r\n }\r\n\r\n KUtil.removeEvent(element, event, KUtilDelegatedEventHandlers[eventId]);\r\n\r\n delete KUtilDelegatedEventHandlers[eventId];\r\n },\r\n\r\n one: function onetime(el, type, callback) {\r\n el = KUtil.get(el);\r\n\r\n el.addEventListener(type, function callee(e) {\r\n // remove event\r\n if (e.target && e.target.removeEventListener) {\r\n e.target.removeEventListener(e.type, callee); \r\n }\r\n \r\n // call handler\r\n return callback(e);\r\n });\r\n },\r\n\r\n hash: function(str) {\r\n var hash = 0,\r\n i, chr;\r\n\r\n if (str.length === 0) return hash;\r\n for (i = 0; i < str.length; i++) {\r\n chr = str.charCodeAt(i);\r\n hash = ((hash << 5) - hash) + chr;\r\n hash |= 0; // Convert to 32bit integer\r\n }\r\n\r\n return hash;\r\n },\r\n\r\n animateClass: function(el, animationName, callback) {\r\n var animation;\r\n var animations = {\r\n animation: 'animationend',\r\n OAnimation: 'oAnimationEnd',\r\n MozAnimation: 'mozAnimationEnd',\r\n WebkitAnimation: 'webkitAnimationEnd',\r\n msAnimation: 'msAnimationEnd',\r\n };\r\n\r\n for (var t in animations) {\r\n if (el.style[t] !== undefined) {\r\n animation = animations[t];\r\n }\r\n }\r\n\r\n KUtil.addClass(el, 'animated ' + animationName);\r\n\r\n KUtil.one(el, animation, function() {\r\n KUtil.removeClass(el, 'animated ' + animationName);\r\n });\r\n\r\n if (callback) {\r\n KUtil.one(el, animation, callback);\r\n }\r\n },\r\n\r\n transitionEnd: function(el, callback) {\r\n var transition;\r\n var transitions = {\r\n transition: 'transitionend',\r\n OTransition: 'oTransitionEnd',\r\n MozTransition: 'mozTransitionEnd',\r\n WebkitTransition: 'webkitTransitionEnd',\r\n msTransition: 'msTransitionEnd'\r\n };\r\n\r\n for (var t in transitions) {\r\n if (el.style[t] !== undefined) {\r\n transition = transitions[t];\r\n }\r\n }\r\n\r\n KUtil.one(el, transition, callback);\r\n },\r\n\r\n animationEnd: function(el, callback) {\r\n var animation;\r\n var animations = {\r\n animation: 'animationend',\r\n OAnimation: 'oAnimationEnd',\r\n MozAnimation: 'mozAnimationEnd',\r\n WebkitAnimation: 'webkitAnimationEnd',\r\n msAnimation: 'msAnimationEnd'\r\n };\r\n\r\n for (var t in animations) {\r\n if (el.style[t] !== undefined) {\r\n animation = animations[t];\r\n }\r\n }\r\n\r\n KUtil.one(el, animation, callback);\r\n },\r\n\r\n animateDelay: function(el, value) {\r\n var vendors = ['webkit-', 'moz-', 'ms-', 'o-', ''];\r\n for (var i = 0; i < vendors.length; i++) {\r\n KUtil.css(el, vendors[i] + 'animation-delay', value);\r\n }\r\n },\r\n\r\n animateDuration: function(el, value) {\r\n var vendors = ['webkit-', 'moz-', 'ms-', 'o-', ''];\r\n for (var i = 0; i < vendors.length; i++) {\r\n KUtil.css(el, vendors[i] + 'animation-duration', value);\r\n }\r\n },\r\n\r\n scrollTo: function(target, offset, duration) {\r\n var duration = duration ? duration : 500;\r\n var target = KUtil.get(target);\r\n var targetPos = target ? KUtil.offset(target).top : 0;\r\n var scrollPos = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;\r\n var from, to;\r\n\r\n if (targetPos > scrollPos) {\r\n from = targetPos;\r\n to = scrollPos;\r\n } else {\r\n from = scrollPos;\r\n to = targetPos;\r\n }\r\n\r\n if (offset) {\r\n to += offset;\r\n }\r\n\r\n KUtil.animate(from, to, duration, function(value) {\r\n document.documentElement.scrollTop = value;\r\n document.body.parentNode.scrollTop = value;\r\n document.body.scrollTop = value;\r\n }); //, easing, done\r\n },\r\n\r\n scrollTop: function(offset, duration) {\r\n KUtil.scrollTo(null, offset, duration);\r\n },\r\n\r\n isArray: function(obj) {\r\n return obj && Array.isArray(obj);\r\n },\r\n\r\n ready: function(callback) {\r\n if (document.attachEvent ? document.readyState === \"complete\" : document.readyState !== \"loading\") {\r\n callback();\r\n } else {\r\n document.addEventListener('DOMContentLoaded', callback);\r\n }\r\n },\r\n\r\n isEmpty: function(obj) {\r\n for (var prop in obj) {\r\n if (obj.hasOwnProperty(prop)) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n },\r\n\r\n numberString: function(nStr) {\r\n nStr += '';\r\n var x = nStr.split('.');\r\n var x1 = x[0];\r\n var x2 = x.length > 1 ? '.' + x[1] : '';\r\n var rgx = /(\\d+)(\\d{3})/;\r\n while (rgx.test(x1)) {\r\n x1 = x1.replace(rgx, '$1' + ',' + '$2');\r\n }\r\n return x1 + x2;\r\n },\r\n\r\n detectIE: function() {\r\n var ua = window.navigator.userAgent;\r\n\r\n // Test values; Uncomment to check result …\r\n\r\n // IE 10\r\n // ua = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)';\r\n\r\n // IE 11\r\n // ua = 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko';\r\n\r\n // Edge 12 (Spartan)\r\n // ua = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0';\r\n\r\n // Edge 13\r\n // ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586';\r\n\r\n var msie = ua.indexOf('MSIE ');\r\n if (msie > 0) {\r\n // IE 10 or older => return version number\r\n return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);\r\n }\r\n\r\n var trident = ua.indexOf('Trident/');\r\n if (trident > 0) {\r\n // IE 11 => return version number\r\n var rv = ua.indexOf('rv:');\r\n return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);\r\n }\r\n\r\n var edge = ua.indexOf('Edge/');\r\n if (edge > 0) {\r\n // Edge (IE 12+) => return version number\r\n return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);\r\n }\r\n\r\n // other browser\r\n return false;\r\n },\r\n\r\n isRTL: function() {\r\n return (KUtil.attr(KUtil.get('html'), 'direction') == 'rtl');\r\n },\r\n\r\n // Scroller\r\n scrollInit: function(element, options) {\r\n if(!element) return;\r\n // Define init function\r\n function init() {\r\n var ps;\r\n var height;\r\n\r\n if (options.height instanceof Function) {\r\n height = parseInt(options.height.call());\r\n } else {\r\n height = parseInt(options.height);\r\n }\r\n\r\n // Destroy scroll on table and mobile modes\r\n if (options.disableForMobile && KUtil.isInResponsiveRange('tablet-and-mobile')) {\r\n if (ps = KUtil.data(element).get('ps')) {\r\n if (options.resetHeightOnDestroy) {\r\n KUtil.css(element, 'height', 'auto');\r\n } else {\r\n KUtil.css(element, 'overflow', 'auto');\r\n if (height > 0) {\r\n KUtil.css(element, 'height', height + 'px');\r\n }\r\n }\r\n\r\n ps.destroy();\r\n ps = KUtil.data(element).remove('ps');\r\n } else if (height > 0){\r\n KUtil.css(element, 'overflow', 'auto');\r\n KUtil.css(element, 'height', height + 'px');\r\n }\r\n\r\n return;\r\n }\r\n\r\n if (height > 0) {\r\n KUtil.css(element, 'height', height + 'px');\r\n }\r\n\r\n KUtil.css(element, 'overflow', 'hidden');\r\n\r\n // Init scroll\r\n if (ps = KUtil.data(element).get('ps')) {\r\n ps.update();\r\n } else {\r\n KUtil.addClass(element, 'k-scroll');\r\n ps = new PerfectScrollbar(element, {\r\n wheelSpeed: 0.5,\r\n swipeEasing: true,\r\n wheelPropagation: false,\r\n minScrollbarLength: 40,\r\n maxScrollbarLength: 300, \r\n suppressScrollX: KUtil.attr(element, 'data-scroll-x') != 'true' ? true : false\r\n });\r\n\r\n KUtil.data(element).set('ps', ps);\r\n }\r\n }\r\n\r\n // Init\r\n init();\r\n\r\n // Handle window resize\r\n if (options.handleWindowResize) {\r\n KUtil.addResizeHandler(function() {\r\n init();\r\n });\r\n }\r\n },\r\n\r\n scrollUpdate: function(element) {\r\n var ps;\r\n if (ps = KUtil.data(element).get('ps')) {\r\n ps.update();\r\n }\r\n },\r\n\r\n scrollUpdateAll: function(parent) {\r\n var scrollers = KUtil.findAll(parent, '.ps');\r\n for (var i = 0, len = scrollers.length; i < len; i++) {\r\n KUtil.scrollerUpdate(scrollers[i]);\r\n }\r\n },\r\n\r\n scrollDestroy: function(element) {\r\n var ps;\r\n if (ps = KUtil.data(element).get('ps')) {\r\n ps.destroy();\r\n ps = KUtil.data(element).remove('ps');\r\n }\r\n },\r\n\r\n setHTML: function(el, html) {\r\n if (KUtil.get(el)) {\r\n KUtil.get(el).innerHTML = html;\r\n }\r\n },\r\n\r\n getHTML: function(el) {\r\n if (KUtil.get(el)) {\r\n return KUtil.get(el).innerHTML;\r\n }\r\n } \r\n }\r\n}();\r\n\r\n// Initialize KUtil class on document ready\r\nKUtil.ready(function() {\r\n KUtil.init();\r\n});\r\n\r\n// CSS3 Transitions only after page load(.k-page-loading class added to body tag and remove with JS on page load)\r\nwindow.onload = function() { \r\n KUtil.removeClass(KUtil.get('body'), 'k-page--loading');\r\n}\n\"use strict\";\r\n\r\n/**\r\n * @class KApp\r\n */\r\n\r\nvar KApp = function() {\r\n /** @type {object} colors State colors **/\r\n var colors = {};\r\n\r\n var initTooltip = function(el) {\r\n var skin = el.data('skin') ? 'tooltip-' + el.data('skin') : '';\r\n var width = el.data('width') == 'auto' ? 'tooltop-auto-width' : '';\r\n var triggerValue = el.data('trigger') ? el.data('trigger') : 'hover';\r\n var placement = el.data('placement') ? el.data('placement') : 'left';\r\n\r\n el.tooltip({\r\n trigger: triggerValue,\r\n template: '
\\\r\n
\\\r\n
\\\r\n
'\r\n });\r\n }\r\n\r\n var initTooltips = function() {\r\n // init bootstrap tooltips\r\n $('[data-toggle=\"k-tooltip\"]').each(function() {\r\n initTooltip($(this));\r\n });\r\n }\r\n\r\n var initPopover = function(el) {\r\n var skin = el.data('skin') ? 'popover-' + el.data('skin') : '';\r\n var triggerValue = el.data('trigger') ? el.data('trigger') : 'hover';\r\n\r\n el.popover({\r\n trigger: triggerValue,\r\n template: '\\\r\n
\\\r\n
\\\r\n

\\\r\n
\\\r\n
'\r\n });\r\n }\r\n\r\n var initPopovers = function() {\r\n // init bootstrap popover\r\n $('[data-toggle=\"k-popover\"]').each(function() {\r\n initPopover($(this));\r\n });\r\n }\r\n\r\n var initFileInput = function() {\r\n // init bootstrap popover\r\n $('.custom-file-input').on('change', function() {\r\n var fileName = $(this).val();\r\n $(this).next('.custom-file-label').addClass(\"selected\").html(fileName);\r\n });\r\n }\r\n\r\n var initPortlet = function(el, options) {\r\n // init portlet tools\r\n var el = $(el);\r\n var portlet = new KPortlet(el[0], options);\r\n }\r\n\r\n var initPortlets = function() {\r\n // init portlet tools\r\n $('[data-kportlet=\"true\"]').each(function() {\r\n var el = $(this);\r\n\r\n if (el.data('data-kportlet-initialized') !== true) {\r\n initPortlet(el, {});\r\n el.data('data-kportlet-initialized', true);\r\n }\r\n });\r\n }\r\n\r\n var initScroll = function() {\r\n $('[data-scroll=\"true\"]').each(function() {\r\n var el = $(this);\r\n KUtil.scrollInit(this, {\r\n disableForMobile: true,\r\n handleWindowResize: true,\r\n height: function() {\r\n if (KUtil.isInResponsiveRange('tablet-and-mobile') && el.data('mobile-height')) {\r\n return el.data('mobile-height');\r\n } else {\r\n return el.data('height');\r\n }\r\n }\r\n });\r\n });\r\n }\r\n\r\n var initAlerts = function() {\r\n // init bootstrap popover\r\n $('body').on('click', '[data-close=alert]', function() {\r\n $(this).closest('.alert').hide();\r\n });\r\n }\r\n\r\n var initSticky = function() {\r\n var sticky = new Sticky('[data-sticky=\"true\"]');\r\n }\r\n\r\n var initAbsoluteDropdown = function(dropdown) {\r\n var dropdownMenu;\r\n\r\n if (!dropdown) {\r\n return;\r\n }\r\n\r\n dropdown.on('show.bs.dropdown', function(e) {\r\n dropdownMenu = $(e.target).find('.dropdown-menu');\r\n $('body').append(dropdownMenu.detach());\r\n dropdownMenu.css('display', 'block');\r\n dropdownMenu.position({\r\n 'my': 'right top',\r\n 'at': 'right bottom',\r\n 'of': $(e.relatedTarget)\r\n });\r\n });\r\n\r\n dropdown.on('hide.bs.dropdown', function(e) {\r\n $(e.target).append(dropdownMenu.detach());\r\n dropdownMenu.hide();\r\n });\r\n }\r\n\r\n return {\r\n init: function(options) {\r\n if (options && options.colors) {\r\n colors = options.colors;\r\n }\r\n\r\n KApp.initComponents();\r\n },\r\n\r\n initComponents: function() {\r\n initScroll();\r\n initTooltips();\r\n initPopovers();\r\n initAlerts();\r\n initPortlets();\r\n initFileInput();\r\n initSticky();\r\n },\r\n\r\n initTooltips: function() {\r\n initTooltips();\r\n },\r\n\r\n initTooltip: function(el) {\r\n initTooltip(el);\r\n },\r\n\r\n initPopovers: function() {\r\n initPopovers();\r\n },\r\n\r\n initPopover: function(el) {\r\n initPopover(el);\r\n },\r\n\r\n initPortlet: function(el, options) {\r\n initPortlet(el, options);\r\n },\r\n\r\n initPortlets: function() {\r\n initPortlets();\r\n },\r\n\r\n initSticky: function() {\r\n initSticky();\r\n },\r\n\r\n initAbsoluteDropdown: function(dropdown) {\r\n initAbsoluteDropdown(dropdown);\r\n },\r\n\r\n block: function(target, options) {\r\n var el = $(target);\r\n\r\n options = $.extend(true, {\r\n opacity: 0.03,\r\n overlayColor: '#000000',\r\n type: '',\r\n size: '',\r\n state: 'brand',\r\n centerX: true,\r\n centerY: true,\r\n message: '',\r\n shadow: true,\r\n width: 'auto'\r\n }, options);\r\n\r\n var html;\r\n var version = options.type ? 'k-spinner--' + options.type : '';\r\n var state = options.state ? 'k-spinner--' + options.state : '';\r\n var size = options.size ? 'k-spinner--' + options.size : '';\r\n var spinner = '
0) {\r\n var classes = 'blockui ' + (options.shadow === false ? 'blockui' : '');\r\n\r\n html = '
' + options.message + '' + spinner + '
';\r\n\r\n var el = document.createElement('div');\r\n KUtil.get('body').prepend(el);\r\n KUtil.addClass(el, classes);\r\n el.innerHTML = '' + options.message + '' + spinner + '';\r\n options.width = KUtil.actualWidth(el) + 10;\r\n KUtil.remove(el);\r\n\r\n if (target == 'body') {\r\n html = '
' + options.message + '' + spinner + '
';\r\n }\r\n } else {\r\n html = spinner;\r\n }\r\n\r\n var params = {\r\n message: html,\r\n centerY: options.centerY,\r\n centerX: options.centerX,\r\n css: {\r\n top: '30%',\r\n left: '50%',\r\n border: '0',\r\n padding: '0',\r\n backgroundColor: 'none',\r\n width: options.width\r\n },\r\n overlayCSS: {\r\n backgroundColor: options.overlayColor,\r\n opacity: options.opacity,\r\n cursor: 'wait',\r\n zIndex: '10'\r\n },\r\n onUnblock: function() {\r\n if (el && el[0]) {\r\n KUtil.css(el[0], 'position', '');\r\n KUtil.css(el[0], 'zoom', '');\r\n }\r\n }\r\n };\r\n\r\n if (target == 'body') {\r\n params.css.top = '50%';\r\n $.blockUI(params);\r\n } else {\r\n var el = $(target);\r\n el.block(params);\r\n }\r\n },\r\n\r\n unblock: function(target) {\r\n if (target && target != 'body') {\r\n $(target).unblock();\r\n } else {\r\n $.unblockUI();\r\n }\r\n },\r\n\r\n blockPage: function(options) {\r\n return KApp.block('body', options);\r\n },\r\n\r\n unblockPage: function() {\r\n return KApp.unblock('body');\r\n },\r\n\r\n progress: function(target, options) {\r\n var skin = (options && options.skin) ? options.skin : 'light';\r\n var alignment = (options && options.alignment) ? options.alignment : 'right';\r\n var size = (options && options.size) ? 'k-spinner--' + options.size : '';\r\n var classes = 'k-loader ' + 'k-loader--' + skin + ' k-loader--' + alignment + ' k-loader--' + size;\r\n\r\n KApp.unprogress(target);\r\n\r\n $(target).addClass(classes);\r\n $(target).data('progress-classes', classes);\r\n },\r\n\r\n unprogress: function(target) {\r\n $(target).removeClass($(target).data('progress-classes'));\r\n },\r\n\r\n getStateColor: function(name) {\r\n return colors[\"state\"][name];\r\n },\r\n\r\n getBaseColor: function(type, level) {\r\n return colors[\"base\"][type][level - 1];\r\n }\r\n };\r\n}();\r\n\r\n// Initialize KApp class on document ready\r\n$(document).ready(function() {\r\n KApp.init(KAppOptions);\r\n});\n'use strict';\r\n(function($) {\r\n\r\n\tvar pluginName = 'KDatatable';\r\n\tvar pfx = 'k-';\r\n\tvar util = KUtil;\r\n\tvar app = KApp;\r\n\r\n\tif (typeof util === 'undefined') throw new Error('Util class is required and must be included before ' + pluginName);\r\n\r\n\t// plugin setup\r\n\t$.fn[pluginName] = function(options) {\r\n\t\tif ($(this).length === 0) {\r\n\t\t\tconsole.log('No ' + pluginName + ' element exist.');\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// global variables\r\n\t\tvar datatable = this;\r\n\r\n\t\t// debug enabled?\r\n\t\t// 1) state will be cleared on each refresh\r\n\t\t// 2) enable some logs\r\n\t\t// 3) etc.\r\n\t\tdatatable.debug = false;\r\n\r\n\t\tdatatable.API = {\r\n\t\t\trecord: null,\r\n\t\t\tvalue: null,\r\n\t\t\tparams: null,\r\n\t\t};\r\n\r\n\t\tvar Plugin = {\r\n\t\t\t/********************\r\n\t\t\t ** PRIVATE METHODS\r\n\t\t\t ********************/\r\n\t\t\tisInit: false,\r\n\t\t\tcellOffset: 110,\r\n\t\t\ticonOffset: 15,\r\n\t\t\tstateId: 'meta',\r\n\t\t\tajaxParams: {},\r\n\r\n\t\t\tinit: function(options) {\r\n\t\t\t\tvar isHtmlTable = false;\r\n\t\t\t\t// data source option empty is normal table\r\n\t\t\t\tif (options.data.source === null) {\r\n\t\t\t\t\tPlugin.extractTable();\r\n\t\t\t\t\tisHtmlTable = true;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tPlugin.setupBaseDOM.call();\r\n\t\t\t\tPlugin.setupDOM(datatable.table);\r\n\t\t\t\t// Plugin.spinnerCallback(true);\r\n\r\n\t\t\t\t// set custom query from options\r\n\t\t\t\tPlugin.setDataSourceQuery(Plugin.getOption('data.source.read.params.query'));\r\n\r\n\t\t\t\t// on event after layout had done setup, show datatable\r\n\t\t\t\t$(datatable).on(pfx + 'datatable--on-layout-updated', Plugin.afterRender);\r\n\r\n\t\t\t\tif (datatable.debug) Plugin.stateRemove(Plugin.stateId);\r\n\r\n\t\t\t\t// initialize extensions\r\n\t\t\t\t$.each(Plugin.getOption('extensions'), function(extName, extOptions) {\r\n\t\t\t\t\tif (typeof $.fn[pluginName][extName] === 'function')\r\n\t\t\t\t\t\tnew $.fn[pluginName][extName](datatable, extOptions);\r\n\t\t\t\t});\r\n\r\n\t\t\t\t// get data\r\n\t\t\t\tif (options.data.type === 'remote' || options.data.type === 'local') {\r\n\t\t\t\t\tif (options.data.saveState === false ||\r\n\t\t\t\t\t\toptions.data.saveState.cookie === false &&\r\n\t\t\t\t\t\toptions.data.saveState.webstorage === false) {\r\n\t\t\t\t\t\tPlugin.stateRemove(Plugin.stateId);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// get data for local datatable and local table\r\n\t\t\t\t\tif (options.data.type === 'local' && typeof options.data.source === 'object') {\r\n\t\t\t\t\t\tdatatable.dataSet = datatable.originalDataSet = Plugin.dataMapCallback(options.data.source);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tPlugin.dataRender();\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!isHtmlTable) {\r\n\t\t\t\t\t// if not a html table, setup header\r\n\t\t\t\t\tPlugin.setHeadTitle();\r\n\t\t\t\t\tif (Plugin.getOption('layout.footer')) {\r\n\t\t\t\t\t\tPlugin.setHeadTitle(datatable.tableFoot);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// hide header\r\n\t\t\t\tif (typeof options.layout.header !== 'undefined' &&\r\n\t\t\t\t\toptions.layout.header === false) {\r\n\t\t\t\t\t$(datatable.table).find('thead').remove();\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// hide footer\r\n\t\t\t\tif (typeof options.layout.footer !== 'undefined' &&\r\n\t\t\t\t\toptions.layout.footer === false) {\r\n\t\t\t\t\t$(datatable.table).find('tfoot').remove();\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// for normal and local data type, run layoutUpdate\r\n\t\t\t\tif (options.data.type === null ||\r\n\t\t\t\t\toptions.data.type === 'local') {\r\n\t\t\t\t\tPlugin.setupCellField.call();\r\n\t\t\t\t\tPlugin.setupTemplateCell.call();\r\n\r\n\t\t\t\t\t// setup nested datatable, if option enabled\r\n\t\t\t\t\tPlugin.setupSubDatatable.call();\r\n\r\n\t\t\t\t\t// setup extra system column properties\r\n\t\t\t\t\tPlugin.setupSystemColumn.call();\r\n\t\t\t\t\tPlugin.redraw();\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar width;\r\n\t\t\t\tvar initialWidth = false;\r\n\t\t\t\t$(window).resize(function() {\r\n\t\t\t\t\t// get initial width\r\n\t\t\t\t\tif (!initialWidth) {\r\n\t\t\t\t\t\twidth = $(this).width();\r\n\t\t\t\t\t\tinitialWidth = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// issue: URL Bar Resizing on mobile, https://developers.google.com/web/updates/2016/12/url-bar-resizing\r\n\t\t\t\t\t// trigger datatable resize on width change only\r\n\t\t\t\t\tif ($(this).width() !== width) {\r\n\t\t\t\t\t\twidth = $(this).width();\r\n\t\t\t\t\t\tPlugin.fullRender();\r\n\t\t\t\t\t\t// Plugin.redraw();\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\r\n\t\t\t\t$(datatable).height('');\r\n\r\n\t\t\t\t$(Plugin.getOption('search.input')).on('keyup', function(e) {\r\n\t\t\t\t\tif (Plugin.getOption('search.onEnter') && e.which !== 13) return;\r\n\t\t\t\t\tPlugin.search($(this).val());\r\n\t\t\t\t});\r\n\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Extract static HTML table content into datasource\r\n\t\t\t */\r\n\t\t\textractTable: function() {\r\n\t\t\t\tvar columns = [];\r\n\t\t\t\tvar headers = $(datatable).find('tr:first-child th').get().map(function(cell, i) {\r\n\t\t\t\t\tvar field = $(cell).data('field');\r\n\t\t\t\t\tif (typeof field === 'undefined') {\r\n\t\t\t\t\t\tfield = $(cell).text().trim();\r\n\t\t\t\t\t}\r\n\t\t\t\t\tvar column = {\r\n\t\t\t\t\t\tfield: field,\r\n\t\t\t\t\t\ttitle: field\r\n\t\t\t\t\t};\r\n\t\t\t\t\tfor (var ii in options.columns) {\r\n\t\t\t\t\t\tif (options.columns[ii].field === field) {\r\n\t\t\t\t\t\t\tcolumn = $.extend(true, {}, options.columns[ii], column);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tcolumns.push(column);\r\n\t\t\t\t\treturn field;\r\n\t\t\t\t});\r\n\t\t\t\t// auto create columns config\r\n\t\t\t\toptions.columns = columns;\r\n\r\n\t\t\t\tvar rowProp = [];\r\n\t\t\t\tvar source = [];\r\n\r\n\t\t\t\t$(datatable).find('tr').each(function() {\r\n\t\t\t\t\tif ($(this).find('td').length) {\r\n\t\t\t\t\t\trowProp.push($(this).prop('attributes'));\r\n\t\t\t\t\t}\r\n\t\t\t\t\tvar td = {};\r\n\t\t\t\t\t$(this).find('td').each(function(i, cell) {\r\n\t\t\t\t\t\ttd[headers[i]] = cell.innerHTML.trim();\r\n\t\t\t\t\t});\r\n\t\t\t\t\tif (!util.isEmpty(td)) {\r\n\t\t\t\t\t\tsource.push(td);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\r\n\t\t\t\toptions.data.attr.rowProps = rowProp;\r\n\t\t\t\toptions.data.source = source;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * One time layout update on init\r\n\t\t\t */\r\n\t\t\tlayoutUpdate: function() {\r\n\t\t\t\t// setup nested datatable, if option enabled\r\n\t\t\t\tPlugin.setupSubDatatable.call();\r\n\r\n\t\t\t\t// setup extra system column properties\r\n\t\t\t\tPlugin.setupSystemColumn.call();\r\n\r\n\t\t\t\t// setup cell hover event\r\n\t\t\t\tPlugin.setupHover.call();\r\n\r\n\t\t\t\tif (typeof options.detail === 'undefined'\r\n\t\t\t\t\t// temporary disable lock column in subtable\r\n\t\t\t\t\t&&\r\n\t\t\t\t\tPlugin.getDepth() === 1) {\r\n\t\t\t\t\t// lock columns handler\r\n\t\t\t\t\tPlugin.lockTable.call();\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Plugin.columnHide.call();\r\n\r\n\t\t\t\tPlugin.resetScroll();\r\n\r\n\t\t\t\tif (!Plugin.isInit) {\r\n\t\t\t\t\tPlugin.dropdownFix();\r\n\t\t\t\t\t$(datatable).trigger(pfx + 'datatable--on-init', {\r\n\t\t\t\t\t\ttable: $(datatable.wrap).attr('id'),\r\n\t\t\t\t\t\toptions: options\r\n\t\t\t\t\t});\r\n\t\t\t\t\tPlugin.isInit = true;\r\n\t\t\t\t}\r\n\t\t\t\t// run once dropdown inside datatable\r\n\r\n\t\t\t\t// $(datatable).trigger(pfx + 'datatable-init');\r\n\r\n\t\t\t\t$(datatable).trigger(pfx + 'datatable--on-layout-updated', {\r\n\t\t\t\t\ttable: $(datatable.wrap).attr('id')\r\n\t\t\t\t});\r\n\t\t\t},\r\n\r\n\t\t\tlockTable: function() {\r\n\t\t\t\tvar lock = {\r\n\t\t\t\t\tlockEnabled: false,\r\n\t\t\t\t\tinit: function() {\r\n\t\t\t\t\t\t// check if table should be locked columns\r\n\t\t\t\t\t\tlock.lockEnabled = Plugin.lockEnabledColumns();\r\n\t\t\t\t\t\tif (lock.lockEnabled.left.length === 0 &&\r\n\t\t\t\t\t\t\tlock.lockEnabled.right.length === 0) {\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tlock.enable();\r\n\t\t\t\t\t},\r\n\t\t\t\t\tenable: function() {\r\n\t\t\t\t\t\tvar enableLock = function(tablePart) {\r\n\t\t\t\t\t\t\t// check if already has lock column\r\n\t\t\t\t\t\t\tif ($(tablePart).find('.' + pfx + 'datatable__lock').length > 0) {\r\n\t\t\t\t\t\t\t\tPlugin.log('Locked container already exist in: ', tablePart);\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t// check if no rows exists\r\n\t\t\t\t\t\t\tif ($(tablePart).find('.' + pfx + 'datatable__row').length === 0) {\r\n\t\t\t\t\t\t\t\tPlugin.log('No row exist in: ', tablePart);\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t// locked div container\r\n\t\t\t\t\t\t\tvar lockLeft = $('
').addClass(pfx + 'datatable__lock ' + pfx + 'datatable__lock--left');\r\n\t\t\t\t\t\t\tvar lockScroll = $('
').addClass(pfx + 'datatable__lock ' + pfx + 'datatable__lock--scroll');\r\n\t\t\t\t\t\t\tvar lockRight = $('
').addClass(pfx + 'datatable__lock ' + pfx + 'datatable__lock--right');\r\n\r\n\t\t\t\t\t\t\t$(tablePart).find('.' + pfx + 'datatable__row').each(function() {\r\n\t\t\t\t\t\t\t\tvar rowLeft = $('').addClass(pfx + 'datatable__row').appendTo(lockLeft);\r\n\t\t\t\t\t\t\t\tvar rowScroll = $('').addClass(pfx + 'datatable__row').appendTo(lockScroll);\r\n\t\t\t\t\t\t\t\tvar rowRight = $('').addClass(pfx + 'datatable__row').appendTo(lockRight);\r\n\t\t\t\t\t\t\t\t$(this).find('.' + pfx + 'datatable__cell').each(function() {\r\n\t\t\t\t\t\t\t\t\tvar locked = $(this).data('locked');\r\n\t\t\t\t\t\t\t\t\tif (typeof locked !== 'undefined') {\r\n\t\t\t\t\t\t\t\t\t\tif (typeof locked.left !== 'undefined' || locked === true) {\r\n\t\t\t\t\t\t\t\t\t\t\t// default locked to left\r\n\t\t\t\t\t\t\t\t\t\t\t$(this).appendTo(rowLeft);\r\n\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t\tif (typeof locked.right !== 'undefined') {\r\n\t\t\t\t\t\t\t\t\t\t\t$(this).appendTo(rowRight);\r\n\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\t\t$(this).appendTo(rowScroll);\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t// remove old row\r\n\t\t\t\t\t\t\t\t$(this).remove();\r\n\t\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\t\tif (lock.lockEnabled.left.length > 0) {\r\n\t\t\t\t\t\t\t\t$(datatable.wrap).addClass(pfx + 'datatable--lock');\r\n\t\t\t\t\t\t\t\t$(lockLeft).appendTo(tablePart);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif (lock.lockEnabled.left.length > 0 || lock.lockEnabled.right.length > 0) {\r\n\t\t\t\t\t\t\t\t$(lockScroll).appendTo(tablePart);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif (lock.lockEnabled.right.length > 0) {\r\n\t\t\t\t\t\t\t\t$(datatable.wrap).addClass(pfx + 'datatable--lock');\r\n\t\t\t\t\t\t\t\t$(lockRight).appendTo(tablePart);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t};\r\n\r\n\t\t\t\t\t\t$(datatable.table).find('thead,tbody,tfoot').each(function() {\r\n\t\t\t\t\t\t\tvar tablePart = this;\r\n\t\t\t\t\t\t\tif ($(this).find('.' + pfx + 'datatable__lock').length === 0) {\r\n\t\t\t\t\t\t\t\t$(this).ready(function() {\r\n\t\t\t\t\t\t\t\t\tenableLock(tablePart);\r\n\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t},\r\n\t\t\t\t};\r\n\t\t\t\tlock.init();\r\n\t\t\t\treturn lock;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Render everything for resize\r\n\t\t\t */\r\n\t\t\tfullRender: function() {\r\n\t\t\t\t$(datatable.tableHead).empty();\r\n\t\t\t\tPlugin.setHeadTitle();\r\n\t\t\t\tif (Plugin.getOption('layout.footer')) {\r\n\t\t\t\t\t$(datatable.tableFoot).empty();\r\n\t\t\t\t\tPlugin.setHeadTitle(datatable.tableFoot);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tPlugin.spinnerCallback(true);\r\n\t\t\t\t$(datatable.wrap).removeClass(pfx + 'datatable--loaded');\r\n\r\n\t\t\t\tPlugin.insertData();\r\n\t\t\t},\r\n\r\n\t\t\tlockEnabledColumns: function() {\r\n\t\t\t\tvar screen = $(window).width();\r\n\t\t\t\tvar columns = options.columns;\r\n\t\t\t\tvar enabled = {\r\n\t\t\t\t\tleft: [],\r\n\t\t\t\t\tright: []\r\n\t\t\t\t};\r\n\t\t\t\t$.each(columns, function(i, column) {\r\n\t\t\t\t\tif (typeof column.locked !== 'undefined') {\r\n\t\t\t\t\t\tif (typeof column.locked.left !== 'undefined') {\r\n\t\t\t\t\t\t\tif (util.getBreakpoint(column.locked.left) <= screen) {\r\n\t\t\t\t\t\t\t\tenabled['left'].push(column.locked.left);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (typeof column.locked.right !== 'undefined') {\r\n\t\t\t\t\t\t\tif (util.getBreakpoint(column.locked.right) <= screen) {\r\n\t\t\t\t\t\t\t\tenabled['right'].push(column.locked.right);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t\treturn enabled;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * After render event, called by '+pfx+'-datatable--on-layout-updated\r\n\t\t\t * @param e\r\n\t\t\t * @param args\r\n\t\t\t */\r\n\t\t\tafterRender: function(e, args) {\r\n\t\t\t\tif (args.table == $(datatable.wrap).attr('id')) {\r\n\t\t\t\t\t$(datatable).ready(function() {\r\n\t\t\t\t\t\tif (!Plugin.isLocked()) {\r\n\t\t\t\t\t\t\tPlugin.redraw();\r\n\t\t\t\t\t\t\t// work on non locked columns\r\n\t\t\t\t\t\t\tif (!Plugin.isSubtable() && Plugin.getOption('rows.autoHide') === true) {\r\n\t\t\t\t\t\t\t\tPlugin.autoHide();\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t// reset row\r\n\t\t\t\t\t\t\t$(datatable.table).find('.' + pfx + 'datatable__row').css('height', '');\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tPlugin.rowEvenOdd.call();\r\n\r\n\t\t\t\t\t\t// redraw locked columns table\r\n\t\t\t\t\t\tif (Plugin.isLocked()) Plugin.redraw();\r\n\t\t\t\t\t\t$(datatable.tableBody).css('visibility', '');\r\n\t\t\t\t\t\t$(datatable.wrap).addClass(pfx + 'datatable--loaded');\r\n\r\n\t\t\t\t\t\tPlugin.scrollbar.call();\r\n\r\n\t\t\t\t\t\tPlugin.spinnerCallback(false);\r\n\t\t\t\t\t\tPlugin.sorting.call();\r\n\t\t\t\t\t\tPlugin.isInit = true;\r\n\r\n\t\t\t\t\t\t$(datatable).trigger(pfx + 'datatable--on-layout-rendered');\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\r\n\r\n\t\t\t},\r\n\r\n\t\tdropdownFix: function() {\r\n var dropdownMenu;\r\n $('body').on('show.bs.dropdown', '.' + pfx + 'datatable .' + pfx + 'datatable__body', function (e) {\r\n e.stopImmediatePropagation();\r\n\t\t\t\t\tdropdownMenu = $(e.target).find('.dropdown-menu');\r\n\t\t\t\t\t\r\n\t\t\t\t\t//attaches row data to menu\r\n\t\t\t\t\tdropdownMenu.prop('rowData', $(e.target).parents('tr').data().obj);\r\n\r\n $('body').append(dropdownMenu.detach());\r\n dropdownMenu.css('display', 'block');\r\n dropdownMenu.position({\r\n 'my': 'right top',\r\n 'at': 'right bottom',\r\n 'of': $(e.relatedTarget),\r\n });\r\n // if datatable is inside modal\r\n if (datatable.closest('.modal').length) {\r\n // increase dropdown z-index\r\n dropdownMenu.css('z-index', '2000');\r\n\t\t\t\t\t}\r\n }).on('hide.bs.dropdown','.' + pfx + 'datatable .' + pfx + 'datatable__body', function (e) {\r\n if (dropdownMenu != null) {\r\n $(e.target).append(dropdownMenu.detach());\r\n dropdownMenu.hide();\r\n }\r\n });\r\n\t\t\t},\r\n\r\n\t\t\thoverTimer: 0,\r\n\t\t\tisScrolling: false,\r\n\t\t\tsetupHover: function() {\r\n\t\t\t\t$(window).scroll(function(e) {\r\n\t\t\t\t\t// stop hover when scrolling\r\n\t\t\t\t\tclearTimeout(Plugin.hoverTimer);\r\n\t\t\t\t\tPlugin.isScrolling = true;\r\n\t\t\t\t});\r\n\r\n\t\t\t\t$(datatable.tableBody).find('.' + pfx + 'datatable__cell').off('mouseenter', 'mouseleave').on('mouseenter', function() {\r\n\t\t\t\t\t// reset scroll timer to hover class\r\n\t\t\t\t\tPlugin.hoverTimer = setTimeout(function() {\r\n\t\t\t\t\t\tPlugin.isScrolling = false;\r\n\t\t\t\t\t}, 200);\r\n\t\t\t\t\tif (Plugin.isScrolling) return;\r\n\r\n\t\t\t\t\t// normal table\r\n\t\t\t\t\tvar row = $(this).closest('.' + pfx + 'datatable__row').addClass(pfx + 'datatable__row--hover');\r\n\t\t\t\t\tvar index = $(row).index() + 1;\r\n\r\n\t\t\t\t\t// lock table\r\n\t\t\t\t\t$(row).closest('.' + pfx + 'datatable__lock').parent().find('.' + pfx + 'datatable__row:nth-child(' + index + ')').addClass(pfx + 'datatable__row--hover');\r\n\t\t\t\t}).on('mouseleave', function() {\r\n\t\t\t\t\t// normal table\r\n\t\t\t\t\tvar row = $(this).closest('.' + pfx + 'datatable__row').removeClass(pfx + 'datatable__row--hover');\r\n\t\t\t\t\tvar index = $(row).index() + 1;\r\n\r\n\t\t\t\t\t// look table\r\n\t\t\t\t\t$(row).closest('.' + pfx + 'datatable__lock').parent().find('.' + pfx + 'datatable__row:nth-child(' + index + ')').removeClass(pfx + 'datatable__row--hover');\r\n\t\t\t\t});\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Adjust width of locked table containers by resize handler\r\n\t\t\t * @returns {number}\r\n\t\t\t */\r\n\t\t\tadjustLockContainer: function() {\r\n\t\t\t\tif (!Plugin.isLocked()) return 0;\r\n\r\n\t\t\t\t// refer to head dimension\r\n\t\t\t\tvar containerWidth = $(datatable.tableHead).width();\r\n\t\t\t\tvar lockLeft = $(datatable.tableHead).find('.' + pfx + 'datatable__lock--left').width();\r\n\t\t\t\tvar lockRight = $(datatable.tableHead).find('.' + pfx + 'datatable__lock--right').width();\r\n\r\n\t\t\t\tif (typeof lockLeft === 'undefined') lockLeft = 0;\r\n\t\t\t\tif (typeof lockRight === 'undefined') lockRight = 0;\r\n\r\n\t\t\t\tvar lockScroll = Math.floor(containerWidth - lockLeft - lockRight);\r\n\t\t\t\t$(datatable.table).find('.' + pfx + 'datatable__lock--scroll').css('width', lockScroll);\r\n\r\n\t\t\t\treturn lockScroll;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * todo; not in use\r\n\t\t\t */\r\n\t\t\tdragResize: function() {\r\n\t\t\t\tvar pressed = false;\r\n\t\t\t\tvar start = undefined;\r\n\t\t\t\tvar startX, startWidth;\r\n\t\t\t\t$(datatable.tableHead).find('.' + pfx + 'datatable__cell').mousedown(function(e) {\r\n\t\t\t\t\tstart = $(this);\r\n\t\t\t\t\tpressed = true;\r\n\t\t\t\t\tstartX = e.pageX;\r\n\t\t\t\t\tstartWidth = $(this).width();\r\n\t\t\t\t\t$(start).addClass(pfx + 'datatable__cell--resizing');\r\n\r\n\t\t\t\t}).mousemove(function(e) {\r\n\t\t\t\t\tif (pressed) {\r\n\t\t\t\t\t\tvar i = $(start).index();\r\n\t\t\t\t\t\tvar tableBody = $(datatable.tableBody);\r\n\t\t\t\t\t\tvar ifLocked = $(start).closest('.' + pfx + 'datatable__lock');\r\n\r\n\t\t\t\t\t\tif (ifLocked) {\r\n\t\t\t\t\t\t\tvar lockedIndex = $(ifLocked).index();\r\n\t\t\t\t\t\t\ttableBody = $(datatable.tableBody).find('.' + pfx + 'datatable__lock').eq(lockedIndex);\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t$(tableBody).find('.' + pfx + 'datatable__row').each(function(tri, tr) {\r\n\t\t\t\t\t\t\t$(tr).find('.' + pfx + 'datatable__cell').eq(i).width(startWidth + (e.pageX - startX)).children().width(startWidth + (e.pageX - startX));\r\n\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\t$(start).children().css('width', startWidth + (e.pageX - startX));\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}).mouseup(function() {\r\n\t\t\t\t\t$(start).removeClass(pfx + 'datatable__cell--resizing');\r\n\t\t\t\t\tpressed = false;\r\n\t\t\t\t});\r\n\r\n\t\t\t\t$(document).mouseup(function() {\r\n\t\t\t\t\t$(start).removeClass(pfx + 'datatable__cell--resizing');\r\n\t\t\t\t\tpressed = false;\r\n\t\t\t\t});\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * To prepare placeholder for table before content is loading\r\n\t\t\t */\r\n\t\t\tinitHeight: function() {\r\n\t\t\t\tif (options.layout.height && options.layout.scroll) {\r\n\t\t\t\t\tvar theadHeight = $(datatable.tableHead).find('.' + pfx + 'datatable__row').outerHeight();\r\n\t\t\t\t\tvar tfootHeight = $(datatable.tableFoot).find('.' + pfx + 'datatable__row').outerHeight();\r\n\t\t\t\t\tvar bodyHeight = options.layout.height;\r\n\t\t\t\t\tif (theadHeight > 0) {\r\n\t\t\t\t\t\tbodyHeight -= theadHeight;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (tfootHeight > 0) {\r\n\t\t\t\t\t\tbodyHeight -= tfootHeight;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// scrollbar offset\r\n\t\t\t\t\tbodyHeight -= 2;\r\n\r\n\t\t\t\t\t$(datatable.tableBody).css('max-height', bodyHeight);\r\n\r\n\t\t\t\t\t// set scrollable area fixed height\r\n\t\t\t\t\t$(datatable.tableBody).find('.' + pfx + 'datatable__lock--scroll').css('height', bodyHeight);\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Setup base DOM (table, thead, tbody, tfoot) and create if not exist.\r\n\t\t\t */\r\n\t\t\tsetupBaseDOM: function() {\r\n\t\t\t\t// keep original state before datatable initialize\r\n\t\t\t\tdatatable.initialDatatable = $(datatable).clone();\r\n\r\n\t\t\t\t// main element\r\n\t\t\t\tif ($(datatable).prop('tagName') === 'TABLE') {\r\n\t\t\t\t\t// if main init element is , wrap with div\r\n\t\t\t\t\tdatatable.table = $(datatable).removeClass(pfx + 'datatable').addClass(pfx + 'datatable__table');\r\n\t\t\t\t\tif ($(datatable.table).parents('.' + pfx + 'datatable').length === 0) {\r\n\t\t\t\t\t\tdatatable.table.wrap($('
').addClass(pfx + 'datatable').addClass(pfx + 'datatable--' + options.layout.theme));\r\n\t\t\t\t\t\tdatatable.wrap = $(datatable.table).parent();\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// create table\r\n\t\t\t\t\tdatatable.wrap = $(datatable).addClass(pfx + 'datatable').addClass(pfx + 'datatable--' + options.layout.theme);\r\n\t\t\t\t\tdatatable.table = $('
').addClass(pfx + 'datatable__table').appendTo(datatable);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (typeof options.layout.class !== 'undefined') {\r\n\t\t\t\t\t$(datatable.wrap).addClass(options.layout.class);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$(datatable.table).removeClass(pfx + 'datatable--destroyed').css('display', 'block');\r\n\r\n\t\t\t\t// force disable save state\r\n\t\t\t\tif (typeof $(datatable).attr('id') === 'undefined') {\r\n\t\t\t\t\tPlugin.setOption('data.saveState', false);\r\n\t\t\t\t\t$(datatable.table).attr('id', util.getUniqueID(pfx + 'datatable--'));\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// predefine table height\r\n\t\t\t\tif (Plugin.getOption('layout.minHeight'))\r\n\t\t\t\t\t$(datatable.table).css('min-height', Plugin.getOption('layout.minHeight'));\r\n\r\n\t\t\t\tif (Plugin.getOption('layout.height'))\r\n\t\t\t\t\t$(datatable.table).css('max-height', Plugin.getOption('layout.height'));\r\n\r\n\t\t\t\t// for normal table load\r\n\t\t\t\tif (options.data.type === null) {\r\n\t\t\t\t\t$(datatable.table).css('width', '').css('display', '');\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// create table head element\r\n\t\t\t\tdatatable.tableHead = $(datatable.table).find('thead');\r\n\t\t\t\tif ($(datatable.tableHead).length === 0) {\r\n\t\t\t\t\tdatatable.tableHead = $('').prependTo(datatable.table);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// create table head element\r\n\t\t\t\tdatatable.tableBody = $(datatable.table).find('tbody');\r\n\t\t\t\tif ($(datatable.tableBody).length === 0) {\r\n\t\t\t\t\tdatatable.tableBody = $('').appendTo(datatable.table);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (typeof options.layout.footer !== 'undefined' &&\r\n\t\t\t\t\toptions.layout.footer) {\r\n\t\t\t\t\t// create table foot element\r\n\t\t\t\t\tdatatable.tableFoot = $(datatable.table).find('tfoot');\r\n\t\t\t\t\tif ($(datatable.tableFoot).length === 0) {\r\n\t\t\t\t\t\tdatatable.tableFoot = $('').appendTo(datatable.table);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Set column data before table manipulation.\r\n\t\t\t */\r\n\t\t\tsetupCellField: function(tableParts) {\r\n\t\t\t\tif (typeof tableParts === 'undefined') tableParts = $(datatable.table).children();\r\n\t\t\t\tvar columns = options.columns;\r\n\t\t\t\t$.each(tableParts, function(part, tablePart) {\r\n\t\t\t\t\t$(tablePart).find('.' + pfx + 'datatable__row').each(function(tri, tr) {\r\n\t\t\t\t\t\t// prepare data\r\n\t\t\t\t\t\t$(tr).find('.' + pfx + 'datatable__cell').each(function(tdi, td) {\r\n\t\t\t\t\t\t\tif (typeof columns[tdi] !== 'undefined') {\r\n\t\t\t\t\t\t\t\t$(td).data(columns[tdi]);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Set column template callback\r\n\t\t\t * @param tablePart\r\n\t\t\t */\r\n\t\t\tsetupTemplateCell: function(tablePart) {\r\n\t\t\t\tif (typeof tablePart === 'undefined') tablePart = datatable.tableBody;\r\n\t\t\t\tvar columns = options.columns;\r\n\t\t\t\t$(tablePart).find('.' + pfx + 'datatable__row').each(function(tri, tr) {\r\n\t\t\t\t\t// row data object, if any\r\n\t\t\t\t\tvar obj = $(tr).data('obj') || {};\r\n\r\n\t\t\t\t\t// @deprecated in v5.0.6\r\n\t\t\t\t\t// obj['getIndex'] = function() {\r\n\t\t\t\t\t// \treturn tri;\r\n\t\t\t\t\t// };\r\n\t\t\t\t\t// @deprecated in v5.0.6\r\n\t\t\t\t\t// obj['getDatatable'] = function() {\r\n\t\t\t\t\t// \treturn datatable;\r\n\t\t\t\t\t// };\r\n\r\n\t\t\t\t\t// @deprecated in v5.0.6\r\n\t\t\t\t\tvar rowCallback = Plugin.getOption('rows.callback');\r\n\t\t\t\t\tif (typeof rowCallback === 'function') {\r\n\t\t\t\t\t\trowCallback($(tr), obj, tri);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// before template row callback\r\n\t\t\t\t\tvar beforeTemplate = Plugin.getOption('rows.beforeTemplate');\r\n\t\t\t\t\tif (typeof beforeTemplate === 'function') {\r\n\t\t\t\t\t\tbeforeTemplate($(tr), obj, tri);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// if data object is undefined, collect from table\r\n\t\t\t\t\tif (typeof obj === 'undefined') {\r\n\t\t\t\t\t\tobj = {};\r\n\t\t\t\t\t\t$(tr).find('.' + pfx + 'datatable__cell').each(function(tdi, td) {\r\n\t\t\t\t\t\t\t// get column settings by field\r\n\t\t\t\t\t\t\tvar column = $.grep(columns, function(n, i) {\r\n\t\t\t\t\t\t\t\treturn $(td).data('field') === n.field;\r\n\t\t\t\t\t\t\t})[0];\r\n\t\t\t\t\t\t\tif (typeof column !== 'undefined') {\r\n\t\t\t\t\t\t\t\tobj[column['field']] = $(td).text();\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t$(tr).find('.' + pfx + 'datatable__cell').each(function(tdi, td) {\r\n\t\t\t\t\t\t// get column settings by field\r\n\t\t\t\t\t\tvar column = $.grep(columns, function(n, i) {\r\n\t\t\t\t\t\t\treturn $(td).data('field') === n.field;\r\n\t\t\t\t\t\t})[0];\r\n\t\t\t\t\t\tif (typeof column !== 'undefined') {\r\n\t\t\t\t\t\t\t// column template\r\n\t\t\t\t\t\t\tif (typeof column.template !== 'undefined') {\r\n\t\t\t\t\t\t\t\tvar finalValue = '';\r\n\t\t\t\t\t\t\t\t// template string\r\n\t\t\t\t\t\t\t\tif (typeof column.template === 'string') {\r\n\t\t\t\t\t\t\t\t\tfinalValue = Plugin.dataPlaceholder(column.template, obj);\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t// template callback function\r\n\t\t\t\t\t\t\t\tif (typeof column.template === 'function') {\r\n\t\t\t\t\t\t\t\t\tfinalValue = column.template(obj, tri, datatable);\r\n\t\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t\t// sanitize using DOMPurify if installed\r\n\t\t\t\t\t\t\t\tif (typeof DOMPurify !== 'undefined') {\r\n\t\t\t\t\t\t\t\t\tfinalValue = DOMPurify.sanitize(finalValue);\r\n\t\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t\tvar span = document.createElement('span');\r\n\t\t\t\t\t\t\t\tspan.innerHTML = finalValue;\r\n\r\n\t\t\t\t\t\t\t\t// insert to cell, wrap with span\r\n\t\t\t\t\t\t\t\t$(td).html(span);\r\n\r\n\t\t\t\t\t\t\t\t// set span overflow\r\n\t\t\t\t\t\t\t\tif (typeof column.overflow !== 'undefined') {\r\n\t\t\t\t\t\t\t\t\t$(span).css('overflow', column.overflow);\r\n\t\t\t\t\t\t\t\t\t$(span).css('position', 'relative');\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\t// after template row callback\r\n\t\t\t\t\tvar afterTemplate = Plugin.getOption('rows.afterTemplate');\r\n\r\n\t\t\t\t\t//add tabindex per row\r\n\t\t\t\t\t$(tr).attr(\"tabindex\", 0);\r\n\r\n\t\t\t\t\tif (typeof afterTemplate === 'function') {\r\n\t\t\t\t\t\tafterTemplate($(tr), obj, tri);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Setup extra system column properties\r\n\t\t\t * Note: selector checkbox, subtable toggle\r\n\t\t\t */\r\n\t\t\tsetupSystemColumn: function() {\r\n\t\t\t\tdatatable.dataSet = datatable.dataSet || [];\r\n\t\t\t\t// no records available\r\n\t\t\t\tif (datatable.dataSet.length === 0) return;\r\n\r\n\t\t\t\tvar columns = options.columns;\r\n\t\t\t\t$(datatable.tableBody).find('.' + pfx + 'datatable__row').each(function(tri, tr) {\r\n\t\t\t\t\t$(tr).find('.' + pfx + 'datatable__cell').each(function(tdi, td) {\r\n\t\t\t\t\t\t// get column settings by field\r\n\t\t\t\t\t\tvar column = $.grep(columns, function(n, i) {\r\n\t\t\t\t\t\t\treturn $(td).data('field') === n.field;\r\n\t\t\t\t\t\t})[0];\r\n\t\t\t\t\t\tif (typeof column !== 'undefined') {\r\n\t\t\t\t\t\t\tvar value = $(td).text();\r\n\r\n\t\t\t\t\t\t\t// enable column selector\r\n\t\t\t\t\t\t\tif (typeof column.selector !== 'undefined' && column.selector !== false) {\r\n\t\t\t\t\t\t\t\t// check if checkbox exist\r\n\t\t\t\t\t\t\t\tif ($(td).find('.' + pfx + 'checkbox [type=\"checkbox\"]').length > 0) return;\r\n\r\n\t\t\t\t\t\t\t\t$(td).addClass(pfx + 'datatable__cell--check');\r\n\r\n\t\t\t\t\t\t\t\t// append checkbox\r\n\t\t\t\t\t\t\t\tvar chk = $(' as parent and add as child table\r\n\t\t\t\t\t\tsubTableRow = $('').\r\n\t\t\t\t\t\taddClass(pfx + 'datatable__row-subtable ' + pfx + 'datatable__row-loading').\r\n\t\t\t\t\t\thide().\r\n\t\t\t\t\t\tappend($('').addClass(pfx + 'datatable__row-detail').insertAfter(row);\r\n\t\t\t\t\t\tvar detailRowTd = $('
').addClass(pfx + 'datatable__subtable').attr('colspan', Plugin.getTotalColumns()));\r\n\t\t\t\t\t\t$(parentRow).after(subTableRow);\r\n\t\t\t\t\t\t// add class to even row\r\n\t\t\t\t\t\tif ($(parentRow).hasClass(pfx + 'datatable__row--even')) {\r\n\t\t\t\t\t\t\t$(subTableRow).addClass(pfx + 'datatable__row-subtable--even');\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t$(subTableRow).toggle();\r\n\r\n\t\t\t\t\tvar subTable = $(subTableRow).find('.' + pfx + 'datatable__subtable');\r\n\r\n\t\t\t\t\t// get id from first column of parent row\r\n\t\t\t\t\tvar primaryKey = $(this).closest('[data-field]:first-child').find('.' + pfx + 'datatable__toggle-subtable').data('value');\r\n\r\n\t\t\t\t\tvar icon = $(this).find('i').removeAttr('class');\r\n\r\n\t\t\t\t\t// prevent duplicate datatable init\r\n\t\t\t\t\tif ($(parentRow).hasClass(pfx + 'datatable__row--subtable-expanded')) {\r\n\t\t\t\t\t\t$(icon).addClass(Plugin.getOption('layout.icons.rowDetail.collapse'));\r\n\t\t\t\t\t\t// remove expand class from parent row\r\n\t\t\t\t\t\t$(parentRow).removeClass(pfx + 'datatable__row--subtable-expanded');\r\n\t\t\t\t\t\t// trigger event on collapse\r\n\t\t\t\t\t\t$(datatable).trigger(pfx + 'datatable--on-collapse-subtable', [parentRow]);\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t// expand and run callback function\r\n\t\t\t\t\t\t$(icon).addClass(Plugin.getOption('layout.icons.rowDetail.expand'));\r\n\t\t\t\t\t\t// add expand class to parent row\r\n\t\t\t\t\t\t$(parentRow).addClass(pfx + 'datatable__row--subtable-expanded');\r\n\t\t\t\t\t\t// trigger event on expand\r\n\t\t\t\t\t\t$(datatable).trigger(pfx + 'datatable--on-expand-subtable', [parentRow]);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// prevent duplicate datatable init\r\n\t\t\t\t\tif ($(subTable).find('.' + pfx + 'datatable').length === 0) {\r\n\t\t\t\t\t\t// get data by primary id\r\n\t\t\t\t\t\t$.map(datatable.dataSet, function(n, i) {\r\n\t\t\t\t\t\t\t// primary id must be at the first column, otherwise e.data will be undefined\r\n\t\t\t\t\t\t\tif (primaryKey === n[options.columns[0].field]) {\r\n\t\t\t\t\t\t\t\te.data = n;\r\n\t\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\t// deprecated in v5.0.6\r\n\t\t\t\t\t\te.detailCell = subTable;\r\n\r\n\t\t\t\t\t\te.parentRow = parentRow;\r\n\t\t\t\t\t\te.subTable = subTable;\r\n\r\n\t\t\t\t\t\t// run callback with event\r\n\t\t\t\t\t\tsubTableCallback(e);\r\n\r\n\t\t\t\t\t\t$(subTable).children('.' + pfx + 'datatable').on(pfx + 'datatable--on-init', function(e) {\r\n\t\t\t\t\t\t\t$(subTableRow).removeClass(pfx + 'datatable__row-loading');\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tif (Plugin.getOption('data.type') === 'local') {\r\n\t\t\t\t\t\t\t$(subTableRow).removeClass(pfx + 'datatable__row-loading');\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t};\r\n\r\n\t\t\t\tvar columns = options.columns;\r\n\t\t\t\t$(datatable.tableBody).find('.' + pfx + 'datatable__row').each(function(tri, tr) {\r\n\t\t\t\t\t$(tr).find('.' + pfx + 'datatable__cell').each(function(tdi, td) {\r\n\t\t\t\t\t\t// get column settings by field\r\n\t\t\t\t\t\tvar column = $.grep(columns, function(n, i) {\r\n\t\t\t\t\t\t\treturn $(td).data('field') === n.field;\r\n\t\t\t\t\t\t})[0];\r\n\t\t\t\t\t\tif (typeof column !== 'undefined') {\r\n\t\t\t\t\t\t\tvar value = $(td).text();\r\n\t\t\t\t\t\t\t// enable column subtable toggle\r\n\t\t\t\t\t\t\tif (typeof column.subtable !== 'undefined' && column.subtable) {\r\n\t\t\t\t\t\t\t\t// check if subtable toggle exist\r\n\t\t\t\t\t\t\t\tif ($(td).find('.' + pfx + 'datatable__toggle-subtable').length > 0) return;\r\n\t\t\t\t\t\t\t\t// append subtable toggle\r\n\t\t\t\t\t\t\t\t$(td).\r\n\t\t\t\t\t\t\t\thtml($('').addClass(pfx + 'datatable__toggle-subtable').attr('href', '#').attr('data-value', value).attr('title', Plugin.getOption('detail.title')).on('click', toggleSubTable).append($('').css('width', $(td).data('width')).addClass(Plugin.getOption('layout.icons.rowDetail.collapse'))));\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\r\n\t\t\t\t// $(datatable.tableHead).find('.'+pfx+'-datatable__row').first()\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Datasource mapping callback\r\n\t\t\t */\r\n\t\t\tdataMapCallback: function(raw) {\r\n\t\t\t\t// static dataset array\r\n\t\t\t\tvar dataSet = raw;\r\n\t\t\t\t// dataset mapping callback\r\n\t\t\t\tif (typeof Plugin.getOption('data.source.read.map') === 'function') {\r\n\t\t\t\t\treturn Plugin.getOption('data.source.read.map')(raw);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// default data mapping fallback\r\n\t\t\t\t\tif (typeof raw !== 'undefined' && typeof raw.data !== 'undefined') {\r\n\t\t\t\t\t\tdataSet = raw.data;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\treturn dataSet;\r\n\t\t\t},\r\n\r\n\t\t\tisSpinning: false,\r\n\t\t\t/**\r\n\t\t\t * BlockUI spinner callback\r\n\t\t\t * @param block\r\n\t\t\t * @param target\r\n\t\t\t */\r\n\t\t\tspinnerCallback: function(block, target) {\r\n\t\t\t\tif (typeof target === 'undefined') target = datatable;\r\n\t\t\t\t// get spinner options\r\n\t\t\t\tvar spinnerOptions = Plugin.getOption('layout.spinner');\r\n\t\t\t\t// spinner is disabled\r\n\t\t\t\tif (typeof spinnerOptions === 'undefined' || !spinnerOptions) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tif (block) {\r\n\t\t\t\t\tif (!Plugin.isSpinning) {\r\n\t\t\t\t\t\tif (typeof spinnerOptions.message !== 'undefined' && spinnerOptions.message === true) {\r\n\t\t\t\t\t\t\t// use default spinner message from translation\r\n\t\t\t\t\t\t\tspinnerOptions.message = Plugin.getOption('translate.records.processing');\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tPlugin.isSpinning = true;\r\n\t\t\t\t\t\tif (typeof app !== 'undefined') {\r\n\t\t\t\t\t\t\tapp.block(target, spinnerOptions);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tPlugin.isSpinning = false;\r\n\t\t\t\t\tif (typeof app !== 'undefined') {\r\n\t\t\t\t\t\tapp.unblock(target);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Default sort callback function\r\n\t\t\t * @param data\r\n\t\t\t * @param sort\r\n\t\t\t * @param column\r\n\t\t\t * @returns {*|Array.|{sort, field}|{asc, desc}}\r\n\t\t\t */\r\n\t\t\tsortCallback: function(data, sort, column) {\r\n\t\t\t\tvar type = column['type'] || 'string';\r\n\t\t\t\tvar format = column['format'] || '';\r\n\t\t\t\tvar field = column['field'];\r\n\r\n\t\t\t\treturn $(data).sort(function(a, b) {\r\n\t\t\t\t\tvar aField = a[field];\r\n\t\t\t\t\tvar bField = b[field];\r\n\r\n\t\t\t\t\tswitch (type) {\r\n\t\t\t\t\t\tcase 'date':\r\n\t\t\t\t\t\t\tif (typeof moment === 'undefined') {\r\n\t\t\t\t\t\t\t\tthrow new Error('Moment.js is required.');\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tvar diff = moment(aField, format).diff(moment(bField, format));\r\n\t\t\t\t\t\t\tif (sort === 'asc') {\r\n\t\t\t\t\t\t\t\treturn diff > 0 ? 1 : diff < 0 ? -1 : 0;\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\treturn diff < 0 ? 1 : diff > 0 ? -1 : 0;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\tcase 'number':\r\n\t\t\t\t\t\t\tif (isNaN(parseFloat(aField)) && aField != null) {\r\n\t\t\t\t\t\t\t\taField = Number(aField.replace(/[^0-9\\.-]+/g, ''));\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif (isNaN(parseFloat(bField)) && bField != null) {\r\n\t\t\t\t\t\t\t\tbField = Number(bField.replace(/[^0-9\\.-]+/g, ''));\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\taField = parseFloat(aField);\r\n\t\t\t\t\t\t\tbField = parseFloat(bField);\r\n\t\t\t\t\t\t\tif (sort === 'asc') {\r\n\t\t\t\t\t\t\t\treturn aField > bField ? 1 : aField < bField ? -1 : 0;\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\treturn aField < bField ? 1 : aField > bField ? -1 : 0;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\tcase 'string':\r\n\t\t\t\t\t\tdefault:\r\n\t\t\t\t\t\t\tif (sort === 'asc') {\r\n\t\t\t\t\t\t\t\treturn aField > bField ? 1 : aField < bField ? -1 : 0;\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\treturn aField < bField ? 1 : aField > bField ? -1 : 0;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Custom debug log\r\n\t\t\t * @param text\r\n\t\t\t * @param obj\r\n\t\t\t */\r\n\t\t\tlog: function(text, obj) {\r\n\t\t\t\tif (typeof obj === 'undefined') obj = '';\r\n\t\t\t\tif (datatable.debug) {\r\n\t\t\t\t\tconsole.log(text, obj);\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Auto hide columnds overflow in row\r\n\t\t\t */\r\n\t\t\tautoHide: function() {\r\n\t\t\t\tvar hiddenExist = false;\r\n\t\t\t\t$(datatable.table).find('.' + pfx + 'datatable__cell').show();\r\n\r\n\t\t\t\t// force hide enabled\r\n\t\t\t\tvar hidDefault = $(datatable.table).find('[data-autohide-enabled]');\r\n\t\t\t\tif (hidDefault.length) {\r\n\t\t\t\t\thiddenExist = true;\r\n\t\t\t\t\thidDefault.hide();\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$(datatable.tableBody).each(function() {\r\n\t\t\t\t\twhile ($(this)[0].offsetWidth < $(this)[0].scrollWidth) {\r\n\t\t\t\t\t\t$(datatable.table).find('.' + pfx + 'datatable__row').each(function(i) {\r\n\t\t\t\t\t\t\tvar cell = $(this).find('.' + pfx + 'datatable__cell').not(':hidden').not('[data-autohide-disabled]').last();\r\n\t\t\t\t\t\t\t$(cell).hide();\r\n\t\t\t\t\t\t\thiddenExist = true;\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\r\n\t\t\t\tif (!hiddenExist) {\r\n\t\t\t\t\t// no column is hidden, skip expand icons\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar toggleHiddenColumns = function(e) {\r\n\t\t\t\t\te.preventDefault();\r\n\r\n\t\t\t\t\tvar row = $(this).closest('.' + pfx + 'datatable__row');\r\n\t\t\t\t\tvar detailRow = $(row).next();\r\n\r\n\t\t\t\t\tif (!$(detailRow).hasClass(pfx + 'datatable__row-detail')) {\r\n\t\t\t\t\t\t$(this).find('i').removeClass(Plugin.getOption('layout.icons.rowDetail.collapse')).addClass(Plugin.getOption('layout.icons.rowDetail.expand'));\r\n\r\n\t\t\t\t\t\tvar hidden = $(row).find('.' + pfx + 'datatable__cell:hidden').clone().show();\r\n\r\n\t\t\t\t\t\tdetailRow = $('
').addClass(pfx + 'datatable__detail').attr('colspan', Plugin.getTotalColumns()).appendTo(detailRow);\r\n\r\n\t\t\t\t\t\tvar detailSubTable = $('');\r\n\t\t\t\t\t\t$(hidden).each(function() {\r\n\t\t\t\t\t\t\tvar field = $(this).data('field');\r\n\t\t\t\t\t\t\tvar column = $.grep(options.columns, function(n, i) {\r\n\t\t\t\t\t\t\t\treturn field === n.field;\r\n\t\t\t\t\t\t\t})[0];\r\n\t\t\t\t\t\t\t$(detailSubTable).\r\n\t\t\t\t\t\t\tappend($('').append($('').append($('').append(column.title))).append(this));\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\t$(detailRowTd).append(detailSubTable);\r\n\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t$(this).find('i').removeClass(Plugin.getOption('layout.icons.rowDetail.expand')).addClass(Plugin.getOption('layout.icons.rowDetail.collapse'));\r\n\t\t\t\t\t\t$(detailRow).remove();\r\n\t\t\t\t\t}\r\n\t\t\t\t};\r\n\r\n\t\t\t\t// toggle show hidden columns\r\n\t\t\t\t$(datatable.tableBody).find('.' + pfx + 'datatable__row').each(function() {\r\n\t\t\t\t\t$(this).\r\n\t\t\t\t\tprepend($('');\r\n\t\t\t\t\t\t$(datatable.tableFoot).\r\n\t\t\t\t\t\tfind('.' + pfx + 'datatable__row').\r\n\t\t\t\t\t\tfirst().\r\n\t\t\t\t\t\tprepend('');\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t$(datatable.tableHead).find('.' + pfx + 'datatable__toggle-detail').find('span');\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\r\n\t\t\t\tPlugin.adjustCellsWidth.call();\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * To enable auto columns features for remote data source\r\n\t\t\t */\r\n\t\t\tsetAutoColumns: function() {\r\n\t\t\t\tif (Plugin.getOption('data.autoColumns')) {\r\n\t\t\t\t\t$.each(datatable.dataSet[0], function(k, v) {\r\n\t\t\t\t\t\tvar found = $.grep(options.columns, function(n, i) {\r\n\t\t\t\t\t\t\treturn k === n.field;\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tif (found.length === 0) {\r\n\t\t\t\t\t\t\toptions.columns.push({\r\n\t\t\t\t\t\t\t\tfield: k,\r\n\t\t\t\t\t\t\t\ttitle: k\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t\t$(datatable.tableHead).find('.' + pfx + 'datatable__row').remove();\r\n\t\t\t\t\tPlugin.setHeadTitle();\r\n\t\t\t\t\tif (Plugin.getOption('layout.footer')) {\r\n\t\t\t\t\t\t$(datatable.tableFoot).find('.' + pfx + 'datatable__row').remove();\r\n\t\t\t\t\t\tPlugin.setHeadTitle(datatable.tableFoot);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t/********************\r\n\t\t\t ** HELPERS\r\n\t\t\t ********************/\r\n\r\n\t\t\t/**\r\n\t\t\t * Check if table is a locked colums table\r\n\t\t\t */\r\n\t\t\tisLocked: function() {\r\n\t\t\t\treturn util.hasClass(datatable.wrap[0], pfx + 'datatable--lock') || false;\r\n\t\t\t},\r\n\r\n\t\t\tisSubtable: function() {\r\n\t\t\t\treturn util.hasClass(datatable.wrap[0], pfx + 'datatable--subtable') || false;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get total extra space of an element for width calculation, including\r\n\t\t\t * padding, margin, border\r\n\t\t\t * @param element\r\n\t\t\t * @returns {number}\r\n\t\t\t */\r\n\t\t\tgetExtraSpace: function(element) {\r\n\t\t\t\tvar padding = parseInt($(element).css('paddingRight')) +\r\n\t\t\t\t\tparseInt($(element).css('paddingLeft'));\r\n\t\t\t\tvar margin = parseInt($(element).css('marginRight')) +\r\n\t\t\t\t\tparseInt($(element).css('marginLeft'));\r\n\t\t\t\tvar border = Math.ceil(\r\n\t\t\t\t\t$(element).css('border-right-width').replace('px', ''));\r\n\t\t\t\treturn padding + margin + border;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Insert data of array into {{ }} template placeholder\r\n\t\t\t * @param template\r\n\t\t\t * @param data\r\n\t\t\t * @returns {*}\r\n\t\t\t */\r\n\t\t\tdataPlaceholder: function(template, data) {\r\n\t\t\t\tvar result = template;\r\n\t\t\t\t$.each(data, function(key, val) {\r\n\t\t\t\t\tresult = result.replace('{{' + key + '}}', val);\r\n\t\t\t\t});\r\n\t\t\t\treturn result;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get table unique ID\r\n\t\t\t * Note: table unique change each time refreshed\r\n\t\t\t * @param suffix\r\n\t\t\t * @returns {*}\r\n\t\t\t */\r\n\t\t\tgetTableId: function(suffix) {\r\n\t\t\t\tif (typeof suffix === 'undefined') suffix = '';\r\n\t\t\t\tvar id = $(datatable).attr('id');\r\n\t\t\t\tif (typeof id === 'undefined') {\r\n\t\t\t\t\tid = $(datatable).attr('class').split(' ')[0];\r\n\t\t\t\t}\r\n\t\t\t\treturn id + suffix;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get table prefix with depth number\r\n\t\t\t */\r\n\t\t\tgetTablePrefix: function(suffix) {\r\n\t\t\t\tif (typeof suffix !== 'undefined') suffix = '-' + suffix;\r\n\t\t\t\treturn Plugin.getTableId() + '-' + Plugin.getDepth() + suffix;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get current table depth of sub table\r\n\t\t\t * @returns {number}\r\n\t\t\t */\r\n\t\t\tgetDepth: function() {\r\n\t\t\t\tvar depth = 0;\r\n\t\t\t\tvar table = datatable.table;\r\n\t\t\t\tdo {\r\n\t\t\t\t\ttable = $(table).parents('.' + pfx + 'datatable__table');\r\n\t\t\t\t\tdepth++;\r\n\t\t\t\t} while ($(table).length > 0);\r\n\t\t\t\treturn depth;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Keep state item\r\n\t\t\t * @param key\r\n\t\t\t * @param value\r\n\t\t\t */\r\n\t\t\tstateKeep: function(key, value) {\r\n\t\t\t\tkey = Plugin.getTablePrefix(key);\r\n\t\t\t\tif (Plugin.getOption('data.saveState') === false) return;\r\n\t\t\t\tif (Plugin.getOption('data.saveState.webstorage') && localStorage) {\r\n\t\t\t\t\tlocalStorage.setItem(key, JSON.stringify(value));\r\n\t\t\t\t}\r\n\t\t\t\tif (Plugin.getOption('data.saveState.cookie')) {\r\n\t\t\t\t\tCookies.set(key, JSON.stringify(value));\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get state item\r\n\t\t\t * @param key\r\n\t\t\t * @param defValue\r\n\t\t\t */\r\n\t\t\tstateGet: function(key, defValue) {\r\n\t\t\t\tkey = Plugin.getTablePrefix(key);\r\n\t\t\t\tif (Plugin.getOption('data.saveState') === false) return;\r\n\t\t\t\tvar value = null;\r\n\t\t\t\tif (Plugin.getOption('data.saveState.webstorage') && localStorage) {\r\n\t\t\t\t\tvalue = localStorage.getItem(key);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue = Cookies.get(key);\r\n\t\t\t\t}\r\n\t\t\t\tif (typeof value !== 'undefined' && value !== null) {\r\n\t\t\t\t\treturn JSON.parse(value);\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Update data in state without clear existing\r\n\t\t\t * @param key\r\n\t\t\t * @param value\r\n\t\t\t */\r\n\t\t\tstateUpdate: function(key, value) {\r\n\t\t\t\tvar ori = Plugin.stateGet(key);\r\n\t\t\t\tif (typeof ori === 'undefined' || ori === null) ori = {};\r\n\t\t\t\tPlugin.stateKeep(key, $.extend({}, ori, value));\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Remove state item\r\n\t\t\t * @param key\r\n\t\t\t */\r\n\t\t\tstateRemove: function(key) {\r\n\t\t\t\tkey = Plugin.getTablePrefix(key);\r\n\t\t\t\tif (localStorage) {\r\n\t\t\t\t\tlocalStorage.removeItem(key);\r\n\t\t\t\t}\r\n\t\t\t\tCookies.remove(key);\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get total columns.\r\n\t\t\t */\r\n\t\t\tgetTotalColumns: function(tablePart) {\r\n\t\t\t\tif (typeof tablePart === 'undefined') tablePart = datatable.tableBody;\r\n\t\t\t\treturn $(tablePart).find('.' + pfx + 'datatable__row').first().find('.' + pfx + 'datatable__cell').length;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get table row. Useful to get row when current table is in lock mode.\r\n\t\t\t * Can be used for both lock and normal table mode.\r\n\t\t\t * By default, returning result will be in a list of \r\n\t\t\t\tvar result = $(tablePart).find('.' + pfx + 'datatable__row:not(.' + pfx + 'datatable__row-detail):nth-child(' + row + ')');\r\n\t\t\t\tif (tdOnly) {\r\n\t\t\t\t\t// get list of
').addClass(pfx + 'datatable__cell ' + pfx + 'datatable__toggle-detail').append($('').addClass(pfx + 'datatable__toggle-detail').attr('href', '').on('click', toggleHiddenColumns).append('')));\r\n\r\n\t\t\t\t\t// check if subtable toggle exist\r\n\t\t\t\t\tif ($(datatable.tableHead).find('.' + pfx + 'datatable__toggle-detail').length === 0) {\r\n\t\t\t\t\t\t$(datatable.tableHead).\r\n\t\t\t\t\t\tfind('.' + pfx + 'datatable__row').\r\n\t\t\t\t\t\tfirst().\r\n\t\t\t\t\t\tprepend('.\r\n\t\t\t * @param tablePart\r\n\t\t\t * @param row 1-based index\r\n\t\t\t * @param tdOnly Optional. Default true\r\n\t\t\t * @returns {*}\r\n\t\t\t */\r\n\t\t\tgetOneRow: function(tablePart, row, tdOnly) {\r\n\t\t\t\tif (typeof tdOnly === 'undefined') tdOnly = true;\r\n\t\t\t\t// get list of
or \r\n\t\t\t\t\tresult = result.find('.' + pfx + 'datatable__cell');\r\n\t\t\t\t}\r\n\t\t\t\treturn result;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Check if element has vertical overflow\r\n\t\t\t * @param element\r\n\t\t\t * @returns {boolean}\r\n\t\t\t */\r\n\t\t\thasOverflowY: function(element) {\r\n\t\t\t\tvar children = $(element).find('.' + pfx + 'datatable__row');\r\n\t\t\t\tvar maxHeight = 0;\r\n\r\n\t\t\t\tif (children.length > 0) {\r\n\t\t\t\t\t$(children).each(function(tdi, td) {\r\n\t\t\t\t\t\tmaxHeight += Math.floor($(td).innerHeight());\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\treturn maxHeight > $(element).innerHeight();\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn false;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Sort table row at HTML level by column index.\r\n\t\t\t * todo; Not in use.\r\n\t\t\t * @param header Header sort clicked\r\n\t\t\t * @param sort asc|desc. Optional. Default asc\r\n\t\t\t * @param int Boolean. Optional. Comparison value parse to integer.\r\n\t\t\t * Default false\r\n\t\t\t */\r\n\t\t\tsortColumn: function(header, sort, int) {\r\n\t\t\t\tif (typeof sort === 'undefined') sort = 'asc'; // desc\r\n\t\t\t\tif (typeof int === 'undefined') int = false;\r\n\r\n\t\t\t\tvar column = $(header).index();\r\n\t\t\t\tvar rows = $(datatable.tableBody).find('.' + pfx + 'datatable__row');\r\n\t\t\t\tvar hIndex = $(header).closest('.' + pfx + 'datatable__lock').index();\r\n\t\t\t\tif (hIndex !== -1) {\r\n\t\t\t\t\trows = $(datatable.tableBody).find('.' + pfx + 'datatable__lock:nth-child(' + (hIndex + 1) + ')').find('.' + pfx + 'datatable__row');\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar container = $(rows).parent();\r\n\t\t\t\t$(rows).sort(function(a, b) {\r\n\t\t\t\t\tvar tda = $(a).find('td:nth-child(' + column + ')').text();\r\n\t\t\t\t\tvar tdb = $(b).find('td:nth-child(' + column + ')').text();\r\n\r\n\t\t\t\t\tif (int) {\r\n\t\t\t\t\t\t// useful for integer type sorting\r\n\t\t\t\t\t\ttda = parseInt(tda);\r\n\t\t\t\t\t\ttdb = parseInt(tdb);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (sort === 'asc') {\r\n\t\t\t\t\t\treturn tda > tdb ? 1 : tda < tdb ? -1 : 0;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\treturn tda < tdb ? 1 : tda > tdb ? -1 : 0;\r\n\t\t\t\t\t}\r\n\t\t\t\t}).appendTo(container);\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Perform sort remote and local\r\n\t\t\t */\r\n\t\t\tsorting: function() {\r\n\t\t\t\tvar sortObj = {\r\n\t\t\t\t\tinit: function() {\r\n\t\t\t\t\t\tif (options.sortable) {\r\n\t\t\t\t\t\t\t$(datatable.tableHead).\r\n\t\t\t\t\t\t\tfind('.' + pfx + 'datatable__cell:not(.' + pfx + 'datatable__cell--check)').\r\n\t\t\t\t\t\t\taddClass(pfx + 'datatable__cell--sort').\r\n\t\t\t\t\t\t\toff('click').\r\n\t\t\t\t\t\t\ton('click', sortObj.sortClick);\r\n\t\t\t\t\t\t\t// first init\r\n\t\t\t\t\t\t\tsortObj.setIcon();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t},\r\n\t\t\t\t\tsetIcon: function() {\r\n\t\t\t\t\t\tvar meta = Plugin.getDataSourceParam('sort');\r\n\t\t\t\t\t\tif ($.isEmptyObject(meta)) return;\r\n\r\n\t\t\t\t\t\tvar column = Plugin.getColumnByField(meta.field);\r\n\t\t\t\t\t\t// sort is disabled for this column\r\n\t\t\t\t\t\tif (typeof column !== 'undefined' && typeof column.sortable !== 'undefined' && column.sortable === false) return;\r\n\r\n\t\t\t\t\t\t// sort icon beside column header\r\n\t\t\t\t\t\tvar td = $(datatable.tableHead).find('.' + pfx + 'datatable__cell[data-field=\"' + meta.field + '\"]').attr('data-sort', meta.sort);\r\n\t\t\t\t\t\tvar sorting = $(td).find('span');\r\n\t\t\t\t\t\tvar icon = $(sorting).find('i');\r\n\r\n\t\t\t\t\t\tvar icons = Plugin.getOption('layout.icons.sort');\r\n\t\t\t\t\t\t// update sort icon; desc & asc\r\n\t\t\t\t\t\tif ($(icon).length > 0) {\r\n\t\t\t\t\t\t\t$(icon).removeAttr('class').addClass(icons[meta.sort]);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t$(sorting).append($('').addClass(icons[meta.sort]));\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// set sorted class to header on init\r\n\t\t\t\t\t\t$(td).addClass(pfx + 'datatable__cell--sorted');\r\n\t\t\t\t\t},\r\n\t\t\t\t\tsortClick: function(e) {\r\n\t\t\t\t\t\tvar meta = Plugin.getDataSourceParam('sort');\r\n\t\t\t\t\t\tvar field = $(this).data('field');\r\n\t\t\t\t\t\tvar column = Plugin.getColumnByField(field);\r\n\t\t\t\t\t\t// sort is disabled for this column\r\n\t\t\t\t\t\tif (typeof column.sortable !== 'undefined' && column.sortable === false) return;\r\n\r\n\t\t\t\t\t\t// set sorted class to header\r\n\t\t\t\t\t\t$(datatable.tableHead).find('th').removeClass(pfx + 'datatable__cell--sorted');\r\n\t\t\t\t\t\tutil.addClass(this, pfx + 'datatable__cell--sorted');\r\n\r\n\t\t\t\t\t\t$(datatable.tableHead).find('.' + pfx + 'datatable__cell > span > i').remove();\r\n\r\n\t\t\t\t\t\tif (options.sortable) {\r\n\t\t\t\t\t\t\tPlugin.spinnerCallback(true);\r\n\r\n\t\t\t\t\t\t\tvar sort = 'desc';\r\n\t\t\t\t\t\t\tif (Plugin.getObject('field', meta) === field) {\r\n\t\t\t\t\t\t\t\tsort = Plugin.getObject('sort', meta);\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t// toggle sort\r\n\t\t\t\t\t\t\tsort = typeof sort === 'undefined' || sort === 'desc' ?\r\n\t\t\t\t\t\t\t\t'asc' :\r\n\t\t\t\t\t\t\t\t'desc';\r\n\r\n\t\t\t\t\t\t\t// update field and sort params\r\n\t\t\t\t\t\t\tmeta = {\r\n\t\t\t\t\t\t\t\tfield: field,\r\n\t\t\t\t\t\t\t\tsort: sort\r\n\t\t\t\t\t\t\t};\r\n\t\t\t\t\t\t\tPlugin.setDataSourceParam('sort', meta);\r\n\r\n\t\t\t\t\t\t\tsortObj.setIcon();\r\n\r\n\t\t\t\t\t\t\tsetTimeout(function() {\r\n\t\t\t\t\t\t\t\tPlugin.dataRender('sort');\r\n\t\t\t\t\t\t\t\t$(datatable).trigger(pfx + 'datatable--on-sort', meta);\r\n\t\t\t\t\t\t\t}, 300);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t},\r\n\t\t\t\t};\r\n\t\t\t\tsortObj.init();\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Update JSON data list linked with sort, filter and pagination.\r\n\t\t\t * Call this method, before using dataSet variable.\r\n\t\t\t * @returns {*|null}\r\n\t\t\t */\r\n\t\t\tlocalDataUpdate: function() {\r\n\t\t\t\tvar params = Plugin.getDataSourceParam();\r\n\t\t\t\tif (typeof datatable.originalDataSet === 'undefined') {\r\n\t\t\t\t\tdatatable.originalDataSet = datatable.dataSet;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar field = Plugin.getObject('sort.field', params);\r\n\t\t\t\tvar sort = Plugin.getObject('sort.sort', params);\r\n\t\t\t\tvar column = Plugin.getColumnByField(field);\r\n\t\t\t\tif (typeof column !== 'undefined' && Plugin.getOption('data.serverSorting') !== true) {\r\n\t\t\t\t\tif (typeof column.sortCallback === 'function') {\r\n\t\t\t\t\t\tdatatable.dataSet = column.sortCallback(datatable.originalDataSet, sort, column);\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdatatable.dataSet = Plugin.sortCallback(datatable.originalDataSet, sort, column);\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tdatatable.dataSet = datatable.originalDataSet;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// if server filter enable, don't pass local filter\r\n\t\t\t\tif (typeof params.query === 'object' && !Plugin.getOption('data.serverFiltering')) {\r\n\t\t\t\t\tparams.query = params.query || {};\r\n\r\n\t\t\t\t\tvar nestedSearch = function(obj) {\r\n\t\t\t\t\t\tfor (var field in obj) {\r\n\t\t\t\t\t\t\tif (!obj.hasOwnProperty(field)) continue;\r\n\t\t\t\t\t\t\tif (typeof obj[field] === 'string') {\r\n\t\t\t\t\t\t\t\tif (obj[field].toLowerCase() == search || obj[field].toLowerCase().indexOf(search) !== -1) {\r\n\t\t\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t} else if (typeof obj[field] === 'number') {\r\n\t\t\t\t\t\t\t\tif (obj[field] === search) {\r\n\t\t\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t} else if (typeof obj[field] === 'object') {\r\n\t\t\t\t\t\t\t\tif (nestedSearch(obj[field])) {\r\n\t\t\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\t\tvar search = $(Plugin.getOption('search.input')).val();\r\n\t\t\t\t\tif (typeof search !== 'undefined' && search !== '') {\r\n\t\t\t\t\t\tsearch = search.toLowerCase();\r\n\t\t\t\t\t\tdatatable.dataSet = $.grep(datatable.dataSet, nestedSearch);\r\n\t\t\t\t\t\t// remove generalSearch as we don't need this for next columns filter\r\n\t\t\t\t\t\tdelete params.query[Plugin.getGeneralSearchKey()];\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// remove empty element from array\r\n\t\t\t\t\t$.each(params.query, function(k, v) {\r\n\t\t\t\t\t\tif (v === '') {\r\n\t\t\t\t\t\t\tdelete params.query[k];\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\t// filter array by query\r\n\t\t\t\t\tdatatable.dataSet = Plugin.filterArray(datatable.dataSet, params.query);\r\n\r\n\t\t\t\t\t// reset array index\r\n\t\t\t\t\tdatatable.dataSet = datatable.dataSet.filter(function() {\r\n\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn datatable.dataSet;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Utility helper to filter array by object pair of {key:value}\r\n\t\t\t * @param list\r\n\t\t\t * @param args\r\n\t\t\t * @param operator\r\n\t\t\t * @returns {*}\r\n\t\t\t */\r\n\t\t\tfilterArray: function(list, args, operator) {\r\n\t\t\t\tif (typeof list !== 'object') {\r\n\t\t\t\t\treturn [];\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (typeof operator === 'undefined') operator = 'AND';\r\n\r\n\t\t\t\tif (typeof args !== 'object') {\r\n\t\t\t\t\treturn list;\r\n\t\t\t\t}\r\n\r\n\t\t\t\toperator = operator.toUpperCase();\r\n\r\n\t\t\t\tif ($.inArray(operator, ['AND', 'OR', 'NOT']) === -1) {\r\n\t\t\t\t\treturn [];\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar count = Object.keys(args).length;\r\n\t\t\t\tvar filtered = [];\r\n\r\n\t\t\t\t$.each(list, function(key, obj) {\r\n\t\t\t\t\tvar to_match = obj;\r\n\r\n\t\t\t\t\tvar matched = 0;\r\n\t\t\t\t\t$.each(args, function(m_key, m_value) {\r\n\t\t\t\t\t\tm_value = m_value instanceof Array ? m_value : [m_value];\r\n\t\t\t\t\t\tvar match_property = Plugin.getObject(m_key, to_match);\r\n\t\t\t\t\t\tif (typeof match_property !== 'undefined') {\r\n\t\t\t\t\t\t\tvar lhs = match_property.toString().toLowerCase();\r\n\t\t\t\t\t\t\tm_value.forEach(function(item, index) {\r\n\t\t\t\t\t\t\t\tif (item.toString().toLowerCase() == lhs || lhs.indexOf(item.toString().toLowerCase()) !== -1) {\r\n\t\t\t\t\t\t\t\t\tmatched++;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\tif (('AND' == operator && matched == count) ||\r\n\t\t\t\t\t\t('OR' == operator && matched > 0) ||\r\n\t\t\t\t\t\t('NOT' == operator && 0 == matched)) {\r\n\t\t\t\t\t\tfiltered[key] = obj;\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\r\n\t\t\t\tlist = filtered;\r\n\r\n\t\t\t\treturn list;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Reset lock column scroll to 0 when resize\r\n\t\t\t */\r\n\t\t\tresetScroll: function() {\r\n\t\t\t\tif (typeof options.detail === 'undefined' && Plugin.getDepth() === 1) {\r\n\t\t\t\t\t$(datatable.table).find('.' + pfx + 'datatable__row').css('left', 0);\r\n\t\t\t\t\t$(datatable.table).find('.' + pfx + 'datatable__lock').css('top', 0);\r\n\t\t\t\t\t$(datatable.tableBody).scrollTop(0);\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get column options by field\r\n\t\t\t * @param field\r\n\t\t\t * @returns {boolean}\r\n\t\t\t */\r\n\t\t\tgetColumnByField: function(field) {\r\n\t\t\t\tif (typeof field === 'undefined') return;\r\n\t\t\t\tvar result;\r\n\t\t\t\t$.each(options.columns, function(i, column) {\r\n\t\t\t\t\tif (field === column.field) {\r\n\t\t\t\t\t\tresult = column;\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t\treturn result;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get default sort column\r\n\t\t\t */\r\n\t\t\tgetDefaultSortColumn: function() {\r\n\t\t\t\tvar result;\r\n\t\t\t\t$.each(options.columns, function(i, column) {\r\n\t\t\t\t\tif (typeof column.sortable !== 'undefined' &&\r\n\t\t\t\t\t\t$.inArray(column.sortable, ['asc', 'desc']) !== -1) {\r\n\t\t\t\t\t\tresult = {\r\n\t\t\t\t\t\t\tsort: column.sortable,\r\n\t\t\t\t\t\t\tfield: column.field\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t\treturn result;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Helper to get element dimensions, when the element is hidden\r\n\t\t\t * @param element\r\n\t\t\t * @param includeMargin\r\n\t\t\t * @returns {{width: number, height: number, innerWidth: number,\r\n\t\t\t * innerHeight: number, outerWidth: number, outerHeight: number}}\r\n\t\t\t */\r\n\t\t\tgetHiddenDimensions: function(element, includeMargin) {\r\n\t\t\t\tvar props = {\r\n\t\t\t\t\t\tposition: 'absolute',\r\n\t\t\t\t\t\tvisibility: 'hidden',\r\n\t\t\t\t\t\tdisplay: 'block',\r\n\t\t\t\t\t},\r\n\t\t\t\t\tdim = {\r\n\t\t\t\t\t\twidth: 0,\r\n\t\t\t\t\t\theight: 0,\r\n\t\t\t\t\t\tinnerWidth: 0,\r\n\t\t\t\t\t\tinnerHeight: 0,\r\n\t\t\t\t\t\touterWidth: 0,\r\n\t\t\t\t\t\touterHeight: 0,\r\n\t\t\t\t\t},\r\n\t\t\t\t\thiddenParents = $(element).parents().addBack().not(':visible');\r\n\t\t\t\tincludeMargin = (typeof includeMargin === 'boolean') ?\r\n\t\t\t\t\tincludeMargin :\r\n\t\t\t\t\tfalse;\r\n\r\n\t\t\t\tvar oldProps = [];\r\n\t\t\t\thiddenParents.each(function() {\r\n\t\t\t\t\tvar old = {};\r\n\r\n\t\t\t\t\tfor (var name in props) {\r\n\t\t\t\t\t\told[name] = this.style[name];\r\n\t\t\t\t\t\tthis.style[name] = props[name];\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\toldProps.push(old);\r\n\t\t\t\t});\r\n\r\n\t\t\t\tdim.width = $(element).width();\r\n\t\t\t\tdim.outerWidth = $(element).outerWidth(includeMargin);\r\n\t\t\t\tdim.innerWidth = $(element).innerWidth();\r\n\t\t\t\tdim.height = $(element).height();\r\n\t\t\t\tdim.innerHeight = $(element).innerHeight();\r\n\t\t\t\tdim.outerHeight = $(element).outerHeight(includeMargin);\r\n\r\n\t\t\t\thiddenParents.each(function(i) {\r\n\t\t\t\t\tvar old = oldProps[i];\r\n\t\t\t\t\tfor (var name in props) {\r\n\t\t\t\t\t\tthis.style[name] = old[name];\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\r\n\t\t\t\treturn dim;\r\n\t\t\t},\r\n\r\n\t\t\tgetGeneralSearchKey: function() {\r\n\t\t\t\tvar searchInput = $(Plugin.getOption('search.input'));\r\n\t\t\t\treturn $(searchInput).prop('name') || $(searchInput).prop('id');\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get value by dot notation path string and to prevent undefined errors\r\n\t\t\t * @param path String Dot notation path in string\r\n\t\t\t * @param object Object to iterate\r\n\t\t\t * @returns {*}\r\n\t\t\t */\r\n\t\t\tgetObject: function(path, object) {\r\n\t\t\t\treturn path.split('.').reduce(function(obj, i) {\r\n\t\t\t\t\treturn obj !== null && typeof obj[i] !== 'undefined' ? obj[i] : null;\r\n\t\t\t\t}, object);\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Extend object\r\n\t\t\t * @param obj\r\n\t\t\t * @param path\r\n\t\t\t * @param value\r\n\t\t\t * @returns {*}\r\n\t\t\t */\r\n\t\t\textendObj: function(obj, path, value) {\r\n\t\t\t\tvar levels = path.split('.'),\r\n\t\t\t\t\ti = 0;\r\n\r\n\t\t\t\tfunction createLevel(child) {\r\n\t\t\t\t\tvar name = levels[i++];\r\n\t\t\t\t\tif (typeof child[name] !== 'undefined' && child[name] !== null) {\r\n\t\t\t\t\t\tif (typeof child[name] !== 'object' &&\r\n\t\t\t\t\t\t\ttypeof child[name] !== 'function') {\r\n\t\t\t\t\t\t\tchild[name] = {};\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tchild[name] = {};\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (i === levels.length) {\r\n\t\t\t\t\t\tchild[name] = value;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tcreateLevel(child[name]);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcreateLevel(obj);\r\n\t\t\t\treturn obj;\r\n\t\t\t},\r\n\r\n\t\t\trowEvenOdd: function() {\r\n\t\t\t\t// row even class\r\n\t\t\t\t$(datatable.tableBody).find('.' + pfx + 'datatable__row').removeClass(pfx + 'datatable__row--even');\r\n\t\t\t\tif ($(datatable.wrap).hasClass(pfx + 'datatable--subtable')) {\r\n\t\t\t\t\t$(datatable.tableBody).find('.' + pfx + 'datatable__row:not(.' + pfx + 'datatable__row-detail):even').addClass(pfx + 'datatable__row--even');\r\n\t\t\t\t} else {\r\n\t\t\t\t\t$(datatable.tableBody).find('.' + pfx + 'datatable__row:nth-child(even)').addClass(pfx + 'datatable__row--even');\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t/********************\r\n\t\t\t ** PUBLIC API METHODS\r\n\t\t\t ********************/\r\n\r\n\t\t\t// delay timer\r\n\t\t\ttimer: 0,\r\n\r\n\t\t\t/**\r\n\t\t\t * Redraw datatable by recalculating its DOM elements, etc.\r\n\t\t\t * @returns {jQuery}\r\n\t\t\t */\r\n\t\t\tredraw: function() {\r\n\t\t\t\tPlugin.adjustCellsWidth.call();\r\n\t\t\t\tif (Plugin.isLocked()) {\r\n\t\t\t\t\t// fix hiding cell width issue\r\n\t\t\t\t\tPlugin.scrollbar();\r\n\t\t\t\t\tPlugin.resetScroll();\r\n\t\t\t\t\tPlugin.adjustCellsHeight.call();\r\n\t\t\t\t}\r\n\t\t\t\tPlugin.adjustLockContainer.call();\r\n\t\t\t\tPlugin.initHeight.call();\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Shortcode to reload\r\n\t\t\t * @returns {jQuery}\r\n\t\t\t */\r\n\t\t\tload: function() {\r\n\t\t\t\tPlugin.reload();\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Datasource reload\r\n\t\t\t * @returns {jQuery}\r\n\t\t\t */\r\n\t\t\treload: function() {\r\n\t\t\t\tvar delay = (function() {\r\n\t\t\t\t\treturn function(callback, ms) {\r\n\t\t\t\t\t\tclearTimeout(Plugin.timer);\r\n\t\t\t\t\t\tPlugin.timer = setTimeout(callback, ms);\r\n\t\t\t\t\t};\r\n\t\t\t\t})();\r\n\t\t\t\tdelay(function() {\r\n\t\t\t\t\t// local only. remote pagination will skip this block\r\n\t\t\t\t\tif (!options.data.serverFiltering) {\r\n\t\t\t\t\t\tPlugin.localDataUpdate();\r\n\t\t\t\t\t}\r\n\t\t\t\t\tPlugin.dataRender();\r\n\t\t\t\t\t$(datatable).trigger(pfx + 'datatable--on-reloaded');\r\n\t\t\t\t}, Plugin.getOption('search.delay'));\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get record by record ID\r\n\t\t\t * @param id\r\n\t\t\t * @returns {jQuery}\r\n\t\t\t */\r\n\t\t\tgetRecord: function(id) {\r\n\t\t\t\tif (typeof datatable.tableBody === 'undefined') datatable.tableBody = $(datatable.table).children('tbody');\r\n\t\t\t\t$(datatable.tableBody).find('.' + pfx + 'datatable__cell:first-child').each(function(i, cell) {\r\n\t\t\t\t\tif (id == $(cell).text()) {\r\n\t\t\t\t\t\tvar rowNumber = $(cell).closest('.' + pfx + 'datatable__row').index() + 1;\r\n\t\t\t\t\t\tdatatable.API.record = datatable.API.value = Plugin.getOneRow(datatable.tableBody, rowNumber);\r\n\t\t\t\t\t\treturn datatable;\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * @deprecated in v5.0.6\r\n\t\t\t * Get column of current record ID\r\n\t\t\t * @param columnName\r\n\t\t\t * @returns {jQuery}\r\n\t\t\t */\r\n\t\t\tgetColumn: function(columnName) {\r\n\t\t\t\tPlugin.setSelectedRecords();\r\n\t\t\t\tdatatable.API.value = $(datatable.API.record).find('[data-field=\"' + columnName + '\"]');\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Destroy datatable to original DOM state before datatable was\r\n\t\t\t * initialized\r\n\t\t\t * @returns {jQuery}\r\n\t\t\t */\r\n\t\t\tdestroy: function() {\r\n\t\t\t\t$(datatable).parent().find('.' + pfx + 'datatable__pager').remove();\r\n\t\t\t\tvar initialDatatable = $(datatable.initialDatatable).addClass(pfx + 'datatable--destroyed').show();\r\n\t\t\t\t$(datatable).replaceWith(initialDatatable);\r\n\t\t\t\tdatatable = initialDatatable;\r\n\t\t\t\t$(datatable).trigger(pfx + 'datatable--on-destroy');\r\n\t\t\t\tPlugin.isInit = false;\r\n\t\t\t\tinitialDatatable = null;\r\n\t\t\t\treturn initialDatatable;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Sort by column field\r\n\t\t\t * @param field\r\n\t\t\t * @param sort\r\n\t\t\t */\r\n\t\t\tsort: function(field, sort) {\r\n\t\t\t\t// toggle sort\r\n\t\t\t\tsort = typeof sort === 'undefined' ? 'asc' : sort;\r\n\r\n\t\t\t\tPlugin.spinnerCallback(true);\r\n\r\n\t\t\t\t// update field and sort params\r\n\t\t\t\tvar meta = {\r\n\t\t\t\t\tfield: field,\r\n\t\t\t\t\tsort: sort\r\n\t\t\t\t};\r\n\t\t\t\tPlugin.setDataSourceParam('sort', meta);\r\n\r\n\t\t\t\tsetTimeout(function() {\r\n\t\t\t\t\tPlugin.dataRender('sort');\r\n\t\t\t\t\t$(datatable).trigger(pfx + 'datatable--on-sort', meta);\r\n\t\t\t\t\t$(datatable.tableHead).find('.' + pfx + 'datatable__cell > span > i').remove();\r\n\t\t\t\t}, 300);\r\n\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * @deprecated in v5.0.6\r\n\t\t\t * Get current selected column value\r\n\t\t\t * @returns {jQuery}\r\n\t\t\t */\r\n\t\t\tgetValue: function() {\r\n\t\t\t\treturn $(datatable.API.value).text();\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Set checkbox active\r\n\t\t\t * @param cell JQuery selector or checkbox ID\r\n\t\t\t */\r\n\t\t\tsetActive: function(cell) {\r\n\t\t\t\tif (typeof cell === 'string') {\r\n\t\t\t\t\t// set by checkbox id\r\n\t\t\t\t\tcell = $(datatable.tableBody).find('.' + pfx + 'checkbox--single > [type=\"checkbox\"][value=\"' + cell + '\"]');\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$(cell).prop('checked', true);\r\n\r\n\t\t\t\t// normal table\r\n\t\t\t\tvar row = $(cell).closest('.' + pfx + 'datatable__row').addClass(pfx + 'datatable__row--active');\r\n\r\n\t\t\t\tvar index = $(row).index() + 1;\r\n\t\t\t\t// lock table\r\n\t\t\t\t$(row).closest('.' + pfx + 'datatable__lock').parent().find('.' + pfx + 'datatable__row:nth-child(' + index + ')').addClass(pfx + 'datatable__row--active');\r\n\r\n\t\t\t\tvar ids = [];\r\n\t\t\t\t$(row).each(function(i, td) {\r\n\t\t\t\t\tvar id = $(td).find('.' + pfx + 'checkbox--single:not(.' + pfx + 'checkbox--all) > [type=\"checkbox\"]').val();\r\n\t\t\t\t\tif (typeof id !== 'undefined') {\r\n\t\t\t\t\t\tids.push(id);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\r\n\t\t\t\t$(datatable).trigger(pfx + 'datatable--on-check', [ids]);\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Set checkbox inactive\r\n\t\t\t * @param cell JQuery selector or checkbox ID\r\n\t\t\t */\r\n\t\t\tsetInactive: function(cell) {\r\n\t\t\t\tif (typeof cell === 'string') {\r\n\t\t\t\t\t// set by checkbox id\r\n\t\t\t\t\tcell = $(datatable.tableBody).find('.' + pfx + 'checkbox--single > [type=\"checkbox\"][value=\"' + cell + '\"]');\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$(cell).prop('checked', false);\r\n\r\n\t\t\t\t// normal table\r\n\t\t\t\tvar row = $(cell).closest('.' + pfx + 'datatable__row').removeClass(pfx + 'datatable__row--active');\r\n\t\t\t\tvar index = $(row).index() + 1;\r\n\r\n\t\t\t\t// lock table\r\n\t\t\t\t$(row).closest('.' + pfx + 'datatable__lock').parent().find('.' + pfx + 'datatable__row:nth-child(' + index + ')').removeClass(pfx + 'datatable__row--active');\r\n\r\n\t\t\t\tvar ids = [];\r\n\t\t\t\t$(row).each(function(i, td) {\r\n\t\t\t\t\tvar id = $(td).find('.' + pfx + 'checkbox--single:not(.' + pfx + 'checkbox--all) > [type=\"checkbox\"]').val();\r\n\t\t\t\t\tif (typeof id !== 'undefined') {\r\n\t\t\t\t\t\tids.push(id);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\r\n\t\t\t\t$(datatable).trigger(pfx + 'datatable--on-uncheck', [ids]);\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Set all checkboxes active or inactive\r\n\t\t\t * @param active\r\n\t\t\t */\r\n\t\t\tsetActiveAll: function(active) {\r\n\t\t\t\tvar checkboxes = $(datatable.table).\r\n\t\t\t\tfind('> tbody, > thead').\r\n\t\t\t\tfind('> tr:not(.' + pfx + 'datatable__row-subtable)').\r\n\t\t\t\tfind('.' + pfx + 'datatable__cell--check [type=\"checkbox\"]');\r\n\t\t\t\tif (active) {\r\n\t\t\t\t\tPlugin.setActive(checkboxes);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tPlugin.setInactive(checkboxes);\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * @deprecated in v5.0.6\r\n\t\t\t * Get selected rows which are active\r\n\t\t\t * @returns {jQuery}\r\n\t\t\t */\r\n\t\t\tsetSelectedRecords: function() {\r\n\t\t\t\tdatatable.API.record = $(datatable.tableBody).find('.' + pfx + 'datatable__row--active');\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get selected records\r\n\t\t\t * @returns {null}\r\n\t\t\t */\r\n\t\t\tgetSelectedRecords: function() {\r\n\t\t\t\t// support old method\r\n\t\t\t\tPlugin.setSelectedRecords();\r\n\t\t\t\tdatatable.API.record = datatable.rows('.' + pfx + 'datatable__row--active').nodes();\r\n\t\t\t\treturn datatable.API.record;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get options by dots notation path\r\n\t\t\t * @param path String Dot notation path in string\r\n\t\t\t * @returns {*}\r\n\t\t\t */\r\n\t\t\tgetOption: function(path) {\r\n\t\t\t\treturn Plugin.getObject(path, options);\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Set global options nodes by dots notation path\r\n\t\t\t * @param path\r\n\t\t\t * @param object\r\n\t\t\t */\r\n\t\t\tsetOption: function(path, object) {\r\n\t\t\t\toptions = Plugin.extendObj(options, path, object);\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Search filter for local & remote\r\n\t\t\t * @param value\r\n\t\t\t * @param columns. Optional list of columns to be filtered.\r\n\t\t\t */\r\n\t\t\tsearch: function(value, columns) {\r\n\t\t\t\tif (typeof columns !== 'undefined') columns = $.makeArray(columns);\r\n\t\t\t\tvar delay = (function() {\r\n\t\t\t\t\treturn function(callback, ms) {\r\n\t\t\t\t\t\tclearTimeout(Plugin.timer);\r\n\t\t\t\t\t\tPlugin.timer = setTimeout(callback, ms);\r\n\t\t\t\t\t};\r\n\t\t\t\t})();\r\n\r\n\t\t\t\tdelay(function() {\r\n\t\t\t\t\t// get query parameters\r\n\t\t\t\t\tvar query = Plugin.getDataSourceQuery();\r\n\r\n\t\t\t\t\t// search not by columns\r\n\t\t\t\t\tif (typeof columns === 'undefined' && typeof value !== 'undefined') {\r\n\t\t\t\t\t\tvar key = Plugin.getGeneralSearchKey();\r\n\t\t\t\t\t\tquery[key] = value;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// search by columns, support multiple columns\r\n\t\t\t\t\tif (typeof columns === 'object') {\r\n\t\t\t\t\t\t$.each(columns, function(k, column) {\r\n\t\t\t\t\t\t\tquery[column] = value;\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\t// remove empty element from arrays\r\n\t\t\t\t\t\t$.each(query, function(k, v) {\r\n\t\t\t\t\t\t\tif (v === '' || $.isEmptyObject(v)) {\r\n\t\t\t\t\t\t\t\tdelete query[k];\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tPlugin.setDataSourceQuery(query);\r\n\r\n\t\t\t\t\t// local filter only. remote pagination will skip this block\r\n\t\t\t\t\tif (!options.data.serverFiltering) {\r\n\t\t\t\t\t\tPlugin.localDataUpdate();\r\n\t\t\t\t\t}\r\n\t\t\t\t\tPlugin.dataRender('search');\r\n\t\t\t\t}, Plugin.getOption('search.delay'));\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Set datasource params extract\r\n\t\t\t * @param param\r\n\t\t\t * @param value\r\n\t\t\t */\r\n\t\t\tsetDataSourceParam: function(param, value) {\r\n\t\t\t\tdatatable.API.params = $.extend({}, {\r\n\t\t\t\t\tpagination: {\r\n\t\t\t\t\t\tpage: 1,\r\n\t\t\t\t\t\tperpage: Plugin.getOption('data.pageSize')\r\n\t\t\t\t\t},\r\n\t\t\t\t\tsort: Plugin.getDefaultSortColumn(),\r\n\t\t\t\t\tquery: {},\r\n\t\t\t\t}, datatable.API.params, Plugin.stateGet(Plugin.stateId));\r\n\r\n\t\t\t\tdatatable.API.params = Plugin.extendObj(datatable.API.params, param, value);\r\n\r\n\t\t\t\tPlugin.stateKeep(Plugin.stateId, datatable.API.params);\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get datasource params\r\n\t\t\t * @param param\r\n\t\t\t */\r\n\t\t\tgetDataSourceParam: function(param) {\r\n\t\t\t\tdatatable.API.params = $.extend({}, {\r\n\t\t\t\t\tpagination: {\r\n\t\t\t\t\t\tpage: 1,\r\n\t\t\t\t\t\tperpage: Plugin.getOption('data.pageSize')\r\n\t\t\t\t\t},\r\n\t\t\t\t\tsort: Plugin.getDefaultSortColumn(),\r\n\t\t\t\t\tquery: {},\r\n\t\t\t\t}, datatable.API.params, Plugin.stateGet(Plugin.stateId));\r\n\r\n\t\t\t\tif (typeof param === 'string') {\r\n\t\t\t\t\treturn Plugin.getObject(param, datatable.API.params);\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn datatable.API.params;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Shortcode to datatable.getDataSourceParam('query');\r\n\t\t\t * @returns {*}\r\n\t\t\t */\r\n\t\t\tgetDataSourceQuery: function() {\r\n\t\t\t\treturn Plugin.getDataSourceParam('query') || {};\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Shortcode to datatable.setDataSourceParam('query', query);\r\n\t\t\t * @param query\r\n\t\t\t */\r\n\t\t\tsetDataSourceQuery: function(query) {\r\n\t\t\t\tPlugin.setDataSourceParam('query', query);\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get current page number\r\n\t\t\t * @returns {number}\r\n\t\t\t */\r\n\t\t\tgetCurrentPage: function() {\r\n\t\t\t\treturn $(datatable.table).\r\n\t\t\t\tsiblings('.' + pfx + 'datatable__pager').\r\n\t\t\t\tlast().\r\n\t\t\t\tfind('.' + pfx + 'datatable__pager-nav').\r\n\t\t\t\tfind('.' + pfx + 'datatable__pager-link.' + pfx + 'datatable__pager-link--active').\r\n\t\t\t\tdata('page') || 1;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get selected dropdown page size\r\n\t\t\t * @returns {*|number}\r\n\t\t\t */\r\n\t\t\tgetPageSize: function() {\r\n\t\t\t\treturn $(datatable.table).siblings('.' + pfx + 'datatable__pager').last().find('select.' + pfx + 'datatable__pager-size').val() || 10;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get total rows\r\n\t\t\t */\r\n\t\t\tgetTotalRows: function() {\r\n\t\t\t\treturn datatable.API.params.pagination.total;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get full dataset in grid\r\n\t\t\t * @returns {*|null|Array}\r\n\t\t\t */\r\n\t\t\tgetDataSet: function() {\r\n\t\t\t\treturn datatable.originalDataSet;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * @deprecated in v5.0.6\r\n\t\t\t * Hide column by column's field name\r\n\t\t\t * @param fieldName\r\n\t\t\t */\r\n\t\t\thideColumn: function(fieldName) {\r\n\t\t\t\t// add hide option for this column\r\n\t\t\t\t$.map(options.columns, function(column) {\r\n\t\t\t\t\tif (fieldName === column.field) {\r\n\t\t\t\t\t\tcolumn.responsive = {\r\n\t\t\t\t\t\t\thidden: 'xl'\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn column;\r\n\t\t\t\t});\r\n\t\t\t\t// hide current displayed column\r\n\t\t\t\tvar tds = $.grep($(datatable.table).find('.' + pfx + 'datatable__cell'), function(n, i) {\r\n\t\t\t\t\treturn fieldName === $(n).data('field');\r\n\t\t\t\t});\r\n\t\t\t\t$(tds).hide();\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * @deprecated in v5.0.6\r\n\t\t\t * Show column by column's field name\r\n\t\t\t * @param fieldName\r\n\t\t\t */\r\n\t\t\tshowColumn: function(fieldName) {\r\n\t\t\t\t// add hide option for this column\r\n\t\t\t\t$.map(options.columns, function(column) {\r\n\t\t\t\t\tif (fieldName === column.field) {\r\n\t\t\t\t\t\tdelete column.responsive;\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn column;\r\n\t\t\t\t});\r\n\t\t\t\t// hide current displayed column\r\n\t\t\t\tvar tds = $.grep($(datatable.table).find('.' + pfx + 'datatable__cell'), function(n, i) {\r\n\t\t\t\t\treturn fieldName === $(n).data('field');\r\n\t\t\t\t});\r\n\t\t\t\t$(tds).show();\r\n\t\t\t},\r\n\r\n\t\t\tnodeTr: [],\r\n\t\t\tnodeTd: [],\r\n\t\t\tnodeCols: [],\r\n\t\t\trecentNode: [],\r\n\r\n\t\t\ttable: function() {\r\n\t\t\t\tif (typeof datatable.table !== 'undefined') {\r\n\t\t\t\t\treturn datatable.table;\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Select a single row from the table\r\n\t\t\t * @param selector\r\n\t\t\t * @returns {jQuery}\r\n\t\t\t */\r\n\t\t\trow: function(selector) {\r\n\t\t\t\tPlugin.rows(selector);\r\n\t\t\t\tPlugin.nodeTr = Plugin.recentNode = $(Plugin.nodeTr).first();\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Select multiple rows from the table\r\n\t\t\t * @param selector\r\n\t\t\t * @returns {jQuery}\r\n\t\t\t */\r\n\t\t\trows: function(selector) {\r\n\t\t\t\tPlugin.nodeTr = Plugin.recentNode = $(datatable.tableBody).find(selector).filter('.' + pfx + 'datatable__row');\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Select a single column from the table\r\n\t\t\t * @param index zero-based index\r\n\t\t\t * @returns {jQuery}\r\n\t\t\t */\r\n\t\t\tcolumn: function(index) {\r\n\t\t\t\tPlugin.nodeCols = Plugin.recentNode = $(datatable.tableBody).find('.' + pfx + 'datatable__cell:nth-child(' + (index + 1) + ')');\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Select multiple columns from the table\r\n\t\t\t * @param selector\r\n\t\t\t * @returns {jQuery}\r\n\t\t\t */\r\n\t\t\tcolumns: function(selector) {\r\n\t\t\t\tvar context = datatable.table;\r\n\t\t\t\tif (Plugin.nodeTr === Plugin.recentNode) {\r\n\t\t\t\t\tcontext = Plugin.nodeTr;\r\n\t\t\t\t}\r\n\t\t\t\tvar columns = $(context).find('.' + pfx + 'datatable__cell[data-field=\"' + selector + '\"]');\r\n\t\t\t\tif (columns.length > 0) {\r\n\t\t\t\t\tPlugin.nodeCols = Plugin.recentNode = columns;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tPlugin.nodeCols = Plugin.recentNode = $(context).find(selector).filter('.' + pfx + 'datatable__cell');\r\n\t\t\t\t}\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\tcell: function(selector) {\r\n\t\t\t\tPlugin.cells(selector);\r\n\t\t\t\tPlugin.nodeTd = Plugin.recentNode = $(Plugin.nodeTd).first();\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\tcells: function(selector) {\r\n\t\t\t\tvar cells = $(datatable.tableBody).find('.' + pfx + 'datatable__cell');\r\n\t\t\t\tif (typeof selector !== 'undefined') {\r\n\t\t\t\t\tcells = $(cells).filter(selector);\r\n\t\t\t\t}\r\n\t\t\t\tPlugin.nodeTd = Plugin.recentNode = cells;\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Delete the selected row from the table\r\n\t\t\t * @returns {jQuery}\r\n\t\t\t */\r\n\t\t\tremove: function() {\r\n\t\t\t\tif ($(Plugin.nodeTr.length) && Plugin.nodeTr === Plugin.recentNode) {\r\n\t\t\t\t\t$(Plugin.nodeTr).remove();\r\n\t\t\t\t}\r\n\t\t\t\tPlugin.layoutUpdate();\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Show or hide the columns or rows\r\n\t\t\t */\r\n\t\t\tvisible: function(bool) {\r\n\t\t\t\tif ($(Plugin.recentNode.length)) {\r\n\t\t\t\t\tvar locked = Plugin.lockEnabledColumns();\r\n\t\t\t\t\tif (Plugin.recentNode === Plugin.nodeCols) {\r\n\t\t\t\t\t\tvar index = Plugin.recentNode.index();\r\n\r\n\t\t\t\t\t\tif (Plugin.isLocked()) {\r\n\t\t\t\t\t\t\tvar scrollColumns = $(Plugin.recentNode).closest('.' + pfx + 'datatable__lock--scroll').length;\r\n\t\t\t\t\t\t\tif (scrollColumns) {\r\n\t\t\t\t\t\t\t\t// is at center of scrollable area\r\n\t\t\t\t\t\t\t\tindex += locked.left.length + 1;\r\n\t\t\t\t\t\t\t} else if ($(Plugin.recentNode).closest('.' + pfx + 'datatable__lock--right').length) {\r\n\t\t\t\t\t\t\t\t// is at the right locked table\r\n\t\t\t\t\t\t\t\tindex += locked.left.length + scrollColumns + 1;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (bool) {\r\n\t\t\t\t\t\tif (Plugin.recentNode === Plugin.nodeCols) {\r\n\t\t\t\t\t\t\tdelete options.columns[index].responsive;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t$(Plugin.recentNode).show();\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tif (Plugin.recentNode === Plugin.nodeCols) {\r\n\t\t\t\t\t\t\tPlugin.setOption('columns.' + index + '.responsive', {\r\n\t\t\t\t\t\t\t\thidden: 'xl'\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t$(Plugin.recentNode).hide();\r\n\t\t\t\t\t}\r\n\t\t\t\t\tPlugin.redraw();\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Get the the DOM element for the selected rows or columns\r\n\t\t\t * @returns {Array}\r\n\t\t\t */\r\n\t\t\tnodes: function() {\r\n\t\t\t\treturn Plugin.recentNode;\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * will be implemented soon\r\n\t\t\t * @returns {jQuery}\r\n\t\t\t */\r\n\t\t\tdataset: function() {\r\n\t\t\t\treturn datatable;\r\n\t\t\t},\r\n\r\n\t\t};\r\n\r\n\t\t/**\r\n\t\t * Public API methods can be used directly by datatable\r\n\t\t */\r\n\t\t$.each(Plugin, function(funcName, func) {\r\n\t\t\tdatatable[funcName] = func;\r\n\t\t});\r\n\r\n\t\t// initialize main datatable plugin\r\n\t\tif (typeof options !== 'undefined') {\r\n\t\t\tif (typeof options === 'string') {\r\n\t\t\t\tvar method = options;\r\n\t\t\t\tdatatable = $(this).data(pluginName);\r\n\t\t\t\tif (typeof datatable !== 'undefined') {\r\n\t\t\t\t\toptions = datatable.options;\r\n\t\t\t\t\tPlugin[method].apply(this, Array.prototype.slice.call(arguments, 1));\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (!datatable.data(pluginName) && !$(this).hasClass(pfx + 'datatable--loaded')) {\r\n\t\t\t\t\tdatatable.dataSet = null;\r\n\t\t\t\t\tdatatable.textAlign = {\r\n\t\t\t\t\t\tleft: pfx + 'datatable__cell--left',\r\n\t\t\t\t\t\tcenter: pfx + 'datatable__cell--center',\r\n\t\t\t\t\t\tright: pfx + 'datatable__cell--right',\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\t\t// merge default and user defined options\r\n\t\t\t\t\toptions = $.extend(true, {}, $.fn[pluginName].defaults, options);\r\n\r\n\t\t\t\t\tdatatable.options = options;\r\n\r\n\t\t\t\t\t// init plugin process\r\n\t\t\t\t\tPlugin.init.apply(this, [options]);\r\n\r\n\t\t\t\t\t$(datatable.wrap).data(pluginName, datatable);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t// get existing instance datatable\r\n\t\t\tdatatable = $(this).data(pluginName);\r\n\t\t\tif (typeof datatable === 'undefined') {\r\n\t\t\t\t$.error(pluginName + ' not initialized');\r\n\t\t\t}\r\n\t\t\toptions = datatable.options;\r\n\t\t}\r\n\r\n\t\treturn datatable;\r\n\t};\r\n\r\n\t// default options\r\n\t$.fn[pluginName].defaults = {\r\n\t\t// datasource definition\r\n\t\tdata: {\r\n\t\t\ttype: 'local',\r\n\t\t\tsource: null,\r\n\t\t\tpageSize: 10, // display records per page\r\n\t\t\tsaveState: {\r\n\t\t\t\t// save datatable state(pagination, filtering, sorting, etc) in cookie or browser webstorage\r\n\t\t\t\tcookie: false,\r\n\t\t\t\twebstorage: true,\r\n\t\t\t},\r\n\r\n\t\t\tserverPaging: false,\r\n\t\t\tserverFiltering: false,\r\n\t\t\tserverSorting: false,\r\n\r\n\t\t\tautoColumns: false,\r\n\t\t\tattr: {\r\n\t\t\t\trowProps: [],\r\n\t\t\t},\r\n\t\t},\r\n\r\n\t\t// layout definition\r\n\t\tlayout: {\r\n\t\t\ttheme: 'default', // datatable will support multiple themes and designs\r\n\t\t\tclass: pfx + 'datatable--brand', // custom wrapper class\r\n\t\t\tscroll: false, // enable/disable datatable scroll both horizontal and vertical when needed.\r\n\t\t\theight: null, // datatable's body's fixed height\r\n\t\t\tminHeight: 300,\r\n\t\t\tfooter: false, // display/hide footer\r\n\t\t\theader: true, // display/hide header\r\n\t\t\tcustomScrollbar: true, // set false to disable custom scrollbar\r\n\r\n\t\t\t// datatable spinner\r\n\t\t\tspinner: {\r\n\t\t\t\toverlayColor: '#000000',\r\n\t\t\t\topacity: 0,\r\n\t\t\t\ttype: 'loader',\r\n\t\t\t\tstate: 'brand',\r\n\t\t\t\tmessage: true,\r\n\t\t\t},\r\n\r\n\t\t\t// datatable UI icons\r\n\t\t\ticons: {\r\n\t\t\t\tsort: {\r\n\t\t\t\t\tasc: 'la la-arrow-up',\r\n\t\t\t\t\tdesc: 'la la-arrow-down'\r\n\t\t\t\t},\r\n\t\t\t\tpagination: {\r\n\t\t\t\t\tnext: 'la la-angle-right',\r\n\t\t\t\t\tprev: 'la la-angle-left',\r\n\t\t\t\t\tfirst: 'la la-angle-double-left',\r\n\t\t\t\t\tlast: 'la la-angle-double-right',\r\n\t\t\t\t\tmore: 'la la-ellipsis-h',\r\n\t\t\t\t},\r\n\t\t\t\trowDetail: {\r\n\t\t\t\t\texpand: 'fa fa-caret-down',\r\n\t\t\t\t\tcollapse: 'fa fa-caret-right'\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t},\r\n\r\n\t\t// column sorting\r\n\t\tsortable: true,\r\n\r\n\t\t// resize column size with mouse drag coming soon)\r\n\t\tresizable: false,\r\n\r\n\t\t// column based filtering (coming soon)\r\n\t\tfilterable: false,\r\n\r\n\t\tpagination: true,\r\n\r\n\t\t// inline and bactch editing (cooming soon)\r\n\t\teditable: false,\r\n\r\n\t\t// columns definition\r\n\t\tcolumns: [],\r\n\r\n\t\tsearch: {\r\n\t\t\t// enable trigger search by keyup enter\r\n\t\t\tonEnter: false,\r\n\t\t\t// input text for search\r\n\t\t\tinput: null,\r\n\t\t\t// search delay in milliseconds\r\n\t\t\tdelay: 400,\r\n\t\t},\r\n\r\n\t\trows: {\r\n\t\t\t// deprecated\r\n\t\t\tcallback: function() {},\r\n\t\t\t// call before row template\r\n\t\t\tbeforeTemplate: function() {},\r\n\t\t\t// call after row template\r\n\t\t\tafterTemplate: function() {},\r\n\t\t\tautoHide: true,\r\n\t\t},\r\n\r\n\t\t// toolbar\r\n\t\ttoolbar: {\r\n\t\t\t// place pagination and displayInfo blocks according to the array order\r\n\t\t\tlayout: ['pagination', 'info'],\r\n\r\n\t\t\t// toolbar placement can be at top or bottom or both top and bottom repeated\r\n\t\t\tplacement: ['bottom'], //'top', 'bottom'\r\n\r\n\t\t\t// toolbar items\r\n\t\t\titems: {\r\n\t\t\t\t// pagination\r\n\t\t\t\tpagination: {\r\n\t\t\t\t\t// pagination type(default or scroll)\r\n\t\t\t\t\ttype: 'default',\r\n\r\n\t\t\t\t\t// number of pages to display by breakpoints\r\n\t\t\t\t\tpages: {\r\n\t\t\t\t\t\tdesktop: {\r\n\t\t\t\t\t\t\tlayout: 'default',\r\n\t\t\t\t\t\t\tpagesNumber: 5,\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\ttablet: {\r\n\t\t\t\t\t\t\tlayout: 'default',\r\n\t\t\t\t\t\t\tpagesNumber: 3,\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\tmobile: {\r\n\t\t\t\t\t\t\tlayout: 'compact',\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t},\r\n\r\n\t\t\t\t\t// navigation buttons\r\n\t\t\t\t\tnavigation: {\r\n\t\t\t\t\t\tprev: true, // display prev link\r\n\t\t\t\t\t\tnext: true, // display next link\r\n\t\t\t\t\t\tfirst: true, // display first link\r\n\t\t\t\t\t\tlast: true, // display last link\r\n\t\t\t\t\t},\r\n\r\n\t\t\t\t\t// page size select\r\n\t\t\t\t\tpageSizeSelect: [], // display dropdown to select pagination size. -1 is used for \"ALl\" option\r\n\t\t\t\t},\r\n\r\n\t\t\t\t// records info\r\n\t\t\t\tinfo: true,\r\n\t\t\t},\r\n\t\t},\r\n\r\n\t\t// here we will keep all strings and message used by datatable UI so developer can easiliy translate to any language.\r\n\t\t// By default the stirngs will be in the plugin source and here can override it\r\n\t\ttranslate: {\r\n\t\t\trecords: {\r\n\t\t\t\tprocessing: 'Please wait...',\r\n\t\t\t\tnoRecords: 'No records found',\r\n\t\t\t},\r\n\t\t\ttoolbar: {\r\n\t\t\t\tpagination: {\r\n\t\t\t\t\titems: {\r\n\t\t\t\t\t\tdefault: {\r\n\t\t\t\t\t\t\tfirst: 'First',\r\n\t\t\t\t\t\t\tprev: 'Previous',\r\n\t\t\t\t\t\t\tnext: 'Next',\r\n\t\t\t\t\t\t\tlast: 'Last',\r\n\t\t\t\t\t\t\tmore: 'More pages',\r\n\t\t\t\t\t\t\tinput: 'Page number',\r\n\t\t\t\t\t\t\tselect: 'Select page size',\r\n\t\t\t\t\t\t\tall: 'all'\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\tinfo: 'Showing {{start}} - {{end}} of {{total}}',\r\n\t\t\t\t\t},\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t},\r\n\r\n\t\textensions: {},\r\n\t};\r\n\r\n}(jQuery));\r\n\n\"use strict\";\r\n(function($) {\r\n\r\n\tvar pluginName = 'KDatatable';\r\n\tvar pfx = 'k-';\r\n\r\n\t$.fn[pluginName] = $.fn[pluginName] || {};\r\n\r\n\t/**\r\n\t * @param datatable Main datatable plugin instance\r\n\t * @param options Extension options\r\n\t * @returns {*}\r\n\t */\r\n\t$.fn[pluginName].checkbox = function(datatable, options) {\r\n\t\tvar Extension = {\r\n\t\t\tselectedAllRows: false,\r\n\t\t\tselectedRows: [],\r\n\t\t\tunselectedRows: [],\r\n\r\n\t\t\tinit: function() {\r\n\t\t\t\tif (Extension.selectorEnabled()) {\r\n\t\t\t\t\t// reset\r\n\t\t\t\t\tdatatable.setDataSourceParam(options.vars.selectedAllRows, false);\r\n\t\t\t\t\tdatatable.stateRemove('checkbox');\r\n\r\n\t\t\t\t\t// requestIds is not null\r\n\t\t\t\t\tif (options.vars.requestIds) {\r\n\t\t\t\t\t\t// request ids in response\r\n\t\t\t\t\t\tdatatable.setDataSourceParam(options.vars.requestIds, true);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// remove selected checkbox on datatable reload\r\n\t\t\t\t\t$(datatable).on(pfx + 'datatable--on-reloaded', function() {\r\n\t\t\t\t\t\tdatatable.stateRemove('checkbox');\r\n\t\t\t\t\t\tdatatable.setDataSourceParam(options.vars.selectedAllRows, false);\r\n\t\t\t\t\t\tExtension.selectedAllRows = false;\r\n\t\t\t\t\t\tExtension.selectedRows = [];\r\n\t\t\t\t\t\tExtension.unselectedRows = [];\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\t// select all on extension init\r\n\t\t\t\t\tExtension.selectedAllRows = datatable.getDataSourceParam(options.vars.selectedAllRows);\r\n\r\n\t\t\t\t\t$(datatable).on(pfx + 'datatable--on-layout-updated', function(e, args) {\r\n\t\t\t\t\t\tif (args.table != $(datatable.wrap).attr('id')) {\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tdatatable.ready(function() {\r\n\t\t\t\t\t\t\tExtension.initVars();\r\n\t\t\t\t\t\t\tExtension.initEvent();\r\n\t\t\t\t\t\t\tExtension.initSelect();\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\t$(datatable).on(pfx + 'datatable--on-check', function(e, ids) {\r\n\t\t\t\t\t\tids.forEach(function(id) {\r\n\t\t\t\t\t\t\tExtension.selectedRows.push(id);\r\n\t\t\t\t\t\t\t// // remove from unselected rows\r\n\t\t\t\t\t\t\tExtension.unselectedRows = Extension.remove(Extension.unselectedRows, id);\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tvar storage = {};\r\n\t\t\t\t\t\tstorage['selectedRows'] = $.unique(Extension.selectedRows);\r\n\t\t\t\t\t\tstorage['unselectedRows'] = $.unique(Extension.unselectedRows);\r\n\t\t\t\t\t\tdatatable.stateKeep('checkbox', storage);\r\n\t\t\t\t\t});\r\n\t\t\t\t\t$(datatable).on(pfx + 'datatable--on-uncheck', function(e, ids) {\r\n\t\t\t\t\t\tids.forEach(function(id) {\r\n\t\t\t\t\t\t\tExtension.unselectedRows.push(id);\r\n\t\t\t\t\t\t\t// // remove from selected rows\r\n\t\t\t\t\t\t\tExtension.selectedRows = Extension.remove(Extension.selectedRows, id);\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tvar storage = {};\r\n\t\t\t\t\t\tstorage['selectedRows'] = $.unique(Extension.selectedRows);\r\n\t\t\t\t\t\tstorage['unselectedRows'] = $.unique(Extension.unselectedRows);\r\n\t\t\t\t\t\tdatatable.stateKeep('checkbox', storage);\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Init checkbox clicks event\r\n\t\t\t */\r\n\t\t\tinitEvent: function() {\r\n\t\t\t\t// select all checkbox click\r\n\t\t\t\t$(datatable.tableHead).find('.' + pfx + 'checkbox--all > [type=\"checkbox\"]').click(function(e) {\r\n\t\t\t\t\t// clear selected and unselected rows\r\n\t\t\t\t\tExtension.selectedRows = Extension.unselectedRows = [];\r\n\t\t\t\t\tdatatable.stateRemove('checkbox');\r\n\r\n\t\t\t\t\t// select all rows\r\n\t\t\t\t\tif ($(this).is(':checked')) {\r\n\t\t\t\t\t\tExtension.selectedAllRows = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\tExtension.selectedAllRows = false;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// local select all current page rows\r\n\t\t\t\t\tif (!options.vars.requestIds) {\r\n\t\t\t\t\t\tif ($(this).is(':checked')) {\r\n\t\t\t\t\t\t\tExtension.selectedRows = $.makeArray($(datatable.tableBody).find('.' + pfx + 'checkbox--single > [type=\"checkbox\"]').map(function(i, chk) {\r\n\t\t\t\t\t\t\t\treturn $(chk).val();\r\n\t\t\t\t\t\t\t}));\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tvar storage = {};\r\n\t\t\t\t\t\tstorage['selectedRows'] = $.unique(Extension.selectedRows);\r\n\t\t\t\t\t\tdatatable.stateKeep('checkbox', storage);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// keep selectedAllRows in datasource params\r\n\t\t\t\t\tdatatable.setDataSourceParam(options.vars.selectedAllRows, Extension.selectedAllRows);\r\n\r\n\t\t\t\t\t$(datatable).trigger(pfx + 'datatable--on-click-checkbox', [$(this)]);\r\n\t\t\t\t});\r\n\r\n\t\t\t\t// single row checkbox click\r\n\t\t\t\t$(datatable.tableBody).find('.' + pfx + 'checkbox--single > [type=\"checkbox\"]').click(function(e) {\r\n\t\t\t\t\tvar id = $(this).val();\r\n\t\t\t\t\tif ($(this).is(':checked')) {\r\n\t\t\t\t\t\tExtension.selectedRows.push(id);\r\n\t\t\t\t\t\t// remove from unselected rows\r\n\t\t\t\t\t\tExtension.unselectedRows = Extension.remove(Extension.unselectedRows, id);\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\tExtension.unselectedRows.push(id);\r\n\t\t\t\t\t\t// remove from selected rows\r\n\t\t\t\t\t\tExtension.selectedRows = Extension.remove(Extension.selectedRows, id);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// local checkbox header check\r\n\t\t\t\t\tif (!options.vars.requestIds && Extension.selectedRows.length < 1) {\r\n\t\t\t\t\t\t// remove select all checkbox, if there is no checked checkbox left\r\n\t\t\t\t\t\t$(datatable.tableHead).find('.' + pfx + 'checkbox--all > [type=\"checkbox\"]').prop('checked', false);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tvar storage = {};\r\n\t\t\t\t\tstorage['selectedRows'] = $.unique(Extension.selectedRows);\r\n\t\t\t\t\tstorage['unselectedRows'] = $.unique(Extension.unselectedRows);\r\n\t\t\t\t\tdatatable.stateKeep('checkbox', storage);\r\n\r\n\t\t\t\t\t$(datatable).trigger(pfx + 'datatable--on-click-checkbox', [$(this)]);\r\n\t\t\t\t});\r\n\t\t\t},\r\n\r\n\t\t\tinitSelect: function() {\r\n\t\t\t\t// selected all rows from server\r\n\t\t\t\tif (Extension.selectedAllRows && options.vars.requestIds) {\r\n\t\t\t\t\tif (!datatable.hasClass(pfx + 'datatable--error')) {\r\n\t\t\t\t\t\t// set header select all checkbox checked\r\n\t\t\t\t\t\t$(datatable.tableHead).find('.' + pfx + 'checkbox--all > [type=\"checkbox\"]').prop('checked', true);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// set all checkbox in table body\r\n\t\t\t\t\tdatatable.setActiveAll(true);\r\n\r\n\t\t\t\t\t// remove unselected rows\r\n\t\t\t\t\tExtension.unselectedRows.forEach(function(id) {\r\n\t\t\t\t\t\tdatatable.setInactive(id);\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\t// single check for server and local\r\n\t\t\t\t\tExtension.selectedRows.forEach(function(id) {\r\n\t\t\t\t\t\tdatatable.setActive(id);\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\t// local checkbox; check if all checkboxes of currect page are checked\r\n\t\t\t\t\tif (!datatable.hasClass(pfx + 'datatable--error') && $(datatable.tableBody).find('.' + pfx + 'checkbox--single > [type=\"checkbox\"]').not(':checked').length < 1) {\r\n\t\t\t\t\t\t// set header select all checkbox checked\r\n\t\t\t\t\t\t$(datatable.tableHead).find('.' + pfx + 'checkbox--all > [type=\"checkbox\"]').prop('checked', true);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\t/**\r\n\t\t\t * Check if selector is enabled from options\r\n\t\t\t */\r\n\t\t\tselectorEnabled: function() {\r\n\t\t\t\treturn $.grep(datatable.options.columns, function(n, i) {\r\n\t\t\t\t\treturn n.selector || false;\r\n\t\t\t\t})[0];\r\n\t\t\t},\r\n\r\n\t\t\tinitVars: function() {\r\n\t\t\t\t// get single select/unselect from localstorage\r\n\t\t\t\tvar storage = datatable.stateGet('checkbox');\r\n\t\t\t\tif (typeof storage !== 'undefined') {\r\n\t\t\t\t\tExtension.selectedRows = storage['selectedRows'] || [];\r\n\t\t\t\t\tExtension.unselectedRows = storage['unselectedRows'] || [];\r\n\t\t\t\t}\r\n\t\t\t},\r\n\r\n\t\t\tgetSelectedId: function(path) {\r\n\t\t\t\tExtension.initVars();\r\n\r\n\t\t\t\t// server selected all rows\r\n\t\t\t\tif (Extension.selectedAllRows && options.vars.requestIds) {\r\n\t\t\t\t\tif (typeof path === 'undefined') {\r\n\t\t\t\t\t\tpath = options.vars.rowIds;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// if selected all rows, return id from response meta\r\n\t\t\t\t\tvar selectedAllRows = datatable.getObject(path, datatable.lastResponse) || [];\r\n\r\n\t\t\t\t\tif (selectedAllRows.length > 0) {\r\n\t\t\t\t\t\t// remove single unselected rows from selectedAllRows ids from server response emta\r\n\t\t\t\t\t\tExtension.unselectedRows.forEach(function(id) {\r\n\t\t\t\t\t\t\tselectedAllRows = Extension.remove(selectedAllRows, parseInt(id));\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn selectedAllRows;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// else return single checked selected rows\r\n\t\t\t\treturn Extension.selectedRows;\r\n\t\t\t},\r\n\r\n\t\t\tremove: function(array, element) {\r\n\t\t\t\treturn array.filter(function(e) {\r\n\t\t\t\t\treturn e !== element;\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t};\r\n\r\n\t\t// make the extension accessible from datatable init\r\n\t\tdatatable.checkbox = function() {\r\n\t\t\treturn Extension;\r\n\t\t};\r\n\r\n\t\tif (typeof options === 'object') {\r\n\t\t\toptions = $.extend(true, {}, $.fn[pluginName].checkbox.default, options);\r\n\t\t\tExtension.init.apply(this, [options]);\r\n\t\t}\r\n\r\n\t\treturn datatable;\r\n\t};\r\n\r\n\t$.fn[pluginName].checkbox.default = {\r\n\t\tvars: {\r\n\t\t\t// select all rows flag to be sent to the server\r\n\t\t\tselectedAllRows: 'selectedAllRows',\r\n\t\t\t// request id parameter's name\r\n\t\t\trequestIds: 'requestIds',\r\n\t\t\t// response path to all rows id\r\n\t\t\trowIds: 'meta.rowIds',\r\n\t\t},\r\n\t};\r\n\r\n}(jQuery));\nvar defaults = {\r\n\tlayout: {\r\n\t\ticons: {\r\n\t\t\tpagination: {\r\n\t\t\t\tnext: 'la la-angle-right',\r\n\t\t\t\tprev: 'la la-angle-left',\r\n\t\t\t\tfirst: 'la la-angle-double-left',\r\n\t\t\t\tlast: 'la la-angle-double-right',\r\n\t\t\t\tmore: 'la la-ellipsis-h',\r\n\t\t\t},\r\n\t\t\trowDetail: {expand: 'fa fa-caret-down', collapse: 'fa fa-caret-right'},\r\n\t\t}\r\n\t}\r\n};\r\n\r\nif (KUtil.isRTL()) {\r\n\tdefaults = {\r\n\t\tlayout: {\r\n\t\t\ticons: {\r\n\t\t\t\tpagination: {\r\n\t\t\t\t\tnext: 'la la-angle-left',\r\n\t\t\t\t\tprev: 'la la-angle-right',\r\n\t\t\t\t\tlast: 'la la-angle-double-left',\r\n\t\t\t\t\tfirst: 'la la-angle-double-right',\r\n\t\t\t\t},\r\n\t\t\t\trowDetail: {collapse: 'fa fa-caret-down', expand: 'fa fa-caret-right'},\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n\r\n$.extend(true, $.fn.KDatatable.defaults, defaults);\n\"use strict\";\r\nvar KHeader = function(elementId, options) {\r\n // Main object\r\n var the = this;\r\n var init = false;\r\n\r\n // Get element object\r\n var element = KUtil.get(elementId);\r\n var body = KUtil.get('body');\r\n\r\n if (element === undefined) {\r\n return;\r\n }\r\n\r\n // Default options\r\n var defaultOptions = {\r\n classic: false,\r\n offset: {\r\n mobile: 150,\r\n desktop: 200\r\n },\r\n minimize: {\r\n mobile: false,\r\n desktop: false\r\n }\r\n };\r\n\r\n ////////////////////////////\r\n // ** Private Methods ** //\r\n ////////////////////////////\r\n\r\n var Plugin = {\r\n /**\r\n * Run plugin\r\n * @returns {KHeader}\r\n */\r\n construct: function(options) {\r\n if (KUtil.data(element).has('header')) {\r\n the = KUtil.data(element).get('header');\r\n } else {\r\n // reset header\r\n Plugin.init(options);\r\n\r\n // build header\r\n Plugin.build();\r\n\r\n KUtil.data(element).set('header', the);\r\n }\r\n\r\n return the;\r\n },\r\n\r\n /**\r\n * Handles subheader click toggle\r\n * @returns {KHeader}\r\n */\r\n init: function(options) {\r\n the.events = [];\r\n\r\n // merge default and user defined options\r\n the.options = KUtil.deepExtend({}, defaultOptions, options);\r\n },\r\n\r\n /**\r\n * Reset header\r\n * @returns {KHeader}\r\n */\r\n build: function() {\r\n var lastScrollTop = 0;\r\n var eventTriggerState = true;\r\n var viewportHeight = KUtil.getViewPort().height;\r\n\r\n if (the.options.minimize.mobile === false && the.options.minimize.desktop === false) {\r\n return;\r\n }\r\n\r\n window.addEventListener('scroll', function() {\r\n var offset = 0, on, off, st;\r\n\r\n if (KUtil.isInResponsiveRange('desktop')) {\r\n offset = the.options.offset.desktop;\r\n on = the.options.minimize.desktop.on;\r\n off = the.options.minimize.desktop.off;\r\n } else if (KUtil.isInResponsiveRange('tablet-and-mobile')) {\r\n offset = the.options.offset.mobile;\r\n on = the.options.minimize.mobile.on;\r\n off = the.options.minimize.mobile.off;\r\n }\r\n\r\n st = window.pageYOffset;\r\n\r\n if (\r\n (KUtil.isInResponsiveRange('tablet-and-mobile') && the.options.classic && the.options.classic.mobile) ||\r\n (KUtil.isInResponsiveRange('desktop') && the.options.classic && the.options.classic.desktop)\r\n\r\n ) {\r\n if (st > offset) { // down scroll mode\r\n KUtil.addClass(body, on);\r\n KUtil.removeClass(body, off);\r\n \r\n if (eventTriggerState) {\r\n Plugin.eventTrigger('minimizeOn', the);\r\n eventTriggerState = false;\r\n }\r\n } else { // back scroll mode\r\n KUtil.addClass(body, off);\r\n KUtil.removeClass(body, on);\r\n\r\n if (eventTriggerState == false) {\r\n Plugin.eventTrigger('minimizeOff', the);\r\n eventTriggerState = true; \r\n }\r\n }\r\n } else {\r\n if (st > offset && lastScrollTop < st) { // down scroll mode\r\n KUtil.addClass(body, on);\r\n KUtil.removeClass(body, off);\r\n\r\n if (eventTriggerState) {\r\n Plugin.eventTrigger('minimizeOn', the);\r\n eventTriggerState = false;\r\n }\r\n } else { // back scroll mode\r\n KUtil.addClass(body, off);\r\n KUtil.removeClass(body, on);\r\n\r\n if (eventTriggerState == false) {\r\n Plugin.eventTrigger('minimizeOff', the);\r\n eventTriggerState = true;\r\n }\r\n }\r\n\r\n lastScrollTop = st;\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Trigger events\r\n */\r\n eventTrigger: function(name, args) {\r\n for (var i = 0; i < the.events.length; i++) {\r\n var event = the.events[i];\r\n if (event.name == name) {\r\n if (event.one == true) {\r\n if (event.fired == false) {\r\n the.events[i].fired = true;\r\n event.handler.call(this, the, args);\r\n }\r\n } else {\r\n event.handler.call(this, the, args);\r\n }\r\n }\r\n }\r\n },\r\n\r\n addEvent: function(name, handler, one) {\r\n the.events.push({\r\n name: name,\r\n handler: handler,\r\n one: one,\r\n fired: false\r\n });\r\n }\r\n };\r\n\r\n //////////////////////////\r\n // ** Public Methods ** //\r\n //////////////////////////\r\n\r\n /**\r\n * Set default options \r\n */\r\n\r\n the.setDefaults = function(options) {\r\n defaultOptions = options;\r\n };\r\n\r\n /**\r\n * Register event\r\n */\r\n the.on = function(name, handler) {\r\n return Plugin.addEvent(name, handler);\r\n };\r\n\r\n ///////////////////////////////\r\n // ** Plugin Construction ** //\r\n ///////////////////////////////\r\n\r\n // Run plugin\r\n Plugin.construct.apply(the, [options]);\r\n\r\n // Init done\r\n init = true;\r\n\r\n // Return plugin instance\r\n return the;\r\n};\n\"use strict\";\r\nvar KMenu = function(elementId, options) {\r\n // Main object\r\n var the = this;\r\n var init = false;\r\n\r\n // Get element object\r\n var element = KUtil.get(elementId);\r\n var body = KUtil.get('body'); \r\n\r\n if (!element) {\r\n return;\r\n }\r\n\r\n // Default options\r\n var defaultOptions = { \r\n // accordion submenu mode\r\n accordion: {\r\n slideSpeed: 200, // accordion toggle slide speed in milliseconds\r\n autoScroll: false, // enable auto scrolling(focus) to the clicked menu item\r\n autoScrollSpeed: 1200,\r\n expandAll: true // allow having multiple expanded accordions in the menu\r\n },\r\n\r\n // dropdown submenu mode\r\n dropdown: {\r\n timeout: 500 // timeout in milliseconds to show and hide the hoverable submenu dropdown\r\n }\r\n };\r\n\r\n ////////////////////////////\r\n // ** Private Methods ** //\r\n ////////////////////////////\r\n\r\n var Plugin = {\r\n /**\r\n * Run plugin\r\n * @returns {KMenu}\r\n */\r\n construct: function(options) {\r\n if (KUtil.data(element).has('menu')) {\r\n the = KUtil.data(element).get('menu');\r\n } else {\r\n // reset menu\r\n Plugin.init(options);\r\n\r\n // reset menu\r\n Plugin.reset();\r\n\r\n // build menu\r\n Plugin.build();\r\n\r\n KUtil.data(element).set('menu', the);\r\n }\r\n\r\n return the;\r\n },\r\n\r\n /**\r\n * Handles submenu click toggle\r\n * @returns {KMenu}\r\n */\r\n init: function(options) {\r\n the.events = [];\r\n\r\n the.eventHandlers = {};\r\n\r\n // merge default and user defined options\r\n the.options = KUtil.deepExtend({}, defaultOptions, options);\r\n\r\n // pause menu\r\n the.pauseDropdownHoverTime = 0;\r\n\r\n the.uid = KUtil.getUniqueID();\r\n },\r\n\r\n update: function(options) {\r\n // merge default and user defined options\r\n the.options = KUtil.deepExtend({}, defaultOptions, options);\r\n\r\n // pause menu\r\n the.pauseDropdownHoverTime = 0;\r\n\r\n // reset menu\r\n Plugin.reset();\r\n\r\n the.eventHandlers = {};\r\n\r\n // build menu\r\n Plugin.build();\r\n\r\n KUtil.data(element).set('menu', the);\r\n },\r\n\r\n reload: function() {\r\n // reset menu\r\n Plugin.reset();\r\n\r\n // build menu\r\n Plugin.build();\r\n\r\n // reset submenu props\r\n Plugin.resetSubmenuProps();\r\n },\r\n\r\n /**\r\n * Reset menu\r\n * @returns {KMenu}\r\n */\r\n build: function() {\r\n // General accordion submenu toggle\r\n the.eventHandlers['event_1'] = KUtil.on( element, '.k-menu__toggle', 'click', Plugin.handleSubmenuAccordion);\r\n\r\n // Dropdown mode(hoverable)\r\n if (Plugin.getSubmenuMode() === 'dropdown' || Plugin.isConditionalSubmenuDropdown()) {\r\n // dropdown submenu - hover toggle\r\n the.eventHandlers['event_2'] = KUtil.on( element, '[data-kmenu-submenu-toggle=\"hover\"]', 'mouseover', Plugin.handleSubmenuDrodownHoverEnter);\r\n the.eventHandlers['event_3'] = KUtil.on( element, '[data-kmenu-submenu-toggle=\"hover\"]', 'mouseout', Plugin.handleSubmenuDrodownHoverExit);\r\n\r\n // dropdown submenu - click toggle\r\n the.eventHandlers['event_4'] = KUtil.on( element, '[data-kmenu-submenu-toggle=\"click\"] > .k-menu__toggle, [data-kmenu-submenu-toggle=\"click\"] > .k-menu__link .k-menu__toggle', 'click', Plugin.handleSubmenuDropdownClick);\r\n the.eventHandlers['event_5'] = KUtil.on( element, '[data-kmenu-submenu-toggle=\"tab\"] > .k-menu__toggle, [data-kmenu-submenu-toggle=\"tab\"] > .k-menu__link .k-menu__toggle', 'click', Plugin.handleSubmenuDropdownTabClick);\r\n }\r\n\r\n // General link click\r\n // the.eventHandlers['event_6'] = KUtil.on(element, '.k-menu__item:not(.k-menu__item--submenu) > .k-menu__link:not(.k-menu__toggle):not(.k-menu__link--toggle-skip)', 'click', Plugin.handleLinkClick);\r\n\r\n // Init scrollable menu\r\n if (the.options.scroll && the.options.scroll.height) {\r\n Plugin.scrollInit();\r\n }\r\n },\r\n\r\n /**\r\n * Reset menu\r\n * @returns {KMenu}\r\n */\r\n reset: function() { \r\n KUtil.off( element, 'click', the.eventHandlers['event_1']);\r\n\r\n // dropdown submenu - hover toggle\r\n KUtil.off( element, 'mouseover', the.eventHandlers['event_2']);\r\n KUtil.off( element, 'mouseout', the.eventHandlers['event_3']);\r\n\r\n // dropdown submenu - click toggle\r\n KUtil.off( element, 'click', the.eventHandlers['event_4']);\r\n KUtil.off( element, 'click', the.eventHandlers['event_5']);\r\n \r\n KUtil.off(element, 'click', the.eventHandlers['event_6']);\r\n },\r\n\r\n /**\r\n * Init scroll menu\r\n *\r\n */\r\n scrollInit: function() {\r\n if ( the.options.scroll && the.options.scroll.height ) {\r\n KUtil.scrollDestroy(element);\r\n KUtil.scrollInit(element, {disableForMobile: true, resetHeightOnDestroy: true, handleWindowResize: true, height: the.options.scroll.height});\r\n } else {\r\n KUtil.scrollDestroy(element);\r\n } \r\n },\r\n\r\n /**\r\n * Update scroll menu\r\n */\r\n scrollUpdate: function() {\r\n if ( the.options.scroll && the.options.scroll.height ) {\r\n KUtil.scrollUpdate(element);\r\n }\r\n },\r\n\r\n /**\r\n * Scroll top\r\n */\r\n scrollTop: function() {\r\n if ( the.options.scroll && the.options.scroll.height ) {\r\n KUtil.scrollTop(element);\r\n }\r\n },\r\n\r\n /**\r\n * Get submenu mode for current breakpoint and menu state\r\n * @returns {KMenu}\r\n */\r\n getSubmenuMode: function(el) {\r\n if ( KUtil.isInResponsiveRange('desktop') ) {\r\n if (el && KUtil.hasAttr(el, 'data-kmenu-submenu-toggle')) {\r\n return KUtil.attr(el, 'data-kmenu-submenu-toggle');\r\n }\r\n\r\n if ( KUtil.isset(the.options.submenu, 'desktop.state.body') ) {\r\n if ( KUtil.hasClass(body, the.options.submenu.desktop.state.body) ) {\r\n return the.options.submenu.desktop.state.mode;\r\n } else {\r\n return the.options.submenu.desktop.default;\r\n }\r\n } else if ( KUtil.isset(the.options.submenu, 'desktop') ) {\r\n return the.options.submenu.desktop;\r\n }\r\n } else if ( KUtil.isInResponsiveRange('tablet') && KUtil.isset(the.options.submenu, 'tablet') ) {\r\n return the.options.submenu.tablet;\r\n } else if ( KUtil.isInResponsiveRange('mobile') && KUtil.isset(the.options.submenu, 'mobile') ) {\r\n return the.options.submenu.mobile;\r\n } else {\r\n return false;\r\n }\r\n },\r\n\r\n /**\r\n * Get submenu mode for current breakpoint and menu state\r\n * @returns {KMenu}\r\n */\r\n isConditionalSubmenuDropdown: function() {\r\n if ( KUtil.isInResponsiveRange('desktop') && KUtil.isset(the.options.submenu, 'desktop.state.body') ) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n },\r\n\r\n\r\n /**\r\n * Reset submenu attributes\r\n * @returns {KMenu}\r\n */\r\n resetSubmenuProps: function(e) {\r\n var submenus = KUtil.findAll(element, '.k-menu__submenu');\r\n if ( submenus ) {\r\n for (var i = 0, len = submenus.length; i < len; i++) {\r\n KUtil.css(submenus[0], 'display', '');\r\n KUtil.css(submenus[0], 'overflow', ''); \r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Handles submenu hover toggle\r\n * @returns {KMenu}\r\n */\r\n handleSubmenuDrodownHoverEnter: function(e) {\r\n if ( Plugin.getSubmenuMode(this) === 'accordion' ) {\r\n return;\r\n }\r\n\r\n if ( the.resumeDropdownHover() === false ) {\r\n return;\r\n }\r\n\r\n var item = this;\r\n\r\n if ( item.getAttribute('data-hover') == '1' ) {\r\n item.removeAttribute('data-hover');\r\n clearTimeout( item.getAttribute('data-timeout') );\r\n item.removeAttribute('data-timeout');\r\n //Plugin.hideSubmenuDropdown(item, false);\r\n }\r\n\r\n // console.log('test!');\r\n\r\n Plugin.showSubmenuDropdown(item);\r\n },\r\n\r\n /**\r\n * Handles submenu hover toggle\r\n * @returns {KMenu}\r\n */\r\n handleSubmenuDrodownHoverExit: function(e) {\r\n if ( the.resumeDropdownHover() === false ) {\r\n return;\r\n }\r\n\r\n if ( Plugin.getSubmenuMode(this) === 'accordion' ) {\r\n return;\r\n }\r\n\r\n var item = this;\r\n var time = the.options.dropdown.timeout;\r\n\r\n var timeout = setTimeout(function() {\r\n if ( item.getAttribute('data-hover') == '1' ) {\r\n Plugin.hideSubmenuDropdown(item, true);\r\n } \r\n }, time);\r\n\r\n item.setAttribute('data-hover', '1');\r\n item.setAttribute('data-timeout', timeout); \r\n },\r\n\r\n /**\r\n * Handles submenu click toggle\r\n * @returns {KMenu}\r\n */\r\n handleSubmenuDropdownClick: function(e) {\r\n if ( Plugin.getSubmenuMode(this) === 'accordion' ) {\r\n return;\r\n }\r\n \r\n var item = this.closest('.k-menu__item'); \r\n\r\n if ( item.getAttribute('data-kmenu-submenu-mode') == 'accordion' ) {\r\n return;\r\n }\r\n\r\n if ( KUtil.hasClass(item, 'k-menu__item--hover') === false ) {\r\n KUtil.addClass(item, 'k-menu__item--open-dropdown');\r\n Plugin.showSubmenuDropdown(item);\r\n } else {\r\n KUtil.removeClass(item, 'k-menu__item--open-dropdown' );\r\n Plugin.hideSubmenuDropdown(item, true);\r\n }\r\n\r\n e.preventDefault();\r\n },\r\n\r\n /**\r\n * Handles tab click toggle\r\n * @returns {KMenu}\r\n */\r\n handleSubmenuDropdownTabClick: function(e) {\r\n if (Plugin.getSubmenuMode(this) === 'accordion') {\r\n return;\r\n }\r\n\r\n var item = this.closest('.k-menu__item');\r\n\r\n if (item.getAttribute('data-kmenu-submenu-mode') == 'accordion') {\r\n return;\r\n }\r\n\r\n if (KUtil.hasClass(item, 'k-menu__item--hover') == false) {\r\n KUtil.addClass(item, 'k-menu__item--open-dropdown');\r\n Plugin.showSubmenuDropdown(item);\r\n }\r\n\r\n e.preventDefault();\r\n },\r\n\r\n /**\r\n * Handles submenu dropdown close on link click\r\n * @returns {KMenu}\r\n */\r\n handleSubmenuDropdownClose: function(e, el) {\r\n // exit if its not submenu dropdown mode\r\n if (Plugin.getSubmenuMode(el) === 'accordion') {\r\n return;\r\n }\r\n\r\n var shown = element.querySelectorAll('.k-menu__item.k-menu__item--submenu.k-menu__item--hover:not(.k-menu__item--tabs)');\r\n\r\n // check if currently clicked link's parent item ha\r\n if (shown.length > 0 && KUtil.hasClass(el, 'k-menu__toggle') === false && el.querySelectorAll('.k-menu__toggle').length === 0) {\r\n // close opened dropdown menus\r\n for (var i = 0, len = shown.length; i < len; i++) {\r\n Plugin.hideSubmenuDropdown(shown[0], true);\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * helper functions\r\n * @returns {KMenu}\r\n */\r\n handleSubmenuAccordion: function(e, el) {\r\n var query;\r\n var item = el ? el : this;\r\n\r\n if ( Plugin.getSubmenuMode(el) === 'dropdown' && (query = item.closest('.k-menu__item') ) ) {\r\n if (query.getAttribute('data-kmenu-submenu-mode') != 'accordion' ) {\r\n e.preventDefault();\r\n return;\r\n }\r\n }\r\n\r\n var li = item.closest('.k-menu__item');\r\n var submenu = KUtil.child(li, '.k-menu__submenu, .k-menu__inner');\r\n\r\n if (KUtil.hasClass(item.closest('.k-menu__item'), 'k-menu__item--open-always')) {\r\n return;\r\n }\r\n\r\n if ( li && submenu ) {\r\n e.preventDefault();\r\n var speed = the.options.accordion.slideSpeed;\r\n var hasClosables = false;\r\n\r\n if ( KUtil.hasClass(li, 'k-menu__item--open') === false ) {\r\n // hide other accordions \r\n if ( the.options.accordion.expandAll === false ) {\r\n var subnav = item.closest('.k-menu__nav, .k-menu__subnav');\r\n var closables = KUtil.children(subnav, '.k-menu__item.k-menu__item--open.k-menu__item--submenu:not(.k-menu__item--here):not(.k-menu__item--open-always)');\r\n\r\n if ( subnav && closables ) {\r\n for (var i = 0, len = closables.length; i < len; i++) {\r\n var el_ = closables[0];\r\n var submenu_ = KUtil.child(el_, '.k-menu__submenu');\r\n if ( submenu_ ) {\r\n KUtil.slideUp(submenu_, speed, function() {\r\n Plugin.scrollUpdate();\r\n KUtil.removeClass(el_, 'k-menu__item--open');\r\n }); \r\n }\r\n }\r\n }\r\n }\r\n\r\n KUtil.slideDown(submenu, speed, function() {\r\n Plugin.scrollToItem(item);\r\n Plugin.scrollUpdate();\r\n \r\n Plugin.eventTrigger('submenuToggle', submenu);\r\n });\r\n \r\n KUtil.addClass(li, 'k-menu__item--open');\r\n\r\n } else {\r\n KUtil.slideUp(submenu, speed, function() {\r\n Plugin.scrollToItem(item);\r\n Plugin.eventTrigger('submenuToggle', submenu);\r\n });\r\n\r\n KUtil.removeClass(li, 'k-menu__item--open'); \r\n }\r\n }\r\n },\r\n\r\n /**\r\n * scroll to item function\r\n * @returns {KMenu}\r\n */\r\n scrollToItem: function(item) {\r\n // handle auto scroll for accordion submenus\r\n if ( KUtil.isInResponsiveRange('desktop') && the.options.accordion.autoScroll && element.getAttribute('data-kmenu-scroll') !== '1' ) {\r\n KUtil.scrollTo(item, the.options.accordion.autoScrollSpeed);\r\n }\r\n },\r\n\r\n /**\r\n * helper functions\r\n * @returns {KMenu}\r\n */\r\n hideSubmenuDropdown: function(item, classAlso) {\r\n // remove submenu activation class\r\n if ( classAlso ) {\r\n KUtil.removeClass(item, 'k-menu__item--hover');\r\n KUtil.removeClass(item, 'k-menu__item--active-tab');\r\n }\r\n\r\n // clear timeout\r\n item.removeAttribute('data-hover');\r\n\r\n if ( item.getAttribute('data-kmenu-dropdown-toggle-class') ) {\r\n KUtil.removeClass(body, item.getAttribute('data-kmenu-dropdown-toggle-class'));\r\n }\r\n\r\n var timeout = item.getAttribute('data-timeout');\r\n item.removeAttribute('data-timeout');\r\n clearTimeout(timeout);\r\n },\r\n\r\n /**\r\n * helper functions\r\n * @returns {KMenu}\r\n */\r\n showSubmenuDropdown: function(item) {\r\n // close active submenus\r\n var list = element.querySelectorAll('.k-menu__item--submenu.k-menu__item--hover, .k-menu__item--submenu.k-menu__item--active-tab');\r\n\r\n if ( list ) {\r\n for (var i = 0, len = list.length; i < len; i++) {\r\n var el = list[i];\r\n if ( item !== el && el.contains(item) === false && item.contains(el) === false ) {\r\n Plugin.hideSubmenuDropdown(el, true);\r\n }\r\n }\r\n } \r\n\r\n // add submenu activation class\r\n KUtil.addClass(item, 'k-menu__item--hover');\r\n \r\n if ( item.getAttribute('data-kmenu-dropdown-toggle-class') ) {\r\n KUtil.addClass(body, item.getAttribute('data-kmenu-dropdown-toggle-class'));\r\n }\r\n },\r\n\r\n /**\r\n * Handles submenu slide toggle\r\n * @returns {KMenu}\r\n */\r\n createSubmenuDropdownClickDropoff: function(el) {\r\n var query;\r\n var zIndex = (query = KUtil.child(el, '.k-menu__submenu') ? KUtil.css(query, 'z-index') : 0) - 1;\r\n\r\n var dropoff = document.createElement('
');\r\n\r\n body.appendChild(dropoff);\r\n\r\n KUtil.addEvent(dropoff, 'click', function(e) {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n KUtil.remove(this);\r\n Plugin.hideSubmenuDropdown(el, true);\r\n });\r\n },\r\n\r\n /**\r\n * Handles submenu hover toggle\r\n * @returns {KMenu}\r\n */\r\n pauseDropdownHover: function(time) {\r\n var date = new Date();\r\n\r\n the.pauseDropdownHoverTime = date.getTime() + time;\r\n },\r\n\r\n /**\r\n * Handles submenu hover toggle\r\n * @returns {KMenu}\r\n */\r\n resumeDropdownHover: function() {\r\n var date = new Date();\r\n\r\n return (date.getTime() > the.pauseDropdownHoverTime ? true : false);\r\n },\r\n\r\n /**\r\n * Reset menu's current active item\r\n * @returns {KMenu}\r\n */\r\n resetActiveItem: function(item) {\r\n var list;\r\n var parents;\r\n\r\n list = element.querySelectorAll('.k-menu__item--active');\r\n \r\n for (var i = 0, len = list.length; i < len; i++) {\r\n var el = list[0];\r\n KUtil.removeClass(el, 'k-menu__item--active');\r\n KUtil.hide( KUtil.child(el, '.k-menu__submenu') );\r\n parents = KUtil.parents(el, '.k-menu__item--submenu');\r\n\r\n for (var i_ = 0, len_ = parents.length; i_ < len_; i_++) {\r\n var el_ = parents[i];\r\n KUtil.removeClass(el_, 'k-menu__item--open');\r\n KUtil.hide( KUtil.child(el_, '.k-menu__submenu') );\r\n }\r\n }\r\n\r\n // close open submenus\r\n if ( the.options.accordion.expandAll === false ) {\r\n if ( list = element.querySelectorAll('.k-menu__item--open') ) {\r\n for (var i = 0, len = list.length; i < len; i++) {\r\n KUtil.removeClass(parents[0], 'k-menu__item--open');\r\n }\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Sets menu's active item\r\n * @returns {KMenu}\r\n */\r\n setActiveItem: function(item) {\r\n // reset current active item\r\n Plugin.resetActiveItem();\r\n\r\n KUtil.addClass(item, 'k-menu__item--active');\r\n \r\n var parents = KUtil.parents(item, '.k-menu__item--submenu');\r\n for (var i = 0, len = parents.length; i < len; i++) {\r\n KUtil.addClass(parents[i], 'k-menu__item--open');\r\n }\r\n },\r\n\r\n /**\r\n * Returns page breadcrumbs for the menu's active item\r\n * @returns {KMenu}\r\n */\r\n getBreadcrumbs: function(item) {\r\n var query;\r\n var breadcrumbs = [];\r\n var link = KUtil.child(item, '.k-menu__link');\r\n\r\n breadcrumbs.push({\r\n text: (query = KUtil.child(link, '.k-menu__link-text') ? query.innerHTML : ''),\r\n title: link.getAttribute('title'),\r\n href: link.getAttribute('href')\r\n });\r\n\r\n var parents = KUtil.parents(item, '.k-menu__item--submenu');\r\n for (var i = 0, len = parents.length; i < len; i++) {\r\n var submenuLink = KUtil.child(parents[i], '.k-menu__link');\r\n\r\n breadcrumbs.push({\r\n text: (query = KUtil.child(submenuLink, '.k-menu__link-text') ? query.innerHTML : ''),\r\n title: submenuLink.getAttribute('title'),\r\n href: submenuLink.getAttribute('href')\r\n });\r\n }\r\n\r\n return breadcrumbs.reverse();\r\n },\r\n\r\n /**\r\n * Returns page title for the menu's active item\r\n * @returns {KMenu}\r\n */\r\n getPageTitle: function(item) {\r\n var query;\r\n\r\n return (query = KUtil.child(item, '.k-menu__link-text') ? query.innerHTML : '');\r\n },\r\n\r\n /**\r\n * Trigger events\r\n */\r\n eventTrigger: function(name, args) {\r\n for (var i = 0; i < the.events.length; i++ ) {\r\n var event = the.events[i];\r\n if ( event.name == name ) {\r\n if ( event.one == true ) {\r\n if ( event.fired == false ) {\r\n the.events[i].fired = true;\r\n event.handler.call(this, the, args);\r\n }\r\n } else {\r\n event.handler.call(this, the, args);\r\n }\r\n }\r\n }\r\n },\r\n\r\n addEvent: function(name, handler, one) {\r\n the.events.push({\r\n name: name,\r\n handler: handler,\r\n one: one,\r\n fired: false\r\n });\r\n },\r\n\r\n removeEvent: function(name) {\r\n if (the.events[name]) {\r\n delete the.events[name];\r\n }\r\n }\r\n };\r\n\r\n //////////////////////////\r\n // ** Public Methods ** //\r\n //////////////////////////\r\n\r\n /**\r\n * Set default options \r\n */\r\n\r\n the.setDefaults = function(options) {\r\n defaultOptions = options;\r\n };\r\n\r\n /**\r\n * Update scroll\r\n */\r\n the.scrollUpdate = function() {\r\n return Plugin.scrollUpdate();\r\n };\r\n\r\n /**\r\n * Re-init scroll\r\n */\r\n the.scrollReInit = function() {\r\n return Plugin.scrollInit();\r\n };\r\n\r\n /**\r\n * Scroll top\r\n */\r\n the.scrollTop = function() {\r\n return Plugin.scrollTop();\r\n };\r\n\r\n /**\r\n * Set active menu item\r\n */\r\n the.setActiveItem = function(item) {\r\n return Plugin.setActiveItem(item);\r\n };\r\n\r\n the.reload = function() {\r\n return Plugin.reload();\r\n };\r\n\r\n the.update = function(options) {\r\n return Plugin.update(options);\r\n };\r\n\r\n /**\r\n * Set breadcrumb for menu item\r\n */\r\n the.getBreadcrumbs = function(item) {\r\n return Plugin.getBreadcrumbs(item);\r\n };\r\n\r\n /**\r\n * Set page title for menu item\r\n */\r\n the.getPageTitle = function(item) {\r\n return Plugin.getPageTitle(item);\r\n };\r\n\r\n /**\r\n * Get submenu mode\r\n */\r\n the.getSubmenuMode = function(el) {\r\n return Plugin.getSubmenuMode(el);\r\n };\r\n\r\n /**\r\n * Hide dropdown submenu\r\n * @returns {jQuery}\r\n */\r\n the.hideDropdown = function(item) {\r\n Plugin.hideSubmenuDropdown(item, true);\r\n };\r\n\r\n /**\r\n * Disable menu for given time\r\n * @returns {jQuery}\r\n */\r\n the.pauseDropdownHover = function(time) {\r\n Plugin.pauseDropdownHover(time);\r\n };\r\n\r\n /**\r\n * Disable menu for given time\r\n * @returns {jQuery}\r\n */\r\n the.resumeDropdownHover = function() {\r\n return Plugin.resumeDropdownHover();\r\n };\r\n\r\n /**\r\n * Register event\r\n */\r\n the.on = function(name, handler) {\r\n return Plugin.addEvent(name, handler);\r\n };\r\n\r\n the.off = function(name) {\r\n return Plugin.removeEvent(name);\r\n };\r\n\r\n the.one = function(name, handler) {\r\n return Plugin.addEvent(name, handler, true);\r\n };\r\n\r\n ///////////////////////////////\r\n // ** Plugin Construction ** //\r\n ///////////////////////////////\r\n\r\n // Run plugin\r\n Plugin.construct.apply(the, [options]);\r\n\r\n // Handle plugin on window resize\r\n KUtil.addResizeHandler(function() {\r\n if (init) {\r\n the.reload();\r\n } \r\n });\r\n\r\n // Init done\r\n init = true;\r\n\r\n // Return plugin instance\r\n return the;\r\n};\r\n\r\n// Plugin global lazy initialization\r\ndocument.addEventListener(\"click\", function (e) {\r\n var body = KUtil.get('body');\r\n var query;\r\n if ( query = body.querySelectorAll('.k-menu__nav .k-menu__item.k-menu__item--submenu.k-menu__item--hover:not(.k-menu__item--tabs)[data-kmenu-submenu-toggle=\"click\"]') ) {\r\n for (var i = 0, len = query.length; i < len; i++) {\r\n var element = query[i].closest('.k-menu__nav').parentNode;\r\n\r\n if ( element ) {\r\n var the = KUtil.data(element).get('menu');\r\n\r\n if ( !the ) {\r\n break;\r\n }\r\n\r\n if ( !the || the.getSubmenuMode() !== 'dropdown' ) {\r\n break;\r\n }\r\n\r\n if ( e.target !== element && element.contains(e.target) === false ) {\r\n var items;\r\n if ( items = element.querySelectorAll('.k-menu__item--submenu.k-menu__item--hover:not(.k-menu__item--tabs)[data-kmenu-submenu-toggle=\"click\"]') ) {\r\n for (var j = 0, cnt = items.length; j < cnt; j++) {\r\n the.hideDropdown(items[j]);\r\n }\r\n }\r\n }\r\n } \r\n }\r\n } \r\n});\n\"use strict\";\r\nvar KOffcanvas = function(elementId, options) {\r\n // Main object\r\n var the = this;\r\n var init = false;\r\n\r\n // Get element object\r\n var element = KUtil.get(elementId);\r\n var body = KUtil.get('body');\r\n\r\n if (!element) {\r\n return;\r\n }\r\n\r\n // Default options\r\n var defaultOptions = {};\r\n\r\n ////////////////////////////\r\n // ** Private Methods ** //\r\n ////////////////////////////\r\n\r\n var Plugin = {\r\n construct: function(options) {\r\n if (KUtil.data(element).has('offcanvas')) {\r\n the = KUtil.data(element).get('offcanvas');\r\n } else {\r\n // reset offcanvas\r\n Plugin.init(options);\r\n \r\n // build offcanvas\r\n Plugin.build();\r\n\r\n KUtil.data(element).set('offcanvas', the);\r\n }\r\n\r\n return the;\r\n },\r\n\r\n init: function(options) {\r\n the.events = [];\r\n\r\n // merge default and user defined options\r\n the.options = KUtil.deepExtend({}, defaultOptions, options);\r\n the.overlay;\r\n\r\n the.classBase = the.options.baseClass;\r\n the.classShown = the.classBase + '--on';\r\n the.classOverlay = the.classBase + '-overlay';\r\n\r\n the.state = KUtil.hasClass(element, the.classShown) ? 'shown' : 'hidden';\r\n },\r\n\r\n build: function() {\r\n // offcanvas toggle\r\n if (the.options.toggleBy) {\r\n if (typeof the.options.toggleBy === 'string') { \r\n KUtil.addEvent( the.options.toggleBy, 'click', function(e) {\r\n e.preventDefault();\r\n Plugin.toggle();\r\n }); \r\n } else if (the.options.toggleBy && the.options.toggleBy[0] && the.options.toggleBy[0].target) {\r\n for (var i in the.options.toggleBy) { \r\n KUtil.addEvent( the.options.toggleBy[i].target, 'click', function(e) {\r\n e.preventDefault();\r\n Plugin.toggle();\r\n }); \r\n }\r\n } else if (the.options.toggleBy && the.options.toggleBy.target) {\r\n KUtil.addEvent( the.options.toggleBy.target, 'click', function(e) {\r\n e.preventDefault();\r\n Plugin.toggle();\r\n }); \r\n } \r\n }\r\n\r\n // offcanvas close\r\n var closeBy = KUtil.get(the.options.closeBy);\r\n if (closeBy) {\r\n KUtil.addEvent(closeBy, 'click', function(e) {\r\n e.preventDefault();\r\n Plugin.hide();\r\n });\r\n }\r\n },\r\n\r\n isShown: function(target) {\r\n return (the.state == 'shown' ? true : false);\r\n },\r\n\r\n toggle: function() {;\r\n Plugin.eventTrigger('toggle'); \r\n\r\n if (the.state == 'shown') {\r\n Plugin.hide(this);\r\n } else {\r\n Plugin.show(this);\r\n }\r\n },\r\n\r\n show: function(target) {\r\n if (the.state == 'shown') {\r\n return;\r\n }\r\n\r\n Plugin.eventTrigger('beforeShow');\r\n\r\n Plugin.togglerClass(target, 'show');\r\n\r\n // Offcanvas panel\r\n KUtil.addClass(body, the.classShown);\r\n KUtil.addClass(element, the.classShown);\r\n\r\n the.state = 'shown';\r\n\r\n if (the.options.overlay) {\r\n the.overlay = KUtil.insertAfter(document.createElement('DIV') , element );\r\n KUtil.addClass(the.overlay, the.classOverlay);\r\n KUtil.addEvent(the.overlay, 'click', function(e) {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n Plugin.hide(target); \r\n });\r\n }\r\n\r\n Plugin.eventTrigger('afterShow');\r\n },\r\n\r\n hide: function(target) {\r\n if (the.state == 'hidden') {\r\n return;\r\n }\r\n\r\n Plugin.eventTrigger('beforeHide');\r\n\r\n Plugin.togglerClass(target, 'hide');\r\n\r\n KUtil.removeClass(body, the.classShown);\r\n KUtil.removeClass(element, the.classShown);\r\n\r\n the.state = 'hidden';\r\n\r\n if (the.options.overlay && the.overlay) {\r\n KUtil.remove(the.overlay);\r\n }\r\n\r\n Plugin.eventTrigger('afterHide');\r\n },\r\n\r\n togglerClass: function(target, mode) {\r\n // Toggler\r\n var id = KUtil.attr(target, 'id');\r\n var toggleBy;\r\n\r\n if (the.options.toggleBy && the.options.toggleBy[0] && the.options.toggleBy[0].target) {\r\n for (var i in the.options.toggleBy) {\r\n if (the.options.toggleBy[i].target === id) {\r\n toggleBy = the.options.toggleBy[i];\r\n } \r\n }\r\n } else if (the.options.toggleBy && the.options.toggleBy.target) {\r\n toggleBy = the.options.toggleBy;\r\n }\r\n\r\n if (toggleBy) { \r\n var el = KUtil.get(toggleBy.target);\r\n \r\n if (mode === 'show') {\r\n KUtil.addClass(el, toggleBy.state);\r\n }\r\n\r\n if (mode === 'hide') {\r\n KUtil.removeClass(el, toggleBy.state);\r\n }\r\n }\r\n },\r\n\r\n eventTrigger: function(name, args) {\r\n for (var i = 0; i < the.events.length; i++) {\r\n var event = the.events[i];\r\n if (event.name == name) {\r\n if (event.one == true) {\r\n if (event.fired == false) {\r\n the.events[i].fired = true;\r\n event.handler.call(this, the, args);\r\n }\r\n } else {\r\n event.handler.call(this, the, args);\r\n }\r\n }\r\n }\r\n },\r\n\r\n addEvent: function(name, handler, one) {\r\n the.events.push({\r\n name: name,\r\n handler: handler,\r\n one: one,\r\n fired: false\r\n });\r\n }\r\n };\r\n\r\n //////////////////////////\r\n // ** Public Methods ** //\r\n //////////////////////////\r\n the.setDefaults = function(options) {\r\n defaultOptions = options;\r\n };\r\n\r\n the.isShown = function() {\r\n return Plugin.isShown();\r\n };\r\n\r\n the.hide = function() {\r\n return Plugin.hide();\r\n };\r\n\r\n the.show = function() {\r\n return Plugin.show();\r\n };\r\n\r\n the.on = function(name, handler) {\r\n return Plugin.addEvent(name, handler);\r\n };\r\n\r\n the.one = function(name, handler) {\r\n return Plugin.addEvent(name, handler, true);\r\n };\r\n\r\n ///////////////////////////////\r\n // ** Plugin Construction ** //\r\n ///////////////////////////////\r\n\r\n // Run plugin\r\n Plugin.construct.apply(the, [options]);\r\n\r\n // Init done\r\n init = true;\r\n\r\n // Return plugin instance\r\n return the;\r\n};\n\"use strict\";\r\n// plugin setup\r\nvar KPortlet = function(elementId, options) {\r\n // Main object\r\n var the = this;\r\n var init = false;\r\n\r\n // Get element object\r\n var element = KUtil.get(elementId);\r\n var body = KUtil.get('body');\r\n\r\n if (!element) {\r\n return;\r\n }\r\n\r\n // Default options\r\n var defaultOptions = {\r\n bodyToggleSpeed: 400,\r\n tooltips: true,\r\n tools: {\r\n toggle: {\r\n collapse: 'Collapse',\r\n expand: 'Expand'\r\n },\r\n reload: 'Reload',\r\n remove: 'Remove',\r\n fullscreen: {\r\n on: 'Fullscreen',\r\n off: 'Exit Fullscreen'\r\n }\r\n },\r\n sticky: {\r\n offset: 300,\r\n zIndex: 101\r\n }\r\n };\r\n\r\n ////////////////////////////\r\n // ** Private Methods ** //\r\n ////////////////////////////\r\n\r\n var Plugin = {\r\n /**\r\n * Construct\r\n */\r\n\r\n construct: function(options) {\r\n if (KUtil.data(element).has('portlet')) {\r\n the = KUtil.data(element).get('portlet');\r\n } else {\r\n // reset menu\r\n Plugin.init(options);\r\n\r\n // build menu\r\n Plugin.build();\r\n\r\n KUtil.data(element).set('portlet', the);\r\n }\r\n\r\n return the;\r\n },\r\n\r\n /**\r\n * Init portlet\r\n */\r\n init: function(options) {\r\n the.element = element;\r\n the.events = [];\r\n\r\n // merge default and user defined options\r\n the.options = KUtil.deepExtend({}, defaultOptions, options);\r\n the.head = KUtil.child(element, '.k-portlet__head');\r\n the.foot = KUtil.child(element, '.k-portlet__foot');\r\n\r\n if (KUtil.child(element, '.k-portlet__body')) {\r\n the.body = KUtil.child(element, '.k-portlet__body');\r\n } else if (KUtil.child(element, '.k-form').length !== 0) {\r\n the.body = KUtil.child(element, '.k-form');\r\n }\r\n },\r\n\r\n /**\r\n * Build Form Wizard\r\n */\r\n build: function() {\r\n // Remove\r\n var remove = KUtil.find(the.head, '[data-kportlet-tool=remove]');\r\n if (remove) {\r\n KUtil.addEvent(remove, 'click', function(e) {\r\n e.preventDefault();\r\n Plugin.remove();\r\n });\r\n }\r\n\r\n // Reload\r\n var reload = KUtil.find(the.head, '[data-kportlet-tool=reload]');\r\n if (reload) {\r\n KUtil.addEvent(reload, 'click', function(e) {\r\n e.preventDefault();\r\n Plugin.reload();\r\n });\r\n }\r\n\r\n // Toggle\r\n var toggle = KUtil.find(the.head, '[data-kportlet-tool=toggle]');\r\n if (toggle) {\r\n KUtil.addEvent(toggle, 'click', function(e) {\r\n e.preventDefault();\r\n Plugin.toggle();\r\n });\r\n }\r\n\r\n //== Fullscreen\r\n var fullscreen = KUtil.find(the.head, '[data-kportlet-tool=fullscreen]');\r\n if (fullscreen) {\r\n KUtil.addEvent(fullscreen, 'click', function(e) {\r\n e.preventDefault();\r\n Plugin.fullscreen();\r\n });\r\n }\r\n\r\n Plugin.setupTooltips();\r\n },\r\n\r\n /**\r\n * Enable stickt mode\r\n */\r\n initSticky: function() {\r\n var lastScrollTop = 0;\r\n var offset = the.options.sticky.offset;\r\n\r\n if (!the.head) {\r\n return;\r\n }\r\n\r\n\t window.addEventListener('scroll', Plugin.onScrollSticky);\r\n },\r\n\r\n\t /**\r\n\t * Window scroll handle event for sticky portlet\r\n\t */\r\n\t onScrollSticky: function(e) {\r\n\t\t var offset = the.options.sticky.offset;\r\n\t\t if(isNaN(offset)) return;\r\n\r\n\t\t var st = document.documentElement.scrollTop;\r\n\r\n\t\t if (st >= offset && KUtil.hasClass(body, 'k-portlet--sticky') === false) {\r\n\t\t\t Plugin.eventTrigger('stickyOn');\r\n\r\n\t\t\t KUtil.addClass(body, 'k-portlet--sticky');\r\n\t\t\t KUtil.addClass(element, 'k-portlet--sticky');\r\n\r\n\t\t\t Plugin.updateSticky();\r\n\r\n\t\t } else if ((st*1.5) <= offset && KUtil.hasClass(body, 'k-portlet--sticky')) {\r\n\t\t\t // back scroll mode\r\n\t\t\t Plugin.eventTrigger('stickyOff');\r\n\r\n\t\t\t KUtil.removeClass(body, 'k-portlet--sticky');\r\n\t\t\t KUtil.removeClass(element, 'k-portlet--sticky');\r\n\r\n\t\t\t Plugin.resetSticky();\r\n\t\t }\r\n\t },\r\n\r\n updateSticky: function() {\r\n if (!the.head) {\r\n return;\r\n }\r\n\r\n var top;\r\n\r\n if (KUtil.hasClass(body, 'k-portlet--sticky')) {\r\n if (the.options.sticky.position.top instanceof Function) {\r\n top = parseInt(the.options.sticky.position.top.call());\r\n } else {\r\n top = parseInt(the.options.sticky.position.top);\r\n }\r\n\r\n var left;\r\n if (the.options.sticky.position.left instanceof Function) {\r\n left = parseInt(the.options.sticky.position.left.call());\r\n } else {\r\n left = parseInt(the.options.sticky.position.left);\r\n }\r\n\r\n var right;\r\n if (the.options.sticky.position.right instanceof Function) {\r\n right = parseInt(the.options.sticky.position.right.call());\r\n } else {\r\n right = parseInt(the.options.sticky.position.right);\r\n }\r\n\r\n KUtil.css(the.head, 'z-index', the.options.sticky.zIndex);\r\n KUtil.css(the.head, 'top', top + 'px');\r\n KUtil.css(the.head, 'left', left + 'px');\r\n KUtil.css(the.head, 'right', right + 'px');\r\n }\r\n },\r\n\r\n resetSticky: function() {\r\n if (!the.head) {\r\n return;\r\n }\r\n\r\n if (KUtil.hasClass(body, 'k-portlet--sticky') === false) {\r\n KUtil.css(the.head, 'z-index', '');\r\n KUtil.css(the.head, 'top', '');\r\n KUtil.css(the.head, 'left', '');\r\n KUtil.css(the.head, 'right', '');\r\n }\r\n },\r\n\r\n /**\r\n * Remove portlet\r\n */\r\n remove: function() {\r\n if (Plugin.eventTrigger('beforeRemove') === false) {\r\n return;\r\n }\r\n\r\n if (KUtil.hasClass(body, 'k-portlet--fullscreen') && KUtil.hasClass(element, 'k-portlet--fullscreen')) {\r\n Plugin.fullscreen('off');\r\n }\r\n\r\n Plugin.removeTooltips();\r\n\r\n KUtil.remove(element);\r\n\r\n Plugin.eventTrigger('afterRemove');\r\n },\r\n\r\n /**\r\n * Set content\r\n */\r\n setContent: function(html) {\r\n if (html) {\r\n the.body.innerHTML = html;\r\n }\r\n },\r\n\r\n /**\r\n * Get body\r\n */\r\n getBody: function() {\r\n return the.body;\r\n },\r\n\r\n /**\r\n * Get self\r\n */\r\n getSelf: function() {\r\n return element;\r\n },\r\n\r\n /**\r\n * Setup tooltips\r\n */\r\n setupTooltips: function() {\r\n if (the.options.tooltips) {\r\n var collapsed = KUtil.hasClass(element, 'k-portlet--collapse') || KUtil.hasClass(element, 'k-portlet--collapsed');\r\n var fullscreenOn = KUtil.hasClass(body, 'k-portlet--fullscreen') && KUtil.hasClass(element, 'k-portlet--fullscreen');\r\n\r\n //== Remove\r\n var remove = KUtil.find(the.head, '[data-kportlet-tool=remove]');\r\n if (remove) {\r\n var placement = (fullscreenOn ? 'bottom' : 'top');\r\n var tip = new Tooltip(remove, {\r\n title: the.options.tools.remove,\r\n placement: placement,\r\n offset: (fullscreenOn ? '0,10px,0,0' : '0,5px'),\r\n trigger: 'hover',\r\n template: '
\\\r\n
\\\r\n
\\\r\n
'\r\n });\r\n\r\n KUtil.data(remove).set('tooltip', tip);\r\n }\r\n\r\n //== Reload\r\n var reload = KUtil.find(the.head, '[data-kportlet-tool=reload]');\r\n if (reload) {\r\n var placement = (fullscreenOn ? 'bottom' : 'top');\r\n var tip = new Tooltip(reload, {\r\n title: the.options.tools.reload,\r\n placement: placement,\r\n offset: (fullscreenOn ? '0,10px,0,0' : '0,5px'),\r\n trigger: 'hover',\r\n template: '
\\\r\n
\\\r\n
\\\r\n
'\r\n });\r\n\r\n KUtil.data(reload).set('tooltip', tip);\r\n }\r\n\r\n //== Toggle\r\n var toggle = KUtil.find(the.head, '[data-kportlet-tool=toggle]');\r\n if (toggle) {\r\n var placement = (fullscreenOn ? 'bottom' : 'top');\r\n var tip = new Tooltip(toggle, {\r\n title: (collapsed ? the.options.tools.toggle.expand : the.options.tools.toggle.collapse),\r\n placement: placement,\r\n offset: (fullscreenOn ? '0,10px,0,0' : '0,5px'),\r\n trigger: 'hover',\r\n template: '
\\\r\n
\\\r\n
\\\r\n
'\r\n });\r\n\r\n KUtil.data(toggle).set('tooltip', tip);\r\n }\r\n\r\n //== Fullscreen\r\n var fullscreen = KUtil.find(the.head, '[data-kportlet-tool=fullscreen]');\r\n if (fullscreen) {\r\n var placement = (fullscreenOn ? 'bottom' : 'top');\r\n var tip = new Tooltip(fullscreen, {\r\n title: (fullscreenOn ? the.options.tools.fullscreen.off : the.options.tools.fullscreen.on),\r\n placement: placement,\r\n offset: (fullscreenOn ? '0,10px,0,0' : '0,5px'),\r\n trigger: 'hover',\r\n template: '
\\\r\n
\\\r\n
\\\r\n
'\r\n });\r\n\r\n KUtil.data(fullscreen).set('tooltip', tip);\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Setup tooltips\r\n */\r\n removeTooltips: function() {\r\n if (the.options.tooltips) {\r\n //== Remove\r\n var remove = KUtil.find(the.head, '[data-kportlet-tool=remove]');\r\n if (remove && KUtil.data(remove).has('tooltip')) {\r\n KUtil.data(remove).get('tooltip').dispose();\r\n }\r\n\r\n //== Reload\r\n var reload = KUtil.find(the.head, '[data-kportlet-tool=reload]');\r\n if (reload && KUtil.data(reload).has('tooltip')) {\r\n KUtil.data(reload).get('tooltip').dispose();\r\n }\r\n\r\n //== Toggle\r\n var toggle = KUtil.find(the.head, '[data-kportlet-tool=toggle]');\r\n if (toggle && KUtil.data(toggle).has('tooltip')) {\r\n KUtil.data(toggle).get('tooltip').dispose();\r\n }\r\n\r\n //== Fullscreen\r\n var fullscreen = KUtil.find(the.head, '[data-kportlet-tool=fullscreen]');\r\n if (fullscreen && KUtil.data(fullscreen).has('tooltip')) {\r\n KUtil.data(fullscreen).get('tooltip').dispose();\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Reload\r\n */\r\n reload: function() {\r\n Plugin.eventTrigger('reload');\r\n },\r\n\r\n /**\r\n * Toggle\r\n */\r\n toggle: function() {\r\n if (KUtil.hasClass(element, 'k-portlet--collapse') || KUtil.hasClass(element, 'k-portlet--collapsed')) {\r\n Plugin.expand();\r\n } else {\r\n Plugin.collapse();\r\n }\r\n },\r\n\r\n /**\r\n * Collapse\r\n */\r\n collapse: function() {\r\n if (Plugin.eventTrigger('beforeCollapse') === false) {\r\n return;\r\n }\r\n\r\n KUtil.slideUp(the.body, the.options.bodyToggleSpeed, function() {\r\n Plugin.eventTrigger('afterCollapse');\r\n });\r\n\r\n KUtil.addClass(element, 'k-portlet--collapse');\r\n\r\n var toggle = KUtil.find(the.head, '[data-kportlet-tool=toggle]');\r\n if (toggle && KUtil.data(toggle).has('tooltip')) {\r\n KUtil.data(toggle).get('tooltip').updateTitleContent(the.options.tools.toggle.expand);\r\n }\r\n },\r\n\r\n /**\r\n * Expand\r\n */\r\n expand: function() {\r\n if (Plugin.eventTrigger('beforeExpand') === false) {\r\n return;\r\n }\r\n\r\n KUtil.slideDown(the.body, the.options.bodyToggleSpeed, function() {\r\n Plugin.eventTrigger('afterExpand');\r\n });\r\n\r\n KUtil.removeClass(element, 'k-portlet--collapse');\r\n KUtil.removeClass(element, 'k-portlet--collapsed');\r\n\r\n var toggle = KUtil.find(the.head, '[data-kportlet-tool=toggle]');\r\n if (toggle && KUtil.data(toggle).has('tooltip')) {\r\n KUtil.data(toggle).get('tooltip').updateTitleContent(the.options.tools.toggle.collapse);\r\n }\r\n },\r\n\r\n /**\r\n * fullscreen\r\n */\r\n fullscreen: function(mode) {\r\n var d = {};\r\n var speed = 300;\r\n\r\n if (mode === 'off' || (KUtil.hasClass(body, 'k-portlet--fullscreen') && KUtil.hasClass(element, 'k-portlet--fullscreen'))) {\r\n Plugin.eventTrigger('beforeFullscreenOff');\r\n\r\n KUtil.removeClass(body, 'k-portlet--fullscreen');\r\n KUtil.removeClass(element, 'k-portlet--fullscreen');\r\n\r\n Plugin.removeTooltips();\r\n Plugin.setupTooltips();\r\n\r\n if (the.foot) {\r\n KUtil.css(the.body, 'margin-bottom', '');\r\n KUtil.css(the.foot, 'margin-top', '');\r\n }\r\n\r\n Plugin.eventTrigger('afterFullscreenOff');\r\n } else {\r\n Plugin.eventTrigger('beforeFullscreenOn');\r\n\r\n KUtil.addClass(element, 'k-portlet--fullscreen');\r\n KUtil.addClass(body, 'k-portlet--fullscreen');\r\n\r\n Plugin.removeTooltips();\r\n Plugin.setupTooltips();\r\n\r\n\r\n if (the.foot) {\r\n var height1 = parseInt(KUtil.css(the.foot, 'height'));\r\n var height2 = parseInt(KUtil.css(the.foot, 'height')) + parseInt(KUtil.css(the.head, 'height'));\r\n KUtil.css(the.body, 'margin-bottom', height1 + 'px');\r\n KUtil.css(the.foot, 'margin-top', '-' + height2 + 'px');\r\n }\r\n\r\n Plugin.eventTrigger('afterFullscreenOn');\r\n }\r\n },\r\n\r\n /**\r\n * Trigger events\r\n */\r\n eventTrigger: function(name) {\r\n //KUtil.triggerCustomEvent(name);\r\n for (var i = 0; i < the.events.length; i++) {\r\n var event = the.events[i];\r\n if (event.name == name) {\r\n if (event.one == true) {\r\n if (event.fired == false) {\r\n the.events[i].fired = true;\r\n event.handler.call(this, the);\r\n }\r\n } else {\r\n event.handler.call(this, the);\r\n }\r\n }\r\n }\r\n },\r\n\r\n addEvent: function(name, handler, one) {\r\n the.events.push({\r\n name: name,\r\n handler: handler,\r\n one: one,\r\n fired: false\r\n });\r\n\r\n return the;\r\n }\r\n };\r\n\r\n //////////////////////////\r\n // ** Public Methods ** //\r\n //////////////////////////\r\n\r\n /**\r\n * Set default options\r\n */\r\n\r\n the.setDefaults = function(options) {\r\n defaultOptions = options;\r\n };\r\n\r\n /**\r\n * Remove portlet\r\n * @returns {KPortlet}\r\n */\r\n the.remove = function() {\r\n return Plugin.remove(html);\r\n };\r\n\r\n /**\r\n * Remove portlet\r\n * @returns {KPortlet}\r\n */\r\n the.initSticky = function() {\r\n return Plugin.initSticky();\r\n };\r\n\r\n /**\r\n * Remove portlet\r\n * @returns {KPortlet}\r\n */\r\n the.updateSticky = function() {\r\n return Plugin.updateSticky();\r\n };\r\n\r\n /**\r\n * Remove portlet\r\n * @returns {KPortlet}\r\n */\r\n the.resetSticky = function() {\r\n return Plugin.resetSticky();\r\n };\r\n\r\n\t/**\r\n\t * Destroy sticky portlet\r\n\t */\r\n\tthe.destroySticky = function() {\r\n\t\tPlugin.resetSticky();\r\n\t\twindow.removeEventListener('scroll', Plugin.onScrollSticky);\r\n\t};\r\n\r\n /**\r\n * Reload portlet\r\n * @returns {KPortlet}\r\n */\r\n the.reload = function() {\r\n return Plugin.reload();\r\n };\r\n\r\n /**\r\n * Set portlet content\r\n * @returns {KPortlet}\r\n */\r\n the.setContent = function(html) {\r\n return Plugin.setContent(html);\r\n };\r\n\r\n /**\r\n * Toggle portlet\r\n * @returns {KPortlet}\r\n */\r\n the.toggle = function() {\r\n return Plugin.toggle();\r\n };\r\n\r\n /**\r\n * Collapse portlet\r\n * @returns {KPortlet}\r\n */\r\n the.collapse = function() {\r\n return Plugin.collapse();\r\n };\r\n\r\n /**\r\n * Expand portlet\r\n * @returns {KPortlet}\r\n */\r\n the.expand = function() {\r\n return Plugin.expand();\r\n };\r\n\r\n /**\r\n * Fullscreen portlet\r\n * @returns {MPortlet}\r\n */\r\n the.fullscreen = function() {\r\n return Plugin.fullscreen('on');\r\n };\r\n\r\n /**\r\n * Fullscreen portlet\r\n * @returns {MPortlet}\r\n */\r\n the.unFullscreen = function() {\r\n return Plugin.fullscreen('off');\r\n };\r\n\r\n /**\r\n * Get portletbody\r\n * @returns {jQuery}\r\n */\r\n the.getBody = function() {\r\n return Plugin.getBody();\r\n };\r\n\r\n /**\r\n * Get portletbody\r\n * @returns {jQuery}\r\n */\r\n the.getSelf = function() {\r\n return Plugin.getSelf();\r\n };\r\n\r\n /**\r\n * Attach event\r\n */\r\n the.on = function(name, handler) {\r\n return Plugin.addEvent(name, handler);\r\n };\r\n\r\n /**\r\n * Attach event that will be fired once\r\n */\r\n the.one = function(name, handler) {\r\n return Plugin.addEvent(name, handler, true);\r\n };\r\n\r\n // Construct plugin\r\n Plugin.construct.apply(the, [options]);\r\n\r\n return the;\r\n};\n\"use strict\";\r\nvar KScrolltop = function(elementId, options) {\r\n // Main object\r\n var the = this;\r\n var init = false;\r\n\r\n // Get element object\r\n var element = KUtil.get(elementId);\r\n var body = KUtil.get('body');\r\n\r\n if (!element) {\r\n return;\r\n }\r\n\r\n // Default options\r\n var defaultOptions = {\r\n offset: 300,\r\n speed: 600,\r\n toggleClass: 'k-scrolltop--on'\r\n };\r\n\r\n ////////////////////////////\r\n // ** Private Methods ** //\r\n ////////////////////////////\r\n\r\n var Plugin = {\r\n /**\r\n * Run plugin\r\n * @returns {mscrolltop}\r\n */\r\n construct: function(options) {\r\n if (KUtil.data(element).has('scrolltop')) {\r\n the = KUtil.data(element).get('scrolltop');\r\n } else {\r\n // reset scrolltop\r\n Plugin.init(options);\r\n\r\n // build scrolltop\r\n Plugin.build();\r\n\r\n KUtil.data(element).set('scrolltop', the);\r\n }\r\n\r\n return the;\r\n },\r\n\r\n /**\r\n * Handles subscrolltop click toggle\r\n * @returns {mscrolltop}\r\n */\r\n init: function(options) {\r\n the.events = [];\r\n\r\n // merge default and user defined options\r\n the.options = KUtil.deepExtend({}, defaultOptions, options);\r\n },\r\n\r\n build: function() {\r\n // handle window scroll\r\n if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\r\n window.addEventListener('touchend', function() {\r\n Plugin.handle();\r\n });\r\n\r\n window.addEventListener('touchcancel', function() {\r\n Plugin.handle();\r\n });\r\n\r\n window.addEventListener('touchleave', function() {\r\n Plugin.handle();\r\n });\r\n } else {\r\n window.addEventListener('scroll', function() { \r\n Plugin.handle();\r\n });\r\n }\r\n\r\n // handle button click \r\n KUtil.addEvent(element, 'click', Plugin.scroll);\r\n },\r\n\r\n /**\r\n * Handles scrolltop click scrollTop\r\n */\r\n handle: function() {\r\n var pos = window.pageYOffset; // current vertical position\r\n if (pos > the.options.offset) {\r\n KUtil.addClass(body, the.options.toggleClass);\r\n } else {\r\n KUtil.removeClass(body, the.options.toggleClass);\r\n }\r\n },\r\n\r\n /**\r\n * Handles scrolltop click scrollTop\r\n */\r\n scroll: function(e) {\r\n e.preventDefault();\r\n\r\n KUtil.scrollTop(0, the.options.speed);\r\n },\r\n\r\n\r\n /**\r\n * Trigger events\r\n */\r\n eventTrigger: function(name, args) {\r\n for (var i = 0; i < the.events.length; i++) {\r\n var event = the.events[i];\r\n if (event.name == name) {\r\n if (event.one == true) {\r\n if (event.fired == false) {\r\n the.events[i].fired = true;\r\n event.handler.call(this, the, args);\r\n }\r\n } else {\r\n event.handler.call(this, the, args);\r\n }\r\n }\r\n }\r\n },\r\n\r\n addEvent: function(name, handler, one) {\r\n the.events.push({\r\n name: name,\r\n handler: handler,\r\n one: one,\r\n fired: false\r\n });\r\n }\r\n };\r\n\r\n //////////////////////////\r\n // ** Public Methods ** //\r\n //////////////////////////\r\n\r\n /**\r\n * Set default options \r\n */\r\n\r\n the.setDefaults = function(options) {\r\n defaultOptions = options;\r\n };\r\n\r\n /**\r\n * Get subscrolltop mode\r\n */\r\n the.on = function(name, handler) {\r\n return Plugin.addEvent(name, handler);\r\n };\r\n\r\n /**\r\n * Set scrolltop content\r\n * @returns {mscrolltop}\r\n */\r\n the.one = function(name, handler) {\r\n return Plugin.addEvent(name, handler, true);\r\n };\r\n\r\n ///////////////////////////////\r\n // ** Plugin Construction ** //\r\n ///////////////////////////////\r\n\r\n // Run plugin\r\n Plugin.construct.apply(the, [options]);\r\n\r\n // Init done\r\n init = true;\r\n\r\n // Return plugin instance\r\n return the;\r\n};\n\"use strict\";\r\n\r\n// plugin setup\r\nvar KToggle = function(elementId, options) {\r\n // Main object\r\n var the = this;\r\n var init = false;\r\n\r\n // Get element object\r\n var element = KUtil.get(elementId);\r\n var body = KUtil.get('body'); \r\n\r\n if (!element) {\r\n return;\r\n }\r\n\r\n // Default options\r\n var defaultOptions = {\r\n togglerState: '',\r\n targetState: ''\r\n }; \r\n\r\n ////////////////////////////\r\n // ** Private Methods ** //\r\n ////////////////////////////\r\n\r\n var Plugin = {\r\n /**\r\n * Construct\r\n */\r\n\r\n construct: function(options) {\r\n if (KUtil.data(element).has('toggle')) {\r\n the = KUtil.data(element).get('toggle');\r\n } else {\r\n // reset menu\r\n Plugin.init(options);\r\n\r\n // build menu\r\n Plugin.build();\r\n\r\n KUtil.data(element).set('toggle', the);\r\n }\r\n\r\n return the;\r\n },\r\n\r\n /**\r\n * Handles subtoggle click toggle\r\n */\r\n init: function(options) {\r\n the.element = element;\r\n the.events = [];\r\n\r\n // merge default and user defined options\r\n the.options = KUtil.deepExtend({}, defaultOptions, options);\r\n\r\n the.target = KUtil.get(the.options.target);\r\n the.targetState = the.options.targetState;\r\n the.togglerState = the.options.togglerState;\r\n\r\n the.state = KUtil.hasClasses(the.target, the.targetState) ? 'on' : 'off';\r\n },\r\n\r\n /**\r\n * Setup toggle\r\n */\r\n build: function() {\r\n KUtil.addEvent(element, 'mouseup', Plugin.toggle);\r\n },\r\n \r\n /**\r\n * Handles offcanvas click toggle\r\n */\r\n toggle: function(e) {\r\n Plugin.eventTrigger('beforeToggle');\r\n\r\n if (the.state == 'off') {\r\n Plugin.toggleOn();\r\n } else {\r\n Plugin.toggleOff();\r\n }\r\n\r\n Plugin.eventTrigger('afterToggle');\r\n\r\n e.preventDefault();\r\n\r\n return the;\r\n },\r\n\r\n /**\r\n * Handles toggle click toggle\r\n */\r\n toggleOn: function() {\r\n Plugin.eventTrigger('beforeOn');\r\n\r\n KUtil.addClass(the.target, the.targetState);\r\n\r\n if (the.togglerState) {\r\n KUtil.addClass(element, the.togglerState);\r\n }\r\n\r\n the.state = 'on';\r\n\r\n Plugin.eventTrigger('afterOn');\r\n\r\n Plugin.eventTrigger('toggle');\r\n\r\n return the;\r\n },\r\n\r\n /**\r\n * Handles toggle click toggle\r\n */\r\n toggleOff: function() {\r\n Plugin.eventTrigger('beforeOff');\r\n\r\n KUtil.removeClass(the.target, the.targetState);\r\n\r\n if (the.togglerState) {\r\n KUtil.removeClass(element, the.togglerState);\r\n }\r\n\r\n the.state = 'off';\r\n\r\n Plugin.eventTrigger('afterOff');\r\n\r\n Plugin.eventTrigger('toggle');\r\n\r\n return the;\r\n },\r\n\r\n /**\r\n * Trigger events\r\n */\r\n eventTrigger: function(name) {\r\n for (var i = 0; i < the.events.length; i++) {\r\n var event = the.events[i];\r\n\r\n if (event.name == name) {\r\n if (event.one == true) {\r\n if (event.fired == false) {\r\n the.events[i].fired = true; \r\n event.handler.call(this, the);\r\n }\r\n } else {\r\n event.handler.call(this, the);\r\n }\r\n }\r\n }\r\n },\r\n\r\n addEvent: function(name, handler, one) {\r\n the.events.push({\r\n name: name,\r\n handler: handler,\r\n one: one,\r\n fired: false\r\n });\r\n\r\n return the;\r\n }\r\n };\r\n\r\n //////////////////////////\r\n // ** Public Methods ** //\r\n //////////////////////////\r\n\r\n /**\r\n * Set default options \r\n */\r\n\r\n the.setDefaults = function(options) {\r\n defaultOptions = options;\r\n };\r\n\r\n /**\r\n * Get toggle state \r\n */\r\n the.getState = function() {\r\n return the.state;\r\n };\r\n\r\n /**\r\n * Toggle \r\n */\r\n the.toggle = function() {\r\n return Plugin.toggle();\r\n };\r\n\r\n /**\r\n * Toggle on \r\n */\r\n the.toggleOn = function() {\r\n return Plugin.toggleOn();\r\n };\r\n\r\n /**\r\n * Toggle off \r\n */\r\n the.toggleOff = function() {\r\n return Plugin.toggleOff();\r\n };\r\n\r\n /**\r\n * Attach event\r\n * @returns {KToggle}\r\n */\r\n the.on = function(name, handler) {\r\n return Plugin.addEvent(name, handler);\r\n };\r\n\r\n /**\r\n * Attach event that will be fired once\r\n * @returns {KToggle}\r\n */\r\n the.one = function(name, handler) {\r\n return Plugin.addEvent(name, handler, true);\r\n };\r\n\r\n // Construct plugin\r\n Plugin.construct.apply(the, [options]);\r\n\r\n return the;\r\n};\n// plugin setup\r\nvar KWizard = function(elementId, options) {\r\n // Main object\r\n var the = this;\r\n var init = false;\r\n\r\n // Get element object\r\n var element = KUtil.get(elementId);\r\n var body = KUtil.get('body');\r\n\r\n if (!element) {\r\n return; \r\n }\r\n\r\n // Default options\r\n var defaultOptions = {\r\n startStep: 1,\r\n manualStepForward: false\r\n };\r\n\r\n ////////////////////////////\r\n // ** Private Methods ** //\r\n ////////////////////////////\r\n\r\n var Plugin = {\r\n /**\r\n * Construct\r\n */\r\n\r\n construct: function(options) {\r\n if (KUtil.data(element).has('wizard')) {\r\n the = KUtil.data(element).get('wizard');\r\n } else {\r\n // reset menu\r\n Plugin.init(options);\r\n\r\n // build menu\r\n Plugin.build();\r\n\r\n KUtil.data(element).set('wizard', the);\r\n }\r\n\r\n return the;\r\n },\r\n\r\n /**\r\n * Init wizard\r\n */\r\n init: function(options) {\r\n the.element = element;\r\n the.events = [];\r\n\r\n // merge default and user defined options\r\n the.options = KUtil.deepExtend({}, defaultOptions, options);\r\n\r\n // Elements\r\n the.steps = KUtil.findAll(element, '[data-kwizard-type=\"step\"]');\r\n\r\n the.btnSubmit = KUtil.find(element, '[data-kwizard-type=\"action-submit\"]');\r\n the.btnNext = KUtil.find(element, '[data-kwizard-type=\"action-next\"]');\r\n the.btnPrev = KUtil.find(element, '[data-kwizard-type=\"action-prev\"]');\r\n the.btnLast = KUtil.find(element, '[data-kwizard-type=\"action-last\"]');\r\n the.btnFirst = KUtil.find(element, '[data-kwizard-type=\"action-first\"]');\r\n\r\n // Variables\r\n the.events = [];\r\n the.currentStep = 1;\r\n the.stopped = false;\r\n the.totalSteps = the.steps.length;\r\n\r\n // Init current step\r\n if (the.options.startStep > 1) {\r\n Plugin.goTo(the.options.startStep);\r\n }\r\n\r\n // Init UI\r\n Plugin.updateUI();\r\n },\r\n\r\n /**\r\n * Build Form Wizard\r\n */\r\n build: function() {\r\n // Next button event handler\r\n KUtil.addEvent(the.btnNext, 'click', function(e) {\r\n e.preventDefault();\r\n Plugin.goNext();\r\n });\r\n\r\n // Prev button event handler\r\n KUtil.addEvent(the.btnPrev, 'click', function(e) {\r\n e.preventDefault();\r\n Plugin.goPrev();\r\n });\r\n\r\n // First button event handler\r\n KUtil.addEvent(the.btnFirst, 'click', function(e) {\r\n e.preventDefault();\r\n Plugin.goFirst();\r\n });\r\n\r\n // Last button event handler\r\n KUtil.addEvent(the.btnLast, 'click', function(e) {\r\n e.preventDefault();\r\n Plugin.goLast();\r\n });\r\n\r\n KUtil.on(element, 'a[data-kwizard-type=\"step\"]', 'click', function() {\r\n var index = KUtil.index(this) + 1;\r\n if (index !== the.currentStep) {\r\n Plugin.goTo(index);\r\n } \r\n });\r\n },\r\n\r\n /**\r\n * Handles wizard click wizard\r\n */\r\n goTo: function(number) {\r\n // Skip if this step is already shown\r\n if (number === the.currentStep || number > the.totalSteps || number < 0) {\r\n return;\r\n }\r\n\r\n // Validate step number\r\n if (number) {\r\n number = parseInt(number);\r\n } else {\r\n number = Plugin.getNextStep();\r\n }\r\n\r\n // Before next and prev events\r\n var callback;\r\n\r\n if (number > the.currentStep) {\r\n callback = Plugin.eventTrigger('beforeNext');\r\n } else {\r\n callback = Plugin.eventTrigger('beforePrev');\r\n }\r\n \r\n // Skip if stopped\r\n if (the.stopped === true) {\r\n the.stopped = false;\r\n return;\r\n }\r\n\r\n // Continue if no exit\r\n if (callback !== false) {\r\n // Before change\r\n Plugin.eventTrigger('beforeChange');\r\n\r\n // Set current step \r\n the.currentStep = number;\r\n\r\n Plugin.updateUI();\r\n\r\n // Trigger change event\r\n Plugin.eventTrigger('change');\r\n }\r\n\r\n // After next and prev events\r\n if (number > the.startStep) {\r\n Plugin.eventTrigger('afterNext');\r\n } else {\r\n Plugin.eventTrigger('afterPrev');\r\n }\r\n\r\n return the;\r\n },\r\n\r\n /**\r\n * Cancel\r\n */\r\n stop: function() {\r\n the.stopped = true;\r\n },\r\n\r\n /**\r\n * Resume\r\n */\r\n start: function() {\r\n the.stopped = false;\r\n },\r\n\r\n /**\r\n * Check last step\r\n */\r\n isLastStep: function() {\r\n return the.currentStep === the.totalSteps;\r\n },\r\n\r\n /**\r\n * Check first step\r\n */\r\n isFirstStep: function() {\r\n return the.currentStep === 1;\r\n },\r\n\r\n /**\r\n * Check between step\r\n */\r\n isBetweenStep: function() {\r\n return Plugin.isLastStep() === false && Plugin.isFirstStep() === false;\r\n },\r\n\r\n /**\r\n * Go to the next step\r\n */\r\n goNext: function() {\r\n return Plugin.goTo(Plugin.getNextStep());\r\n },\r\n\r\n /**\r\n * Go to the prev step\r\n */\r\n goPrev: function() {\r\n return Plugin.goTo(Plugin.getPrevStep());\r\n },\r\n\r\n /**\r\n * Go to the last step\r\n */\r\n goLast: function() {\r\n return Plugin.goTo(the.totalSteps);\r\n },\r\n\r\n /**\r\n * Go to the first step\r\n */\r\n goFirst: function() {\r\n return Plugin.goTo(1);\r\n },\r\n\r\n /**\r\n * Go to the first step\r\n */\r\n updateUI: function() {\r\n var stepType = '';\r\n var index = the.currentStep - 1;\r\n\r\n if (Plugin.isLastStep()) {\r\n stepType = 'last';\r\n } else if (Plugin.isFirstStep()) {\r\n stepType = 'first';\r\n } else {\r\n stepType = 'between';\r\n }\r\n\r\n KUtil.attr(the.element, 'data-kwizard-state', stepType);\r\n\r\n // Steps\r\n var steps = KUtil.findAll(the.element, '[data-kwizard-type=\"step\"]');\r\n\r\n if (steps && steps.length > 0) {\r\n for (var i = 0, len = steps.length; i < len; i++) {\r\n if (i == index) {\r\n KUtil.attr(steps[i], 'data-kwizard-state', 'current');\r\n } else {\r\n if (i < index) {\r\n KUtil.attr(steps[i], 'data-kwizard-state', 'done');\r\n } else {\r\n KUtil.attr(steps[i], 'data-kwizard-state', 'pending');\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Steps Info\r\n var stepsInfo = KUtil.findAll(the.element, '[data-kwizard-type=\"step-info\"]');\r\n if (stepsInfo &&stepsInfo.length > 0) {\r\n for (var i = 0, len = stepsInfo.length; i < len; i++) {\r\n if (i == index) {\r\n KUtil.attr(stepsInfo[i], 'data-kwizard-state', 'current');\r\n } else {\r\n KUtil.removeAttr(stepsInfo[i], 'data-kwizard-state');\r\n }\r\n }\r\n } \r\n\r\n // Steps Content\r\n var stepsContent = KUtil.findAll(the.element, '[data-kwizard-type=\"step-content\"]');\r\n if (stepsContent&& stepsContent.length > 0) {\r\n for (var i = 0, len = stepsContent.length; i < len; i++) {\r\n if (i == index) {\r\n KUtil.attr(stepsContent[i], 'data-kwizard-state', 'current');\r\n } else {\r\n KUtil.removeAttr(stepsContent[i], 'data-kwizard-state');\r\n }\r\n }\r\n } \r\n },\r\n\r\n /**\r\n * Get next step\r\n */\r\n getNextStep: function() {\r\n if (the.totalSteps >= (the.currentStep + 1)) {\r\n return the.currentStep + 1;\r\n } else {\r\n return the.totalSteps;\r\n }\r\n },\r\n\r\n /**\r\n * Get prev step\r\n */\r\n getPrevStep: function() {\r\n if ((the.currentStep - 1) >= 1) {\r\n return the.currentStep - 1;\r\n } else {\r\n return 1;\r\n }\r\n },\r\n\r\n /**\r\n * Trigger events\r\n */\r\n eventTrigger: function(name) {\r\n //KUtil.triggerCustomEvent(name);\r\n for (var i = 0; i < the.events.length; i++) {\r\n var event = the.events[i];\r\n if (event.name == name) {\r\n if (event.one == true) {\r\n if (event.fired == false) {\r\n the.events[i].fired = true;\r\n event.handler.call(this, the);\r\n }\r\n } else {\r\n event.handler.call(this, the);\r\n }\r\n }\r\n }\r\n },\r\n\r\n addEvent: function(name, handler, one) {\r\n the.events.push({\r\n name: name,\r\n handler: handler,\r\n one: one,\r\n fired: false\r\n });\r\n\r\n return the;\r\n }\r\n };\r\n\r\n //////////////////////////\r\n // ** Public Methods ** //\r\n //////////////////////////\r\n\r\n /**\r\n * Set default options \r\n */\r\n\r\n the.setDefaults = function(options) {\r\n defaultOptions = options;\r\n };\r\n\r\n /**\r\n * Go to the next step \r\n */\r\n the.goNext = function() {\r\n return Plugin.goNext();\r\n };\r\n\r\n /**\r\n * Go to the prev step \r\n */\r\n the.goPrev = function() {\r\n return Plugin.goPrev();\r\n };\r\n\r\n /**\r\n * Go to the last step \r\n */\r\n the.goLast = function() {\r\n return Plugin.goLast();\r\n };\r\n\r\n /**\r\n * Cancel step \r\n */\r\n the.stop = function() {\r\n return Plugin.stop();\r\n };\r\n\r\n /**\r\n * Resume step \r\n */\r\n the.start = function() {\r\n return Plugin.start();\r\n };\r\n\r\n /**\r\n * Go to the first step \r\n */\r\n the.goFirst = function() {\r\n return Plugin.goFirst();\r\n };\r\n\r\n /**\r\n * Go to a step\r\n */\r\n the.goTo = function(number) {\r\n return Plugin.goTo(number);\r\n };\r\n\r\n /**\r\n * Get current step number \r\n */\r\n the.getStep = function() {\r\n return the.currentStep;\r\n };\r\n\r\n /**\r\n * Check last step \r\n */\r\n the.isLastStep = function() {\r\n return Plugin.isLastStep();\r\n };\r\n\r\n /**\r\n * Check first step \r\n */\r\n the.isFirstStep = function() {\r\n return Plugin.isFirstStep();\r\n };\r\n \r\n /**\r\n * Attach event\r\n */\r\n the.on = function(name, handler) {\r\n return Plugin.addEvent(name, handler);\r\n };\r\n\r\n /**\r\n * Attach event that will be fired once\r\n */\r\n the.one = function(name, handler) {\r\n return Plugin.addEvent(name, handler, true);\r\n };\r\n\r\n // Construct plugin\r\n Plugin.construct.apply(the, [options]);\r\n\r\n return the;\r\n};\n// plugin setup\r\nvar KAvatar = function(elementId, options) {\r\n // Main object\r\n var the = this;\r\n var init = false;\r\n\r\n // Get element object\r\n var element = KUtil.get(elementId);\r\n var body = KUtil.get('body');\r\n\r\n if (!element) {\r\n return; \r\n }\r\n\r\n // Default options\r\n var defaultOptions = {\r\n };\r\n\r\n ////////////////////////////\r\n // ** Private Methods ** //\r\n ////////////////////////////\r\n\r\n var Plugin = {\r\n /**\r\n * Construct\r\n */\r\n\r\n construct: function(options) {\r\n if (KUtil.data(element).has('avatar')) {\r\n the = KUtil.data(element).get('avatar');\r\n } else {\r\n // reset menu\r\n Plugin.init(options);\r\n\r\n // build menu\r\n Plugin.build();\r\n\r\n KUtil.data(element).set('avatar', the);\r\n }\r\n\r\n return the;\r\n },\r\n\r\n /**\r\n * Init avatar\r\n */\r\n init: function(options) {\r\n the.element = element;\r\n the.events = [];\r\n\r\n the.input = KUtil.find(element, 'input[type=\"file\"]');\r\n the.holder = KUtil.find(element, '.k-avatar__holder');\r\n the.cancel = KUtil.find(element, '.k-avatar__cancel');\r\n the.src = KUtil.css(the.holder, 'backgroundImage');\r\n\r\n // merge default and user defined options\r\n the.options = KUtil.deepExtend({}, defaultOptions, options);\r\n },\r\n\r\n /**\r\n * Build Form Wizard\r\n */\r\n build: function() {\r\n // Handle avatar change\r\n KUtil.addEvent(the.input, 'change', function(e) {\r\n e.preventDefault();\r\n\r\n\t if (the.input && the.input.files && the.input.files[0]) {\r\n\t var reader = new FileReader();\r\n\t reader.onload = function(e) {\r\n\t KUtil.css(the.holder, 'background-image', 'url('+e.target.result +')');\r\n\t }\r\n\t reader.readAsDataURL(the.input.files[0]);\r\n\r\n\t KUtil.addClass(the.element, 'k-avatar--changed');\r\n\t }\r\n });\r\n\r\n // Handle avatar cancel\r\n KUtil.addEvent(the.cancel, 'click', function(e) {\r\n e.preventDefault();\r\n\r\n\t KUtil.removeClass(the.element, 'k-avatar--changed');\r\n\t KUtil.css(the.holder, 'background-image', the.src);\r\n\t the.input.value = \"\";\r\n });\r\n },\r\n\r\n /**\r\n * Trigger events\r\n */\r\n eventTrigger: function(name) {\r\n //KUtil.triggerCustomEvent(name);\r\n for (var i = 0; i < the.events.length; i++) {\r\n var event = the.events[i];\r\n if (event.name == name) {\r\n if (event.one == true) {\r\n if (event.fired == false) {\r\n the.events[i].fired = true;\r\n event.handler.call(this, the);\r\n }\r\n } else {\r\n event.handler.call(this, the);\r\n }\r\n }\r\n }\r\n },\r\n\r\n addEvent: function(name, handler, one) {\r\n the.events.push({\r\n name: name,\r\n handler: handler,\r\n one: one,\r\n fired: false\r\n });\r\n\r\n return the;\r\n }\r\n };\r\n\r\n //////////////////////////\r\n // ** Public Methods ** //\r\n //////////////////////////\r\n\r\n /**\r\n * Set default options \r\n */\r\n\r\n the.setDefaults = function(options) {\r\n defaultOptions = options;\r\n };\r\n \r\n /**\r\n * Attach event\r\n */\r\n the.on = function(name, handler) {\r\n return Plugin.addEvent(name, handler);\r\n };\r\n\r\n /**\r\n * Attach event that will be fired once\r\n */\r\n the.one = function(name, handler) {\r\n return Plugin.addEvent(name, handler, true);\r\n };\r\n\r\n // Construct plugin\r\n Plugin.construct.apply(the, [options]);\r\n\r\n return the;\r\n};\n\"use strict\";\r\nvar KLayout = function() {\r\n var body;\r\n\r\n var header;\r\n var headerMenu;\r\n var headerMenuOffcanvas;\r\n\r\n var asideMenu;\r\n var asideMenuOffcanvas;\r\n var asideToggler;\r\n\r\n var scrollTop;\r\n\r\n var pageStickyPortlet;\r\n\r\n // Header\r\n var initHeader = function() {\r\n var tmp;\r\n var headerEl = KUtil.get('k_header');\r\n var options = {\r\n offset: {},\r\n minimize: {}\r\n };\r\n\r\n if (KUtil.attr(headerEl, 'data-kheader-minimize-mobile') == 'hide') {\r\n options.minimize.mobile = {};\r\n options.minimize.mobile.on = 'k-header--hide';\r\n options.minimize.mobile.off = 'k-header--show';\r\n } else {\r\n options.minimize.mobile = false;\r\n }\r\n\r\n if (KUtil.attr(headerEl, 'data-kheader-minimize') == 'hide') {\r\n options.minimize.desktop = {};\r\n options.minimize.desktop.on = 'k-header--hide';\r\n options.minimize.desktop.off = 'k-header--show';\r\n } else {\r\n options.minimize.desktop = false;\r\n }\r\n\r\n if (tmp = KUtil.attr(headerEl, 'data-kheader-minimize-offset')) {\r\n options.offset.desktop = tmp;\r\n }\r\n\r\n if (tmp = KUtil.attr(headerEl, 'data-kheader-minimize-mobile-offset')) {\r\n options.offset.mobile = tmp;\r\n }\r\n\r\n header = new KHeader('k_header', options);\r\n }\r\n\r\n // Header Menu\r\n var initHeaderMenu = function() {\r\n // init aside left offcanvas\r\n headerMenuOffcanvas = new KOffcanvas('k_header_menu_wrapper', {\r\n overlay: true,\r\n baseClass: 'k-header-menu-wrapper',\r\n closeBy: 'k_header_menu_mobile_close_btn',\r\n toggleBy: {\r\n target: 'k_header_mobile_toggler',\r\n state: 'k-header-mobile__toolbar-toggler--active'\r\n }\r\n });\r\n\r\n headerMenu = new KMenu('k_header_menu', {\r\n submenu: {\r\n desktop: 'dropdown',\r\n tablet: 'accordion',\r\n mobile: 'accordion'\r\n },\r\n accordion: {\r\n slideSpeed: 200, // accordion toggle slide speed in milliseconds\r\n expandAll: false // allow having multiple expanded accordions in the menu\r\n }\r\n });\r\n }\r\n\r\n // Header Topbar\r\n var initHeaderTopbar = function() {\r\n asideToggler = new KToggle('k_header_mobile_topbar_toggler', {\r\n target: 'body',\r\n targetState: 'k-header__topbar--mobile-on',\r\n togglerState: 'k-header-mobile__toolbar-topbar-toggler--active'\r\n });\r\n }\r\n\r\n // Aside\r\n var initAside = function() {\r\n // init aside left offcanvas\r\n var asidBrandHover = false;\r\n var aside = KUtil.get('k_aside');\r\n var asideBrand = KUtil.get('k_aside_brand');\r\n var asideOffcanvasClass = KUtil.hasClass(aside, 'k-aside--offcanvas-default') ? 'k-aside--offcanvas-default' : 'k-aside';\r\n\r\n asideMenuOffcanvas = new KOffcanvas('k_aside', {\r\n baseClass: asideOffcanvasClass,\r\n overlay: true,\r\n closeBy: 'k_aside_close',\r\n toggleBy: {\r\n target: 'k_aside_toggler',\r\n state: 'k-subheader__toggler--active'\r\n }\r\n });\r\n\r\n \r\n }\r\n\r\n // Aside menu\r\n var initAsideMenu = function() {\r\n // Init aside menu\r\n var aside = KUtil.get('k_aside');\r\n var menu = KUtil.get('k_aside_menu');\r\n var menuDesktopMode = (KUtil.attr(menu, 'data-kmenu-dropdown') === '1' ? 'dropdown' : 'accordion');\r\n\r\n var scroll;\r\n if (KUtil.attr(menu, 'data-kmenu-scroll') === '1') {\r\n scroll = {\r\n height: function() {\r\n var height;\r\n \r\n height = parseInt(KUtil.getViewPort().height);\r\n\r\n var head = KUtil.find(aside, '.k-aside__head');\r\n\r\n if (head) {\r\n height = height - parseInt(KUtil.actualHeight(head));\r\n height = height - parseInt(KUtil.css(head, 'marginBottom'));\r\n }\r\n\r\n height = height - (parseInt(KUtil.css(menu, 'marginBottom')) + parseInt(KUtil.css(menu, 'marginTop')));\r\n height = height - (parseInt(KUtil.css(aside, 'paddingBottom')) + parseInt(KUtil.css(aside, 'paddingTop'))); \r\n\r\n return height;\r\n }\r\n };\r\n }\r\n\r\n asideMenu = new KMenu('k_aside_menu', {\r\n // vertical scroll\r\n scroll: scroll,\r\n\r\n // submenu setup\r\n submenu: {\r\n desktop: 'accordion', // menu set to accordion in tablet mode\r\n tablet: 'accordion', // menu set to accordion in tablet mode\r\n mobile: 'accordion' // menu set to accordion in mobile mode\r\n },\r\n\r\n //accordion setup\r\n accordion: {\r\n expandAll: false // allow having multiple expanded accordions in the menu\r\n }\r\n });\r\n }\r\n\r\n // Scrolltop\r\n var initScrolltop = function() {\r\n var scrolltop = new KScrolltop('k_scrolltop', {\r\n offset: 300,\r\n speed: 600\r\n });\r\n }\r\n\r\n // Init page sticky portlet\r\n var initPageStickyPortlet = function() {\r\n return new KPortlet('k_page_portlet', {\r\n sticky: {\r\n offset: parseInt(KUtil.css( KUtil.get('k_header'), 'height')),\r\n zIndex: 90,\r\n position: {\r\n top: function() {\r\n var h = 0;\r\n\r\n if (KUtil.isInResponsiveRange('desktop')) {\r\n if (KUtil.hasClass(body, 'k-header--fixed')) {\r\n h = h + parseInt(KUtil.css( KUtil.get('k_header'), 'height') );\r\n }\r\n } else {\r\n if (KUtil.hasClass(body, 'k-header-mobile--fixed')) {\r\n h = h + parseInt(KUtil.css( KUtil.get('k_header_mobile'), 'height') );\r\n }\r\n } \r\n \r\n return h; \r\n },\r\n left: function() {\r\n if (KUtil.isInResponsiveRange('tablet-and-mobile')) { \r\n return parseInt(KUtil.css( KUtil.get('k_content'), 'paddingLeft')); \r\n }\r\n\r\n return;\r\n },\r\n right: function() {\r\n if (KUtil.isInResponsiveRange('tablet-and-mobile')) { \r\n return parseInt(KUtil.css( KUtil.get('k_content'), 'paddingRight')); \r\n }\r\n\r\n return;\r\n }\r\n }\r\n }\r\n });\r\n }\r\n\r\n return {\r\n init: function() {\r\n body = KUtil.get('body');\r\n\r\n this.initHeader();\r\n this.initAside();\r\n this.initPageStickyPortlet();\r\n\r\n // Non functional links notice(can be removed in production)\r\n $('#k_aside_menu, #k_header_menu').on('click', '.k-menu__link[href=\"#\"]', function(e) {\r\n swal(\"\", \"You have clicked on a non-functional dummy link!\");\r\n\r\n e.preventDefault();\r\n });\r\n },\r\n\r\n initHeader: function() {\r\n initHeader();\r\n initHeaderMenu();\r\n initHeaderTopbar();\r\n initScrolltop();\r\n },\r\n\r\n initAside: function() { \r\n initAside();\r\n // initAsideMenu();\r\n \r\n this.onAsideToggle(function(e) {\r\n // Update sticky portlet\r\n if (pageStickyPortlet) {\r\n pageStickyPortlet.updateSticky();\r\n }\r\n\r\n // Reload datatable\r\n var datatables = $('.k-datatable');\r\n if (datatables) {\r\n datatables.each(function() {\r\n $(this).KDatatable('redraw');\r\n });\r\n } \r\n });\r\n },\r\n\r\n initPageStickyPortlet: function() {\r\n if (!KUtil.get('k_page_portlet')) {\r\n return;\r\n }\r\n \r\n pageStickyPortlet = initPageStickyPortlet();\r\n pageStickyPortlet.initSticky();\r\n \r\n KUtil.addResizeHandler(function(){\r\n pageStickyPortlet.updateSticky();\r\n });\r\n\r\n initPageStickyPortlet();\r\n },\r\n\r\n getAsideMenu: function() {\r\n return asideMenu;\r\n },\r\n\r\n onAsideToggle: function(handler) {\r\n if (typeof asideToggler.element !== 'undefined') {\r\n asideToggler.on('toggle', handler);\r\n }\r\n },\r\n\r\n getAsideToggler: function() {\r\n return asideToggler;\r\n },\r\n \r\n closeMobileAsideMenuOffcanvas: function() {\r\n if (KUtil.isMobileDevice()) {\r\n asideMenuOffcanvas.hide();\r\n }\r\n },\r\n\r\n closeMobileHeaderMenuOffcanvas: function() {\r\n if (KUtil.isMobileDevice()) {\r\n headerMenuOffcanvas.hide();\r\n }\r\n }\r\n };\r\n}();\r\n\r\n$(document).ready(function() {\r\n KLayout.init();\r\n});"],"file":"scripts.bundle.js"}