10767 lines
315 KiB
JavaScript
10767 lines
315 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
// Component Definition
|
||
|
var KTApp = function() {
|
||
|
/** @type {object} colors State colors **/
|
||
|
var settings = {};
|
||
|
|
||
|
var initTooltip = function(el) {
|
||
|
var theme = el.data('theme') ? 'tooltip-' + el.data('theme') : '';
|
||
|
var width = el.data('width') == 'auto' ? 'tooltop-auto-width' : '';
|
||
|
var trigger = el.data('trigger') ? el.data('trigger') : 'hover';
|
||
|
|
||
|
$(el).tooltip({
|
||
|
trigger: trigger,
|
||
|
template: '<div class="tooltip ' + theme + ' ' + width + '" role="tooltip">\
|
||
|
<div class="arrow"></div>\
|
||
|
<div class="tooltip-inner"></div>\
|
||
|
</div>'
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var initTooltips = function() {
|
||
|
// init bootstrap tooltips
|
||
|
$('[data-toggle="tooltip"]').each(function() {
|
||
|
initTooltip($(this));
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var initPopover = function(el) {
|
||
|
var skin = el.data('skin') ? 'popover-' + el.data('skin') : '';
|
||
|
var triggerValue = el.data('trigger') ? el.data('trigger') : 'hover';
|
||
|
|
||
|
el.popover({
|
||
|
trigger: triggerValue,
|
||
|
template: '\
|
||
|
<div class="popover ' + skin + '" role="tooltip">\
|
||
|
<div class="arrow"></div>\
|
||
|
<h3 class="popover-header"></h3>\
|
||
|
<div class="popover-body"></div>\
|
||
|
</div>'
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var initPopovers = function() {
|
||
|
// init bootstrap popover
|
||
|
$('[data-toggle="popover"]').each(function() {
|
||
|
initPopover($(this));
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var initFileInput = function() {
|
||
|
// init bootstrap popover
|
||
|
$('.custom-file-input').on('change', function() {
|
||
|
var fileName = $(this).val();
|
||
|
$(this).next('.custom-file-label').addClass("selected").html(fileName);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var initScroll = function() {
|
||
|
$('[data-scroll="true"]').each(function() {
|
||
|
var el = $(this);
|
||
|
|
||
|
KTUtil.scrollInit(this, {
|
||
|
mobileNativeScroll: true,
|
||
|
handleWindowResize: true,
|
||
|
rememberPosition: (el.data('remember-position') == 'true' ? true : false),
|
||
|
height: function() {
|
||
|
if (KTUtil.isBreakpointDown('lg') && el.data('mobile-height')) {
|
||
|
return el.data('mobile-height');
|
||
|
} else {
|
||
|
return el.data('height');
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var initAlerts = function() {
|
||
|
// init bootstrap popover
|
||
|
$('body').on('click', '[data-close=alert]', function() {
|
||
|
$(this).closest('.alert').hide();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var initCard = function(el, options) {
|
||
|
// init card tools
|
||
|
var el = $(el);
|
||
|
var card = new KTCard(el[0], options);
|
||
|
}
|
||
|
|
||
|
var initCards = function() {
|
||
|
// init card tools
|
||
|
$('[data-card="true"]').each(function() {
|
||
|
var el = $(this);
|
||
|
var options = {};
|
||
|
|
||
|
if (el.data('data-card-initialized') !== true) {
|
||
|
initCard(el, options);
|
||
|
el.data('data-card-initialized', true);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var initStickyCard = function() {
|
||
|
if (typeof Sticky === 'undefined') {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var sticky = new Sticky('[data-sticky="true"]');
|
||
|
}
|
||
|
|
||
|
var initAbsoluteDropdown = function(context) {
|
||
|
var dropdownMenu;
|
||
|
|
||
|
if (!context) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
$('body').on('show.bs.dropdown', context, function(e) {
|
||
|
dropdownMenu = $(e.target).find('.dropdown-menu');
|
||
|
$('body').append(dropdownMenu.detach());
|
||
|
dropdownMenu.css('display', 'block');
|
||
|
dropdownMenu.position({
|
||
|
'my': 'right top',
|
||
|
'at': 'right bottom',
|
||
|
'of': $(e.relatedTarget),
|
||
|
});
|
||
|
}).on('hide.bs.dropdown', context, function(e) {
|
||
|
$(e.target).append(dropdownMenu.detach());
|
||
|
dropdownMenu.hide();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var initAbsoluteDropdowns = function() {
|
||
|
$('body').on('show.bs.dropdown', function(e) {
|
||
|
// e.target is always parent (contains toggler and menu)
|
||
|
var $toggler = $(e.target).find("[data-attach='body']");
|
||
|
if ($toggler.length === 0) {
|
||
|
return;
|
||
|
}
|
||
|
var $dropdownMenu = $(e.target).find('.dropdown-menu');
|
||
|
// save detached menu
|
||
|
var $detachedDropdownMenu = $dropdownMenu.detach();
|
||
|
// save reference to detached menu inside data of toggler
|
||
|
$toggler.data('dropdown-menu', $detachedDropdownMenu);
|
||
|
|
||
|
$('body').append($detachedDropdownMenu);
|
||
|
$detachedDropdownMenu.css('display', 'block');
|
||
|
$detachedDropdownMenu.position({
|
||
|
my: 'right top',
|
||
|
at: 'right bottom',
|
||
|
of: $(e.relatedTarget),
|
||
|
});
|
||
|
});
|
||
|
|
||
|
$('body').on('hide.bs.dropdown', function(e) {
|
||
|
var $toggler = $(e.target).find("[data-attach='body']");
|
||
|
if ($toggler.length === 0) {
|
||
|
return;
|
||
|
}
|
||
|
// access to reference of detached menu from data of toggler
|
||
|
var $detachedDropdownMenu = $toggler.data('dropdown-menu');
|
||
|
// re-append detached menu inside parent
|
||
|
$(e.target).append($detachedDropdownMenu.detach());
|
||
|
// hide dropdown
|
||
|
$detachedDropdownMenu.hide();
|
||
|
});
|
||
|
};
|
||
|
|
||
|
return {
|
||
|
init: function(settingsArray) {
|
||
|
if (settingsArray) {
|
||
|
settings = settingsArray;
|
||
|
}
|
||
|
|
||
|
KTApp.initComponents();
|
||
|
},
|
||
|
|
||
|
initComponents: function() {
|
||
|
initScroll();
|
||
|
initTooltips();
|
||
|
initPopovers();
|
||
|
initAlerts();
|
||
|
initFileInput();
|
||
|
initCards();
|
||
|
initStickyCard();
|
||
|
initAbsoluteDropdowns();
|
||
|
},
|
||
|
|
||
|
initTooltips: function() {
|
||
|
initTooltips();
|
||
|
},
|
||
|
|
||
|
initTooltip: function(el) {
|
||
|
initTooltip(el);
|
||
|
},
|
||
|
|
||
|
initPopovers: function() {
|
||
|
initPopovers();
|
||
|
},
|
||
|
|
||
|
initPopover: function(el) {
|
||
|
initPopover(el);
|
||
|
},
|
||
|
|
||
|
initCard: function(el, options) {
|
||
|
initCard(el, options);
|
||
|
},
|
||
|
|
||
|
initCards: function() {
|
||
|
initCards();
|
||
|
},
|
||
|
|
||
|
initSticky: function() {
|
||
|
initSticky();
|
||
|
},
|
||
|
|
||
|
initAbsoluteDropdown: function(context) {
|
||
|
initAbsoluteDropdown(context);
|
||
|
},
|
||
|
|
||
|
block: function(target, options) {
|
||
|
var el = $(target);
|
||
|
|
||
|
options = $.extend(true, {
|
||
|
opacity: 0.05,
|
||
|
overlayColor: '#000000',
|
||
|
type: '',
|
||
|
size: '',
|
||
|
state: 'primary',
|
||
|
centerX: true,
|
||
|
centerY: true,
|
||
|
message: '',
|
||
|
shadow: true,
|
||
|
width: 'auto'
|
||
|
}, options);
|
||
|
|
||
|
var html;
|
||
|
var version = options.type ? 'spinner-' + options.type : '';
|
||
|
var state = options.state ? 'spinner-' + options.state : '';
|
||
|
var size = options.size ? 'spinner-' + options.size : '';
|
||
|
var spinner = '<span class="spinner ' + version + ' ' + state + ' ' + size + '"></span';
|
||
|
|
||
|
if (options.message && options.message.length > 0) {
|
||
|
var classes = 'blockui ' + (options.shadow === false ? 'blockui' : '');
|
||
|
|
||
|
html = '<div class="' + classes + '"><span>' + options.message + '</span>' + spinner + '</div>';
|
||
|
|
||
|
var el = document.createElement('div');
|
||
|
|
||
|
$('body').prepend(el);
|
||
|
KTUtil.addClass(el, classes);
|
||
|
el.innerHTML = html;
|
||
|
options.width = KTUtil.actualWidth(el) + 10;
|
||
|
KTUtil.remove(el);
|
||
|
|
||
|
if (target == 'body') {
|
||
|
html = '<div class="' + classes + '" style="margin-left:-' + (options.width / 2) + 'px;"><span>' + options.message + '</span><span>' + spinner + '</span></div>';
|
||
|
}
|
||
|
} else {
|
||
|
html = spinner;
|
||
|
}
|
||
|
|
||
|
var params = {
|
||
|
message: html,
|
||
|
centerY: options.centerY,
|
||
|
centerX: options.centerX,
|
||
|
css: {
|
||
|
top: '30%',
|
||
|
left: '50%',
|
||
|
border: '0',
|
||
|
padding: '0',
|
||
|
backgroundColor: 'none',
|
||
|
width: options.width
|
||
|
},
|
||
|
overlayCSS: {
|
||
|
backgroundColor: options.overlayColor,
|
||
|
opacity: options.opacity,
|
||
|
cursor: 'wait',
|
||
|
zIndex: (target == 'body' ? 1100 : 10)
|
||
|
},
|
||
|
onUnblock: function() {
|
||
|
if (el && el[0]) {
|
||
|
KTUtil.css(el[0], 'position', '');
|
||
|
KTUtil.css(el[0], 'zoom', '');
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
if (target == 'body') {
|
||
|
params.css.top = '50%';
|
||
|
$.blockUI(params);
|
||
|
} else {
|
||
|
var el = $(target);
|
||
|
el.block(params);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
unblock: function(target) {
|
||
|
if (target && target != 'body') {
|
||
|
$(target).unblock();
|
||
|
} else {
|
||
|
$.unblockUI();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
blockPage: function(options) {
|
||
|
return KTApp.block('body', options);
|
||
|
},
|
||
|
|
||
|
unblockPage: function() {
|
||
|
return KTApp.unblock('body');
|
||
|
},
|
||
|
|
||
|
getSettings: function() {
|
||
|
return settings;
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// webpack support
|
||
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||
|
module.exports = KTApp;
|
||
|
}
|
||
|
|
||
|
// Initialize KTApp class on document ready
|
||
|
$(document).ready(function() {
|
||
|
KTApp.init(KTAppSettings);
|
||
|
});
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
// Component Definition
|
||
|
var KTCard = function(elementId, options) {
|
||
|
// Main object
|
||
|
var the = this;
|
||
|
var init = false;
|
||
|
|
||
|
// Get element object
|
||
|
var element = KTUtil.getById(elementId);
|
||
|
var body = KTUtil.getBody();
|
||
|
|
||
|
if (!element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Default options
|
||
|
var defaultOptions = {
|
||
|
toggleSpeed: 400,
|
||
|
sticky: {
|
||
|
releseOnReverse: false,
|
||
|
offset: 300,
|
||
|
zIndex: 101
|
||
|
}
|
||
|
};
|
||
|
|
||
|
////////////////////////////
|
||
|
// ** Private Methods ** //
|
||
|
////////////////////////////
|
||
|
|
||
|
var Plugin = {
|
||
|
/**
|
||
|
* Construct
|
||
|
*/
|
||
|
|
||
|
construct: function(options) {
|
||
|
if (KTUtil.data(element).has('card')) {
|
||
|
the = KTUtil.data(element).get('card');
|
||
|
} else {
|
||
|
// reset menu
|
||
|
Plugin.init(options);
|
||
|
|
||
|
// build menu
|
||
|
Plugin.build();
|
||
|
|
||
|
KTUtil.data(element).set('card', the);
|
||
|
}
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Init card
|
||
|
*/
|
||
|
init: function(options) {
|
||
|
the.element = element;
|
||
|
the.events = [];
|
||
|
|
||
|
// merge default and user defined options
|
||
|
the.options = KTUtil.deepExtend({}, defaultOptions, options);
|
||
|
the.header = KTUtil.child(element, '.card-header');
|
||
|
the.footer = KTUtil.child(element, '.card-footer');
|
||
|
|
||
|
if (KTUtil.child(element, '.card-body')) {
|
||
|
the.body = KTUtil.child(element, '.card-body');
|
||
|
} else if (KTUtil.child(element, '.form')) {
|
||
|
the.body = KTUtil.child(element, '.form');
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Build Form Wizard
|
||
|
*/
|
||
|
build: function() {
|
||
|
// Remove
|
||
|
var remove = KTUtil.find(the.header, '[data-card-tool=remove]');
|
||
|
if (remove) {
|
||
|
KTUtil.addEvent(remove, 'click', function(e) {
|
||
|
e.preventDefault();
|
||
|
Plugin.remove();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Reload
|
||
|
var reload = KTUtil.find(the.header, '[data-card-tool=reload]');
|
||
|
if (reload) {
|
||
|
KTUtil.addEvent(reload, 'click', function(e) {
|
||
|
e.preventDefault();
|
||
|
Plugin.reload();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Toggle
|
||
|
var toggle = KTUtil.find(the.header, '[data-card-tool=toggle]');
|
||
|
if (toggle) {
|
||
|
KTUtil.addEvent(toggle, 'click', function(e) {
|
||
|
e.preventDefault();
|
||
|
Plugin.toggle();
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Enable stickt mode
|
||
|
*/
|
||
|
initSticky: function() {
|
||
|
var lastScrollTop = 0;
|
||
|
var offset = the.options.sticky.offset;
|
||
|
|
||
|
if (!the.header) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
window.addEventListener('scroll', Plugin.onScrollSticky);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Window scroll handle event for sticky card
|
||
|
*/
|
||
|
onScrollSticky: function(e) {
|
||
|
var offset = the.options.sticky.offset;
|
||
|
|
||
|
if(isNaN(offset)) return;
|
||
|
|
||
|
var st = KTUtil.getScrollTop();
|
||
|
|
||
|
if (st >= offset && KTUtil.hasClass(body, 'card-sticky-on') === false) {
|
||
|
Plugin.eventTrigger('stickyOn');
|
||
|
|
||
|
KTUtil.addClass(body, 'card-sticky-on');
|
||
|
|
||
|
Plugin.updateSticky();
|
||
|
|
||
|
} else if ((st*1.5) <= offset && KTUtil.hasClass(body, 'card-sticky-on')) {
|
||
|
// Back scroll mode
|
||
|
Plugin.eventTrigger('stickyOff');
|
||
|
|
||
|
KTUtil.removeClass(body, 'card-sticky-on');
|
||
|
|
||
|
Plugin.resetSticky();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
updateSticky: function() {
|
||
|
if (!the.header) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var top;
|
||
|
|
||
|
if (KTUtil.hasClass(body, 'card-sticky-on')) {
|
||
|
if (the.options.sticky.position.top instanceof Function) {
|
||
|
top = parseInt(the.options.sticky.position.top.call(this, the));
|
||
|
} else {
|
||
|
top = parseInt(the.options.sticky.position.top);
|
||
|
}
|
||
|
|
||
|
var left;
|
||
|
if (the.options.sticky.position.left instanceof Function) {
|
||
|
left = parseInt(the.options.sticky.position.left.call(this, the));
|
||
|
} else {
|
||
|
left = parseInt(the.options.sticky.position.left);
|
||
|
}
|
||
|
|
||
|
var right;
|
||
|
if (the.options.sticky.position.right instanceof Function) {
|
||
|
right = parseInt(the.options.sticky.position.right.call(this, the));
|
||
|
} else {
|
||
|
right = parseInt(the.options.sticky.position.right);
|
||
|
}
|
||
|
|
||
|
KTUtil.css(the.header, 'z-index', the.options.sticky.zIndex);
|
||
|
KTUtil.css(the.header, 'top', top + 'px');
|
||
|
KTUtil.css(the.header, 'left', left + 'px');
|
||
|
KTUtil.css(the.header, 'right', right + 'px');
|
||
|
}
|
||
|
},
|
||
|
|
||
|
resetSticky: function() {
|
||
|
if (!the.header) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (KTUtil.hasClass(body, 'card-sticky-on') === false) {
|
||
|
KTUtil.css(the.header, 'z-index', '');
|
||
|
KTUtil.css(the.header, 'top', '');
|
||
|
KTUtil.css(the.header, 'left', '');
|
||
|
KTUtil.css(the.header, 'right', '');
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Remove card
|
||
|
*/
|
||
|
remove: function() {
|
||
|
if (Plugin.eventTrigger('beforeRemove') === false) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
KTUtil.remove(element);
|
||
|
|
||
|
Plugin.eventTrigger('afterRemove');
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Set content
|
||
|
*/
|
||
|
setContent: function(html) {
|
||
|
if (html) {
|
||
|
the.body.innerHTML = html;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get body
|
||
|
*/
|
||
|
getBody: function() {
|
||
|
return the.body;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get self
|
||
|
*/
|
||
|
getSelf: function() {
|
||
|
return element;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Reload
|
||
|
*/
|
||
|
reload: function() {
|
||
|
Plugin.eventTrigger('reload');
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Toggle
|
||
|
*/
|
||
|
toggle: function() {
|
||
|
if (KTUtil.hasClass(element, 'card-collapse') || KTUtil.hasClass(element, 'card-collapsed')) {
|
||
|
Plugin.expand();
|
||
|
} else {
|
||
|
Plugin.collapse();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Collapse
|
||
|
*/
|
||
|
collapse: function() {
|
||
|
if (Plugin.eventTrigger('beforeCollapse') === false) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
KTUtil.slideUp(the.body, the.options.toggleSpeed, function() {
|
||
|
Plugin.eventTrigger('afterCollapse');
|
||
|
});
|
||
|
|
||
|
KTUtil.addClass(element, 'card-collapse');
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Expand
|
||
|
*/
|
||
|
expand: function() {
|
||
|
if (Plugin.eventTrigger('beforeExpand') === false) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
KTUtil.slideDown(the.body, the.options.toggleSpeed, function() {
|
||
|
Plugin.eventTrigger('afterExpand');
|
||
|
});
|
||
|
|
||
|
KTUtil.removeClass(element, 'card-collapse');
|
||
|
KTUtil.removeClass(element, 'card-collapsed');
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Trigger events
|
||
|
*/
|
||
|
eventTrigger: function(name) {
|
||
|
//KTUtil.triggerCustomEvent(name);
|
||
|
for (var i = 0; i < the.events.length; i++) {
|
||
|
var event = the.events[i];
|
||
|
if (event.name == name) {
|
||
|
if (event.one == true) {
|
||
|
if (event.fired == false) {
|
||
|
the.events[i].fired = true;
|
||
|
return event.handler.call(this, the);
|
||
|
}
|
||
|
} else {
|
||
|
return event.handler.call(this, the);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
addEvent: function(name, handler, one) {
|
||
|
the.events.push({
|
||
|
name: name,
|
||
|
handler: handler,
|
||
|
one: one,
|
||
|
fired: false
|
||
|
});
|
||
|
|
||
|
return the;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//////////////////////////
|
||
|
// ** Public Methods ** //
|
||
|
//////////////////////////
|
||
|
|
||
|
/**
|
||
|
* Set default options
|
||
|
*/
|
||
|
|
||
|
the.setDefaults = function(options) {
|
||
|
defaultOptions = options;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Remove card
|
||
|
*/
|
||
|
the.remove = function() {
|
||
|
return Plugin.remove(html);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Init sticky card
|
||
|
*/
|
||
|
the.initSticky = function() {
|
||
|
return Plugin.initSticky();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Rerender sticky layout
|
||
|
*/
|
||
|
the.updateSticky = function() {
|
||
|
return Plugin.updateSticky();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Reset the sticky
|
||
|
*/
|
||
|
the.resetSticky = function() {
|
||
|
return Plugin.resetSticky();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Destroy sticky card
|
||
|
*/
|
||
|
the.destroySticky = function() {
|
||
|
Plugin.resetSticky();
|
||
|
window.removeEventListener('scroll', Plugin.onScrollSticky);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Reload card
|
||
|
*/
|
||
|
the.reload = function() {
|
||
|
return Plugin.reload();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Set card content
|
||
|
*/
|
||
|
the.setContent = function(html) {
|
||
|
return Plugin.setContent(html);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Toggle card
|
||
|
*/
|
||
|
the.toggle = function() {
|
||
|
return Plugin.toggle();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Collapse card
|
||
|
*/
|
||
|
the.collapse = function() {
|
||
|
return Plugin.collapse();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Expand card
|
||
|
*/
|
||
|
the.expand = function() {
|
||
|
return Plugin.expand();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Get cardbody
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
the.getBody = function() {
|
||
|
return Plugin.getBody();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Get cardbody
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
the.getSelf = function() {
|
||
|
return Plugin.getSelf();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Attach event
|
||
|
*/
|
||
|
the.on = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Attach event that will be fired once
|
||
|
*/
|
||
|
the.one = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler, true);
|
||
|
};
|
||
|
|
||
|
// Construct plugin
|
||
|
Plugin.construct.apply(the, [options]);
|
||
|
|
||
|
return the;
|
||
|
};
|
||
|
|
||
|
// webpack support
|
||
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||
|
module.exports = KTCard;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
// DOCS: https://javascript.info/cookie
|
||
|
|
||
|
// Component Definition
|
||
|
var KTCookie = function() {
|
||
|
return {
|
||
|
// returns the cookie with the given name,
|
||
|
// or undefined if not found
|
||
|
getCookie: function(name) {
|
||
|
var matches = document.cookie.match(new RegExp(
|
||
|
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
|
||
|
));
|
||
|
return matches ? decodeURIComponent(matches[1]) : undefined;
|
||
|
},
|
||
|
// Please note that a cookie value is encoded,
|
||
|
// so getCookie uses a built-in decodeURIComponent function to decode it.
|
||
|
setCookie: function(name, value, options) {
|
||
|
if (!options) {
|
||
|
options = {};
|
||
|
}
|
||
|
|
||
|
options = Object.assign({}, {path: '/'}, options);
|
||
|
|
||
|
if (options.expires instanceof Date) {
|
||
|
options.expires = options.expires.toUTCString();
|
||
|
}
|
||
|
|
||
|
var updatedCookie = encodeURIComponent(name) + "=" + encodeURIComponent(value);
|
||
|
|
||
|
for (var optionKey in options) {
|
||
|
if (!options.hasOwnProperty(optionKey)) {
|
||
|
continue;
|
||
|
}
|
||
|
updatedCookie += "; " + optionKey;
|
||
|
var optionValue = options[optionKey];
|
||
|
if (optionValue !== true) {
|
||
|
updatedCookie += "=" + optionValue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
document.cookie = updatedCookie;
|
||
|
},
|
||
|
// To delete a cookie, we can call it with a negative expiration date:
|
||
|
deleteCookie: function(name) {
|
||
|
setCookie(name, "", {
|
||
|
'max-age': -1
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
}();
|
||
|
|
||
|
// webpack support
|
||
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||
|
module.exports = KTCookie;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
// Component Definition
|
||
|
var KTDialog = function(options) {
|
||
|
// Main object
|
||
|
var the = this;
|
||
|
|
||
|
// Get element object
|
||
|
var element;
|
||
|
var body = KTUtil.getBody();
|
||
|
|
||
|
// Default options
|
||
|
var defaultOptions = {
|
||
|
'placement' : 'top center',
|
||
|
'type' : 'loader',
|
||
|
'width' : 100,
|
||
|
'state' : 'default',
|
||
|
'message' : 'Loading...'
|
||
|
};
|
||
|
|
||
|
////////////////////////////
|
||
|
// ** Private Methods ** //
|
||
|
////////////////////////////
|
||
|
|
||
|
var Plugin = {
|
||
|
/**
|
||
|
* Construct
|
||
|
*/
|
||
|
|
||
|
construct: function(options) {
|
||
|
Plugin.init(options);
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles subtoggle click toggle
|
||
|
*/
|
||
|
init: function(options) {
|
||
|
the.events = [];
|
||
|
|
||
|
// merge default and user defined options
|
||
|
the.options = KTUtil.deepExtend({}, defaultOptions, options);
|
||
|
|
||
|
the.state = false;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Show dialog
|
||
|
*/
|
||
|
show: function() {
|
||
|
Plugin.eventTrigger('show');
|
||
|
|
||
|
element = document.createElement("DIV");
|
||
|
KTUtil.setHTML(element, the.options.message);
|
||
|
|
||
|
KTUtil.addClass(element, 'dialog dialog-shown');
|
||
|
KTUtil.addClass(element, 'dialog-' + the.options.state);
|
||
|
KTUtil.addClass(element, 'dialog-' + the.options.type);
|
||
|
|
||
|
if (the.options.placement == 'top center') {
|
||
|
KTUtil.addClass(element, 'dialog-top-center');
|
||
|
}
|
||
|
|
||
|
body.appendChild(element);
|
||
|
|
||
|
the.state = 'shown';
|
||
|
|
||
|
Plugin.eventTrigger('shown');
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Hide dialog
|
||
|
*/
|
||
|
hide: function() {
|
||
|
if (element) {
|
||
|
Plugin.eventTrigger('hide');
|
||
|
|
||
|
element.remove();
|
||
|
the.state = 'hidden';
|
||
|
|
||
|
Plugin.eventTrigger('hidden');
|
||
|
}
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Trigger events
|
||
|
*/
|
||
|
eventTrigger: function(name) {
|
||
|
for (var i = 0; i < the.events.length; i++) {
|
||
|
var event = the.events[i];
|
||
|
|
||
|
if (event.name == name) {
|
||
|
if (event.one == true) {
|
||
|
if (event.fired == false) {
|
||
|
the.events[i].fired = true;
|
||
|
return event.handler.call(this, the);
|
||
|
}
|
||
|
} else {
|
||
|
return event.handler.call(this, the);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
addEvent: function(name, handler, one) {
|
||
|
the.events.push({
|
||
|
name: name,
|
||
|
handler: handler,
|
||
|
one: one,
|
||
|
fired: false
|
||
|
});
|
||
|
|
||
|
return the;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//////////////////////////
|
||
|
// ** Public Methods ** //
|
||
|
//////////////////////////
|
||
|
|
||
|
/**
|
||
|
* Set default options
|
||
|
*/
|
||
|
|
||
|
the.setDefaults = function(options) {
|
||
|
defaultOptions = options;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Check shown state
|
||
|
*/
|
||
|
the.shown = function() {
|
||
|
return the.state == 'shown';
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Check hidden state
|
||
|
*/
|
||
|
the.hidden = function() {
|
||
|
return the.state == 'hidden';
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Show dialog
|
||
|
*/
|
||
|
the.show = function() {
|
||
|
return Plugin.show();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Hide dialog
|
||
|
*/
|
||
|
the.hide = function() {
|
||
|
return Plugin.hide();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Attach event
|
||
|
* @returns {KTToggle}
|
||
|
*/
|
||
|
the.on = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Attach event that will be fired once
|
||
|
* @returns {KTToggle}
|
||
|
*/
|
||
|
the.one = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler, true);
|
||
|
};
|
||
|
|
||
|
// Construct plugin
|
||
|
Plugin.construct.apply(the, [options]);
|
||
|
|
||
|
return the;
|
||
|
};
|
||
|
|
||
|
// webpack support
|
||
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||
|
module.exports = KTDialog;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
// Component Definition
|
||
|
var KTHeader = function(elementId, options) {
|
||
|
// Main object
|
||
|
var the = this;
|
||
|
var init = false;
|
||
|
|
||
|
// Get element object
|
||
|
var element = KTUtil.getById(elementId);
|
||
|
var body = KTUtil.getBody();
|
||
|
|
||
|
if (element === undefined) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Default options
|
||
|
var defaultOptions = {
|
||
|
offset: {
|
||
|
desktop: true,
|
||
|
tabletAndMobile: true
|
||
|
},
|
||
|
releseOnReverse: {
|
||
|
desktop: false,
|
||
|
tabletAndMobile: false
|
||
|
}
|
||
|
};
|
||
|
|
||
|
////////////////////////////
|
||
|
// ** Private Methods ** //
|
||
|
////////////////////////////
|
||
|
|
||
|
var Plugin = {
|
||
|
/**
|
||
|
* Run plugin
|
||
|
* @returns {KTHeader}
|
||
|
*/
|
||
|
construct: function(options) {
|
||
|
if (KTUtil.data(element).has('header')) {
|
||
|
the = KTUtil.data(element).get('header');
|
||
|
} else {
|
||
|
// reset header
|
||
|
Plugin.init(options);
|
||
|
|
||
|
// build header
|
||
|
Plugin.build();
|
||
|
|
||
|
KTUtil.data(element).set('header', the);
|
||
|
}
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles subheader click toggle
|
||
|
* @returns {KTHeader}
|
||
|
*/
|
||
|
init: function(options) {
|
||
|
the.events = [];
|
||
|
|
||
|
// merge default and user defined options
|
||
|
the.options = KTUtil.deepExtend({}, defaultOptions, options);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Reset header
|
||
|
* @returns {KTHeader}
|
||
|
*/
|
||
|
build: function() {
|
||
|
var eventTriggerState = true;
|
||
|
var lastScrollTop = 0;
|
||
|
|
||
|
window.addEventListener('scroll', function() {
|
||
|
var offset = 0, st, attrName;
|
||
|
|
||
|
if (KTUtil.isBreakpointDown('lg') && the.options.offset.tabletAndMobile === false) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (KTUtil.isBreakpointUp('lg') && the.options.offset.desktop === false) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (KTUtil.isBreakpointUp('lg')) {
|
||
|
offset = the.options.offset.desktop;
|
||
|
} else if (KTUtil.isBreakpointDown('lg')) {
|
||
|
offset = the.options.offset.tabletAndMobile;
|
||
|
}
|
||
|
|
||
|
st = KTUtil.getScrollTop();
|
||
|
|
||
|
if (
|
||
|
(KTUtil.isBreakpointDown('lg') && the.options.releseOnReverse.tabletAndMobile) ||
|
||
|
(KTUtil.isBreakpointUp('lg') && the.options.releseOnReverse.desktop)
|
||
|
) {
|
||
|
if (st > offset && lastScrollTop < st) { // down scroll mode
|
||
|
if (body.hasAttribute('data-header-scroll') === false) {
|
||
|
body.setAttribute('data-header-scroll', 'on');
|
||
|
}
|
||
|
|
||
|
if (eventTriggerState) {
|
||
|
Plugin.eventTrigger('scrollOn', the);
|
||
|
eventTriggerState = false;
|
||
|
}
|
||
|
} else { // back scroll mode
|
||
|
if (body.hasAttribute('data-header-scroll') === true) {
|
||
|
body.removeAttribute('data-header-scroll');
|
||
|
}
|
||
|
|
||
|
if (eventTriggerState == false) {
|
||
|
Plugin.eventTrigger('scrollOff', the);
|
||
|
eventTriggerState = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
lastScrollTop = st;
|
||
|
} else {
|
||
|
if (st > offset) { // down scroll mode
|
||
|
if (body.hasAttribute('data-header-scroll') === false) {
|
||
|
body.setAttribute('data-header-scroll', 'on');
|
||
|
}
|
||
|
|
||
|
if (eventTriggerState) {
|
||
|
Plugin.eventTrigger('scrollOn', the);
|
||
|
eventTriggerState = false;
|
||
|
}
|
||
|
} else { // back scroll mode
|
||
|
if (body.hasAttribute('data-header-scroll') === true) {
|
||
|
body.removeAttribute('data-header-scroll');
|
||
|
}
|
||
|
|
||
|
if (eventTriggerState == false) {
|
||
|
Plugin.eventTrigger('scrollOff', the);
|
||
|
eventTriggerState = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Trigger events
|
||
|
*/
|
||
|
eventTrigger: function(name, args) {
|
||
|
for (var i = 0; i < the.events.length; i++) {
|
||
|
var event = the.events[i];
|
||
|
if (event.name == name) {
|
||
|
if (event.one == true) {
|
||
|
if (event.fired == false) {
|
||
|
the.events[i].fired = true;
|
||
|
return event.handler.call(this, the, args);
|
||
|
}
|
||
|
} else {
|
||
|
return event.handler.call(this, the, args);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
addEvent: function(name, handler, one) {
|
||
|
the.events.push({
|
||
|
name: name,
|
||
|
handler: handler,
|
||
|
one: one,
|
||
|
fired: false
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//////////////////////////
|
||
|
// ** Public Methods ** //
|
||
|
//////////////////////////
|
||
|
|
||
|
/**
|
||
|
* Set default options
|
||
|
*/
|
||
|
|
||
|
the.setDefaults = function(options) {
|
||
|
defaultOptions = options;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Register event
|
||
|
*/
|
||
|
the.on = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler);
|
||
|
};
|
||
|
|
||
|
///////////////////////////////
|
||
|
// ** Plugin Construction ** //
|
||
|
///////////////////////////////
|
||
|
|
||
|
// Run plugin
|
||
|
Plugin.construct.apply(the, [options]);
|
||
|
|
||
|
// Init done
|
||
|
init = true;
|
||
|
|
||
|
// Return plugin instance
|
||
|
return the;
|
||
|
};
|
||
|
|
||
|
// webpack support
|
||
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||
|
module.exports = KTHeader;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
// Component Definition
|
||
|
var KTImageInput = function(elementId, options) {
|
||
|
// Main object
|
||
|
var the = this;
|
||
|
var init = false;
|
||
|
|
||
|
// Get element object
|
||
|
var element = KTUtil.getById(elementId);
|
||
|
var body = KTUtil.getBody();
|
||
|
|
||
|
if (!element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Default options
|
||
|
var defaultOptions = {
|
||
|
editMode: false
|
||
|
};
|
||
|
|
||
|
////////////////////////////
|
||
|
// ** Private Methods ** //
|
||
|
////////////////////////////
|
||
|
|
||
|
var Plugin = {
|
||
|
/**
|
||
|
* Construct
|
||
|
*/
|
||
|
|
||
|
construct: function(options) {
|
||
|
if (KTUtil.data(element).has('imageinput')) {
|
||
|
the = KTUtil.data(element).get('imageinput');
|
||
|
} else {
|
||
|
// reset menu
|
||
|
Plugin.init(options);
|
||
|
|
||
|
// build menu
|
||
|
Plugin.build();
|
||
|
|
||
|
KTUtil.data(element).set('imageinput', the);
|
||
|
}
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Init avatar
|
||
|
*/
|
||
|
init: function(options) {
|
||
|
the.element = element;
|
||
|
the.events = [];
|
||
|
|
||
|
the.input = KTUtil.find(element, 'input[type="file"]');
|
||
|
the.wrapper = KTUtil.find(element, '.image-input-wrapper');
|
||
|
the.cancel = KTUtil.find(element, '[data-action="cancel"]');
|
||
|
the.remove = KTUtil.find(element, '[data-action="remove"]');
|
||
|
the.src = KTUtil.css(the.wrapper, 'backgroundImage');
|
||
|
the.hidden = KTUtil.find(element, 'input[type="hidden"]');
|
||
|
|
||
|
// merge default and user defined options
|
||
|
the.options = KTUtil.deepExtend({}, defaultOptions, options);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Build
|
||
|
*/
|
||
|
build: function() {
|
||
|
// Handle change
|
||
|
KTUtil.addEvent(the.input, 'change', function(e) {
|
||
|
e.preventDefault();
|
||
|
|
||
|
if (the.input && the.input.files && the.input.files[0]) {
|
||
|
var reader = new FileReader();
|
||
|
reader.onload = function(e) {
|
||
|
KTUtil.css(the.wrapper, 'background-image', 'url('+e.target.result +')');
|
||
|
}
|
||
|
reader.readAsDataURL(the.input.files[0]);
|
||
|
|
||
|
KTUtil.addClass(the.element, 'image-input-changed');
|
||
|
KTUtil.removeClass(the.element, 'image-input-empty');
|
||
|
|
||
|
// Fire change event
|
||
|
Plugin.eventTrigger('change');
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Handle cancel
|
||
|
KTUtil.addEvent(the.cancel, 'click', function(e) {
|
||
|
e.preventDefault();
|
||
|
|
||
|
// Fire cancel event
|
||
|
Plugin.eventTrigger('cancel');
|
||
|
|
||
|
KTUtil.removeClass(the.element, 'image-input-changed');
|
||
|
KTUtil.removeClass(the.element, 'image-input-empty');
|
||
|
KTUtil.css(the.wrapper, 'background-image', the.src);
|
||
|
the.input.value = "";
|
||
|
|
||
|
if (the.hidden) {
|
||
|
the.hidden.value = "0";
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Handle remove
|
||
|
KTUtil.addEvent(the.remove, 'click', function(e) {
|
||
|
e.preventDefault();
|
||
|
|
||
|
// Fire cancel event
|
||
|
Plugin.eventTrigger('remove');
|
||
|
|
||
|
KTUtil.removeClass(the.element, 'image-input-changed');
|
||
|
KTUtil.addClass(the.element, 'image-input-empty');
|
||
|
KTUtil.css(the.wrapper, 'background-image', "none");
|
||
|
the.input.value = "";
|
||
|
|
||
|
if (the.hidden) {
|
||
|
the.hidden.value = "1";
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Trigger events
|
||
|
*/
|
||
|
eventTrigger: function(name) {
|
||
|
//KTUtil.triggerCustomEvent(name);
|
||
|
for (var i = 0; i < the.events.length; i++) {
|
||
|
var event = the.events[i];
|
||
|
if (event.name == name) {
|
||
|
if (event.one == true) {
|
||
|
if (event.fired == false) {
|
||
|
the.events[i].fired = true;
|
||
|
return event.handler.call(this, the);
|
||
|
}
|
||
|
} else {
|
||
|
return event.handler.call(this, the);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
addEvent: function(name, handler, one) {
|
||
|
the.events.push({
|
||
|
name: name,
|
||
|
handler: handler,
|
||
|
one: one,
|
||
|
fired: false
|
||
|
});
|
||
|
|
||
|
return the;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//////////////////////////
|
||
|
// ** Public Methods ** //
|
||
|
//////////////////////////
|
||
|
|
||
|
/**
|
||
|
* Set default options
|
||
|
*/
|
||
|
|
||
|
the.setDefaults = function(options) {
|
||
|
defaultOptions = options;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Attach event
|
||
|
*/
|
||
|
the.on = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Attach event that will be fired once
|
||
|
*/
|
||
|
the.one = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler, true);
|
||
|
};
|
||
|
|
||
|
// Construct plugin
|
||
|
Plugin.construct.apply(the, [options]);
|
||
|
|
||
|
return the;
|
||
|
};
|
||
|
|
||
|
// webpack support
|
||
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||
|
module.exports = KTImageInput;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
// Component Definition
|
||
|
var KTMenu = function(elementId, options) {
|
||
|
// Main object
|
||
|
var the = this;
|
||
|
var init = false;
|
||
|
|
||
|
// Get element object
|
||
|
var element = KTUtil.getById(elementId);
|
||
|
var body = KTUtil.getBody();
|
||
|
|
||
|
if (!element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Default options
|
||
|
var defaultOptions = {
|
||
|
// scrollable area with Perfect Scroll
|
||
|
scroll: {
|
||
|
rememberPosition: false
|
||
|
},
|
||
|
|
||
|
// accordion submenu mode
|
||
|
accordion: {
|
||
|
slideSpeed: 200, // accordion toggle slide speed in milliseconds
|
||
|
autoScroll: false, // enable auto scrolling(focus) to the clicked menu item
|
||
|
autoScrollSpeed: 1200,
|
||
|
expandAll: true // allow having multiple expanded accordions in the menu
|
||
|
},
|
||
|
|
||
|
// dropdown submenu mode
|
||
|
dropdown: {
|
||
|
timeout: 500 // timeout in milliseconds to show and hide the hoverable submenu dropdown
|
||
|
}
|
||
|
};
|
||
|
|
||
|
////////////////////////////
|
||
|
// ** Private Methods ** //
|
||
|
////////////////////////////
|
||
|
|
||
|
var Plugin = {
|
||
|
/**
|
||
|
* Run plugin
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
construct: function(options) {
|
||
|
if (KTUtil.data(element).has('menu')) {
|
||
|
the = KTUtil.data(element).get('menu');
|
||
|
} else {
|
||
|
// reset menu
|
||
|
Plugin.init(options);
|
||
|
|
||
|
// reset menu
|
||
|
Plugin.reset();
|
||
|
|
||
|
// build menu
|
||
|
Plugin.build();
|
||
|
|
||
|
KTUtil.data(element).set('menu', the);
|
||
|
}
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles submenu click toggle
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
init: function(options) {
|
||
|
the.events = [];
|
||
|
|
||
|
the.eventHandlers = {};
|
||
|
|
||
|
// merge default and user defined options
|
||
|
the.options = KTUtil.deepExtend({}, defaultOptions, options);
|
||
|
|
||
|
// pause menu
|
||
|
the.pauseDropdownHoverTime = 0;
|
||
|
|
||
|
the.uid = KTUtil.getUniqueID();
|
||
|
},
|
||
|
|
||
|
update: function(options) {
|
||
|
// merge default and user defined options
|
||
|
the.options = KTUtil.deepExtend({}, defaultOptions, options);
|
||
|
|
||
|
// pause menu
|
||
|
the.pauseDropdownHoverTime = 0;
|
||
|
|
||
|
// reset menu
|
||
|
Plugin.reset();
|
||
|
|
||
|
the.eventHandlers = {};
|
||
|
|
||
|
// build menu
|
||
|
Plugin.build();
|
||
|
|
||
|
KTUtil.data(element).set('menu', the);
|
||
|
},
|
||
|
|
||
|
reload: function() {
|
||
|
// reset menu
|
||
|
Plugin.reset();
|
||
|
|
||
|
// build menu
|
||
|
Plugin.build();
|
||
|
|
||
|
// reset submenu props
|
||
|
Plugin.resetSubmenuProps();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Reset menu
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
build: function() {
|
||
|
// General accordion submenu toggle
|
||
|
the.eventHandlers['event_1'] = KTUtil.on( element, '.menu-toggle', 'click', Plugin.handleSubmenuAccordion);
|
||
|
|
||
|
// Dropdown mode(hoverable)
|
||
|
if (Plugin.getSubmenuMode() === 'dropdown' || Plugin.isConditionalSubmenuDropdown()) {
|
||
|
// dropdown submenu - hover toggle
|
||
|
the.eventHandlers['event_2'] = KTUtil.on( element, '[data-menu-toggle="hover"]', 'mouseover', Plugin.handleSubmenuDrodownHoverEnter);
|
||
|
the.eventHandlers['event_3'] = KTUtil.on( element, '[data-menu-toggle="hover"]', 'mouseout', Plugin.handleSubmenuDrodownHoverExit);
|
||
|
|
||
|
// dropdown submenu - click toggle
|
||
|
the.eventHandlers['event_4'] = KTUtil.on( element, '[data-menu-toggle="click"] > .menu-toggle, [data-menu-toggle="click"] > .menu-link .menu-toggle', 'click', Plugin.handleSubmenuDropdownClick);
|
||
|
the.eventHandlers['event_5'] = KTUtil.on( element, '[data-menu-toggle="tab"] > .menu-toggle, [data-menu-toggle="tab"] > .menu-link .menu-toggle', 'click', Plugin.handleSubmenuDropdownTabClick);
|
||
|
}
|
||
|
|
||
|
// Handle general link click
|
||
|
the.eventHandlers['event_6'] = KTUtil.on(element, '.menu-item > .menu-link:not(.menu-toggle):not(.menu-link-toggle-skip)', 'click', Plugin.handleLinkClick);
|
||
|
|
||
|
// Init scrollable menu
|
||
|
if (the.options.scroll && the.options.scroll.height) {
|
||
|
Plugin.scrollInit();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Reset menu
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
reset: function() {
|
||
|
KTUtil.off( element, 'click', the.eventHandlers['event_1']);
|
||
|
|
||
|
// dropdown submenu - hover toggle
|
||
|
KTUtil.off( element, 'mouseover', the.eventHandlers['event_2']);
|
||
|
KTUtil.off( element, 'mouseout', the.eventHandlers['event_3']);
|
||
|
|
||
|
// dropdown submenu - click toggle
|
||
|
KTUtil.off( element, 'click', the.eventHandlers['event_4']);
|
||
|
KTUtil.off( element, 'click', the.eventHandlers['event_5']);
|
||
|
|
||
|
// handle link click
|
||
|
KTUtil.off(element, 'click', the.eventHandlers['event_6']);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Init scroll menu
|
||
|
*
|
||
|
*/
|
||
|
scrollInit: function() {
|
||
|
if ( the.options.scroll && the.options.scroll.height ) {
|
||
|
KTUtil.scrollDestroy(element, true);
|
||
|
KTUtil.scrollInit(element, {mobileNativeScroll: true, windowScroll: false, resetHeightOnDestroy: true, handleWindowResize: true, height: the.options.scroll.height, rememberPosition: the.options.scroll.rememberPosition});
|
||
|
} else {
|
||
|
KTUtil.scrollDestroy(element, true);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Update scroll menu
|
||
|
*/
|
||
|
scrollUpdate: function() {
|
||
|
if ( the.options.scroll && the.options.scroll.height ) {
|
||
|
KTUtil.scrollUpdate(element);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Scroll top
|
||
|
*/
|
||
|
scrollTop: function() {
|
||
|
if ( the.options.scroll && the.options.scroll.height ) {
|
||
|
KTUtil.scrollTop(element);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get submenu mode for current breakpoint and menu state
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
getSubmenuMode: function(el) {
|
||
|
if ( KTUtil.isBreakpointUp('lg') ) {
|
||
|
if (el && KTUtil.hasAttr(el, 'data-menu-toggle') && KTUtil.attr(el, 'data-menu-toggle') == 'hover') {
|
||
|
return 'dropdown';
|
||
|
}
|
||
|
|
||
|
if ( KTUtil.isset(the.options.submenu, 'desktop.state.body') ) {
|
||
|
if ( KTUtil.hasClasses(body, the.options.submenu.desktop.state.body) ) {
|
||
|
return the.options.submenu.desktop.state.mode;
|
||
|
} else {
|
||
|
return the.options.submenu.desktop.default;
|
||
|
}
|
||
|
} else if ( KTUtil.isset(the.options.submenu, 'desktop') ) {
|
||
|
return the.options.submenu.desktop;
|
||
|
}
|
||
|
} else if ( KTUtil.isBreakpointUp('md') && KTUtil.isBreakpointDown('lg') && KTUtil.isset(the.options.submenu, 'tablet') ) {
|
||
|
return the.options.submenu.tablet;
|
||
|
} else if ( KTUtil.isBreakpointDown('md') && KTUtil.isset(the.options.submenu, 'mobile') ) {
|
||
|
return the.options.submenu.mobile;
|
||
|
} else {
|
||
|
return false;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get submenu mode for current breakpoint and menu state
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
isConditionalSubmenuDropdown: function() {
|
||
|
if ( KTUtil.isBreakpointUp('lg') && KTUtil.isset(the.options.submenu, 'desktop.state.body') ) {
|
||
|
return true;
|
||
|
} else {
|
||
|
return false;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Reset submenu attributes
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
resetSubmenuProps: function(e) {
|
||
|
var submenus = KTUtil.findAll(element, '.menu-submenu');
|
||
|
if ( submenus ) {
|
||
|
for (var i = 0, len = submenus.length; i < len; i++) {
|
||
|
var submenu = submenus[0];
|
||
|
|
||
|
KTUtil.css(submenu, 'display', '');
|
||
|
KTUtil.css(submenu, 'overflow', '');
|
||
|
|
||
|
if (submenu.hasAttribute('data-hor-direction')) {
|
||
|
KTUtil.removeClass(submenu, 'menu-submenu-left');
|
||
|
KTUtil.removeClass(submenu, 'menu-submenu-right');
|
||
|
KTUtil.addClass(submenu, submenu.getAttribute('data-hor-direction'));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles submenu hover toggle
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
handleSubmenuDrodownHoverEnter: function(e) {
|
||
|
if ( Plugin.getSubmenuMode(this) === 'accordion' ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( the.resumeDropdownHover() === false ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var item = this;
|
||
|
|
||
|
if ( item.getAttribute('data-hover') == '1' ) {
|
||
|
item.removeAttribute('data-hover');
|
||
|
clearTimeout( item.getAttribute('data-timeout') );
|
||
|
item.removeAttribute('data-timeout');
|
||
|
}
|
||
|
|
||
|
Plugin.showSubmenuDropdown(item);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles submenu hover toggle
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
handleSubmenuDrodownHoverExit: function(e) {
|
||
|
if ( the.resumeDropdownHover() === false ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( Plugin.getSubmenuMode(this) === 'accordion' ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var item = this;
|
||
|
var time = the.options.dropdown.timeout;
|
||
|
|
||
|
var timeout = setTimeout(function() {
|
||
|
if ( item.getAttribute('data-hover') == '1' ) {
|
||
|
Plugin.hideSubmenuDropdown(item, true);
|
||
|
}
|
||
|
}, time);
|
||
|
|
||
|
item.setAttribute('data-hover', '1');
|
||
|
item.setAttribute('data-timeout', timeout);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles submenu click toggle
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
handleSubmenuDropdownClick: function(e) {
|
||
|
if ( Plugin.getSubmenuMode(this) === 'accordion' ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var item = this.closest('.menu-item');
|
||
|
|
||
|
// Trigger click event handlers
|
||
|
var result = Plugin.eventTrigger('submenuToggle', this, e);
|
||
|
if (result === false) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( item.getAttribute('data-menu-submenu-mode') == 'accordion' ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( KTUtil.hasClass(item, 'menu-item-hover') === false ) {
|
||
|
KTUtil.addClass(item, 'menu-item-open-dropdown');
|
||
|
Plugin.showSubmenuDropdown(item);
|
||
|
} else {
|
||
|
KTUtil.removeClass(item, 'menu-item-open-dropdown' );
|
||
|
Plugin.hideSubmenuDropdown(item, true);
|
||
|
}
|
||
|
|
||
|
e.preventDefault();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles tab click toggle
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
handleSubmenuDropdownTabClick: function(e) {
|
||
|
if (Plugin.getSubmenuMode(this) === 'accordion') {
|
||
|
return;
|
||
|
}
|
||
|
var item = this.closest('.menu-item');
|
||
|
|
||
|
// Trigger click event handlers
|
||
|
var result = Plugin.eventTrigger('submenuToggle', this, e);
|
||
|
if (result === false) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (item.getAttribute('data-menu-submenu-mode') == 'accordion') {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (KTUtil.hasClass(item, 'menu-item-hover') == false) {
|
||
|
KTUtil.addClass(item, 'menu-item-open-dropdown');
|
||
|
Plugin.showSubmenuDropdown(item);
|
||
|
}
|
||
|
|
||
|
e.preventDefault();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles link click
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
handleLinkClick: function(e) {
|
||
|
var submenu = this.closest('.menu-item.menu-item-submenu');
|
||
|
|
||
|
// Trigger click event handlers
|
||
|
var result = Plugin.eventTrigger('linkClick', this, e);
|
||
|
if (result === false) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( submenu && Plugin.getSubmenuMode(submenu) === 'dropdown' ) {
|
||
|
Plugin.hideSubmenuDropdowns();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles submenu dropdown close on link click
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
handleSubmenuDropdownClose: function(e, el) {
|
||
|
// exit if its not submenu dropdown mode
|
||
|
if (Plugin.getSubmenuMode(el) === 'accordion') {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var shown = element.querySelectorAll('.menu-item.menu-item-submenu.menu-item-hover:not(.menu-item-tabs)');
|
||
|
|
||
|
// check if currently clicked link's parent item ha
|
||
|
if (shown.length > 0 && KTUtil.hasClass(el, 'menu-toggle') === false && el.querySelectorAll('.menu-toggle').length === 0) {
|
||
|
// close opened dropdown menus
|
||
|
for (var i = 0, len = shown.length; i < len; i++) {
|
||
|
Plugin.hideSubmenuDropdown(shown[0], true);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* helper functions
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
handleSubmenuAccordion: function(e, el) {
|
||
|
var query;
|
||
|
var item = el ? el : this;
|
||
|
|
||
|
// Trigger click event handlers
|
||
|
var result = Plugin.eventTrigger('submenuToggle', this, e);
|
||
|
if (result === false) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( Plugin.getSubmenuMode(el) === 'dropdown' && (query = item.closest('.menu-item') ) ) {
|
||
|
if (query.getAttribute('data-menu-submenu-mode') != 'accordion' ) {
|
||
|
e.preventDefault();
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var li = item.closest('.menu-item');
|
||
|
var submenu = KTUtil.child(li, '.menu-submenu, .menu-inner');
|
||
|
|
||
|
if (KTUtil.hasClass(item.closest('.menu-item'), 'menu-item-open-always')) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( li && submenu ) {
|
||
|
e.preventDefault();
|
||
|
var speed = the.options.accordion.slideSpeed;
|
||
|
var hasClosables = false;
|
||
|
|
||
|
if ( KTUtil.hasClass(li, 'menu-item-open') === false ) {
|
||
|
// hide other accordions
|
||
|
if ( the.options.accordion.expandAll === false ) {
|
||
|
var subnav = item.closest('.menu-nav, .menu-subnav');
|
||
|
var closables = KTUtil.children(subnav, '.menu-item.menu-item-open.menu-item-submenu:not(.menu-item-here):not(.menu-item-open-always)');
|
||
|
|
||
|
if ( subnav && closables ) {
|
||
|
for (var i = 0, len = closables.length; i < len; i++) {
|
||
|
var el_ = closables[0];
|
||
|
var submenu_ = KTUtil.child(el_, '.menu-submenu');
|
||
|
if ( submenu_ ) {
|
||
|
KTUtil.slideUp(submenu_, speed, function() {
|
||
|
Plugin.scrollUpdate();
|
||
|
KTUtil.removeClass(el_, 'menu-item-open');
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
KTUtil.slideDown(submenu, speed, function() {
|
||
|
Plugin.scrollToItem(item);
|
||
|
Plugin.scrollUpdate();
|
||
|
|
||
|
Plugin.eventTrigger('submenuToggle', submenu, e);
|
||
|
});
|
||
|
|
||
|
KTUtil.addClass(li, 'menu-item-open');
|
||
|
|
||
|
} else {
|
||
|
KTUtil.slideUp(submenu, speed, function() {
|
||
|
Plugin.scrollToItem(item);
|
||
|
Plugin.eventTrigger('submenuToggle', submenu, e);
|
||
|
});
|
||
|
|
||
|
KTUtil.removeClass(li, 'menu-item-open');
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* scroll to item function
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
scrollToItem: function(item) {
|
||
|
// handle auto scroll for accordion submenus
|
||
|
if ( KTUtil.isBreakpointUp('lg') && the.options.accordion.autoScroll && element.getAttribute('data-menu-scroll') !== '1' ) {
|
||
|
KTUtil.scrollTo(item, the.options.accordion.autoScrollSpeed);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Hide submenu dropdown
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
hideSubmenuDropdown: function(item, classAlso) {
|
||
|
// remove submenu activation class
|
||
|
if ( classAlso ) {
|
||
|
KTUtil.removeClass(item, 'menu-item-hover');
|
||
|
KTUtil.removeClass(item, 'menu-item-active-tab');
|
||
|
}
|
||
|
|
||
|
// clear timeout
|
||
|
item.removeAttribute('data-hover');
|
||
|
|
||
|
if ( item.getAttribute('data-menu-toggle-class') ) {
|
||
|
KTUtil.removeClass(body, item.getAttribute('data-menu-toggle-class'));
|
||
|
}
|
||
|
|
||
|
var timeout = item.getAttribute('data-timeout');
|
||
|
item.removeAttribute('data-timeout');
|
||
|
clearTimeout(timeout);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Hide submenu dropdowns
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
hideSubmenuDropdowns: function() {
|
||
|
var items;
|
||
|
if ( items = element.querySelectorAll('.menu-item-submenu.menu-item-hover:not(.menu-item-tabs):not([data-menu-toggle="tab"])') ) {
|
||
|
for (var j = 0, cnt = items.length; j < cnt; j++) {
|
||
|
Plugin.hideSubmenuDropdown(items[j], true);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* helper functions
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
showSubmenuDropdown: function(item) {
|
||
|
// close active submenus
|
||
|
var list = element.querySelectorAll('.menu-item-submenu.menu-item-hover, .menu-item-submenu.menu-item-active-tab');
|
||
|
|
||
|
if ( list ) {
|
||
|
for (var i = 0, len = list.length; i < len; i++) {
|
||
|
var el = list[i];
|
||
|
if ( item !== el && el.contains(item) === false && item.contains(el) === false ) {
|
||
|
Plugin.hideSubmenuDropdown(el, true);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// add submenu activation class
|
||
|
KTUtil.addClass(item, 'menu-item-hover');
|
||
|
|
||
|
// Change the alignment of submenu is offscreen.
|
||
|
var submenu = KTUtil.find(item, '.menu-submenu');
|
||
|
|
||
|
if (submenu && submenu.hasAttribute('data-hor-direction') === false) {
|
||
|
if (KTUtil.hasClass(submenu, 'menu-submenu-left')) {
|
||
|
submenu.setAttribute('data-hor-direction', 'menu-submenu-left');
|
||
|
} else if (KTUtil.hasClass(submenu, 'menu-submenu-right')) {
|
||
|
submenu.setAttribute('data-hor-direction', 'menu-submenu-right');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( submenu && KTUtil.isOffscreen(submenu, 'left', 15) === true ) {
|
||
|
KTUtil.removeClass(submenu, 'menu-submenu-left');
|
||
|
KTUtil.addClass(submenu, 'menu-submenu-right');
|
||
|
} else if ( submenu && KTUtil.isOffscreen(submenu, 'right', 15) === true ) {
|
||
|
KTUtil.removeClass(submenu, 'menu-submenu-right');
|
||
|
KTUtil.addClass(submenu, 'menu-submenu-left');
|
||
|
}
|
||
|
|
||
|
if ( item.getAttribute('data-menu-toggle-class') ) {
|
||
|
KTUtil.addClass(body, item.getAttribute('data-menu-toggle-class'));
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles submenu slide toggle
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
createSubmenuDropdownClickDropoff: function(el) {
|
||
|
var query;
|
||
|
var zIndex = (query = KTUtil.child(el, '.menu-submenu') ? KTUtil.css(query, 'z-index') : 0) - 1;
|
||
|
|
||
|
var dropoff = document.createElement('<div class="menu-dropoff" style="background: transparent; position: fixed; top: 0; bottom: 0; left: 0; right: 0; z-index: ' + zIndex + '"></div>');
|
||
|
|
||
|
body.appendChild(dropoff);
|
||
|
|
||
|
KTUtil.addEvent(dropoff, 'click', function(e) {
|
||
|
e.stopPropagation();
|
||
|
e.preventDefault();
|
||
|
KTUtil.remove(this);
|
||
|
Plugin.hideSubmenuDropdown(el, true);
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles submenu hover toggle
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
pauseDropdownHover: function(time) {
|
||
|
var date = new Date();
|
||
|
|
||
|
the.pauseDropdownHoverTime = date.getTime() + time;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles submenu hover toggle
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
resumeDropdownHover: function() {
|
||
|
var date = new Date();
|
||
|
|
||
|
return (date.getTime() > the.pauseDropdownHoverTime ? true : false);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Reset menu's current active item
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
resetActiveItem: function(item) {
|
||
|
var list;
|
||
|
var parents;
|
||
|
|
||
|
list = element.querySelectorAll('.menu-item-active');
|
||
|
|
||
|
for (var i = 0, len = list.length; i < len; i++) {
|
||
|
var el = list[0];
|
||
|
KTUtil.removeClass(el, 'menu-item-active');
|
||
|
KTUtil.hide( KTUtil.child(el, '.menu-submenu') );
|
||
|
parents = KTUtil.parents(el, '.menu-item-submenu') || [];
|
||
|
|
||
|
for (var i_ = 0, len_ = parents.length; i_ < len_; i_++) {
|
||
|
var el_ = parents[i];
|
||
|
KTUtil.removeClass(el_, 'menu-item-open');
|
||
|
KTUtil.hide( KTUtil.child(el_, '.menu-submenu') );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// close open submenus
|
||
|
if ( the.options.accordion.expandAll === false ) {
|
||
|
if ( list = element.querySelectorAll('.menu-item-open') ) {
|
||
|
for (var i = 0, len = list.length; i < len; i++) {
|
||
|
KTUtil.removeClass(parents[0], 'menu-item-open');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Sets menu's active item
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
setActiveItem: function(item) {
|
||
|
// reset current active item
|
||
|
Plugin.resetActiveItem();
|
||
|
|
||
|
var parents = KTUtil.parents(item, '.menu-item-submenu') || [];
|
||
|
for (var i = 0, len = parents.length; i < len; i++) {
|
||
|
KTUtil.addClass(parents[i], 'menu-item-open');
|
||
|
}
|
||
|
|
||
|
KTUtil.addClass(item, 'menu-item-active');
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Returns page breadcrumbs for the menu's active item
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
getBreadcrumbs: function(item) {
|
||
|
var query;
|
||
|
var breadcrumbs = [];
|
||
|
var link = KTUtil.child(item, '.menu-link');
|
||
|
|
||
|
breadcrumbs.push({
|
||
|
text: (query = KTUtil.child(link, '.menu-text') ? query.innerHTML : ''),
|
||
|
title: link.getAttribute('title'),
|
||
|
href: link.getAttribute('href')
|
||
|
});
|
||
|
|
||
|
var parents = KTUtil.parents(item, '.menu-item-submenu');
|
||
|
for (var i = 0, len = parents.length; i < len; i++) {
|
||
|
var submenuLink = KTUtil.child(parents[i], '.menu-link');
|
||
|
|
||
|
breadcrumbs.push({
|
||
|
text: (query = KTUtil.child(submenuLink, '.menu-text') ? query.innerHTML : ''),
|
||
|
title: submenuLink.getAttribute('title'),
|
||
|
href: submenuLink.getAttribute('href')
|
||
|
});
|
||
|
}
|
||
|
|
||
|
return breadcrumbs.reverse();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Returns page title for the menu's active item
|
||
|
* @returns {KTMenu}
|
||
|
*/
|
||
|
getPageTitle: function(item) {
|
||
|
var query;
|
||
|
|
||
|
return (query = KTUtil.child(item, '.menu-text') ? query.innerHTML : '');
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Trigger events
|
||
|
*/
|
||
|
eventTrigger: function(name, target, e) {
|
||
|
for (var i = 0; i < the.events.length; i++ ) {
|
||
|
var event = the.events[i];
|
||
|
if ( event.name == name ) {
|
||
|
if ( event.one == true ) {
|
||
|
if ( event.fired == false ) {
|
||
|
the.events[i].fired = true;
|
||
|
return event.handler.call(this, target, e);
|
||
|
}
|
||
|
} else {
|
||
|
return event.handler.call(this, target, e);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
addEvent: function(name, handler, one) {
|
||
|
the.events.push({
|
||
|
name: name,
|
||
|
handler: handler,
|
||
|
one: one,
|
||
|
fired: false
|
||
|
});
|
||
|
},
|
||
|
|
||
|
removeEvent: function(name) {
|
||
|
if (the.events[name]) {
|
||
|
delete the.events[name];
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//////////////////////////
|
||
|
// ** Public Methods ** //
|
||
|
//////////////////////////
|
||
|
|
||
|
/**
|
||
|
* Set default options
|
||
|
*/
|
||
|
|
||
|
the.setDefaults = function(options) {
|
||
|
defaultOptions = options;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Update scroll
|
||
|
*/
|
||
|
the.scrollUpdate = function() {
|
||
|
return Plugin.scrollUpdate();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Re-init scroll
|
||
|
*/
|
||
|
the.scrollReInit = function() {
|
||
|
return Plugin.scrollInit();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Scroll top
|
||
|
*/
|
||
|
the.scrollTop = function() {
|
||
|
return Plugin.scrollTop();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Set active menu item
|
||
|
*/
|
||
|
the.setActiveItem = function(item) {
|
||
|
return Plugin.setActiveItem(item);
|
||
|
};
|
||
|
|
||
|
the.reload = function() {
|
||
|
return Plugin.reload();
|
||
|
};
|
||
|
|
||
|
the.update = function(options) {
|
||
|
return Plugin.update(options);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Set breadcrumb for menu item
|
||
|
*/
|
||
|
the.getBreadcrumbs = function(item) {
|
||
|
return Plugin.getBreadcrumbs(item);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Set page title for menu item
|
||
|
*/
|
||
|
the.getPageTitle = function(item) {
|
||
|
return Plugin.getPageTitle(item);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Get submenu mode
|
||
|
*/
|
||
|
the.getSubmenuMode = function(el) {
|
||
|
return Plugin.getSubmenuMode(el);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Hide dropdown
|
||
|
* @returns {Object}
|
||
|
*/
|
||
|
the.hideDropdown = function(item) {
|
||
|
Plugin.hideSubmenuDropdown(item, true);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Hide dropdowns
|
||
|
* @returns {Object}
|
||
|
*/
|
||
|
the.hideDropdowns = function() {
|
||
|
Plugin.hideSubmenuDropdowns();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Disable menu for given time
|
||
|
* @returns {Object}
|
||
|
*/
|
||
|
the.pauseDropdownHover = function(time) {
|
||
|
Plugin.pauseDropdownHover(time);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Disable menu for given time
|
||
|
* @returns {Object}
|
||
|
*/
|
||
|
the.resumeDropdownHover = function() {
|
||
|
return Plugin.resumeDropdownHover();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Register event
|
||
|
*/
|
||
|
the.on = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler);
|
||
|
};
|
||
|
|
||
|
the.off = function(name) {
|
||
|
return Plugin.removeEvent(name);
|
||
|
};
|
||
|
|
||
|
the.one = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler, true);
|
||
|
};
|
||
|
|
||
|
///////////////////////////////
|
||
|
// ** Plugin Construction ** //
|
||
|
///////////////////////////////
|
||
|
|
||
|
// Run plugin
|
||
|
Plugin.construct.apply(the, [options]);
|
||
|
|
||
|
// Handle plugin on window resize
|
||
|
KTUtil.addResizeHandler(function() {
|
||
|
if (init) {
|
||
|
the.reload();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Init done
|
||
|
init = true;
|
||
|
|
||
|
// Return plugin instance
|
||
|
return the;
|
||
|
};
|
||
|
|
||
|
// webpack support
|
||
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||
|
module.exports = KTMenu;
|
||
|
}
|
||
|
|
||
|
// Plugin global lazy initialization
|
||
|
document.addEventListener("click", function (e) {
|
||
|
var body = KTUtil.getByTagName('body')[0];
|
||
|
var query;
|
||
|
if ( query = body.querySelectorAll('.menu-nav .menu-item.menu-item-submenu.menu-item-hover:not(.menu-item-tabs)[data-menu-toggle="click"]') ) {
|
||
|
for (var i = 0, len = query.length; i < len; i++) {
|
||
|
var element = query[i].closest('.menu-nav').parentNode;
|
||
|
|
||
|
if ( element ) {
|
||
|
var the = KTUtil.data(element).get('menu');
|
||
|
|
||
|
if ( !the ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ( !the || the.getSubmenuMode() !== 'dropdown' ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ( e.target !== element && element.contains(e.target) === false ) {
|
||
|
the.hideDropdowns();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
// Component Definition
|
||
|
var KTOffcanvas = function(elementId, options) {
|
||
|
// Main object
|
||
|
var the = this;
|
||
|
var init = false;
|
||
|
|
||
|
// Get element object
|
||
|
var element = KTUtil.getById(elementId);
|
||
|
var body = KTUtil.getBody();
|
||
|
|
||
|
if (!element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Default options
|
||
|
var defaultOptions = {
|
||
|
attrCustom: ''
|
||
|
};
|
||
|
|
||
|
////////////////////////////
|
||
|
// ** Private Methods ** //
|
||
|
////////////////////////////
|
||
|
|
||
|
var Plugin = {
|
||
|
construct: function(options) {
|
||
|
if (KTUtil.data(element).has('offcanvas')) {
|
||
|
the = KTUtil.data(element).get('offcanvas');
|
||
|
} else {
|
||
|
// Reset offcanvas
|
||
|
Plugin.init(options);
|
||
|
|
||
|
// Build offcanvas
|
||
|
Plugin.build();
|
||
|
|
||
|
KTUtil.data(element).set('offcanvas', the);
|
||
|
}
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
init: function(options) {
|
||
|
the.events = [];
|
||
|
|
||
|
// merge default and user defined options
|
||
|
the.options = KTUtil.deepExtend({}, defaultOptions, options);
|
||
|
|
||
|
the.classBase = the.options.baseClass;
|
||
|
the.attrCustom = the.options.attrCustom;
|
||
|
the.classShown = the.classBase + '-on';
|
||
|
the.classOverlay = the.classBase + '-overlay';
|
||
|
the.target;
|
||
|
|
||
|
the.state = KTUtil.hasClass(element, the.classShown) ? 'shown' : 'hidden';
|
||
|
},
|
||
|
|
||
|
build: function() {
|
||
|
// offcanvas toggle
|
||
|
if (the.options.toggleBy) {
|
||
|
if (typeof the.options.toggleBy === 'string') {
|
||
|
KTUtil.addEvent(KTUtil.getById(the.options.toggleBy), 'click', function(e) {
|
||
|
e.preventDefault();
|
||
|
the.target = this;
|
||
|
Plugin.toggle();
|
||
|
});
|
||
|
} else if (the.options.toggleBy && the.options.toggleBy[0]) {
|
||
|
if (the.options.toggleBy[0].target) {
|
||
|
for (var i in the.options.toggleBy) {
|
||
|
KTUtil.addEvent(KTUtil.getById(the.options.toggleBy[i].target), 'click', function(e) {
|
||
|
e.preventDefault();
|
||
|
the.target = this;
|
||
|
Plugin.toggle();
|
||
|
});
|
||
|
}
|
||
|
} else {
|
||
|
for (var i in the.options.toggleBy) {
|
||
|
KTUtil.addEvent(KTUtil.getById(the.options.toggleBy[i]), 'click', function(e) {
|
||
|
e.preventDefault();
|
||
|
the.target = this;
|
||
|
Plugin.toggle();
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} else if (the.options.toggleBy && the.options.toggleBy.target) {
|
||
|
KTUtil.addEvent( KTUtil.getById(the.options.toggleBy.target), 'click', function(e) {
|
||
|
e.preventDefault();
|
||
|
the.target = this;
|
||
|
Plugin.toggle();
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// offcanvas close
|
||
|
var closeBy = KTUtil.getById(the.options.closeBy);
|
||
|
if (closeBy) {
|
||
|
KTUtil.addEvent(closeBy, 'click', function(e) {
|
||
|
e.preventDefault();
|
||
|
the.target = this;
|
||
|
Plugin.hide();
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
|
||
|
isShown: function() {
|
||
|
return (the.state == 'shown' ? true : false);
|
||
|
},
|
||
|
|
||
|
toggle: function() {;
|
||
|
Plugin.eventTrigger('toggle');
|
||
|
|
||
|
if (the.state == 'shown') {
|
||
|
Plugin.hide();
|
||
|
} else {
|
||
|
Plugin.show();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
show: function() {
|
||
|
if (the.state == 'shown') {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Plugin.eventTrigger('beforeShow');
|
||
|
|
||
|
Plugin.toggleClass('show');
|
||
|
|
||
|
// Offcanvas panel
|
||
|
KTUtil.attr(body, 'data-offcanvas-' + the.classBase, 'on');
|
||
|
KTUtil.addClass(element, the.classShown);
|
||
|
|
||
|
if (the.attrCustom.length > 0) {
|
||
|
KTUtil.attr(body, 'data-offcanvas-' + the.classCustom, 'on');
|
||
|
//KTUtil.addClass(body, the.classCustom);
|
||
|
}
|
||
|
|
||
|
the.state = 'shown';
|
||
|
|
||
|
if (the.options.overlay) {
|
||
|
the.overlay = KTUtil.insertAfter(document.createElement('DIV') , element );
|
||
|
KTUtil.addClass(the.overlay, the.classOverlay);
|
||
|
|
||
|
KTUtil.addEvent(the.overlay, 'click', function(e) {
|
||
|
//e.stopPropagation();
|
||
|
e.preventDefault();
|
||
|
Plugin.hide(the.target);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
Plugin.eventTrigger('afterShow');
|
||
|
},
|
||
|
|
||
|
hide: function() {
|
||
|
if (the.state == 'hidden') {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Plugin.eventTrigger('beforeHide');
|
||
|
|
||
|
Plugin.toggleClass('hide');
|
||
|
|
||
|
KTUtil.removeAttr(body, 'data-offcanvas-' + the.classBase);
|
||
|
KTUtil.removeClass(element, the.classShown);
|
||
|
|
||
|
if (the.attrCustom.length > 0) {
|
||
|
KTUtil.removeAttr(body, 'data-offcanvas-' + the.attrCustom);
|
||
|
}
|
||
|
|
||
|
the.state = 'hidden';
|
||
|
|
||
|
if (the.options.overlay && the.overlay) {
|
||
|
KTUtil.remove(the.overlay);
|
||
|
}
|
||
|
|
||
|
Plugin.eventTrigger('afterHide');
|
||
|
},
|
||
|
|
||
|
toggleClass: function(mode) {
|
||
|
var id = KTUtil.attr(the.target, 'id');
|
||
|
var toggleBy;
|
||
|
|
||
|
if (the.options.toggleBy && the.options.toggleBy[0] && the.options.toggleBy[0].target) {
|
||
|
for (var i in the.options.toggleBy) {
|
||
|
if (the.options.toggleBy[i].target === id) {
|
||
|
toggleBy = the.options.toggleBy[i];
|
||
|
}
|
||
|
}
|
||
|
} else if (the.options.toggleBy && the.options.toggleBy.target) {
|
||
|
toggleBy = the.options.toggleBy;
|
||
|
}
|
||
|
|
||
|
if (toggleBy) {
|
||
|
var el = KTUtil.getById(toggleBy.target);
|
||
|
|
||
|
if (mode === 'show') {
|
||
|
KTUtil.addClass(el, toggleBy.state);
|
||
|
}
|
||
|
|
||
|
if (mode === 'hide') {
|
||
|
KTUtil.removeClass(el, toggleBy.state);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
eventTrigger: function(name, args) {
|
||
|
for (var i = 0; i < the.events.length; i++) {
|
||
|
var event = the.events[i];
|
||
|
if (event.name == name) {
|
||
|
if (event.one == true) {
|
||
|
if (event.fired == false) {
|
||
|
the.events[i].fired = true;
|
||
|
return event.handler.call(this, the, args);
|
||
|
}
|
||
|
} else {
|
||
|
return event.handler.call(this, the, args);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
addEvent: function(name, handler, one) {
|
||
|
the.events.push({
|
||
|
name: name,
|
||
|
handler: handler,
|
||
|
one: one,
|
||
|
fired: false
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//////////////////////////
|
||
|
// ** Public Methods ** //
|
||
|
//////////////////////////
|
||
|
|
||
|
/**
|
||
|
* Set default options
|
||
|
* @param options
|
||
|
*/
|
||
|
the.setDefaults = function(options) {
|
||
|
defaultOptions = options;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Check if canvas is shown
|
||
|
* @returns {boolean}
|
||
|
*/
|
||
|
the.isShown = function() {
|
||
|
return Plugin.isShown();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Set to hide the canvas
|
||
|
*/
|
||
|
the.hide = function() {
|
||
|
return Plugin.hide();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Set to show the canvas
|
||
|
*/
|
||
|
the.show = function() {
|
||
|
return Plugin.show();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Attach event
|
||
|
* @param name
|
||
|
* @param handler
|
||
|
*/
|
||
|
the.on = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Attach event that will be fired once
|
||
|
* @param name
|
||
|
* @param handler
|
||
|
*/
|
||
|
the.one = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler, true);
|
||
|
};
|
||
|
|
||
|
///////////////////////////////
|
||
|
// ** Plugin Construction ** //
|
||
|
///////////////////////////////
|
||
|
|
||
|
// Run plugin
|
||
|
Plugin.construct.apply(the, [options]);
|
||
|
|
||
|
// Init done
|
||
|
init = true;
|
||
|
|
||
|
// Return plugin instance
|
||
|
return the;
|
||
|
};
|
||
|
|
||
|
// webpack support
|
||
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||
|
module.exports = KTOffcanvas;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
// Component Definition
|
||
|
var KTScrolltop = function(elementId, options) {
|
||
|
// Main object
|
||
|
var the = this;
|
||
|
var init = false;
|
||
|
|
||
|
// Get element object
|
||
|
var element = KTUtil.getById(elementId);
|
||
|
var body = KTUtil.getBody();
|
||
|
|
||
|
if (!element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Default options
|
||
|
var defaultOptions = {
|
||
|
offset: 300,
|
||
|
speed: 6000
|
||
|
};
|
||
|
|
||
|
////////////////////////////
|
||
|
// ** Private Methods ** //
|
||
|
////////////////////////////
|
||
|
|
||
|
var Plugin = {
|
||
|
/**
|
||
|
* Run plugin
|
||
|
* @returns {mscrolltop}
|
||
|
*/
|
||
|
construct: function(options) {
|
||
|
if (KTUtil.data(element).has('scrolltop')) {
|
||
|
the = KTUtil.data(element).get('scrolltop');
|
||
|
} else {
|
||
|
// reset scrolltop
|
||
|
Plugin.init(options);
|
||
|
|
||
|
// build scrolltop
|
||
|
Plugin.build();
|
||
|
|
||
|
KTUtil.data(element).set('scrolltop', the);
|
||
|
}
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles subscrolltop click toggle
|
||
|
* @returns {mscrolltop}
|
||
|
*/
|
||
|
init: function(options) {
|
||
|
the.events = [];
|
||
|
|
||
|
// merge default and user defined options
|
||
|
the.options = KTUtil.deepExtend({}, defaultOptions, options);
|
||
|
},
|
||
|
|
||
|
build: function() {
|
||
|
var timer;
|
||
|
|
||
|
window.addEventListener('scroll', function() {
|
||
|
KTUtil.throttle(timer, function() {
|
||
|
Plugin.handle();
|
||
|
}, 200);
|
||
|
});
|
||
|
|
||
|
// handle button click
|
||
|
KTUtil.addEvent(element, 'click', Plugin.scroll);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles scrolltop click scrollTop
|
||
|
*/
|
||
|
handle: function() {
|
||
|
var pos = KTUtil.getScrollTop(); // current vertical position
|
||
|
|
||
|
if (pos > the.options.offset) {
|
||
|
if (body.hasAttribute('data-scrolltop') === false) {
|
||
|
body.setAttribute('data-scrolltop', 'on');
|
||
|
}
|
||
|
} else {
|
||
|
if (body.hasAttribute('data-scrolltop') === true) {
|
||
|
body.removeAttribute('data-scrolltop');
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles scrolltop click scrollTop
|
||
|
*/
|
||
|
scroll: function(e) {
|
||
|
e.preventDefault();
|
||
|
|
||
|
KTUtil.scrollTop(0, the.options.speed);
|
||
|
},
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Trigger events
|
||
|
*/
|
||
|
eventTrigger: function(name, args) {
|
||
|
for (var i = 0; i < the.events.length; i++) {
|
||
|
var event = the.events[i];
|
||
|
if (event.name == name) {
|
||
|
if (event.one == true) {
|
||
|
if (event.fired == false) {
|
||
|
the.events[i].fired = true;
|
||
|
return event.handler.call(this, the, args);
|
||
|
}
|
||
|
} else {
|
||
|
return event.handler.call(this, the, args);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
addEvent: function(name, handler, one) {
|
||
|
the.events.push({
|
||
|
name: name,
|
||
|
handler: handler,
|
||
|
one: one,
|
||
|
fired: false
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//////////////////////////
|
||
|
// ** Public Methods ** //
|
||
|
//////////////////////////
|
||
|
|
||
|
/**
|
||
|
* Set default options
|
||
|
*/
|
||
|
|
||
|
the.setDefaults = function(options) {
|
||
|
defaultOptions = options;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Get subscrolltop mode
|
||
|
*/
|
||
|
the.on = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Set scrolltop content
|
||
|
* @returns {mscrolltop}
|
||
|
*/
|
||
|
the.one = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler, true);
|
||
|
};
|
||
|
|
||
|
///////////////////////////////
|
||
|
// ** Plugin Construction ** //
|
||
|
///////////////////////////////
|
||
|
|
||
|
// Run plugin
|
||
|
Plugin.construct.apply(the, [options]);
|
||
|
|
||
|
// Init done
|
||
|
init = true;
|
||
|
|
||
|
// Return plugin instance
|
||
|
return the;
|
||
|
};
|
||
|
|
||
|
// webpack support
|
||
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||
|
module.exports = KTScrolltop;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
// Component Definition
|
||
|
var KTToggle = function(elementId, options) {
|
||
|
// Main object
|
||
|
var the = this;
|
||
|
var init = false;
|
||
|
|
||
|
// Get element object
|
||
|
var element = KTUtil.getById(elementId);
|
||
|
|
||
|
if (!element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Default options
|
||
|
var defaultOptions = {
|
||
|
targetToggleMode: 'class' // class|attribute
|
||
|
};
|
||
|
|
||
|
////////////////////////////
|
||
|
// ** Private Methods ** //
|
||
|
////////////////////////////
|
||
|
|
||
|
var Plugin = {
|
||
|
/**
|
||
|
* Construct
|
||
|
*/
|
||
|
|
||
|
construct: function(options) {
|
||
|
if (KTUtil.data(element).has('toggle')) {
|
||
|
the = KTUtil.data(element).get('toggle');
|
||
|
} else {
|
||
|
// reset menu
|
||
|
Plugin.init(options);
|
||
|
|
||
|
// build menu
|
||
|
Plugin.build();
|
||
|
|
||
|
KTUtil.data(element).set('toggle', the);
|
||
|
}
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles subtoggle click toggle
|
||
|
*/
|
||
|
init: function(options) {
|
||
|
the.element = element;
|
||
|
the.events = [];
|
||
|
|
||
|
// Merge default and user defined options
|
||
|
the.options = KTUtil.deepExtend({}, defaultOptions, options);
|
||
|
|
||
|
//alert(the.options.target.tagName);
|
||
|
the.target = KTUtil.getById(options.target);
|
||
|
|
||
|
the.targetState = the.options.targetState;
|
||
|
the.toggleState = the.options.toggleState;
|
||
|
|
||
|
if (the.options.targetToggleMode == 'class') {
|
||
|
the.state = KTUtil.hasClasses(the.target, the.targetState) ? 'on' : 'off';
|
||
|
} else {
|
||
|
the.state = KTUtil.hasAttr(the.target, 'data-' + the.targetState) ? KTUtil.attr(the.target, 'data-' + the.targetState) : 'off';
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Setup toggle
|
||
|
*/
|
||
|
build: function() {
|
||
|
KTUtil.addEvent(element, 'mouseup', Plugin.toggle);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles offcanvas click toggle
|
||
|
*/
|
||
|
toggle: function(e) {
|
||
|
Plugin.eventTrigger('beforeToggle');
|
||
|
|
||
|
if (the.state == 'off') {
|
||
|
Plugin.toggleOn();
|
||
|
} else {
|
||
|
Plugin.toggleOff();
|
||
|
}
|
||
|
|
||
|
Plugin.eventTrigger('afterToggle');
|
||
|
|
||
|
e.preventDefault();
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles toggle click toggle
|
||
|
*/
|
||
|
toggleOn: function() {
|
||
|
Plugin.eventTrigger('beforeOn');
|
||
|
|
||
|
if (the.options.targetToggleMode == 'class') {
|
||
|
KTUtil.addClass(the.target, the.targetState);
|
||
|
} else {
|
||
|
KTUtil.attr(the.target, 'data-' + the.targetState, 'on');
|
||
|
}
|
||
|
|
||
|
if (the.toggleState) {
|
||
|
KTUtil.addClass(element, the.toggleState);
|
||
|
}
|
||
|
|
||
|
the.state = 'on';
|
||
|
|
||
|
Plugin.eventTrigger('afterOn');
|
||
|
|
||
|
Plugin.eventTrigger('toggle');
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles toggle click toggle
|
||
|
*/
|
||
|
toggleOff: function() {
|
||
|
Plugin.eventTrigger('beforeOff');
|
||
|
|
||
|
if (the.options.targetToggleMode == 'class') {
|
||
|
KTUtil.removeClass(the.target, the.targetState);
|
||
|
} else {
|
||
|
KTUtil.removeAttr(the.target, 'data-' + the.targetState);
|
||
|
}
|
||
|
|
||
|
if (the.toggleState) {
|
||
|
KTUtil.removeClass(element, the.toggleState);
|
||
|
}
|
||
|
|
||
|
the.state = 'off';
|
||
|
|
||
|
Plugin.eventTrigger('afterOff');
|
||
|
|
||
|
Plugin.eventTrigger('toggle');
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Trigger events
|
||
|
*/
|
||
|
eventTrigger: function(name) {
|
||
|
for (var i = 0; i < the.events.length; i++) {
|
||
|
var event = the.events[i];
|
||
|
|
||
|
if (event.name == name) {
|
||
|
if (event.one == true) {
|
||
|
if (event.fired == false) {
|
||
|
the.events[i].fired = true;
|
||
|
return event.handler.call(this, the);
|
||
|
}
|
||
|
} else {
|
||
|
return event.handler.call(this, the);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
addEvent: function(name, handler, one) {
|
||
|
the.events.push({
|
||
|
name: name,
|
||
|
handler: handler,
|
||
|
one: one,
|
||
|
fired: false
|
||
|
});
|
||
|
|
||
|
return the;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//////////////////////////
|
||
|
// ** Public Methods ** //
|
||
|
//////////////////////////
|
||
|
|
||
|
/**
|
||
|
* Set default options
|
||
|
*/
|
||
|
|
||
|
the.setDefaults = function(options) {
|
||
|
defaultOptions = options;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Get toggle state
|
||
|
*/
|
||
|
the.getState = function() {
|
||
|
return the.state;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Toggle
|
||
|
*/
|
||
|
the.toggle = function() {
|
||
|
return Plugin.toggle();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Toggle on
|
||
|
*/
|
||
|
the.toggleOn = function() {
|
||
|
return Plugin.toggleOn();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Toggle off
|
||
|
*/
|
||
|
the.toggleOff = function() {
|
||
|
return Plugin.toggleOff();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Attach event
|
||
|
* @returns {KTToggle}
|
||
|
*/
|
||
|
the.on = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Attach event that will be fired once
|
||
|
* @returns {KTToggle}
|
||
|
*/
|
||
|
the.one = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler, true);
|
||
|
};
|
||
|
|
||
|
// Construct plugin
|
||
|
Plugin.construct.apply(the, [options]);
|
||
|
|
||
|
return the;
|
||
|
};
|
||
|
|
||
|
// webpack support
|
||
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||
|
module.exports = KTToggle;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
/**
|
||
|
* @class KTUtil base utilize class that privides helper functions
|
||
|
*/
|
||
|
|
||
|
// Polyfills
|
||
|
/**
|
||
|
* Element.matches() polyfill (simple version)
|
||
|
* https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill
|
||
|
*/
|
||
|
if (!Element.prototype.matches) {
|
||
|
Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Element.closest() polyfill
|
||
|
* https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
|
||
|
*/
|
||
|
if (!Element.prototype.closest) {
|
||
|
if (!Element.prototype.matches) {
|
||
|
Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
|
||
|
}
|
||
|
Element.prototype.closest = function (s) {
|
||
|
var el = this;
|
||
|
var ancestor = this;
|
||
|
if (!document.documentElement.contains(el)) return null;
|
||
|
do {
|
||
|
if (ancestor.matches(s)) return ancestor;
|
||
|
ancestor = ancestor.parentElement;
|
||
|
} while (ancestor !== null);
|
||
|
return null;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* ChildNode.remove() polyfill
|
||
|
* https://gomakethings.com/removing-an-element-from-the-dom-the-es6-way/
|
||
|
* @author Chris Ferdinandi
|
||
|
* @license MIT
|
||
|
*/
|
||
|
(function (elem) {
|
||
|
for (var i = 0; i < elem.length; i++) {
|
||
|
if (!window[elem[i]] || 'remove' in window[elem[i]].prototype) continue;
|
||
|
window[elem[i]].prototype.remove = function () {
|
||
|
this.parentNode.removeChild(this);
|
||
|
};
|
||
|
}
|
||
|
})(['Element', 'CharacterData', 'DocumentType']);
|
||
|
|
||
|
//
|
||
|
// requestAnimationFrame polyfill by Erik Möller.
|
||
|
// With fixes from Paul Irish and Tino Zijdel
|
||
|
//
|
||
|
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
||
|
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
|
||
|
//
|
||
|
// MIT license
|
||
|
//
|
||
|
(function() {
|
||
|
var lastTime = 0;
|
||
|
var vendors = ['webkit', 'moz'];
|
||
|
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
|
||
|
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
|
||
|
window.cancelAnimationFrame =
|
||
|
window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
|
||
|
}
|
||
|
|
||
|
if (!window.requestAnimationFrame)
|
||
|
window.requestAnimationFrame = function(callback) {
|
||
|
var currTime = new Date().getTime();
|
||
|
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
|
||
|
var id = window.setTimeout(function() {
|
||
|
callback(currTime + timeToCall);
|
||
|
}, timeToCall);
|
||
|
lastTime = currTime + timeToCall;
|
||
|
return id;
|
||
|
};
|
||
|
|
||
|
if (!window.cancelAnimationFrame)
|
||
|
window.cancelAnimationFrame = function(id) {
|
||
|
clearTimeout(id);
|
||
|
};
|
||
|
}());
|
||
|
|
||
|
// Source: https://github.com/jserz/js_piece/blob/master/DOM/ParentNode/prepend()/prepend().md
|
||
|
(function(arr) {
|
||
|
arr.forEach(function(item) {
|
||
|
if (item.hasOwnProperty('prepend')) {
|
||
|
return;
|
||
|
}
|
||
|
Object.defineProperty(item, 'prepend', {
|
||
|
configurable: true,
|
||
|
enumerable: true,
|
||
|
writable: true,
|
||
|
value: function prepend() {
|
||
|
var argArr = Array.prototype.slice.call(arguments),
|
||
|
docFrag = document.createDocumentFragment();
|
||
|
|
||
|
argArr.forEach(function(argItem) {
|
||
|
var isNode = argItem instanceof Node;
|
||
|
docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem)));
|
||
|
});
|
||
|
|
||
|
this.insertBefore(docFrag, this.firstChild);
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
})([Element.prototype, Document.prototype, DocumentFragment.prototype]);
|
||
|
|
||
|
// Global variables
|
||
|
window.KTUtilElementDataStore = {};
|
||
|
window.KTUtilElementDataStoreID = 0;
|
||
|
window.KTUtilDelegatedEventHandlers = {};
|
||
|
|
||
|
var KTUtil = function() {
|
||
|
var resizeHandlers = [];
|
||
|
|
||
|
/** @type {object} breakpoints The device width breakpoints **/
|
||
|
var breakpoints = {
|
||
|
sm: 544, // Small screen / phone
|
||
|
md: 768, // Medium screen / tablet
|
||
|
lg: 992, // Large screen / desktop
|
||
|
xl: 1200 // Extra large screen / wide desktop
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Handle window resize event with some
|
||
|
* delay to attach event handlers upon resize complete
|
||
|
*/
|
||
|
var _windowResizeHandler = function() {
|
||
|
var _runResizeHandlers = function() {
|
||
|
// reinitialize other subscribed elements
|
||
|
for (var i = 0; i < resizeHandlers.length; i++) {
|
||
|
var each = resizeHandlers[i];
|
||
|
each.call();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
var timer;
|
||
|
|
||
|
window.addEventListener('resize', function() {
|
||
|
KTUtil.throttle(timer, function() {
|
||
|
_runResizeHandlers();
|
||
|
}, 200);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
return {
|
||
|
/**
|
||
|
* Class main initializer.
|
||
|
* @param {object} settings.
|
||
|
* @returns null
|
||
|
*/
|
||
|
//main function to initiate the theme
|
||
|
init: function(settings) {
|
||
|
if (settings && settings.breakpoints) {
|
||
|
breakpoints = settings.breakpoints;
|
||
|
}
|
||
|
|
||
|
_windowResizeHandler();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Adds window resize event handler.
|
||
|
* @param {function} callback function.
|
||
|
*/
|
||
|
addResizeHandler: function(callback) {
|
||
|
resizeHandlers.push(callback);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Removes window resize event handler.
|
||
|
* @param {function} callback function.
|
||
|
*/
|
||
|
removeResizeHandler: function(callback) {
|
||
|
for (var i = 0; i < resizeHandlers.length; i++) {
|
||
|
if (callback === resizeHandlers[i]) {
|
||
|
delete resizeHandlers[i];
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Trigger window resize handlers.
|
||
|
*/
|
||
|
runResizeHandlers: function() {
|
||
|
_runResizeHandlers();
|
||
|
},
|
||
|
|
||
|
resize: function() {
|
||
|
if (typeof(Event) === 'function') {
|
||
|
// modern browsers
|
||
|
window.dispatchEvent(new Event('resize'));
|
||
|
} else {
|
||
|
// for IE and other old browsers
|
||
|
// causes deprecation warning on modern browsers
|
||
|
var evt = window.document.createEvent('UIEvents');
|
||
|
evt.initUIEvent('resize', true, false, window, 0);
|
||
|
window.dispatchEvent(evt);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get GET parameter value from URL.
|
||
|
* @param {string} paramName Parameter name.
|
||
|
* @returns {string}
|
||
|
*/
|
||
|
getURLParam: function(paramName) {
|
||
|
var searchString = window.location.search.substring(1),
|
||
|
i, val, params = searchString.split("&");
|
||
|
|
||
|
for (i = 0; i < params.length; i++) {
|
||
|
val = params[i].split("=");
|
||
|
if (val[0] == paramName) {
|
||
|
return unescape(val[1]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Checks whether current device is mobile touch.
|
||
|
* @returns {boolean}
|
||
|
*/
|
||
|
isMobileDevice: function() {
|
||
|
var test = (this.getViewPort().width < this.getBreakpoint('lg') ? true : false);
|
||
|
|
||
|
if (test === false) {
|
||
|
// For use within normal web clients
|
||
|
test = navigator.userAgent.match(/iPad/i) != null;
|
||
|
}
|
||
|
|
||
|
return test;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Checks whether current device is desktop.
|
||
|
* @returns {boolean}
|
||
|
*/
|
||
|
isDesktopDevice: function() {
|
||
|
return KTUtil.isMobileDevice() ? false : true;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Gets browser window viewport size. Ref:
|
||
|
* http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/
|
||
|
* @returns {object}
|
||
|
*/
|
||
|
getViewPort: function() {
|
||
|
var e = window,
|
||
|
a = 'inner';
|
||
|
if (!('innerWidth' in window)) {
|
||
|
a = 'client';
|
||
|
e = document.documentElement || document.body;
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
width: e[a + 'Width'],
|
||
|
height: e[a + 'Height']
|
||
|
};
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Checks whether given device mode is currently activated.
|
||
|
* @param {string} mode Responsive mode name(e.g: desktop,
|
||
|
* desktop-and-tablet, tablet, tablet-and-mobile, mobile)
|
||
|
* @returns {boolean}
|
||
|
*/
|
||
|
isInResponsiveRange: function(mode) {
|
||
|
var breakpoint = this.getViewPort().width;
|
||
|
|
||
|
if (mode == 'general') {
|
||
|
return true;
|
||
|
} else if (mode == 'desktop' && breakpoint >= (this.getBreakpoint('lg') + 1)) {
|
||
|
return true;
|
||
|
} else if (mode == 'tablet' && (breakpoint >= (this.getBreakpoint('md') + 1) && breakpoint < this.getBreakpoint('lg'))) {
|
||
|
return true;
|
||
|
} else if (mode == 'mobile' && breakpoint <= this.getBreakpoint('md')) {
|
||
|
return true;
|
||
|
} else if (mode == 'desktop-and-tablet' && breakpoint >= (this.getBreakpoint('md') + 1)) {
|
||
|
return true;
|
||
|
} else if (mode == 'tablet-and-mobile' && breakpoint <= this.getBreakpoint('lg')) {
|
||
|
return true;
|
||
|
} else if (mode == 'minimal-desktop-and-below' && breakpoint <= this.getBreakpoint('xl')) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Checks whether given device mode is currently activated.
|
||
|
* @param {string} mode Responsive mode name(e.g: desktop,
|
||
|
* desktop-and-tablet, tablet, tablet-and-mobile, mobile)
|
||
|
* @returns {boolean}
|
||
|
*/
|
||
|
isBreakpointUp: function(mode) {
|
||
|
var width = this.getViewPort().width;
|
||
|
var breakpoint = this.getBreakpoint(mode);
|
||
|
|
||
|
return (width >= breakpoint);
|
||
|
},
|
||
|
|
||
|
isBreakpointDown: function(mode) {
|
||
|
var width = this.getViewPort().width;
|
||
|
var breakpoint = this.getBreakpoint(mode);
|
||
|
|
||
|
return (width < breakpoint);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Generates unique ID for give prefix.
|
||
|
* @param {string} prefix Prefix for generated ID
|
||
|
* @returns {boolean}
|
||
|
*/
|
||
|
getUniqueID: function(prefix) {
|
||
|
return prefix + Math.floor(Math.random() * (new Date()).getTime());
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Gets window width for give breakpoint mode.
|
||
|
* @param {string} mode Responsive mode name(e.g: xl, lg, md, sm)
|
||
|
* @returns {number}
|
||
|
*/
|
||
|
getBreakpoint: function(mode) {
|
||
|
return breakpoints[mode];
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Checks whether object has property matchs given key path.
|
||
|
* @param {object} obj Object contains values paired with given key path
|
||
|
* @param {string} keys Keys path seperated with dots
|
||
|
* @returns {object}
|
||
|
*/
|
||
|
isset: function(obj, keys) {
|
||
|
var stone;
|
||
|
|
||
|
keys = keys || '';
|
||
|
|
||
|
if (keys.indexOf('[') !== -1) {
|
||
|
throw new Error('Unsupported object path notation.');
|
||
|
}
|
||
|
|
||
|
keys = keys.split('.');
|
||
|
|
||
|
do {
|
||
|
if (obj === undefined) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
stone = keys.shift();
|
||
|
|
||
|
if (!obj.hasOwnProperty(stone)) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
obj = obj[stone];
|
||
|
|
||
|
} while (keys.length);
|
||
|
|
||
|
return true;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Gets highest z-index of the given element parents
|
||
|
* @param {object} el jQuery element object
|
||
|
* @returns {number}
|
||
|
*/
|
||
|
getHighestZindex: function(el) {
|
||
|
var position, value;
|
||
|
|
||
|
while (el && el !== document) {
|
||
|
// Ignore z-index if position is set to a value where z-index is ignored by the browser
|
||
|
// This makes behavior of this function consistent across browsers
|
||
|
// WebKit always returns auto if the element is positioned
|
||
|
position = KTUtil.css(el, 'position');
|
||
|
|
||
|
if (position === "absolute" || position === "relative" || position === "fixed") {
|
||
|
// IE returns 0 when zIndex is not specified
|
||
|
// other browsers return a string
|
||
|
// we ignore the case of nested elements with an explicit value of 0
|
||
|
// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
|
||
|
value = parseInt(KTUtil.css(el, 'z-index'));
|
||
|
|
||
|
if (!isNaN(value) && value !== 0) {
|
||
|
return value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
el = el.parentNode;
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Checks whether the element has any parent with fixed positionfreg
|
||
|
* @param {object} el jQuery element object
|
||
|
* @returns {boolean}
|
||
|
*/
|
||
|
hasFixedPositionedParent: function(el) {
|
||
|
var position;
|
||
|
|
||
|
while (el && el !== document) {
|
||
|
position = KTUtil.css(el, 'position');
|
||
|
|
||
|
if (position === "fixed") {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
el = el.parentNode;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Simulates delay
|
||
|
*/
|
||
|
sleep: function(milliseconds) {
|
||
|
var start = new Date().getTime();
|
||
|
for (var i = 0; i < 1e7; i++) {
|
||
|
if ((new Date().getTime() - start) > milliseconds) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Gets randomly generated integer value within given min and max range
|
||
|
* @param {number} min Range start value
|
||
|
* @param {number} max Range end value
|
||
|
* @returns {number}
|
||
|
*/
|
||
|
getRandomInt: function(min, max) {
|
||
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Checks whether Angular library is included
|
||
|
* @returns {boolean}
|
||
|
*/
|
||
|
isAngularVersion: function() {
|
||
|
return window.Zone !== undefined ? true : false;
|
||
|
},
|
||
|
|
||
|
// jQuery Workarounds
|
||
|
|
||
|
// Deep extend: $.extend(true, {}, objA, objB);
|
||
|
deepExtend: function(out) {
|
||
|
out = out || {};
|
||
|
|
||
|
for (var i = 1; i < arguments.length; i++) {
|
||
|
var obj = arguments[i];
|
||
|
|
||
|
if (!obj)
|
||
|
continue;
|
||
|
|
||
|
for (var key in obj) {
|
||
|
if (obj.hasOwnProperty(key)) {
|
||
|
if (typeof obj[key] === 'object')
|
||
|
out[key] = KTUtil.deepExtend(out[key], obj[key]);
|
||
|
else
|
||
|
out[key] = obj[key];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return out;
|
||
|
},
|
||
|
|
||
|
// extend: $.extend({}, objA, objB);
|
||
|
extend: function(out) {
|
||
|
out = out || {};
|
||
|
|
||
|
for (var i = 1; i < arguments.length; i++) {
|
||
|
if (!arguments[i])
|
||
|
continue;
|
||
|
|
||
|
for (var key in arguments[i]) {
|
||
|
if (arguments[i].hasOwnProperty(key))
|
||
|
out[key] = arguments[i][key];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return out;
|
||
|
},
|
||
|
|
||
|
getById: function(el) {
|
||
|
if (typeof el === 'string') {
|
||
|
return document.getElementById(el);
|
||
|
} else {
|
||
|
return el;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
getByTag: function(query) {
|
||
|
return document.getElementsByTagName(query);
|
||
|
},
|
||
|
|
||
|
getByTagName: function(query) {
|
||
|
return document.getElementsByTagName(query);
|
||
|
},
|
||
|
|
||
|
getByClass: function(query) {
|
||
|
return document.getElementsByClassName(query);
|
||
|
},
|
||
|
|
||
|
getBody: function() {
|
||
|
return document.getElementsByTagName('body')[0];
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Checks whether the element has given classes
|
||
|
* @param {object} el jQuery element object
|
||
|
* @param {string} Classes string
|
||
|
* @returns {boolean}
|
||
|
*/
|
||
|
hasClasses: function(el, classes) {
|
||
|
if (!el) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var classesArr = classes.split(" ");
|
||
|
|
||
|
for (var i = 0; i < classesArr.length; i++) {
|
||
|
if (KTUtil.hasClass(el, KTUtil.trim(classesArr[i])) == false) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
},
|
||
|
|
||
|
hasClass: function(el, className) {
|
||
|
if (!el) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
return el.classList ? el.classList.contains(className) : new RegExp('\\b' + className + '\\b').test(el.className);
|
||
|
},
|
||
|
|
||
|
addClass: function(el, className) {
|
||
|
if (!el || typeof className === 'undefined') {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var classNames = className.split(' ');
|
||
|
|
||
|
if (el.classList) {
|
||
|
for (var i = 0; i < classNames.length; i++) {
|
||
|
if (classNames[i] && classNames[i].length > 0) {
|
||
|
el.classList.add(KTUtil.trim(classNames[i]));
|
||
|
}
|
||
|
}
|
||
|
} else if (!KTUtil.hasClass(el, className)) {
|
||
|
for (var x = 0; x < classNames.length; x++) {
|
||
|
el.className += ' ' + KTUtil.trim(classNames[x]);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
removeClass: function(el, className) {
|
||
|
if (!el || typeof className === 'undefined') {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var classNames = className.split(' ');
|
||
|
|
||
|
if (el.classList) {
|
||
|
for (var i = 0; i < classNames.length; i++) {
|
||
|
el.classList.remove(KTUtil.trim(classNames[i]));
|
||
|
}
|
||
|
} else if (KTUtil.hasClass(el, className)) {
|
||
|
for (var x = 0; x < classNames.length; x++) {
|
||
|
el.className = el.className.replace(new RegExp('\\b' + KTUtil.trim(classNames[x]) + '\\b', 'g'), '');
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
triggerCustomEvent: function(el, eventName, data) {
|
||
|
var event;
|
||
|
if (window.CustomEvent) {
|
||
|
event = new CustomEvent(eventName, {
|
||
|
detail: data
|
||
|
});
|
||
|
} else {
|
||
|
event = document.createEvent('CustomEvent');
|
||
|
event.initCustomEvent(eventName, true, true, data);
|
||
|
}
|
||
|
|
||
|
el.dispatchEvent(event);
|
||
|
},
|
||
|
|
||
|
triggerEvent: function(node, eventName) {
|
||
|
// Make sure we use the ownerDocument from the provided node to avoid cross-window problems
|
||
|
var doc;
|
||
|
if (node.ownerDocument) {
|
||
|
doc = node.ownerDocument;
|
||
|
} else if (node.nodeType == 9) {
|
||
|
// the node may be the document itself, nodeType 9 = DOCUMENT_NODE
|
||
|
doc = node;
|
||
|
} else {
|
||
|
throw new Error("Invalid node passed to fireEvent: " + node.id);
|
||
|
}
|
||
|
|
||
|
if (node.dispatchEvent) {
|
||
|
// Gecko-style approach (now the standard) takes more work
|
||
|
var eventClass = "";
|
||
|
|
||
|
// Different events have different event classes.
|
||
|
// If this switch statement can't map an eventName to an eventClass,
|
||
|
// the event firing is going to fail.
|
||
|
switch (eventName) {
|
||
|
case "click": // Dispatching of 'click' appears to not work correctly in Safari. Use 'mousedown' or 'mouseup' instead.
|
||
|
case "mouseenter":
|
||
|
case "mouseleave":
|
||
|
case "mousedown":
|
||
|
case "mouseup":
|
||
|
eventClass = "MouseEvents";
|
||
|
break;
|
||
|
|
||
|
case "focus":
|
||
|
case "change":
|
||
|
case "blur":
|
||
|
case "select":
|
||
|
eventClass = "HTMLEvents";
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
throw "fireEvent: Couldn't find an event class for event '" + eventName + "'.";
|
||
|
break;
|
||
|
}
|
||
|
var event = doc.createEvent(eventClass);
|
||
|
|
||
|
var bubbles = eventName == "change" ? false : true;
|
||
|
event.initEvent(eventName, bubbles, true); // All events created as bubbling and cancelable.
|
||
|
|
||
|
event.synthetic = true; // allow detection of synthetic events
|
||
|
// The second parameter says go ahead with the default action
|
||
|
node.dispatchEvent(event, true);
|
||
|
} else if (node.fireEvent) {
|
||
|
// IE-old school style
|
||
|
var event = doc.createEventObject();
|
||
|
event.synthetic = true; // allow detection of synthetic events
|
||
|
node.fireEvent("on" + eventName, event);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
index: function( el ){
|
||
|
var c = el.parentNode.children, i = 0;
|
||
|
for(; i < c.length; i++ )
|
||
|
if( c[i] == el ) return i;
|
||
|
},
|
||
|
|
||
|
trim: function(string) {
|
||
|
return string.trim();
|
||
|
},
|
||
|
|
||
|
eventTriggered: function(e) {
|
||
|
if (e.currentTarget.dataset.triggered) {
|
||
|
return true;
|
||
|
} else {
|
||
|
e.currentTarget.dataset.triggered = true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
remove: function(el) {
|
||
|
if (el && el.parentNode) {
|
||
|
el.parentNode.removeChild(el);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
find: function(parent, query) {
|
||
|
parent = KTUtil.getById(parent);
|
||
|
if (parent) {
|
||
|
return parent.querySelector(query);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
findAll: function(parent, query) {
|
||
|
parent = KTUtil.getById(parent);
|
||
|
if (parent) {
|
||
|
return parent.querySelectorAll(query);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
insertAfter: function(el, referenceNode) {
|
||
|
return referenceNode.parentNode.insertBefore(el, referenceNode.nextSibling);
|
||
|
},
|
||
|
|
||
|
parents: function(elem, selector) {
|
||
|
// Element.matches() polyfill
|
||
|
if (!Element.prototype.matches) {
|
||
|
Element.prototype.matches =
|
||
|
Element.prototype.matchesSelector ||
|
||
|
Element.prototype.mozMatchesSelector ||
|
||
|
Element.prototype.msMatchesSelector ||
|
||
|
Element.prototype.oMatchesSelector ||
|
||
|
Element.prototype.webkitMatchesSelector ||
|
||
|
function(s) {
|
||
|
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
|
||
|
i = matches.length;
|
||
|
while (--i >= 0 && matches.item(i) !== this) {}
|
||
|
return i > -1;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
// Set up a parent array
|
||
|
var parents = [];
|
||
|
|
||
|
// Push each parent element to the array
|
||
|
for ( ; elem && elem !== document; elem = elem.parentNode ) {
|
||
|
if (selector) {
|
||
|
if (elem.matches(selector)) {
|
||
|
parents.push(elem);
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
parents.push(elem);
|
||
|
}
|
||
|
|
||
|
// Return our parent array
|
||
|
return parents;
|
||
|
},
|
||
|
|
||
|
children: function(el, selector, log) {
|
||
|
if (!el || !el.childNodes) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var result = [],
|
||
|
i = 0,
|
||
|
l = el.childNodes.length;
|
||
|
|
||
|
for (var i; i < l; ++i) {
|
||
|
if (el.childNodes[i].nodeType == 1 && KTUtil.matches(el.childNodes[i], selector, log)) {
|
||
|
result.push(el.childNodes[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
child: function(el, selector, log) {
|
||
|
var children = KTUtil.children(el, selector, log);
|
||
|
|
||
|
return children ? children[0] : null;
|
||
|
},
|
||
|
|
||
|
matches: function(el, selector, log) {
|
||
|
var p = Element.prototype;
|
||
|
var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) {
|
||
|
return [].indexOf.call(document.querySelectorAll(s), this) !== -1;
|
||
|
};
|
||
|
|
||
|
if (el && el.tagName) {
|
||
|
return f.call(el, selector);
|
||
|
} else {
|
||
|
return false;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
data: function(el) {
|
||
|
return {
|
||
|
set: function(name, data) {
|
||
|
if (!el) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (el.customDataTag === undefined) {
|
||
|
window.KTUtilElementDataStoreID++;
|
||
|
el.customDataTag = window.KTUtilElementDataStoreID;
|
||
|
}
|
||
|
|
||
|
if (window.KTUtilElementDataStore[el.customDataTag] === undefined) {
|
||
|
window.KTUtilElementDataStore[el.customDataTag] = {};
|
||
|
}
|
||
|
|
||
|
window.KTUtilElementDataStore[el.customDataTag][name] = data;
|
||
|
},
|
||
|
|
||
|
get: function(name) {
|
||
|
if (!el) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (el.customDataTag === undefined) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
return this.has(name) ? window.KTUtilElementDataStore[el.customDataTag][name] : null;
|
||
|
},
|
||
|
|
||
|
has: function(name) {
|
||
|
if (!el) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (el.customDataTag === undefined) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return (window.KTUtilElementDataStore[el.customDataTag] && window.KTUtilElementDataStore[el.customDataTag][name]) ? true : false;
|
||
|
},
|
||
|
|
||
|
remove: function(name) {
|
||
|
if (el && this.has(name)) {
|
||
|
delete window.KTUtilElementDataStore[el.customDataTag][name];
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
},
|
||
|
|
||
|
outerWidth: function(el, margin) {
|
||
|
var width;
|
||
|
|
||
|
if (margin === true) {
|
||
|
width = parseFloat(el.offsetWidth);
|
||
|
width += parseFloat(KTUtil.css(el, 'margin-left')) + parseFloat(KTUtil.css(el, 'margin-right'));
|
||
|
|
||
|
return parseFloat(width);
|
||
|
} else {
|
||
|
width = parseFloat(el.offsetWidth);
|
||
|
|
||
|
return width;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
offset: function(el) {
|
||
|
var rect, win;
|
||
|
|
||
|
if ( !el ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
|
||
|
// Support: IE <=11 only
|
||
|
// Running getBoundingClientRect on a
|
||
|
// disconnected node in IE throws an error
|
||
|
|
||
|
if ( !el.getClientRects().length ) {
|
||
|
return { top: 0, left: 0 };
|
||
|
}
|
||
|
|
||
|
// Get document-relative position by adding viewport scroll to viewport-relative gBCR
|
||
|
rect = el.getBoundingClientRect();
|
||
|
win = el.ownerDocument.defaultView;
|
||
|
|
||
|
return {
|
||
|
top: rect.top + win.pageYOffset,
|
||
|
left: rect.left + win.pageXOffset
|
||
|
};
|
||
|
},
|
||
|
|
||
|
height: function(el) {
|
||
|
return KTUtil.css(el, 'height');
|
||
|
},
|
||
|
|
||
|
outerHeight: function(el, withMargic = false) {
|
||
|
var height = el.offsetHeight;
|
||
|
var style;
|
||
|
|
||
|
if (withMargic) {
|
||
|
style = getComputedStyle(el);
|
||
|
height += parseInt(style.marginTop) + parseInt(style.marginBottom);
|
||
|
|
||
|
return height;
|
||
|
} else {
|
||
|
return height;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
visible: function(el) {
|
||
|
return !(el.offsetWidth === 0 && el.offsetHeight === 0);
|
||
|
},
|
||
|
|
||
|
attr: function(el, name, value) {
|
||
|
if (el == undefined) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (value !== undefined) {
|
||
|
el.setAttribute(name, value);
|
||
|
} else {
|
||
|
return el.getAttribute(name);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
hasAttr: function(el, name) {
|
||
|
if (el == undefined) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
return el.getAttribute(name) ? true : false;
|
||
|
},
|
||
|
|
||
|
removeAttr: function(el, name) {
|
||
|
if (el == undefined) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
el.removeAttribute(name);
|
||
|
},
|
||
|
|
||
|
animate: function(from, to, duration, update, easing, done) {
|
||
|
/**
|
||
|
* TinyAnimate.easings
|
||
|
* Adapted from jQuery Easing
|
||
|
*/
|
||
|
var easings = {};
|
||
|
var easing;
|
||
|
|
||
|
easings.linear = function(t, b, c, d) {
|
||
|
return c * t / d + b;
|
||
|
};
|
||
|
|
||
|
easing = easings.linear;
|
||
|
|
||
|
// Early bail out if called incorrectly
|
||
|
if (typeof from !== 'number' ||
|
||
|
typeof to !== 'number' ||
|
||
|
typeof duration !== 'number' ||
|
||
|
typeof update !== 'function') {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Create mock done() function if necessary
|
||
|
if (typeof done !== 'function') {
|
||
|
done = function() {};
|
||
|
}
|
||
|
|
||
|
// Pick implementation (requestAnimationFrame | setTimeout)
|
||
|
var rAF = window.requestAnimationFrame || function(callback) {
|
||
|
window.setTimeout(callback, 1000 / 50);
|
||
|
};
|
||
|
|
||
|
// Animation loop
|
||
|
var canceled = false;
|
||
|
var change = to - from;
|
||
|
|
||
|
function loop(timestamp) {
|
||
|
var time = (timestamp || +new Date()) - start;
|
||
|
|
||
|
if (time >= 0) {
|
||
|
update(easing(time, from, change, duration));
|
||
|
}
|
||
|
if (time >= 0 && time >= duration) {
|
||
|
update(to);
|
||
|
done();
|
||
|
} else {
|
||
|
rAF(loop);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
update(from);
|
||
|
|
||
|
// Start animation loop
|
||
|
var start = window.performance && window.performance.now ? window.performance.now() : +new Date();
|
||
|
|
||
|
rAF(loop);
|
||
|
},
|
||
|
|
||
|
actualCss: function(el, prop, cache) {
|
||
|
var css = '';
|
||
|
|
||
|
if (el instanceof HTMLElement === false) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!el.getAttribute('kt-hidden-' + prop) || cache === false) {
|
||
|
var value;
|
||
|
|
||
|
// the element is hidden so:
|
||
|
// making the el block so we can meassure its height but still be hidden
|
||
|
css = el.style.cssText;
|
||
|
el.style.cssText = 'position: absolute; visibility: hidden; display: block;';
|
||
|
|
||
|
if (prop == 'width') {
|
||
|
value = el.offsetWidth;
|
||
|
} else if (prop == 'height') {
|
||
|
value = el.offsetHeight;
|
||
|
}
|
||
|
|
||
|
el.style.cssText = css;
|
||
|
|
||
|
// store it in cache
|
||
|
el.setAttribute('kt-hidden-' + prop, value);
|
||
|
|
||
|
return parseFloat(value);
|
||
|
} else {
|
||
|
// store it in cache
|
||
|
return parseFloat(el.getAttribute('kt-hidden-' + prop));
|
||
|
}
|
||
|
},
|
||
|
|
||
|
actualHeight: function(el, cache) {
|
||
|
return KTUtil.actualCss(el, 'height', cache);
|
||
|
},
|
||
|
|
||
|
actualWidth: function(el, cache) {
|
||
|
return KTUtil.actualCss(el, 'width', cache);
|
||
|
},
|
||
|
|
||
|
getScroll: function(element, method) {
|
||
|
// The passed in `method` value should be 'Top' or 'Left'
|
||
|
method = 'scroll' + method;
|
||
|
return (element == window || element == document) ? (
|
||
|
self[(method == 'scrollTop') ? 'pageYOffset' : 'pageXOffset'] ||
|
||
|
(browserSupportsBoxModel && document.documentElement[method]) ||
|
||
|
document.body[method]
|
||
|
) : element[method];
|
||
|
},
|
||
|
|
||
|
css: function(el, styleProp, value) {
|
||
|
if (!el) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (value !== undefined) {
|
||
|
el.style[styleProp] = value;
|
||
|
} else {
|
||
|
var defaultView = (el.ownerDocument || document).defaultView;
|
||
|
// W3C standard way:
|
||
|
if (defaultView && defaultView.getComputedStyle) {
|
||
|
// sanitize property name to css notation
|
||
|
// (hyphen separated words eg. font-Size)
|
||
|
styleProp = styleProp.replace(/([A-Z])/g, "-$1").toLowerCase();
|
||
|
return defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
|
||
|
} else if (el.currentStyle) { // IE
|
||
|
// sanitize property name to camelCase
|
||
|
styleProp = styleProp.replace(/\-(\w)/g, function(str, letter) {
|
||
|
return letter.toUpperCase();
|
||
|
});
|
||
|
value = el.currentStyle[styleProp];
|
||
|
// convert other units to pixels on IE
|
||
|
if (/^\d+(em|pt|%|ex)?$/i.test(value)) {
|
||
|
return (function(value) {
|
||
|
var oldLeft = el.style.left,
|
||
|
oldRsLeft = el.runtimeStyle.left;
|
||
|
el.runtimeStyle.left = el.currentStyle.left;
|
||
|
el.style.left = value || 0;
|
||
|
value = el.style.pixelLeft + "px";
|
||
|
el.style.left = oldLeft;
|
||
|
el.runtimeStyle.left = oldRsLeft;
|
||
|
return value;
|
||
|
})(value);
|
||
|
}
|
||
|
return value;
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
slide: function(el, dir, speed, callback, recalcMaxHeight) {
|
||
|
if (!el || (dir == 'up' && KTUtil.visible(el) === false) || (dir == 'down' && KTUtil.visible(el) === true)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
speed = (speed ? speed : 600);
|
||
|
var calcHeight = KTUtil.actualHeight(el);
|
||
|
var calcPaddingTop = false;
|
||
|
var calcPaddingBottom = false;
|
||
|
|
||
|
if (KTUtil.css(el, 'padding-top') && KTUtil.data(el).has('slide-padding-top') !== true) {
|
||
|
KTUtil.data(el).set('slide-padding-top', KTUtil.css(el, 'padding-top'));
|
||
|
}
|
||
|
|
||
|
if (KTUtil.css(el, 'padding-bottom') && KTUtil.data(el).has('slide-padding-bottom') !== true) {
|
||
|
KTUtil.data(el).set('slide-padding-bottom', KTUtil.css(el, 'padding-bottom'));
|
||
|
}
|
||
|
|
||
|
if (KTUtil.data(el).has('slide-padding-top')) {
|
||
|
calcPaddingTop = parseInt(KTUtil.data(el).get('slide-padding-top'));
|
||
|
}
|
||
|
|
||
|
if (KTUtil.data(el).has('slide-padding-bottom')) {
|
||
|
calcPaddingBottom = parseInt(KTUtil.data(el).get('slide-padding-bottom'));
|
||
|
}
|
||
|
|
||
|
if (dir == 'up') { // up
|
||
|
el.style.cssText = 'display: block; overflow: hidden;';
|
||
|
|
||
|
if (calcPaddingTop) {
|
||
|
KTUtil.animate(0, calcPaddingTop, speed, function(value) {
|
||
|
el.style.paddingTop = (calcPaddingTop - value) + 'px';
|
||
|
}, 'linear');
|
||
|
}
|
||
|
|
||
|
if (calcPaddingBottom) {
|
||
|
KTUtil.animate(0, calcPaddingBottom, speed, function(value) {
|
||
|
el.style.paddingBottom = (calcPaddingBottom - value) + 'px';
|
||
|
}, 'linear');
|
||
|
}
|
||
|
|
||
|
KTUtil.animate(0, calcHeight, speed, function(value) {
|
||
|
el.style.height = (calcHeight - value) + 'px';
|
||
|
}, 'linear', function() {
|
||
|
el.style.height = '';
|
||
|
el.style.display = 'none';
|
||
|
|
||
|
if (typeof callback === 'function') {
|
||
|
callback();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
|
||
|
} else if (dir == 'down') { // down
|
||
|
el.style.cssText = 'display: block; overflow: hidden;';
|
||
|
|
||
|
if (calcPaddingTop) {
|
||
|
KTUtil.animate(0, calcPaddingTop, speed, function(value) {//
|
||
|
el.style.paddingTop = value + 'px';
|
||
|
}, 'linear', function() {
|
||
|
el.style.paddingTop = '';
|
||
|
});
|
||
|
}
|
||
|
|
||
|
if (calcPaddingBottom) {
|
||
|
KTUtil.animate(0, calcPaddingBottom, speed, function(value) {
|
||
|
el.style.paddingBottom = value + 'px';
|
||
|
}, 'linear', function() {
|
||
|
el.style.paddingBottom = '';
|
||
|
});
|
||
|
}
|
||
|
|
||
|
KTUtil.animate(0, calcHeight, speed, function(value) {
|
||
|
el.style.height = value + 'px';
|
||
|
}, 'linear', function() {
|
||
|
el.style.height = '';
|
||
|
el.style.display = '';
|
||
|
el.style.overflow = '';
|
||
|
|
||
|
if (typeof callback === 'function') {
|
||
|
callback();
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
|
||
|
slideUp: function(el, speed, callback) {
|
||
|
KTUtil.slide(el, 'up', speed, callback);
|
||
|
},
|
||
|
|
||
|
slideDown: function(el, speed, callback) {
|
||
|
KTUtil.slide(el, 'down', speed, callback);
|
||
|
},
|
||
|
|
||
|
show: function(el, display) {
|
||
|
if (typeof el !== 'undefined') {
|
||
|
el.style.display = (display ? display : 'block');
|
||
|
}
|
||
|
},
|
||
|
|
||
|
hide: function(el) {
|
||
|
if (typeof el !== 'undefined') {
|
||
|
el.style.display = 'none';
|
||
|
}
|
||
|
},
|
||
|
|
||
|
addEvent: function(el, type, handler, one) {
|
||
|
if (typeof el !== 'undefined' && el !== null) {
|
||
|
el.addEventListener(type, handler);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
removeEvent: function(el, type, handler) {
|
||
|
if (el !== null) {
|
||
|
el.removeEventListener(type, handler);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
on: function(element, selector, event, handler) {
|
||
|
if (!selector) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var eventId = KTUtil.getUniqueID('event');
|
||
|
|
||
|
window.KTUtilDelegatedEventHandlers[eventId] = function(e) {
|
||
|
var targets = element.querySelectorAll(selector);
|
||
|
var target = e.target;
|
||
|
|
||
|
while (target && target !== element) {
|
||
|
for (var i = 0, j = targets.length; i < j; i++) {
|
||
|
if (target === targets[i]) {
|
||
|
handler.call(target, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
target = target.parentNode;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
KTUtil.addEvent(element, event, window.KTUtilDelegatedEventHandlers[eventId]);
|
||
|
|
||
|
return eventId;
|
||
|
},
|
||
|
|
||
|
off: function(element, event, eventId) {
|
||
|
if (!element || !window.KTUtilDelegatedEventHandlers[eventId]) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
KTUtil.removeEvent(element, event, window.KTUtilDelegatedEventHandlers[eventId]);
|
||
|
|
||
|
delete window.KTUtilDelegatedEventHandlers[eventId];
|
||
|
},
|
||
|
|
||
|
one: function onetime(el, type, callback) {
|
||
|
el.addEventListener(type, function callee(e) {
|
||
|
// remove event
|
||
|
if (e.target && e.target.removeEventListener) {
|
||
|
e.target.removeEventListener(e.type, callee);
|
||
|
}
|
||
|
|
||
|
// need to verify from https://themeforest.net/author_dashboard#comment_23615588
|
||
|
if (el && el.removeEventListener) {
|
||
|
e.currentTarget.removeEventListener(e.type, callee);
|
||
|
}
|
||
|
|
||
|
// call handler
|
||
|
return callback(e);
|
||
|
});
|
||
|
},
|
||
|
|
||
|
hash: function(str) {
|
||
|
var hash = 0,
|
||
|
i, chr;
|
||
|
|
||
|
if (str.length === 0) return hash;
|
||
|
for (i = 0; i < str.length; i++) {
|
||
|
chr = str.charCodeAt(i);
|
||
|
hash = ((hash << 5) - hash) + chr;
|
||
|
hash |= 0; // Convert to 32bit integer
|
||
|
}
|
||
|
|
||
|
return hash;
|
||
|
},
|
||
|
|
||
|
animateClass: function(el, animationName, callback) {
|
||
|
var animation;
|
||
|
var animations = {
|
||
|
animation: 'animationend',
|
||
|
OAnimation: 'oAnimationEnd',
|
||
|
MozAnimation: 'mozAnimationEnd',
|
||
|
WebkitAnimation: 'webkitAnimationEnd',
|
||
|
msAnimation: 'msAnimationEnd',
|
||
|
};
|
||
|
|
||
|
for (var t in animations) {
|
||
|
if (el.style[t] !== undefined) {
|
||
|
animation = animations[t];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
KTUtil.addClass(el, 'animated ' + animationName);
|
||
|
|
||
|
KTUtil.one(el, animation, function() {
|
||
|
KTUtil.removeClass(el, 'animated ' + animationName);
|
||
|
});
|
||
|
|
||
|
if (callback) {
|
||
|
KTUtil.one(el, animation, callback);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
transitionEnd: function(el, callback) {
|
||
|
var transition;
|
||
|
var transitions = {
|
||
|
transition: 'transitionend',
|
||
|
OTransition: 'oTransitionEnd',
|
||
|
MozTransition: 'mozTransitionEnd',
|
||
|
WebkitTransition: 'webkitTransitionEnd',
|
||
|
msTransition: 'msTransitionEnd'
|
||
|
};
|
||
|
|
||
|
for (var t in transitions) {
|
||
|
if (el.style[t] !== undefined) {
|
||
|
transition = transitions[t];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
KTUtil.one(el, transition, callback);
|
||
|
},
|
||
|
|
||
|
animationEnd: function(el, callback) {
|
||
|
var animation;
|
||
|
var animations = {
|
||
|
animation: 'animationend',
|
||
|
OAnimation: 'oAnimationEnd',
|
||
|
MozAnimation: 'mozAnimationEnd',
|
||
|
WebkitAnimation: 'webkitAnimationEnd',
|
||
|
msAnimation: 'msAnimationEnd'
|
||
|
};
|
||
|
|
||
|
for (var t in animations) {
|
||
|
if (el.style[t] !== undefined) {
|
||
|
animation = animations[t];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
KTUtil.one(el, animation, callback);
|
||
|
},
|
||
|
|
||
|
animateDelay: function(el, value) {
|
||
|
var vendors = ['webkit-', 'moz-', 'ms-', 'o-', ''];
|
||
|
for (var i = 0; i < vendors.length; i++) {
|
||
|
KTUtil.css(el, vendors[i] + 'animation-delay', value);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
animateDuration: function(el, value) {
|
||
|
var vendors = ['webkit-', 'moz-', 'ms-', 'o-', ''];
|
||
|
for (var i = 0; i < vendors.length; i++) {
|
||
|
KTUtil.css(el, vendors[i] + 'animation-duration', value);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
scrollTo: function(target, offset, duration) {
|
||
|
var duration = duration ? duration : 500;
|
||
|
var targetPos = target ? KTUtil.offset(target).top : 0;
|
||
|
var scrollPos = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
|
||
|
var from, to;
|
||
|
|
||
|
if (offset) {
|
||
|
scrollPos += offset;
|
||
|
}
|
||
|
|
||
|
from = scrollPos;
|
||
|
to = targetPos;
|
||
|
|
||
|
KTUtil.animate(from, to, duration, function(value) {
|
||
|
document.documentElement.scrollTop = value;
|
||
|
document.body.parentNode.scrollTop = value;
|
||
|
document.body.scrollTop = value;
|
||
|
}); //, easing, done
|
||
|
},
|
||
|
|
||
|
scrollTop: function(offset, duration) {
|
||
|
KTUtil.scrollTo(null, offset, duration);
|
||
|
},
|
||
|
|
||
|
isArray: function(obj) {
|
||
|
return obj && Array.isArray(obj);
|
||
|
},
|
||
|
|
||
|
ready: function(callback) {
|
||
|
if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading") {
|
||
|
callback();
|
||
|
} else {
|
||
|
document.addEventListener('DOMContentLoaded', callback);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
isEmpty: function(obj) {
|
||
|
for (var prop in obj) {
|
||
|
if (obj.hasOwnProperty(prop)) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
},
|
||
|
|
||
|
numberString: function(nStr) {
|
||
|
nStr += '';
|
||
|
var x = nStr.split('.');
|
||
|
var x1 = x[0];
|
||
|
var x2 = x.length > 1 ? '.' + x[1] : '';
|
||
|
var rgx = /(\d+)(\d{3})/;
|
||
|
while (rgx.test(x1)) {
|
||
|
x1 = x1.replace(rgx, '$1' + ',' + '$2');
|
||
|
}
|
||
|
return x1 + x2;
|
||
|
},
|
||
|
|
||
|
detectIE: function() {
|
||
|
var ua = window.navigator.userAgent;
|
||
|
|
||
|
// Test values; Uncomment to check result …
|
||
|
|
||
|
// IE 10
|
||
|
// ua = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)';
|
||
|
|
||
|
// IE 11
|
||
|
// ua = 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko';
|
||
|
|
||
|
// Edge 12 (Spartan)
|
||
|
// 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';
|
||
|
|
||
|
// Edge 13
|
||
|
// 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';
|
||
|
|
||
|
var msie = ua.indexOf('MSIE ');
|
||
|
if (msie > 0) {
|
||
|
// IE 10 or older => return version number
|
||
|
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
|
||
|
}
|
||
|
|
||
|
var trident = ua.indexOf('Trident/');
|
||
|
if (trident > 0) {
|
||
|
// IE 11 => return version number
|
||
|
var rv = ua.indexOf('rv:');
|
||
|
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
|
||
|
}
|
||
|
|
||
|
var edge = ua.indexOf('Edge/');
|
||
|
if (edge > 0) {
|
||
|
// Edge (IE 12+) => return version number
|
||
|
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
|
||
|
}
|
||
|
|
||
|
// other browser
|
||
|
return false;
|
||
|
},
|
||
|
|
||
|
isRTL: function() {
|
||
|
var html = KTUtil.getByTagName('html')[0];
|
||
|
|
||
|
if (html) {
|
||
|
return (KTUtil.attr(html, 'direction') == 'rtl');
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// Scroller
|
||
|
scrollInit: function(element, options) {
|
||
|
if (!element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Learn more: https://github.com/mdbootstrap/perfect-scrollbar#options
|
||
|
var pluginDefOptions = {
|
||
|
wheelSpeed: 0.5,
|
||
|
swipeEasing: true,
|
||
|
wheelPropagation: false,
|
||
|
minScrollbarLength: 40,
|
||
|
maxScrollbarLength: 300,
|
||
|
suppressScrollX: true
|
||
|
};
|
||
|
|
||
|
options = KTUtil.deepExtend({}, pluginDefOptions, options);
|
||
|
|
||
|
// Define init function
|
||
|
function init() {
|
||
|
var ps;
|
||
|
var height;
|
||
|
|
||
|
// Get extra options via data attributes
|
||
|
var attrs = element.getAttributeNames();
|
||
|
if (attrs.length > 0) {
|
||
|
attrs.forEach(function(attrName) {
|
||
|
// more options; https://github.com/ganlanyuan/tiny-slider#options
|
||
|
if ((/^data-.*/g).test(attrName)) {
|
||
|
if (['scroll', 'height', 'mobile-height'].includes(optionName) == false) {
|
||
|
var optionName = attrName.replace('data-', '').toLowerCase().replace(/(?:[\s-])\w/g, function(match) {
|
||
|
return match.replace('-', '').toUpperCase();
|
||
|
});
|
||
|
|
||
|
options[optionName] = KTUtil.filterBoolean(element.getAttribute(attrName));
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
if (options.height instanceof Function) {
|
||
|
height = options.height.call();
|
||
|
} else {
|
||
|
if (KTUtil.isMobileDevice() === true && options.mobileHeight) {
|
||
|
height = parseInt(options.mobileHeight);
|
||
|
} else {
|
||
|
height = parseInt(options.height);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (height === false) {
|
||
|
KTUtil.scrollDestroy(element, true);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
height = parseInt(height);
|
||
|
|
||
|
// Destroy scroll on table and mobile modes
|
||
|
if ((options.mobileNativeScroll || options.disableForMobile) && KTUtil.isMobileDevice() === true) {
|
||
|
ps = KTUtil.data(element).get('ps');
|
||
|
if (ps) {
|
||
|
if (options.resetHeightOnDestroy) {
|
||
|
KTUtil.css(element, 'height', 'auto');
|
||
|
} else {
|
||
|
KTUtil.css(element, 'overflow', 'auto');
|
||
|
if (height > 0) {
|
||
|
KTUtil.css(element, 'height', height + 'px');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ps.destroy();
|
||
|
ps = KTUtil.data(element).remove('ps');
|
||
|
} else if (height > 0){
|
||
|
KTUtil.css(element, 'overflow', 'auto');
|
||
|
KTUtil.css(element, 'height', height + 'px');
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (height > 0) {
|
||
|
KTUtil.css(element, 'height', height + 'px');
|
||
|
}
|
||
|
|
||
|
if (options.desktopNativeScroll) {
|
||
|
KTUtil.css(element, 'overflow', 'auto');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Pass options via HTML Attributes
|
||
|
if (KTUtil.attr(element, 'data-window-scroll') == 'true') {
|
||
|
options.windowScroll = true;
|
||
|
}
|
||
|
|
||
|
// Init scroll
|
||
|
ps = KTUtil.data(element).get('ps');
|
||
|
|
||
|
if (ps) {
|
||
|
ps.update();
|
||
|
} else {
|
||
|
KTUtil.css(element, 'overflow', 'hidden');
|
||
|
KTUtil.addClass(element, 'scroll');
|
||
|
|
||
|
ps = new PerfectScrollbar(element, options);
|
||
|
|
||
|
KTUtil.data(element).set('ps', ps);
|
||
|
}
|
||
|
|
||
|
// Remember scroll position in cookie
|
||
|
var uid = KTUtil.attr(element, 'id');
|
||
|
// Consider using Localstorage
|
||
|
//if (options.rememberPosition === true && Cookies && uid) {
|
||
|
// if (KTCookie.getCookie(uid)) {
|
||
|
// var pos = parseInt(KTCookie.getCookie(uid));
|
||
|
//
|
||
|
// if (pos > 0) {
|
||
|
// element.scrollTop = pos;
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
// element.addEventListener('ps-scroll-y', function() {
|
||
|
// KTCookie.setCookie(uid, element.scrollTop);
|
||
|
// });
|
||
|
//}
|
||
|
}
|
||
|
|
||
|
// Init
|
||
|
init();
|
||
|
|
||
|
// Handle window resize
|
||
|
if (options.handleWindowResize) {
|
||
|
KTUtil.addResizeHandler(function() {
|
||
|
init();
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
|
||
|
scrollUpdate: function(element) {
|
||
|
var ps = KTUtil.data(element).get('ps');
|
||
|
if (ps) {
|
||
|
ps.update();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
scrollUpdateAll: function(parent) {
|
||
|
var scrollers = KTUtil.findAll(parent, '.ps');
|
||
|
for (var i = 0, len = scrollers.length; i < len; i++) {
|
||
|
KTUtil.scrollUpdate(scrollers[i]);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
scrollDestroy: function(element, resetAll) {
|
||
|
var ps = KTUtil.data(element).get('ps');
|
||
|
|
||
|
if (ps) {
|
||
|
ps.destroy();
|
||
|
ps = KTUtil.data(element).remove('ps');
|
||
|
}
|
||
|
|
||
|
if (element && resetAll) {
|
||
|
element.style.setProperty('overflow', '');
|
||
|
element.style.setProperty('height', '');
|
||
|
}
|
||
|
},
|
||
|
|
||
|
filterBoolean: function(val) {
|
||
|
// Convert string boolean
|
||
|
if (val === true || val === 'true') {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (val === false || val === 'false') {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return val;
|
||
|
},
|
||
|
|
||
|
setHTML: function(el, html) {
|
||
|
el.innerHTML = html;
|
||
|
},
|
||
|
|
||
|
getHTML: function(el) {
|
||
|
if (el) {
|
||
|
return el.innerHTML;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
getDocumentHeight: function() {
|
||
|
var body = document.body;
|
||
|
var html = document.documentElement;
|
||
|
|
||
|
return Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight );
|
||
|
},
|
||
|
|
||
|
getScrollTop: function() {
|
||
|
return (document.scrollingElement || document.documentElement).scrollTop;
|
||
|
},
|
||
|
|
||
|
colorDarken: function(color, amount) {
|
||
|
var subtractLight = function(color, amount){
|
||
|
var cc = parseInt(color,16) - amount;
|
||
|
var c = (cc < 0) ? 0 : (cc);
|
||
|
c = (c.toString(16).length > 1 ) ? c.toString(16) : `0${c.toString(16)}`;
|
||
|
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
color = (color.indexOf("#")>=0) ? color.substring(1,color.length) : color;
|
||
|
amount = parseInt((255*amount)/100);
|
||
|
|
||
|
return color = `#${subtractLight(color.substring(0,2), amount)}${subtractLight(color.substring(2,4), amount)}${subtractLight(color.substring(4,6), amount)}`;
|
||
|
},
|
||
|
|
||
|
colorLighten: function(color, amount) {
|
||
|
var addLight = function(color, amount){
|
||
|
var cc = parseInt(color,16) + amount;
|
||
|
var c = (cc > 255) ? 255 : (cc);
|
||
|
c = (c.toString(16).length > 1 ) ? c.toString(16) : `0${c.toString(16)}`;
|
||
|
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
color = (color.indexOf("#")>=0) ? color.substring(1,color.length) : color;
|
||
|
amount = parseInt((255*amount)/100);
|
||
|
|
||
|
return color = `#${addLight(color.substring(0,2), amount)}${addLight(color.substring(2,4), amount)}${addLight(color.substring(4,6), amount)}`;
|
||
|
},
|
||
|
|
||
|
// Throttle function: Input as function which needs to be throttled and delay is the time interval in milliseconds
|
||
|
throttle: function (timer, func, delay) {
|
||
|
// If setTimeout is already scheduled, no need to do anything
|
||
|
if (timer) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Schedule a setTimeout after delay seconds
|
||
|
timer = setTimeout(function () {
|
||
|
func();
|
||
|
|
||
|
// Once setTimeout function execution is finished, timerId = undefined so that in <br>
|
||
|
// the next scroll event function execution can be scheduled by the setTimeout
|
||
|
timer = undefined;
|
||
|
}, delay);
|
||
|
},
|
||
|
|
||
|
// Debounce function: Input as function which needs to be debounced and delay is the debounced time in milliseconds
|
||
|
debounce: function (timer, func, delay) {
|
||
|
// Cancels the setTimeout method execution
|
||
|
clearTimeout(timer)
|
||
|
|
||
|
// Executes the func after delay time.
|
||
|
timer = setTimeout(func, delay);
|
||
|
},
|
||
|
|
||
|
btnWait: function(el, cls, message, disable = true) {
|
||
|
if (!el) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (disable) {
|
||
|
KTUtil.attr(el, "disabled", true);
|
||
|
}
|
||
|
|
||
|
if (cls) {
|
||
|
KTUtil.addClass(el, cls);
|
||
|
KTUtil.attr(el, "wait-class", cls);
|
||
|
}
|
||
|
|
||
|
if (message) {
|
||
|
var caption = KTUtil.find(el, '.btn-caption');
|
||
|
|
||
|
if (caption) {
|
||
|
KTUtil.data(caption).set('caption', KTUtil.getHTML(caption));
|
||
|
KTUtil.setHTML(caption, message);
|
||
|
} else {
|
||
|
KTUtil.data(el).set('caption', KTUtil.getHTML(el));
|
||
|
KTUtil.setHTML(el, message);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
btnRelease: function(el) {
|
||
|
if (!el) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/// Show loading state on button
|
||
|
KTUtil.removeAttr(el, "disabled");
|
||
|
|
||
|
if (KTUtil.hasAttr(el, "wait-class")) {
|
||
|
KTUtil.removeClass(el, KTUtil.attr(el, "wait-class"));
|
||
|
}
|
||
|
|
||
|
var caption = KTUtil.find(el, '.btn-caption');
|
||
|
|
||
|
if (caption && KTUtil.data(caption).has('caption')) {
|
||
|
KTUtil.setHTML(caption, KTUtil.data(caption).get('caption'));
|
||
|
} else if (KTUtil.data(el).has('caption')) {
|
||
|
KTUtil.setHTML(el, KTUtil.data(el).get('caption'));
|
||
|
}
|
||
|
},
|
||
|
|
||
|
isOffscreen: function(el, direction, offset = 0) {
|
||
|
var windowWidth = KTUtil.getViewPort().width;
|
||
|
var windowHeight = KTUtil.getViewPort().height;
|
||
|
|
||
|
var top = KTUtil.offset(el).top;
|
||
|
var height = KTUtil.outerHeight(el) + offset;
|
||
|
var left = KTUtil.offset(el).left;
|
||
|
var width = KTUtil.outerWidth(el) + offset;
|
||
|
|
||
|
if (direction == 'bottom') {
|
||
|
if (windowHeight < top + height) {
|
||
|
return true;
|
||
|
} else if (windowHeight > top + height * 1.5) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (direction == 'top') {
|
||
|
if (top < 0) {
|
||
|
return true;
|
||
|
} else if (top > height) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (direction == 'left') {
|
||
|
if (left < 0) {
|
||
|
return true;
|
||
|
} else if (left * 2 > width) {
|
||
|
//console.log('left 2');
|
||
|
//return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (direction == 'right') {
|
||
|
if (windowWidth < left + width) {
|
||
|
return true;
|
||
|
} else {
|
||
|
//console.log('right 2');
|
||
|
//return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
}();
|
||
|
|
||
|
// webpack support
|
||
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||
|
module.exports = KTUtil;
|
||
|
}
|
||
|
|
||
|
// Initialize KTUtil class on document ready
|
||
|
KTUtil.ready(function() {
|
||
|
if (typeof KTAppSettings !== 'undefined') {
|
||
|
KTUtil.init(KTAppSettings);
|
||
|
} else {
|
||
|
KTUtil.init();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// CSS3 Transitions only after page load(.page-loading class added to body tag and remove with JS on page load)
|
||
|
window.onload = function() {
|
||
|
var result = KTUtil.getByTagName('body');
|
||
|
if (result && result[0]) {
|
||
|
KTUtil.removeClass(result[0], 'page-loading');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
// Component Definition
|
||
|
var KTWizard = function(elementId, options) {
|
||
|
// Main object
|
||
|
var the = this;
|
||
|
var init = false;
|
||
|
|
||
|
// Get element object
|
||
|
var element = KTUtil.getById(elementId);
|
||
|
var body = KTUtil.getBody();
|
||
|
|
||
|
if (!element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Default options
|
||
|
var defaultOptions = {
|
||
|
startStep: 1,
|
||
|
clickableSteps: false // to make steps clickable this set value true and add data-wizard-clickable="true" in HTML for class="wizard" element
|
||
|
};
|
||
|
|
||
|
////////////////////////////
|
||
|
// ** Private Methods ** //
|
||
|
////////////////////////////
|
||
|
|
||
|
var Plugin = {
|
||
|
/**
|
||
|
* Construct
|
||
|
*/
|
||
|
|
||
|
construct: function(options) {
|
||
|
if (KTUtil.data(element).has('wizard')) {
|
||
|
the = KTUtil.data(element).get('wizard');
|
||
|
} else {
|
||
|
// reset menu
|
||
|
Plugin.init(options);
|
||
|
|
||
|
// build menu
|
||
|
Plugin.build();
|
||
|
|
||
|
KTUtil.data(element).set('wizard', the);
|
||
|
}
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Init wizard
|
||
|
*/
|
||
|
init: function(options) {
|
||
|
the.element = element;
|
||
|
the.events = [];
|
||
|
|
||
|
// merge default and user defined options
|
||
|
the.options = KTUtil.deepExtend({}, defaultOptions, options);
|
||
|
|
||
|
// Elements
|
||
|
the.steps = KTUtil.findAll(element, '[data-wizard-type="step"]');
|
||
|
|
||
|
the.btnSubmit = KTUtil.find(element, '[data-wizard-type="action-submit"]');
|
||
|
the.btnNext = KTUtil.find(element, '[data-wizard-type="action-next"]');
|
||
|
the.btnPrev = KTUtil.find(element, '[data-wizard-type="action-prev"]');
|
||
|
the.btnLast = KTUtil.find(element, '[data-wizard-type="action-last"]');
|
||
|
the.btnFirst = KTUtil.find(element, '[data-wizard-type="action-first"]');
|
||
|
|
||
|
// Variables
|
||
|
the.events = [];
|
||
|
the.currentStep = 1;
|
||
|
the.stopped = false;
|
||
|
the.totalSteps = the.steps.length;
|
||
|
|
||
|
// Init current step
|
||
|
if (the.options.startStep > 1) {
|
||
|
Plugin.goTo(the.options.startStep);
|
||
|
}
|
||
|
|
||
|
// Init UI
|
||
|
Plugin.updateUI();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Build Form Wizard
|
||
|
*/
|
||
|
build: function() {
|
||
|
// Next button event handler
|
||
|
KTUtil.addEvent(the.btnNext, 'click', function(e) {
|
||
|
e.preventDefault();
|
||
|
Plugin.goTo(Plugin.getNextStep(), true);
|
||
|
});
|
||
|
|
||
|
// Prev button event handler
|
||
|
KTUtil.addEvent(the.btnPrev, 'click', function(e) {
|
||
|
e.preventDefault();
|
||
|
Plugin.goTo(Plugin.getPrevStep(), true);
|
||
|
});
|
||
|
|
||
|
// First button event handler
|
||
|
KTUtil.addEvent(the.btnFirst, 'click', function(e) {
|
||
|
e.preventDefault();
|
||
|
Plugin.goTo(Plugin.getFirstStep(), true);
|
||
|
});
|
||
|
|
||
|
// Last button event handler
|
||
|
KTUtil.addEvent(the.btnLast, 'click', function(e) {
|
||
|
e.preventDefault();
|
||
|
Plugin.goTo(Plugin.getLastStep(), true);
|
||
|
});
|
||
|
|
||
|
if (the.options.clickableSteps === true) {
|
||
|
KTUtil.on(element, '[data-wizard-type="step"]', 'click', function() {
|
||
|
var index = KTUtil.index(this) + 1;
|
||
|
if (index !== the.currentStep) {
|
||
|
Plugin.goTo(index, true);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Handles wizard click wizard
|
||
|
*/
|
||
|
goTo: function(number, eventHandle) {
|
||
|
console.log('go to:' + number);
|
||
|
|
||
|
// Skip if this step is already shown
|
||
|
if (number === the.currentStep || number > the.totalSteps || number < 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Validate step number
|
||
|
if (number) {
|
||
|
number = parseInt(number);
|
||
|
} else {
|
||
|
number = Plugin.getNextStep();
|
||
|
}
|
||
|
|
||
|
// Before next and prev events
|
||
|
var callback;
|
||
|
|
||
|
if (eventHandle === true) {
|
||
|
if (number > the.currentStep) {
|
||
|
callback = Plugin.eventTrigger('beforeNext');
|
||
|
} else {
|
||
|
callback = Plugin.eventTrigger('beforePrev');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Skip if stopped
|
||
|
if (the.stopped === true) {
|
||
|
the.stopped = false;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Continue if no exit
|
||
|
if (callback !== false) {
|
||
|
// Before change
|
||
|
if (eventHandle === true) {
|
||
|
Plugin.eventTrigger('beforeChange');
|
||
|
}
|
||
|
|
||
|
// Set current step
|
||
|
the.currentStep = number;
|
||
|
|
||
|
Plugin.updateUI();
|
||
|
|
||
|
// Trigger change event
|
||
|
if (eventHandle === true) {
|
||
|
Plugin.eventTrigger('change');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// After next and prev events
|
||
|
if (eventHandle === true) {
|
||
|
if (number > the.startStep) {
|
||
|
Plugin.eventTrigger('afterNext');
|
||
|
} else {
|
||
|
Plugin.eventTrigger('afterPrev');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return the;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Cancel
|
||
|
*/
|
||
|
stop: function() {
|
||
|
the.stopped = true;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Resume
|
||
|
*/
|
||
|
start: function() {
|
||
|
the.stopped = false;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Check last step
|
||
|
*/
|
||
|
isLastStep: function() {
|
||
|
return the.currentStep === the.totalSteps;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Check first step
|
||
|
*/
|
||
|
isFirstStep: function() {
|
||
|
return the.currentStep === 1;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Check between step
|
||
|
*/
|
||
|
isBetweenStep: function() {
|
||
|
return Plugin.isLastStep() === false && Plugin.isFirstStep() === false;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Go to the first step
|
||
|
*/
|
||
|
updateUI: function() {
|
||
|
var stepType = '';
|
||
|
var index = the.currentStep - 1;
|
||
|
|
||
|
if (Plugin.isLastStep()) {
|
||
|
stepType = 'last';
|
||
|
} else if (Plugin.isFirstStep()) {
|
||
|
stepType = 'first';
|
||
|
} else {
|
||
|
stepType = 'between';
|
||
|
}
|
||
|
|
||
|
KTUtil.attr(the.element, 'data-wizard-state', stepType);
|
||
|
|
||
|
// Steps
|
||
|
var steps = KTUtil.findAll(the.element, '[data-wizard-type="step"]');
|
||
|
|
||
|
if (steps && steps.length > 0) {
|
||
|
for (var i = 0, len = steps.length; i < len; i++) {
|
||
|
if (i == index) {
|
||
|
KTUtil.attr(steps[i], 'data-wizard-state', 'current');
|
||
|
} else {
|
||
|
if (i < index) {
|
||
|
KTUtil.attr(steps[i], 'data-wizard-state', 'done');
|
||
|
} else {
|
||
|
KTUtil.attr(steps[i], 'data-wizard-state', 'pending');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Steps Info
|
||
|
var stepsInfo = KTUtil.findAll(the.element, '[data-wizard-type="step-info"]');
|
||
|
if (stepsInfo &&stepsInfo.length > 0) {
|
||
|
for (var i = 0, len = stepsInfo.length; i < len; i++) {
|
||
|
if (i == index) {
|
||
|
KTUtil.attr(stepsInfo[i], 'data-wizard-state', 'current');
|
||
|
} else {
|
||
|
KTUtil.removeAttr(stepsInfo[i], 'data-wizard-state');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Steps Content
|
||
|
var stepsContent = KTUtil.findAll(the.element, '[data-wizard-type="step-content"]');
|
||
|
if (stepsContent&& stepsContent.length > 0) {
|
||
|
for (var i = 0, len = stepsContent.length; i < len; i++) {
|
||
|
if (i == index) {
|
||
|
KTUtil.attr(stepsContent[i], 'data-wizard-state', 'current');
|
||
|
} else {
|
||
|
KTUtil.removeAttr(stepsContent[i], 'data-wizard-state');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get next step
|
||
|
*/
|
||
|
getNextStep: function() {
|
||
|
if (the.totalSteps >= (the.currentStep + 1)) {
|
||
|
return the.currentStep + 1;
|
||
|
} else {
|
||
|
return the.totalSteps;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get prev step
|
||
|
*/
|
||
|
getPrevStep: function() {
|
||
|
if ((the.currentStep - 1) >= 1) {
|
||
|
return the.currentStep - 1;
|
||
|
} else {
|
||
|
return 1;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Trigger events
|
||
|
*/
|
||
|
eventTrigger: function(name, nested) {
|
||
|
//KTUtil.triggerCustomEvent(name);
|
||
|
for (var i = 0; i < the.events.length; i++) {
|
||
|
var event = the.events[i];
|
||
|
if (event.name == name) {
|
||
|
if (event.one == true) {
|
||
|
if (event.fired == false) {
|
||
|
the.events[i].fired = true;
|
||
|
return event.handler.call(this, the);
|
||
|
}
|
||
|
} else {
|
||
|
return event.handler.call(this, the);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
addEvent: function(name, handler, one) {
|
||
|
the.events.push({
|
||
|
name: name,
|
||
|
handler: handler,
|
||
|
one: one,
|
||
|
fired: false
|
||
|
});
|
||
|
|
||
|
return the;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//////////////////////////
|
||
|
// ** Public Methods ** //
|
||
|
//////////////////////////
|
||
|
|
||
|
/**
|
||
|
* Set default options
|
||
|
*/
|
||
|
|
||
|
the.setDefaults = function(options) {
|
||
|
defaultOptions = options;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Go to the next step
|
||
|
*/
|
||
|
the.goNext = function(eventHandle) {
|
||
|
return Plugin.goTo(Plugin.getNextStep(), eventHandle);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Go to the prev step
|
||
|
*/
|
||
|
the.goPrev = function(eventHandle) {
|
||
|
return Plugin.goTo(Plugin.getPrevStep(),eventHandle);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Go to the last step
|
||
|
*/
|
||
|
the.goLast = function(eventHandle) {
|
||
|
return Plugin.goTo(Plugin.getLastStep(), eventHandle);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Go to the first step
|
||
|
*/
|
||
|
the.goFirst = function(eventHandle) {
|
||
|
return Plugin.goTo(Plugin.getFirstStep(), eventHandle);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Go to a step
|
||
|
*/
|
||
|
the.goTo = function(number, eventHandle) {
|
||
|
return Plugin.goTo(number, eventHandle);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Cancel step
|
||
|
*/
|
||
|
the.stop = function() {
|
||
|
return Plugin.stop();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Resume step
|
||
|
*/
|
||
|
the.start = function() {
|
||
|
return Plugin.start();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Get current step number
|
||
|
*/
|
||
|
the.getStep = function() {
|
||
|
return the.currentStep;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Check last step
|
||
|
*/
|
||
|
the.isLastStep = function() {
|
||
|
return Plugin.isLastStep();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Check first step
|
||
|
*/
|
||
|
the.isFirstStep = function() {
|
||
|
return Plugin.isFirstStep();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Attach event
|
||
|
*/
|
||
|
the.on = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Attach event that will be fired once
|
||
|
*/
|
||
|
the.one = function(name, handler) {
|
||
|
return Plugin.addEvent(name, handler, true);
|
||
|
};
|
||
|
|
||
|
// Construct plugin
|
||
|
Plugin.construct.apply(the, [options]);
|
||
|
|
||
|
return the;
|
||
|
};
|
||
|
|
||
|
// webpack support
|
||
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||
|
module.exports = KTWizard;
|
||
|
}
|
||
|
|
||
|
'use strict';
|
||
|
(function($) {
|
||
|
|
||
|
var pluginName = 'KTDatatable';
|
||
|
var pfx = '';
|
||
|
var util = KTUtil;
|
||
|
var app = KTApp;
|
||
|
|
||
|
if (typeof util === 'undefined') throw new Error('Util class is required and must be included before ' + pluginName);
|
||
|
|
||
|
// plugin setup
|
||
|
$.fn[pluginName] = function(options) {
|
||
|
if ($(this).length === 0) {
|
||
|
console.warn('No ' + pluginName + ' element exist.');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// global variables
|
||
|
var datatable = this;
|
||
|
|
||
|
// debug enabled?
|
||
|
// 1) state will be cleared on each refresh
|
||
|
// 2) enable some logs
|
||
|
// 3) etc.
|
||
|
datatable.debug = false;
|
||
|
|
||
|
datatable.API = {
|
||
|
record: null,
|
||
|
value: null,
|
||
|
params: null,
|
||
|
};
|
||
|
|
||
|
var Plugin = {
|
||
|
/********************
|
||
|
** PRIVATE METHODS
|
||
|
********************/
|
||
|
isInit: false,
|
||
|
cellOffset: 110,
|
||
|
iconOffset: 15,
|
||
|
stateId: 'meta',
|
||
|
ajaxParams: {},
|
||
|
pagingObject: {},
|
||
|
|
||
|
init: function(options) {
|
||
|
var isHtmlTable = false;
|
||
|
// data source option empty is normal table
|
||
|
if (options.data.source === null) {
|
||
|
Plugin.extractTable();
|
||
|
isHtmlTable = true;
|
||
|
}
|
||
|
|
||
|
Plugin.setupBaseDOM.call();
|
||
|
Plugin.setupDOM(datatable.table);
|
||
|
|
||
|
// on event after layout had done setup, show datatable
|
||
|
$(datatable).on(pfx + 'datatable-on-layout-updated', Plugin.afterRender);
|
||
|
|
||
|
if (datatable.debug) {
|
||
|
Plugin.stateRemove(Plugin.stateId);
|
||
|
}
|
||
|
|
||
|
/*var es = Plugin.stateGet(Plugin.stateId);
|
||
|
var eq = {};
|
||
|
if (es && es.hasOwnProperty('query')) {
|
||
|
eq = es.query;
|
||
|
}
|
||
|
Plugin.setDataSourceQuery(Object.assign({}, eq, Plugin.getOption('data.source.read.params.query')));*/
|
||
|
|
||
|
// set custom query from options
|
||
|
Plugin.setDataSourceQuery(Plugin.getOption('data.source.read.params.query'));
|
||
|
|
||
|
// initialize extensions
|
||
|
$.each(Plugin.getOption('extensions'), function(extName, extOptions) {
|
||
|
if (typeof $.fn[pluginName][extName] === 'function') {
|
||
|
if (typeof extOptions !== 'object') {
|
||
|
extOptions = $.extend({}, extOptions);
|
||
|
}
|
||
|
new $.fn[pluginName][extName](datatable, extOptions);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
Plugin.spinnerCallback(true);
|
||
|
// get data
|
||
|
if (options.data.type === 'remote' || options.data.type === 'local') {
|
||
|
if (options.data.saveState === false) {
|
||
|
Plugin.stateRemove(Plugin.stateId);
|
||
|
}
|
||
|
// get data for local datatable and local table
|
||
|
if (options.data.type === 'local' && typeof options.data.source === 'object') {
|
||
|
datatable.dataSet = datatable.originalDataSet = Plugin.dataMapCallback(options.data.source);
|
||
|
}
|
||
|
Plugin.dataRender();
|
||
|
}
|
||
|
|
||
|
// if html table, remove and setup a new header
|
||
|
if (isHtmlTable) {
|
||
|
$(datatable.tableHead).find('tr').remove();
|
||
|
$(datatable.tableFoot).find('tr').remove();
|
||
|
}
|
||
|
|
||
|
Plugin.setHeadTitle();
|
||
|
if (Plugin.getOption('layout.footer')) {
|
||
|
Plugin.setHeadTitle(datatable.tableFoot);
|
||
|
}
|
||
|
|
||
|
// hide header
|
||
|
if (typeof options.layout.header !== 'undefined' &&
|
||
|
options.layout.header === false) {
|
||
|
$(datatable.table).find('thead').remove();
|
||
|
}
|
||
|
|
||
|
// hide footer
|
||
|
if (typeof options.layout.footer !== 'undefined' &&
|
||
|
options.layout.footer === false) {
|
||
|
$(datatable.table).find('tfoot').remove();
|
||
|
}
|
||
|
|
||
|
// for normal and local data type, run layoutUpdate
|
||
|
if (options.data.type === null ||
|
||
|
options.data.type === 'local') {
|
||
|
Plugin.setupCellField.call();
|
||
|
Plugin.setupTemplateCell.call();
|
||
|
|
||
|
// setup nested datatable, if option enabled
|
||
|
Plugin.setupSubDatatable.call();
|
||
|
|
||
|
// setup extra system column properties
|
||
|
Plugin.setupSystemColumn.call();
|
||
|
Plugin.redraw();
|
||
|
}
|
||
|
|
||
|
var width;
|
||
|
var initialWidth = false;
|
||
|
$(window).resize(function() {
|
||
|
// issue: URL Bar Resizing on mobile, https://developers.google.com/web/updates/2016/12/url-bar-resizing
|
||
|
// trigger datatable resize on width change only
|
||
|
if ($(this).width() !== width) {
|
||
|
width = $(this).width();
|
||
|
Plugin.fullRender();
|
||
|
}
|
||
|
// get initial width
|
||
|
if (!initialWidth) {
|
||
|
width = $(this).width();
|
||
|
initialWidth = true;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
$(datatable).height('');
|
||
|
|
||
|
var prevKeyword = '';
|
||
|
$(Plugin.getOption('search.input')).on('keyup', function(e) {
|
||
|
if (Plugin.getOption('search.onEnter') && e.which !== 13) return;
|
||
|
var keyword = $(this).val();
|
||
|
// prevent multiple search request on every button keyup
|
||
|
if (prevKeyword !== keyword) {
|
||
|
Plugin.search(keyword);
|
||
|
prevKeyword = keyword;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Extract static HTML table content into datasource
|
||
|
*/
|
||
|
extractTable: function() {
|
||
|
var columns = [];
|
||
|
var headers = $(datatable).find('tr:first-child th').get().map(function(cell, i) {
|
||
|
var field = $(cell).data('field');
|
||
|
var title = $(cell).data('title');
|
||
|
if (typeof field === 'undefined') {
|
||
|
field = $(cell).text().trim();
|
||
|
}
|
||
|
if (typeof title === 'undefined') {
|
||
|
title = $(cell).text().trim();
|
||
|
}
|
||
|
var column = {field: field, title: title};
|
||
|
for (var ii in options.columns) {
|
||
|
if (options.columns[ii].field === field) {
|
||
|
column = $.extend(true, {}, options.columns[ii], column);
|
||
|
}
|
||
|
}
|
||
|
columns.push(column);
|
||
|
return field;
|
||
|
});
|
||
|
// auto create columns config
|
||
|
options.columns = columns;
|
||
|
|
||
|
var rowProp = [];
|
||
|
var source = [];
|
||
|
|
||
|
$(datatable).find('tr').each(function() {
|
||
|
if ($(this).find('td').length) {
|
||
|
rowProp.push($(this).prop('attributes'));
|
||
|
}
|
||
|
var td = {};
|
||
|
$(this).find('td').each(function(i, cell) {
|
||
|
td[headers[i]] = cell.innerHTML.trim();
|
||
|
});
|
||
|
if (!util.isEmpty(td)) {
|
||
|
source.push(td);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
options.data.attr.rowProps = rowProp;
|
||
|
options.data.source = source;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* One time layout update on init
|
||
|
*/
|
||
|
layoutUpdate: function() {
|
||
|
// setup nested datatable, if option enabled
|
||
|
Plugin.setupSubDatatable.call();
|
||
|
|
||
|
// setup extra system column properties
|
||
|
Plugin.setupSystemColumn.call();
|
||
|
|
||
|
// setup cell hover event
|
||
|
Plugin.setupHover.call();
|
||
|
|
||
|
if (typeof options.detail === 'undefined'
|
||
|
// temporary disable lock column in subtable
|
||
|
&& Plugin.getDepth() === 1) {
|
||
|
// lock columns handler
|
||
|
Plugin.lockTable.call();
|
||
|
}
|
||
|
|
||
|
Plugin.resetScroll();
|
||
|
|
||
|
// check if not is a locked column
|
||
|
if (!Plugin.isLocked()) {
|
||
|
Plugin.redraw.call();
|
||
|
// check if its not a subtable and has autoHide option enabled
|
||
|
if (!Plugin.isSubtable() && Plugin.getOption('rows.autoHide') === true) {
|
||
|
Plugin.autoHide();
|
||
|
}
|
||
|
// reset row
|
||
|
$(datatable.table).find('.' + pfx + 'datatable-row').css('height', '');
|
||
|
}
|
||
|
|
||
|
Plugin.columnHide.call();
|
||
|
|
||
|
Plugin.rowEvenOdd.call();
|
||
|
|
||
|
Plugin.sorting.call();
|
||
|
|
||
|
Plugin.scrollbar.call();
|
||
|
|
||
|
if (!Plugin.isInit) {
|
||
|
// run once dropdown inside datatable
|
||
|
Plugin.dropdownFix();
|
||
|
$(datatable).trigger(pfx + 'datatable-on-init', {table: $(datatable.wrap).attr('id'), options: options});
|
||
|
Plugin.isInit = true;
|
||
|
}
|
||
|
|
||
|
$(datatable).trigger(pfx + 'datatable-on-layout-updated', {table: $(datatable.wrap).attr('id')});
|
||
|
},
|
||
|
|
||
|
dropdownFix: function() {
|
||
|
var dropdownMenu;
|
||
|
$('body').on('show.bs.dropdown', '.' + pfx + 'datatable .' + pfx + 'datatable-body', function(e) {
|
||
|
dropdownMenu = $(e.target).find('.dropdown-menu');
|
||
|
$('body').append(dropdownMenu.detach());
|
||
|
dropdownMenu.css('display', 'block');
|
||
|
dropdownMenu.position({
|
||
|
'my': 'right top',
|
||
|
'at': 'right bottom',
|
||
|
'of': $(e.relatedTarget),
|
||
|
});
|
||
|
// if datatable is inside modal
|
||
|
if (datatable.closest('.modal').length) {
|
||
|
// increase dropdown z-index
|
||
|
dropdownMenu.css('z-index', '2000');
|
||
|
}
|
||
|
}).on('hide.bs.dropdown', '.' + pfx + 'datatable .' + pfx + 'datatable-body', function(e) {
|
||
|
$(e.target).append(dropdownMenu.detach());
|
||
|
dropdownMenu.hide();
|
||
|
});
|
||
|
|
||
|
// remove dropdown if window resize
|
||
|
$(window).on('resize', function(e) {
|
||
|
if (typeof dropdownMenu !== 'undefined') {
|
||
|
dropdownMenu.hide();
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
lockTable: function() {
|
||
|
var lock = {
|
||
|
lockEnabled: false,
|
||
|
init: function() {
|
||
|
// check if table should be locked columns
|
||
|
lock.lockEnabled = Plugin.lockEnabledColumns();
|
||
|
if (lock.lockEnabled.left.length === 0 &&
|
||
|
lock.lockEnabled.right.length === 0) {
|
||
|
return;
|
||
|
}
|
||
|
lock.enable();
|
||
|
},
|
||
|
enable: function() {
|
||
|
var enableLock = function(tablePart) {
|
||
|
// check if already has lock column
|
||
|
if ($(tablePart).find('.' + pfx + 'datatable-lock').length > 0) {
|
||
|
Plugin.log('Locked container already exist in: ', tablePart);
|
||
|
return;
|
||
|
}
|
||
|
// check if no rows exists
|
||
|
if ($(tablePart).find('.' + pfx + 'datatable-row').length === 0) {
|
||
|
Plugin.log('No row exist in: ', tablePart);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// locked div container
|
||
|
var lockLeft = $('<div/>').addClass(pfx + 'datatable-lock ' + pfx + 'datatable-lock-left');
|
||
|
var lockScroll = $('<div/>').addClass(pfx + 'datatable-lock ' + pfx + 'datatable-lock-scroll');
|
||
|
var lockRight = $('<div/>').addClass(pfx + 'datatable-lock ' + pfx + 'datatable-lock-right');
|
||
|
|
||
|
$(tablePart).find('.' + pfx + 'datatable-row').each(function() {
|
||
|
// create new row for lock columns and pass the data
|
||
|
var rowLeft = $('<tr/>').addClass(pfx + 'datatable-row').data('obj', $(this).data('obj')).appendTo(lockLeft);
|
||
|
var rowScroll = $('<tr/>').addClass(pfx + 'datatable-row').data('obj', $(this).data('obj')).appendTo(lockScroll);
|
||
|
var rowRight = $('<tr/>').addClass(pfx + 'datatable-row').data('obj', $(this).data('obj')).appendTo(lockRight);
|
||
|
$(this).find('.' + pfx + 'datatable-cell').each(function() {
|
||
|
var locked = $(this).data('locked');
|
||
|
if (typeof locked !== 'undefined') {
|
||
|
if (typeof locked.left !== 'undefined' || locked === true) {
|
||
|
// default locked to left
|
||
|
$(this).appendTo(rowLeft);
|
||
|
}
|
||
|
if (typeof locked.right !== 'undefined') {
|
||
|
$(this).appendTo(rowRight);
|
||
|
}
|
||
|
} else {
|
||
|
$(this).appendTo(rowScroll);
|
||
|
}
|
||
|
});
|
||
|
// remove old row
|
||
|
$(this).remove();
|
||
|
});
|
||
|
|
||
|
if (lock.lockEnabled.left.length > 0) {
|
||
|
$(datatable.wrap).addClass(pfx + 'datatable-lock');
|
||
|
$(lockLeft).appendTo(tablePart);
|
||
|
}
|
||
|
if (lock.lockEnabled.left.length > 0 || lock.lockEnabled.right.length > 0) {
|
||
|
$(lockScroll).appendTo(tablePart);
|
||
|
}
|
||
|
if (lock.lockEnabled.right.length > 0) {
|
||
|
$(datatable.wrap).addClass(pfx + 'datatable-lock');
|
||
|
$(lockRight).appendTo(tablePart);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
$(datatable.table).find('thead,tbody,tfoot').each(function() {
|
||
|
var tablePart = this;
|
||
|
if ($(this).find('.' + pfx + 'datatable-lock').length === 0) {
|
||
|
$(this).ready(function() {
|
||
|
enableLock(tablePart);
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
};
|
||
|
lock.init();
|
||
|
return lock;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Render everything for resize
|
||
|
*/
|
||
|
fullRender: function() {
|
||
|
$(datatable.tableHead).empty();
|
||
|
Plugin.setHeadTitle();
|
||
|
if (Plugin.getOption('layout.footer')) {
|
||
|
$(datatable.tableFoot).empty();
|
||
|
Plugin.setHeadTitle(datatable.tableFoot);
|
||
|
}
|
||
|
|
||
|
Plugin.spinnerCallback(true);
|
||
|
$(datatable.wrap).removeClass(pfx + 'datatable-loaded');
|
||
|
|
||
|
Plugin.insertData();
|
||
|
},
|
||
|
|
||
|
lockEnabledColumns: function() {
|
||
|
var screen = $(window).width();
|
||
|
var columns = options.columns;
|
||
|
var enabled = {left: [], right: []};
|
||
|
$.each(columns, function(i, column) {
|
||
|
if (typeof column.locked !== 'undefined') {
|
||
|
if (typeof column.locked.left !== 'undefined') {
|
||
|
if (util.getBreakpoint(column.locked.left) <= screen) {
|
||
|
enabled['left'].push(column.locked.left);
|
||
|
}
|
||
|
}
|
||
|
if (typeof column.locked.right !== 'undefined') {
|
||
|
if (util.getBreakpoint(column.locked.right) <= screen) {
|
||
|
enabled['right'].push(column.locked.right);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
return enabled;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* After render event, called by "datatable-on-layout-updated"
|
||
|
* @param e
|
||
|
* @param args
|
||
|
*/
|
||
|
afterRender: function(e, args) {
|
||
|
$(datatable).ready(function() {
|
||
|
// redraw locked columns table
|
||
|
if (Plugin.isLocked()) {
|
||
|
Plugin.redraw();
|
||
|
}
|
||
|
|
||
|
$(datatable.tableBody).css('visibility', '');
|
||
|
$(datatable.wrap).addClass(pfx + 'datatable-loaded');
|
||
|
|
||
|
Plugin.spinnerCallback(false);
|
||
|
});
|
||
|
},
|
||
|
|
||
|
hoverTimer: 0,
|
||
|
isScrolling: false,
|
||
|
setupHover: function() {
|
||
|
$(window).scroll(function(e) {
|
||
|
// stop hover when scrolling
|
||
|
clearTimeout(Plugin.hoverTimer);
|
||
|
Plugin.isScrolling = true;
|
||
|
});
|
||
|
|
||
|
$(datatable.tableBody).find('.' + pfx + 'datatable-cell').off('mouseenter', 'mouseleave').on('mouseenter', function() {
|
||
|
// reset scroll timer to hover class
|
||
|
Plugin.hoverTimer = setTimeout(function() {
|
||
|
Plugin.isScrolling = false;
|
||
|
}, 200);
|
||
|
if (Plugin.isScrolling) return;
|
||
|
|
||
|
// normal table
|
||
|
var row = $(this).closest('.' + pfx + 'datatable-row').addClass(pfx + 'datatable-row-hover');
|
||
|
var index = $(row).index() + 1;
|
||
|
|
||
|
// lock table
|
||
|
$(row).closest('.' + pfx + 'datatable-lock').parent().find('.' + pfx + 'datatable-row:nth-child(' + index + ')').addClass(pfx + 'datatable-row-hover');
|
||
|
}).on('mouseleave', function() {
|
||
|
// normal table
|
||
|
var row = $(this).closest('.' + pfx + 'datatable-row').removeClass(pfx + 'datatable-row-hover');
|
||
|
var index = $(row).index() + 1;
|
||
|
|
||
|
// look table
|
||
|
$(row).closest('.' + pfx + 'datatable-lock').parent().find('.' + pfx + 'datatable-row:nth-child(' + index + ')').removeClass(pfx + 'datatable-row-hover');
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Adjust width of locked table containers by resize handler
|
||
|
* @returns {number}
|
||
|
*/
|
||
|
adjustLockContainer: function() {
|
||
|
if (!Plugin.isLocked()) return 0;
|
||
|
|
||
|
// refer to head dimension
|
||
|
var containerWidth = $(datatable.tableHead).width();
|
||
|
var lockLeft = $(datatable.tableHead).find('.' + pfx + 'datatable-lock-left').width();
|
||
|
var lockRight = $(datatable.tableHead).find('.' + pfx + 'datatable-lock-right').width();
|
||
|
|
||
|
if (typeof lockLeft === 'undefined') lockLeft = 0;
|
||
|
if (typeof lockRight === 'undefined') lockRight = 0;
|
||
|
|
||
|
var lockScroll = Math.floor(containerWidth - lockLeft - lockRight);
|
||
|
$(datatable.table).find('.' + pfx + 'datatable-lock-scroll').css('width', lockScroll);
|
||
|
|
||
|
return lockScroll;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* todo; not in use
|
||
|
*/
|
||
|
dragResize: function() {
|
||
|
var pressed = false;
|
||
|
var start = undefined;
|
||
|
var startX, startWidth;
|
||
|
$(datatable.tableHead).find('.' + pfx + 'datatable-cell').mousedown(function(e) {
|
||
|
start = $(this);
|
||
|
pressed = true;
|
||
|
startX = e.pageX;
|
||
|
startWidth = $(this).width();
|
||
|
$(start).addClass(pfx + 'datatable-cell-resizing');
|
||
|
|
||
|
}).mousemove(function(e) {
|
||
|
if (pressed) {
|
||
|
var i = $(start).index();
|
||
|
var tableBody = $(datatable.tableBody);
|
||
|
var ifLocked = $(start).closest('.' + pfx + 'datatable-lock');
|
||
|
|
||
|
if (ifLocked) {
|
||
|
var lockedIndex = $(ifLocked).index();
|
||
|
tableBody = $(datatable.tableBody).find('.' + pfx + 'datatable-lock').eq(lockedIndex);
|
||
|
}
|
||
|
|
||
|
$(tableBody).find('.' + pfx + 'datatable-row').each(function(tri, tr) {
|
||
|
$(tr).find('.' + pfx + 'datatable-cell').eq(i).width(startWidth + (e.pageX - startX)).children().width(startWidth + (e.pageX - startX));
|
||
|
});
|
||
|
|
||
|
$(start).children().css('width', startWidth + (e.pageX - startX));
|
||
|
}
|
||
|
|
||
|
}).mouseup(function() {
|
||
|
$(start).removeClass(pfx + 'datatable-cell-resizing');
|
||
|
pressed = false;
|
||
|
});
|
||
|
|
||
|
$(document).mouseup(function() {
|
||
|
$(start).removeClass(pfx + 'datatable-cell-resizing');
|
||
|
pressed = false;
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* To prepare placeholder for table before content is loading
|
||
|
*/
|
||
|
initHeight: function() {
|
||
|
if (options.layout.height && options.layout.scroll) {
|
||
|
var theadHeight = $(datatable.tableHead).find('.' + pfx + 'datatable-row').outerHeight();
|
||
|
var tfootHeight = $(datatable.tableFoot).find('.' + pfx + 'datatable-row').outerHeight();
|
||
|
var bodyHeight = options.layout.height;
|
||
|
if (theadHeight > 0) {
|
||
|
bodyHeight -= theadHeight;
|
||
|
}
|
||
|
if (tfootHeight > 0) {
|
||
|
bodyHeight -= tfootHeight;
|
||
|
}
|
||
|
|
||
|
// scrollbar offset
|
||
|
bodyHeight -= 2;
|
||
|
|
||
|
$(datatable.tableBody).css('max-height', Math.floor(parseFloat(bodyHeight)));
|
||
|
|
||
|
// set scrollable area fixed height
|
||
|
// $(datatable.tableBody).find('.' + pfx + 'datatable-lock-scroll').css('height', Math.floor(parseFloat(bodyHeight)));
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Setup base DOM (table, thead, tbody, tfoot) and create if not
|
||
|
* exist.
|
||
|
*/
|
||
|
setupBaseDOM: function() {
|
||
|
// keep original state before datatable initialize
|
||
|
datatable.initialDatatable = $(datatable).clone();
|
||
|
|
||
|
// main element
|
||
|
if ($(datatable).prop('tagName') === 'TABLE') {
|
||
|
// if main init element is <table>, wrap with div
|
||
|
datatable.table = $(datatable).removeClass(pfx + 'datatable').addClass(pfx + 'datatable-table');
|
||
|
if ($(datatable.table).parents('.' + pfx + 'datatable').length === 0) {
|
||
|
datatable.table.wrap($('<div/>').addClass(pfx + 'datatable').addClass(pfx + 'datatable-' + options.layout.theme));
|
||
|
datatable.wrap = $(datatable.table).parent();
|
||
|
}
|
||
|
} else {
|
||
|
// create table
|
||
|
datatable.wrap = $(datatable).addClass(pfx + 'datatable').addClass(pfx + 'datatable-' + options.layout.theme);
|
||
|
datatable.table = $('<table/>').addClass(pfx + 'datatable-table').appendTo(datatable);
|
||
|
}
|
||
|
|
||
|
if (typeof options.layout.class !== 'undefined') {
|
||
|
$(datatable.wrap).addClass(options.layout.class);
|
||
|
}
|
||
|
|
||
|
$(datatable.table).removeClass(pfx + 'datatable-destroyed').css('display', 'block');
|
||
|
|
||
|
// force disable save state
|
||
|
if (typeof $(datatable).attr('id') === 'undefined') {
|
||
|
Plugin.setOption('data.saveState', false);
|
||
|
$(datatable.table).attr('id', util.getUniqueID(pfx + 'datatable-'));
|
||
|
}
|
||
|
|
||
|
// predefine table height
|
||
|
if (Plugin.getOption('layout.minHeight'))
|
||
|
$(datatable.table).css('min-height', Plugin.getOption('layout.minHeight'));
|
||
|
|
||
|
if (Plugin.getOption('layout.height'))
|
||
|
$(datatable.table).css('max-height', Plugin.getOption('layout.height'));
|
||
|
|
||
|
// for normal table load
|
||
|
if (options.data.type === null) {
|
||
|
$(datatable.table).css('width', '').css('display', '');
|
||
|
}
|
||
|
|
||
|
// create table head element
|
||
|
datatable.tableHead = $(datatable.table).find('thead');
|
||
|
if ($(datatable.tableHead).length === 0) {
|
||
|
datatable.tableHead = $('<thead/>').prependTo(datatable.table);
|
||
|
}
|
||
|
|
||
|
// create table head element
|
||
|
datatable.tableBody = $(datatable.table).find('tbody');
|
||
|
if ($(datatable.tableBody).length === 0) {
|
||
|
datatable.tableBody = $('<tbody/>').appendTo(datatable.table);
|
||
|
}
|
||
|
|
||
|
if (typeof options.layout.footer !== 'undefined' &&
|
||
|
options.layout.footer) {
|
||
|
// create table foot element
|
||
|
datatable.tableFoot = $(datatable.table).find('tfoot');
|
||
|
if ($(datatable.tableFoot).length === 0) {
|
||
|
datatable.tableFoot = $('<tfoot/>').appendTo(datatable.table);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Set column data before table manipulation.
|
||
|
*/
|
||
|
setupCellField: function(tableParts) {
|
||
|
if (typeof tableParts === 'undefined') tableParts = $(datatable.table).children();
|
||
|
var columns = options.columns;
|
||
|
$.each(tableParts, function(part, tablePart) {
|
||
|
$(tablePart).find('.' + pfx + 'datatable-row').each(function(tri, tr) {
|
||
|
// prepare data
|
||
|
$(tr).find('.' + pfx + 'datatable-cell').each(function(tdi, td) {
|
||
|
if (typeof columns[tdi] !== 'undefined') {
|
||
|
$(td).data(columns[tdi]);
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Set column template callback
|
||
|
* @param tablePart
|
||
|
*/
|
||
|
setupTemplateCell: function(tablePart) {
|
||
|
if (typeof tablePart === 'undefined') tablePart = datatable.tableBody;
|
||
|
var columns = options.columns;
|
||
|
$(tablePart).find('.' + pfx + 'datatable-row').each(function(tri, tr) {
|
||
|
// row data object, if any
|
||
|
var obj = $(tr).data('obj');
|
||
|
if (typeof obj === 'undefined') {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// @deprecated in v5.0.6
|
||
|
// obj['getIndex'] = function() {
|
||
|
// return tri;
|
||
|
// };
|
||
|
// @deprecated in v5.0.6
|
||
|
// obj['getDatatable'] = function() {
|
||
|
// return datatable;
|
||
|
// };
|
||
|
|
||
|
// @deprecated in v5.0.6
|
||
|
var rowCallback = Plugin.getOption('rows.callback');
|
||
|
if (typeof rowCallback === 'function') {
|
||
|
rowCallback($(tr), obj, tri);
|
||
|
}
|
||
|
// before template row callback
|
||
|
var beforeTemplate = Plugin.getOption('rows.beforeTemplate');
|
||
|
if (typeof beforeTemplate === 'function') {
|
||
|
beforeTemplate($(tr), obj, tri);
|
||
|
}
|
||
|
// if data object is undefined, collect from table
|
||
|
if (typeof obj === 'undefined') {
|
||
|
obj = {};
|
||
|
$(tr).find('.' + pfx + 'datatable-cell').each(function(tdi, td) {
|
||
|
// get column settings by field
|
||
|
var column = $.grep(columns, function(n, i) {
|
||
|
return $(td).data('field') === n.field;
|
||
|
})[0];
|
||
|
if (typeof column !== 'undefined') {
|
||
|
obj[column['field']] = $(td).text();
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
$(tr).find('.' + pfx + 'datatable-cell').each(function(tdi, td) {
|
||
|
// get column settings by field
|
||
|
var column = $.grep(columns, function(n, i) {
|
||
|
return $(td).data('field') === n.field;
|
||
|
})[0];
|
||
|
if (typeof column !== 'undefined') {
|
||
|
// column template
|
||
|
if (typeof column.template !== 'undefined') {
|
||
|
var finalValue = '';
|
||
|
// template string
|
||
|
if (typeof column.template === 'string') {
|
||
|
finalValue = Plugin.dataPlaceholder(column.template, obj);
|
||
|
}
|
||
|
// template callback function
|
||
|
if (typeof column.template === 'function') {
|
||
|
finalValue = column.template(obj, tri, datatable);
|
||
|
}
|
||
|
|
||
|
// sanitize using DOMPurify if installed
|
||
|
if (typeof DOMPurify !== 'undefined') {
|
||
|
finalValue = DOMPurify.sanitize(finalValue);
|
||
|
}
|
||
|
|
||
|
var span = document.createElement('span');
|
||
|
span.innerHTML = finalValue;
|
||
|
|
||
|
// insert to cell, wrap with span
|
||
|
$(td).html(span);
|
||
|
|
||
|
// set span overflow
|
||
|
if (typeof column.overflow !== 'undefined') {
|
||
|
$(span).css('overflow', column.overflow);
|
||
|
$(span).css('position', 'relative');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// after template row callback
|
||
|
var afterTemplate = Plugin.getOption('rows.afterTemplate');
|
||
|
if (typeof afterTemplate === 'function') {
|
||
|
afterTemplate($(tr), obj, tri);
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Setup extra system column properties
|
||
|
* Note: selector checkbox, subtable toggle
|
||
|
*/
|
||
|
setupSystemColumn: function() {
|
||
|
datatable.dataSet = datatable.dataSet || [];
|
||
|
// no records available
|
||
|
if (datatable.dataSet.length === 0) return;
|
||
|
|
||
|
var columns = options.columns;
|
||
|
$(datatable.tableBody).find('.' + pfx + 'datatable-row').each(function(tri, tr) {
|
||
|
$(tr).find('.' + pfx + 'datatable-cell').each(function(tdi, td) {
|
||
|
// get column settings by field
|
||
|
var column = $.grep(columns, function(n, i) {
|
||
|
return $(td).data('field') === n.field;
|
||
|
})[0];
|
||
|
if (typeof column !== 'undefined') {
|
||
|
var value = $(td).text();
|
||
|
|
||
|
// enable column selector
|
||
|
if (typeof column.selector !== 'undefined' && column.selector !== false) {
|
||
|
// check if checkbox exist
|
||
|
if ($(td).find('.' + pfx + 'checkbox [type="checkbox"]').length > 0) return;
|
||
|
|
||
|
$(td).addClass(pfx + 'datatable-cell-check');
|
||
|
|
||
|
// append checkbox
|
||
|
var chk = $('<label/>').
|
||
|
addClass(pfx + 'checkbox ' + pfx + 'checkbox-single').
|
||
|
append($('<input/>').attr('type', 'checkbox').attr('value', value).on('click', function() {
|
||
|
if ($(this).is(':checked')) {
|
||
|
// add checkbox active row class
|
||
|
Plugin.setActive(this);
|
||
|
} else {
|
||
|
// add checkbox active row class
|
||
|
Plugin.setInactive(this);
|
||
|
}
|
||
|
})).
|
||
|
append(' <span></span>');
|
||
|
|
||
|
// checkbox selector has outline style
|
||
|
if (typeof column.selector.class !== 'undefined') {
|
||
|
$(chk).addClass(column.selector.class);
|
||
|
}
|
||
|
|
||
|
$(td).children().html(chk);
|
||
|
}
|
||
|
|
||
|
// enable column subtable toggle
|
||
|
if (typeof column.subtable !== 'undefined' && column.subtable) {
|
||
|
// check if subtable toggle exist
|
||
|
if ($(td).find('.' + pfx + 'datatable-toggle-subtable').length > 0) return;
|
||
|
// append subtable toggle
|
||
|
$(td).
|
||
|
children().
|
||
|
html($('<a/>').
|
||
|
addClass(pfx + 'datatable-toggle-subtable').
|
||
|
attr('href', '#').
|
||
|
attr('data-value', value).
|
||
|
append($('<i/>').addClass(Plugin.getOption('layout.icons.rowDetail.collapse'))));
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
|
||
|
// init checkbox for header/footer
|
||
|
var initCheckbox = function(tr) {
|
||
|
// get column settings by field
|
||
|
var column = $.grep(columns, function(n, i) {
|
||
|
return typeof n.selector !== 'undefined' && n.selector !== false;
|
||
|
})[0];
|
||
|
|
||
|
if (typeof column !== 'undefined') {
|
||
|
// enable column selector
|
||
|
if (typeof column.selector !== 'undefined' && column.selector !== false) {
|
||
|
var td = $(tr).find('[data-field="' + column.field + '"]');
|
||
|
// check if checkbox exist
|
||
|
if ($(td).find('.' + pfx + 'checkbox [type="checkbox"]').length > 0) return;
|
||
|
|
||
|
$(td).addClass(pfx + 'datatable-cell-check');
|
||
|
|
||
|
// append checkbox
|
||
|
var chk = $('<label/>').
|
||
|
addClass(pfx + 'checkbox ' + pfx + 'checkbox-single ' + pfx + 'checkbox-all').
|
||
|
append($('<input/>').attr('type', 'checkbox').on('click', function() {
|
||
|
if ($(this).is(':checked')) {
|
||
|
Plugin.setActiveAll(true);
|
||
|
} else {
|
||
|
Plugin.setActiveAll(false);
|
||
|
}
|
||
|
})).
|
||
|
append(' <span></span>');
|
||
|
|
||
|
// checkbox selector has outline style
|
||
|
if (typeof column.selector.class !== 'undefined') {
|
||
|
$(chk).addClass(column.selector.class);
|
||
|
}
|
||
|
|
||
|
$(td).children().html(chk);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
if (options.layout.header) {
|
||
|
initCheckbox($(datatable.tableHead).find('.' + pfx + 'datatable-row').first());
|
||
|
}
|
||
|
if (options.layout.footer) {
|
||
|
initCheckbox($(datatable.tableFoot).find('.' + pfx + 'datatable-row').first());
|
||
|
}
|
||
|
},
|
||
|
|
||
|
maxWidthList: {},
|
||
|
|
||
|
/**
|
||
|
* Adjust width to match container size
|
||
|
*/
|
||
|
adjustCellsWidth: function() {
|
||
|
// get table width
|
||
|
var containerWidth = $(datatable.tableBody).innerWidth() - Plugin.iconOffset;
|
||
|
|
||
|
// get total number of columns
|
||
|
var columns = $(datatable.tableBody).
|
||
|
find('.' + pfx + 'datatable-row:first-child').
|
||
|
find('.' + pfx + 'datatable-cell').
|
||
|
// exclude expand icon
|
||
|
not('.' + pfx + 'datatable-toggle-detail').
|
||
|
not(':hidden').length;
|
||
|
|
||
|
if (columns > 0) {
|
||
|
// remove reserved sort icon width
|
||
|
containerWidth = containerWidth - (Plugin.iconOffset * columns);
|
||
|
var minWidth = Math.floor(containerWidth / columns);
|
||
|
|
||
|
// minimum width
|
||
|
if (minWidth <= Plugin.cellOffset) {
|
||
|
minWidth = Plugin.cellOffset;
|
||
|
}
|
||
|
|
||
|
$(datatable.table).find('.' + pfx + 'datatable-row').
|
||
|
find('.' + pfx + 'datatable-cell').
|
||
|
// exclude expand icon
|
||
|
not('.' + pfx + 'datatable-toggle-detail').
|
||
|
not(':hidden').each(function(tdi, td) {
|
||
|
|
||
|
var width = minWidth;
|
||
|
var dataWidth = $(td).data('width');
|
||
|
|
||
|
if (typeof dataWidth !== 'undefined') {
|
||
|
if (dataWidth === 'auto') {
|
||
|
var field = $(td).data('field');
|
||
|
if (Plugin.maxWidthList[field]) {
|
||
|
width = Plugin.maxWidthList[field];
|
||
|
}
|
||
|
else {
|
||
|
var cells = $(datatable.table).find('.' + pfx + 'datatable-cell[data-field="' + field + '"]');
|
||
|
width = Plugin.maxWidthList[field] = Math.max.apply(null,
|
||
|
$(cells).map(function() {
|
||
|
return $(this).outerWidth();
|
||
|
}).get());
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
width = dataWidth;
|
||
|
}
|
||
|
}
|
||
|
$(td).children().css('width', Math.ceil(width));
|
||
|
});
|
||
|
}
|
||
|
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Adjust height to match container size
|
||
|
*/
|
||
|
adjustCellsHeight: function() {
|
||
|
$.each($(datatable.table).children(), function(part, tablePart) {
|
||
|
var totalRows = $(tablePart).find('.' + pfx + 'datatable-row').first().parent().find('.' + pfx + 'datatable-row').length;
|
||
|
for (var i = 1; i <= totalRows; i++) {
|
||
|
var rows = $(tablePart).find('.' + pfx + 'datatable-row:nth-child(' + i + ')');
|
||
|
if ($(rows).length > 0) {
|
||
|
var maxHeight = Math.max.apply(null, $(rows).map(function() {
|
||
|
return $(this).outerHeight();
|
||
|
}).get());
|
||
|
$(rows).css('height', Math.ceil(maxHeight));
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Setup table DOM and classes
|
||
|
*/
|
||
|
setupDOM: function(table) {
|
||
|
// set table classes
|
||
|
$(table).find('> thead').addClass(pfx + 'datatable-head');
|
||
|
$(table).find('> tbody').addClass(pfx + 'datatable-body');
|
||
|
$(table).find('> tfoot').addClass(pfx + 'datatable-foot');
|
||
|
$(table).find('tr').addClass(pfx + 'datatable-row');
|
||
|
$(table).find('tr > th, tr > td').addClass(pfx + 'datatable-cell');
|
||
|
$(table).find('tr > th, tr > td').each(function(i, td) {
|
||
|
if ($(td).find('span').length === 0) {
|
||
|
$(td).wrapInner($('<span/>').css('width', Plugin.cellOffset));
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Default scrollbar
|
||
|
* @returns {{tableLocked: null, init: init, onScrolling:
|
||
|
* onScrolling}}
|
||
|
*/
|
||
|
scrollbar: function() {
|
||
|
var scroll = {
|
||
|
scrollable: null,
|
||
|
tableLocked: null,
|
||
|
initPosition: null,
|
||
|
init: function() {
|
||
|
var screen = util.getViewPort().width;
|
||
|
// setup scrollable datatable
|
||
|
if (options.layout.scroll) {
|
||
|
// add scrollable datatable class
|
||
|
$(datatable.wrap).addClass(pfx + 'datatable-scroll');
|
||
|
|
||
|
var scrollable = $(datatable.tableBody).find('.' + pfx + 'datatable-lock-scroll');
|
||
|
|
||
|
// check if scrollable area have rows
|
||
|
if ($(scrollable).find('.' + pfx + 'datatable-row').length > 0 && $(scrollable).length > 0) {
|
||
|
scroll.scrollHead = $(datatable.tableHead).find('> .' + pfx + 'datatable-lock-scroll > .' + pfx + 'datatable-row');
|
||
|
scroll.scrollFoot = $(datatable.tableFoot).find('> .' + pfx + 'datatable-lock-scroll > .' + pfx + 'datatable-row');
|
||
|
scroll.tableLocked = $(datatable.tableBody).find('.' + pfx + 'datatable-lock:not(.' + pfx + 'datatable-lock-scroll)');
|
||
|
if (Plugin.getOption('layout.customScrollbar') && util.detectIE() != 10 && screen > util.getBreakpoint('lg')) {
|
||
|
scroll.initCustomScrollbar(scrollable[0]);
|
||
|
} else {
|
||
|
scroll.initDefaultScrollbar(scrollable);
|
||
|
}
|
||
|
} else if ($(datatable.tableBody).find('.' + pfx + 'datatable-row').length > 0) {
|
||
|
scroll.scrollHead = $(datatable.tableHead).find('> .' + pfx + 'datatable-row');
|
||
|
scroll.scrollFoot = $(datatable.tableFoot).find('> .' + pfx + 'datatable-row');
|
||
|
if (Plugin.getOption('layout.customScrollbar') && util.detectIE() != 10 && screen > util.getBreakpoint('lg')) {
|
||
|
scroll.initCustomScrollbar(datatable.tableBody);
|
||
|
} else {
|
||
|
scroll.initDefaultScrollbar(datatable.tableBody);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
initDefaultScrollbar: function(scrollable) {
|
||
|
// get initial scroll position
|
||
|
scroll.initPosition = $(scrollable).scrollLeft();
|
||
|
$(scrollable).css('overflow-y', 'auto').off().on('scroll', scroll.onScrolling);
|
||
|
$(scrollable).css('overflow-x', 'auto');
|
||
|
},
|
||
|
onScrolling: function(e) {
|
||
|
var left = $(this).scrollLeft();
|
||
|
var top = $(this).scrollTop();
|
||
|
if (util.isRTL()) {
|
||
|
// deduct initial position for RTL
|
||
|
left = left - scroll.initPosition;
|
||
|
}
|
||
|
$(scroll.scrollHead).css('left', -left);
|
||
|
$(scroll.scrollFoot).css('left', -left);
|
||
|
$(scroll.tableLocked).each(function(i, table) {
|
||
|
if (Plugin.isLocked()) {
|
||
|
// scrollbar offset
|
||
|
top -= 1;
|
||
|
}
|
||
|
$(table).css('top', -top);
|
||
|
});
|
||
|
},
|
||
|
initCustomScrollbar: function(scrollable) {
|
||
|
scroll.scrollable = scrollable;
|
||
|
// create a new instance for table body with scrollbar
|
||
|
Plugin.initScrollbar(scrollable);
|
||
|
// get initial scroll position
|
||
|
scroll.initPosition = $(scrollable).scrollLeft();
|
||
|
$(scrollable).off().on('scroll', scroll.onScrolling);
|
||
|
},
|
||
|
};
|
||
|
scroll.init();
|
||
|
return scroll;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Init custom scrollbar and reset position
|
||
|
* @param element
|
||
|
* @param options
|
||
|
*/
|
||
|
initScrollbar: function(element, options) {
|
||
|
if (!element || !element.nodeName) {
|
||
|
return;
|
||
|
}
|
||
|
$(datatable.tableBody).css('overflow', '');
|
||
|
var ps = $(element).data('ps');
|
||
|
if (util.hasClass(element, 'ps') && typeof ps !== 'undefined') {
|
||
|
ps.update();
|
||
|
} else {
|
||
|
ps = new PerfectScrollbar(element, Object.assign({}, {
|
||
|
wheelSpeed: 0.5,
|
||
|
swipeEasing: true,
|
||
|
// wheelPropagation: false,
|
||
|
minScrollbarLength: 40,
|
||
|
maxScrollbarLength: 300,
|
||
|
suppressScrollX: Plugin.getOption('rows.autoHide') && !Plugin.isLocked()
|
||
|
}, options));
|
||
|
$(element).data('ps', ps);
|
||
|
}
|
||
|
|
||
|
// reset perfect scrollbar on resize
|
||
|
$(window).resize(function() {
|
||
|
ps.update();
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Set column title from options.columns settings
|
||
|
*/
|
||
|
setHeadTitle: function(tablePart) {
|
||
|
if (typeof tablePart === 'undefined') tablePart = datatable.tableHead;
|
||
|
tablePart = $(tablePart)[0];
|
||
|
var columns = options.columns;
|
||
|
var row = tablePart.getElementsByTagName('tr')[0];
|
||
|
var ths = tablePart.getElementsByTagName('td');
|
||
|
|
||
|
if (typeof row === 'undefined') {
|
||
|
row = document.createElement('tr');
|
||
|
tablePart.appendChild(row);
|
||
|
}
|
||
|
|
||
|
$.each(columns, function(i, column) {
|
||
|
var th = ths[i];
|
||
|
if (typeof th === 'undefined') {
|
||
|
th = document.createElement('th');
|
||
|
row.appendChild(th);
|
||
|
}
|
||
|
|
||
|
// set column title
|
||
|
if (typeof column['title'] !== 'undefined') {
|
||
|
th.innerHTML = column.title;
|
||
|
th.setAttribute('data-field', column.field);
|
||
|
util.addClass(th, column.class);
|
||
|
// set disable autoHide or force enable
|
||
|
if (typeof column.autoHide !== 'undefined') {
|
||
|
if (column.autoHide !== true) {
|
||
|
th.setAttribute('data-autohide-disabled', column.autoHide);
|
||
|
} else {
|
||
|
th.setAttribute('data-autohide-enabled', column.autoHide);
|
||
|
}
|
||
|
}
|
||
|
$(th).data(column);
|
||
|
}
|
||
|
|
||
|
// set header attr option
|
||
|
if (typeof column.attr !== 'undefined') {
|
||
|
$.each(column.attr, function(key, val) {
|
||
|
th.setAttribute(key, val);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// apply text align to thead/tfoot
|
||
|
if (typeof column.textAlign !== 'undefined') {
|
||
|
var align = typeof datatable.textAlign[column.textAlign] !== 'undefined' ? datatable.textAlign[column.textAlign] : '';
|
||
|
util.addClass(th, align);
|
||
|
}
|
||
|
});
|
||
|
Plugin.setupDOM(tablePart);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Initiate to get remote or local data via ajax
|
||
|
*/
|
||
|
dataRender: function(action) {
|
||
|
$(datatable.table).siblings('.' + pfx + 'datatable-pager').removeClass(pfx + 'datatable-paging-loaded');
|
||
|
|
||
|
var buildMeta = function() {
|
||
|
datatable.dataSet = datatable.dataSet || [];
|
||
|
Plugin.localDataUpdate();
|
||
|
// local pagination meta
|
||
|
var meta = Plugin.getDataSourceParam('pagination');
|
||
|
if (meta.perpage === 0) {
|
||
|
meta.perpage = options.data.pageSize || 10;
|
||
|
}
|
||
|
meta.total = datatable.dataSet.length;
|
||
|
var start = Math.max(meta.perpage * (meta.page - 1), 0);
|
||
|
var end = Math.min(start + meta.perpage, meta.total);
|
||
|
datatable.dataSet = $(datatable.dataSet).slice(start, end);
|
||
|
return meta;
|
||
|
};
|
||
|
|
||
|
var afterGetData = function(result) {
|
||
|
var localPagingCallback = function(ctx, meta) {
|
||
|
if (!$(ctx.pager).hasClass(pfx + 'datatable-paging-loaded')) {
|
||
|
$(ctx.pager).remove();
|
||
|
ctx.init(meta);
|
||
|
}
|
||
|
$(ctx.pager).off().on(pfx + 'datatable-on-goto-page', function(e) {
|
||
|
$(ctx.pager).remove();
|
||
|
ctx.init(meta);
|
||
|
});
|
||
|
|
||
|
var start = Math.max(meta.perpage * (meta.page - 1), 0);
|
||
|
var end = Math.min(start + meta.perpage, meta.total);
|
||
|
|
||
|
Plugin.localDataUpdate();
|
||
|
datatable.dataSet = $(datatable.dataSet).slice(start, end);
|
||
|
|
||
|
// insert data into table content
|
||
|
Plugin.insertData();
|
||
|
};
|
||
|
|
||
|
$(datatable.wrap).removeClass(pfx + 'datatable-error');
|
||
|
// pagination enabled
|
||
|
if (options.pagination) {
|
||
|
if (options.data.serverPaging && options.data.type !== 'local') {
|
||
|
// server pagination
|
||
|
var serverMeta = Plugin.getObject('meta', result || null);
|
||
|
if (serverMeta !== null) {
|
||
|
Plugin.pagingObject = Plugin.paging(serverMeta);
|
||
|
} else {
|
||
|
// no meta object from server response, fallback to local pagination
|
||
|
Plugin.pagingObject = Plugin.paging(buildMeta(), localPagingCallback);
|
||
|
}
|
||
|
} else {
|
||
|
// local pagination can be used by remote data also
|
||
|
Plugin.pagingObject = Plugin.paging(buildMeta(), localPagingCallback);
|
||
|
}
|
||
|
} else {
|
||
|
// pagination is disabled
|
||
|
Plugin.localDataUpdate();
|
||
|
}
|
||
|
// insert data into table content
|
||
|
Plugin.insertData();
|
||
|
};
|
||
|
|
||
|
// get local datasource
|
||
|
if (options.data.type === 'local'
|
||
|
// for remote json datasource
|
||
|
// || typeof options.data.source.read === 'undefined' && datatable.dataSet !== null
|
||
|
// for remote datasource, server sorting is disabled and data already received from remote
|
||
|
|| options.data.serverSorting === false && action === 'sort'
|
||
|
|| options.data.serverFiltering === false && action === 'search'
|
||
|
) {
|
||
|
setTimeout(function() {
|
||
|
afterGetData();
|
||
|
Plugin.setAutoColumns();
|
||
|
});
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// getting data from remote only
|
||
|
Plugin.getData().done(afterGetData);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Process ajax data
|
||
|
*/
|
||
|
insertData: function() {
|
||
|
datatable.dataSet = datatable.dataSet || [];
|
||
|
var params = Plugin.getDataSourceParam();
|
||
|
|
||
|
// get row attributes
|
||
|
var pagination = params.pagination;
|
||
|
var start = (Math.max(pagination.page, 1) - 1) * pagination.perpage;
|
||
|
var end = Math.min(pagination.page, pagination.pages) * pagination.perpage;
|
||
|
var rowProps = {};
|
||
|
if (typeof options.data.attr.rowProps !== 'undefined' && options.data.attr.rowProps.length) {
|
||
|
rowProps = options.data.attr.rowProps.slice(start, end);
|
||
|
}
|
||
|
|
||
|
var tableBody = document.createElement('tbody');
|
||
|
tableBody.style.visibility = 'hidden';
|
||
|
var colLength = options.columns.length;
|
||
|
|
||
|
$.each(datatable.dataSet, function(rowIndex, row) {
|
||
|
var tr = document.createElement('tr');
|
||
|
tr.setAttribute('data-row', rowIndex);
|
||
|
// keep data object to row
|
||
|
$(tr).data('obj', row);
|
||
|
|
||
|
if (typeof rowProps[rowIndex] !== 'undefined') {
|
||
|
$.each(rowProps[rowIndex], function() {
|
||
|
tr.setAttribute(this.name, this.value);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var cellIndex = 0;
|
||
|
var tds = [];
|
||
|
for (var a = 0; a < colLength; a += 1) {
|
||
|
var column = options.columns[a];
|
||
|
var classes = [];
|
||
|
// add sorted class to cells
|
||
|
if (Plugin.getObject('sort.field', params) === column.field) {
|
||
|
classes.push(pfx + 'datatable-cell-sorted');
|
||
|
}
|
||
|
|
||
|
// apply text align
|
||
|
if (typeof column.textAlign !== 'undefined') {
|
||
|
var align = typeof datatable.textAlign[column.textAlign] !== 'undefined' ? datatable.textAlign[column.textAlign] : '';
|
||
|
classes.push(align);
|
||
|
}
|
||
|
|
||
|
// var classAttr = '';
|
||
|
if (typeof column.class !== 'undefined') {
|
||
|
classes.push(column.class);
|
||
|
}
|
||
|
|
||
|
var td = document.createElement('td');
|
||
|
util.addClass(td, classes.join(' '));
|
||
|
td.setAttribute('data-field', column.field);
|
||
|
// set disable autoHide or force enable
|
||
|
if (typeof column.autoHide !== 'undefined') {
|
||
|
if (column.autoHide !== true) {
|
||
|
td.setAttribute('data-autohide-disabled', column.autoHide);
|
||
|
} else {
|
||
|
td.setAttribute('data-autohide-enabled', column.autoHide);
|
||
|
}
|
||
|
}
|
||
|
td.innerHTML = Plugin.getObject(column.field, row);
|
||
|
td.setAttribute('aria-label', Plugin.getObject(column.field, row));
|
||
|
tr.appendChild(td);
|
||
|
}
|
||
|
|
||
|
tableBody.appendChild(tr);
|
||
|
});
|
||
|
|
||
|
// display no records message
|
||
|
if (datatable.dataSet.length === 0) {
|
||
|
var errorSpan = document.createElement('span');
|
||
|
util.addClass(errorSpan, pfx + 'datatable-error');
|
||
|
errorSpan.innerHTML = Plugin.getOption('translate.records.noRecords');
|
||
|
tableBody.appendChild(errorSpan);
|
||
|
$(datatable.wrap).addClass(pfx + 'datatable-error ' + pfx + 'datatable-loaded');
|
||
|
Plugin.spinnerCallback(false);
|
||
|
}
|
||
|
|
||
|
// replace existing table body
|
||
|
$(datatable.tableBody).replaceWith(tableBody);
|
||
|
datatable.tableBody = tableBody;
|
||
|
|
||
|
// layout update
|
||
|
Plugin.setupDOM(datatable.table);
|
||
|
Plugin.setupCellField([datatable.tableBody]);
|
||
|
Plugin.setupTemplateCell(datatable.tableBody);
|
||
|
Plugin.layoutUpdate();
|
||
|
},
|
||
|
|
||
|
updateTableComponents: function() {
|
||
|
datatable.tableHead = $(datatable.table).children('thead').get(0);
|
||
|
datatable.tableBody = $(datatable.table).children('tbody').get(0);
|
||
|
datatable.tableFoot = $(datatable.table).children('tfoot').get(0);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Call ajax for raw JSON data
|
||
|
*/
|
||
|
getData: function() {
|
||
|
// Plugin.spinnerCallback(true);
|
||
|
|
||
|
var ajaxParams = {
|
||
|
dataType: 'json',
|
||
|
method: 'POST',
|
||
|
data: {},
|
||
|
timeout: Plugin.getOption('data.source.read.timeout') || 30000,
|
||
|
};
|
||
|
|
||
|
if (options.data.type === 'local') {
|
||
|
ajaxParams.url = options.data.source;
|
||
|
}
|
||
|
|
||
|
if (options.data.type === 'remote') {
|
||
|
var data = Plugin.getDataSourceParam();
|
||
|
// remove if server params is not enabled
|
||
|
if (!Plugin.getOption('data.serverPaging')) {
|
||
|
delete data['pagination'];
|
||
|
}
|
||
|
if (!Plugin.getOption('data.serverSorting')) {
|
||
|
delete data['sort'];
|
||
|
}
|
||
|
ajaxParams.data = $.extend({}, ajaxParams.data, Plugin.getOption('data.source.read.params'), data);
|
||
|
ajaxParams = $.extend({}, ajaxParams, Plugin.getOption('data.source.read'));
|
||
|
|
||
|
if (typeof ajaxParams.url !== 'string') ajaxParams.url = Plugin.getOption('data.source.read');
|
||
|
if (typeof ajaxParams.url !== 'string') ajaxParams.url = Plugin.getOption('data.source');
|
||
|
// ajaxParams.data = $.extend(ajaxParams.data, data.pagination);
|
||
|
}
|
||
|
|
||
|
return $.ajax(ajaxParams).done(function(response, textStatus, jqXHR) {
|
||
|
datatable.lastResponse = response;
|
||
|
// extendible data map callback for custom datasource
|
||
|
datatable.dataSet = datatable.originalDataSet = Plugin.dataMapCallback(response);
|
||
|
Plugin.setAutoColumns();
|
||
|
$(datatable).trigger(pfx + 'datatable-on-ajax-done', [datatable.dataSet]);
|
||
|
}).fail(function(jqXHR, textStatus, errorThrown) {
|
||
|
$(datatable).trigger(pfx + 'datatable-on-ajax-fail', [jqXHR]);
|
||
|
$(datatable.tableBody).html($('<span/>').addClass(pfx + 'datatable-error').html(Plugin.getOption('translate.records.noRecords')));
|
||
|
$(datatable.wrap).addClass(pfx + 'datatable-error ' + pfx + 'datatable-loaded');
|
||
|
Plugin.spinnerCallback(false);
|
||
|
}).always(function() {
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Pagination object
|
||
|
* @param meta if null, local pagination, otherwise remote
|
||
|
* pagination
|
||
|
* @param callback for update data when navigating page
|
||
|
*/
|
||
|
paging: function(meta, callback) {
|
||
|
var pg = {
|
||
|
meta: null,
|
||
|
pager: null,
|
||
|
paginateEvent: null,
|
||
|
pagerLayout: {pagination: null, info: null},
|
||
|
callback: null,
|
||
|
init: function(meta) {
|
||
|
pg.meta = meta;
|
||
|
|
||
|
// parse pagination meta to integer
|
||
|
pg.meta.page = parseInt(pg.meta.page);
|
||
|
pg.meta.pages = parseInt(pg.meta.pages);
|
||
|
pg.meta.perpage = parseInt(pg.meta.perpage);
|
||
|
pg.meta.total = parseInt(pg.meta.total);
|
||
|
|
||
|
// always recount total pages
|
||
|
pg.meta.pages = Math.max(Math.ceil(pg.meta.total / pg.meta.perpage), 1);
|
||
|
|
||
|
// current page must be not over than total pages
|
||
|
if (pg.meta.page > pg.meta.pages) pg.meta.page = pg.meta.pages;
|
||
|
|
||
|
// set unique event name between tables
|
||
|
pg.paginateEvent = Plugin.getTablePrefix('paging');
|
||
|
|
||
|
pg.pager = $(datatable.table).siblings('.' + pfx + 'datatable-pager');
|
||
|
if ($(pg.pager).hasClass(pfx + 'datatable-paging-loaded')) return;
|
||
|
|
||
|
// if class .'+pfx+'datatable-paging-loaded not exist, recreate pagination
|
||
|
$(pg.pager).remove();
|
||
|
|
||
|
// if no pages available
|
||
|
if (pg.meta.pages === 0) return;
|
||
|
|
||
|
// update datasource params
|
||
|
Plugin.setDataSourceParam('pagination', {
|
||
|
page: pg.meta.page,
|
||
|
pages: pg.meta.pages,
|
||
|
perpage: pg.meta.perpage,
|
||
|
total: pg.meta.total,
|
||
|
});
|
||
|
|
||
|
// default callback function, contains remote pagination handler
|
||
|
pg.callback = pg.serverCallback;
|
||
|
// custom callback function
|
||
|
if (typeof callback === 'function') pg.callback = callback;
|
||
|
|
||
|
pg.addPaginateEvent();
|
||
|
pg.populate();
|
||
|
|
||
|
pg.meta.page = Math.max(pg.meta.page || 1, pg.meta.page);
|
||
|
|
||
|
$(datatable).trigger(pg.paginateEvent, pg.meta);
|
||
|
|
||
|
pg.pagingBreakpoint.call();
|
||
|
$(window).resize(pg.pagingBreakpoint);
|
||
|
},
|
||
|
serverCallback: function(ctx, meta) {
|
||
|
Plugin.dataRender();
|
||
|
},
|
||
|
populate: function() {
|
||
|
var icons = Plugin.getOption('layout.icons.pagination');
|
||
|
var title = Plugin.getOption('translate.toolbar.pagination.items.default');
|
||
|
// pager root element
|
||
|
pg.pager = $('<div/>').addClass(pfx + 'datatable-pager ' + pfx + 'datatable-paging-loaded');
|
||
|
// numbering links
|
||
|
var pagerNumber = $('<ul/>').addClass(pfx + 'datatable-pager-nav mb-5 mb-sm-0');
|
||
|
pg.pagerLayout['pagination'] = pagerNumber;
|
||
|
|
||
|
// pager first/previous button
|
||
|
$('<li/>').
|
||
|
append($('<a/>').
|
||
|
attr('title', title.first).
|
||
|
addClass(pfx + 'datatable-pager-link ' + pfx + 'datatable-pager-link-first').
|
||
|
append($('<i/>').addClass(icons.first)).
|
||
|
on('click', pg.gotoMorePage).
|
||
|
attr('data-page', 1)).
|
||
|
appendTo(pagerNumber);
|
||
|
$('<li/>').
|
||
|
append($('<a/>').
|
||
|
attr('title', title.prev).
|
||
|
addClass(pfx + 'datatable-pager-link ' + pfx + 'datatable-pager-link-prev').
|
||
|
append($('<i/>').addClass(icons.prev)).
|
||
|
on('click', pg.gotoMorePage)).
|
||
|
appendTo(pagerNumber);
|
||
|
|
||
|
// more previous pages
|
||
|
$('<li/>').
|
||
|
append($('<a/>').
|
||
|
attr('title', title.more).
|
||
|
addClass(pfx + 'datatable-pager-link ' + pfx + 'datatable-pager-link-more-prev').
|
||
|
html($('<i/>').addClass(icons.more)).
|
||
|
on('click', pg.gotoMorePage)).
|
||
|
appendTo(pagerNumber);
|
||
|
|
||
|
$('<li/>').append($('<input/>').attr('type', 'text').addClass(pfx + 'datatable-pager-input form-control').attr('title', title.input).on('keyup', function() {
|
||
|
// on keyup update [data-page]
|
||
|
$(this).attr('data-page', Math.abs($(this).val()));
|
||
|
}).on('keypress', function(e) {
|
||
|
// on keypressed enter button
|
||
|
if (e.which === 13) pg.gotoMorePage(e);
|
||
|
})).appendTo(pagerNumber);
|
||
|
|
||
|
var pagesNumber = Plugin.getOption('toolbar.items.pagination.pages.desktop.pagesNumber');
|
||
|
var end = Math.ceil(pg.meta.page / pagesNumber) * pagesNumber;
|
||
|
var start = end - pagesNumber;
|
||
|
if (end > pg.meta.pages) {
|
||
|
end = pg.meta.pages;
|
||
|
}
|
||
|
|
||
|
// keep pagination 1 if there is no records
|
||
|
if (start < 0) {
|
||
|
start = 0;
|
||
|
}
|
||
|
|
||
|
for (var x = start; x < (end || 1); x++) {
|
||
|
var pageNumber = x + 1;
|
||
|
$('<li/>').
|
||
|
append($('<a/>').
|
||
|
addClass(pfx + 'datatable-pager-link ' + pfx + 'datatable-pager-link-number').
|
||
|
text(pageNumber).
|
||
|
attr('data-page', pageNumber).
|
||
|
attr('title', pageNumber).
|
||
|
on('click', pg.gotoPage)).
|
||
|
appendTo(pagerNumber);
|
||
|
}
|
||
|
|
||
|
// more next pages
|
||
|
$('<li/>').
|
||
|
append($('<a/>').
|
||
|
attr('title', title.more).
|
||
|
addClass(pfx + 'datatable-pager-link ' + pfx + 'datatable-pager-link-more-next').
|
||
|
html($('<i/>').addClass(icons.more)).
|
||
|
on('click', pg.gotoMorePage)).
|
||
|
appendTo(pagerNumber);
|
||
|
|
||
|
// pager next/last button
|
||
|
$('<li/>').
|
||
|
append($('<a/>').
|
||
|
attr('title', title.next).
|
||
|
addClass(pfx + 'datatable-pager-link ' + pfx + 'datatable-pager-link-next').
|
||
|
append($('<i/>').addClass(icons.next)).
|
||
|
on('click', pg.gotoMorePage)).
|
||
|
appendTo(pagerNumber);
|
||
|
$('<li/>').
|
||
|
append($('<a/>').
|
||
|
attr('title', title.last).
|
||
|
addClass(pfx + 'datatable-pager-link ' + pfx + 'datatable-pager-link-last').
|
||
|
append($('<i/>').addClass(icons.last)).
|
||
|
on('click', pg.gotoMorePage).
|
||
|
attr('data-page', pg.meta.pages)).
|
||
|
appendTo(pagerNumber);
|
||
|
|
||
|
// page info
|
||
|
if (Plugin.getOption('toolbar.items.info')) {
|
||
|
pg.pagerLayout['info'] = $('<div/>').addClass(pfx + 'datatable-pager-info').append($('<span/>').addClass(pfx + 'datatable-pager-detail'));
|
||
|
}
|
||
|
|
||
|
$.each(Plugin.getOption('toolbar.layout'), function(i, layout) {
|
||
|
$(pg.pagerLayout[layout]).appendTo(pg.pager);
|
||
|
});
|
||
|
|
||
|
// page size select
|
||
|
var pageSizeSelect = $('<select/>').
|
||
|
addClass('selectpicker ' + pfx + 'datatable-pager-size').
|
||
|
attr('title', Plugin.getOption('translate.toolbar.pagination.items.default.select')).
|
||
|
attr('data-width', '60px').
|
||
|
attr('data-container', 'body').
|
||
|
val(pg.meta.perpage).
|
||
|
on('change', pg.updatePerpage).
|
||
|
prependTo(pg.pagerLayout['info']);
|
||
|
|
||
|
var pageSizes = Plugin.getOption('toolbar.items.pagination.pageSizeSelect');
|
||
|
// default value here, to fix override option by user
|
||
|
if (pageSizes.length == 0) pageSizes = [5, 10, 20, 30, 50, 100];
|
||
|
$.each(pageSizes, function(i, size) {
|
||
|
var display = size;
|
||
|
if (size === -1) display = Plugin.getOption('translate.toolbar.pagination.items.default.all');
|
||
|
$('<option/>').attr('value', size).html(display).appendTo(pageSizeSelect);
|
||
|
});
|
||
|
|
||
|
// init selectpicker to dropdown
|
||
|
$(datatable).ready(function() {
|
||
|
$('.selectpicker').
|
||
|
selectpicker().
|
||
|
on('hide.bs.select', function() {
|
||
|
// fix dropup arrow icon on hide
|
||
|
$(this).closest('.bootstrap-select').removeClass('dropup');
|
||
|
}).
|
||
|
siblings('.dropdown-toggle').
|
||
|
attr('title', Plugin.getOption('translate.toolbar.pagination.items.default.select'));
|
||
|
});
|
||
|
|
||
|
pg.paste();
|
||
|
},
|
||
|
paste: function() {
|
||
|
// insert pagination based on placement position, top|bottom
|
||
|
$.each($.unique(Plugin.getOption('toolbar.placement')),
|
||
|
function(i, position) {
|
||
|
if (position === 'bottom') {
|
||
|
$(pg.pager).clone(true).insertAfter(datatable.table);
|
||
|
}
|
||
|
if (position === 'top') {
|
||
|
// pager top need some extra space
|
||
|
$(pg.pager).clone(true).addClass(pfx + 'datatable-pager-top').insertBefore(datatable.table);
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
gotoMorePage: function(e) {
|
||
|
e.preventDefault();
|
||
|
// $(this) is a link of .'+pfx+'datatable-pager-link
|
||
|
|
||
|
if ($(this).attr('disabled') === 'disabled') return false;
|
||
|
|
||
|
var page = $(this).attr('data-page');
|
||
|
|
||
|
// event from text input
|
||
|
if (typeof page === 'undefined') {
|
||
|
page = $(e.target).attr('data-page');
|
||
|
}
|
||
|
|
||
|
pg.openPage(parseInt(page));
|
||
|
return false;
|
||
|
},
|
||
|
gotoPage: function(e) {
|
||
|
e.preventDefault();
|
||
|
// prevent from click same page number
|
||
|
if ($(this).hasClass(pfx + 'datatable-pager-link-active')) return;
|
||
|
|
||
|
pg.openPage(parseInt($(this).data('page')));
|
||
|
},
|
||
|
openPage: function(page) {
|
||
|
// currentPage is 1-based index
|
||
|
pg.meta.page = parseInt(page);
|
||
|
|
||
|
$(datatable).trigger(pg.paginateEvent, pg.meta);
|
||
|
pg.callback(pg, pg.meta);
|
||
|
|
||
|
// update page callback function
|
||
|
$(pg.pager).trigger(pfx + 'datatable-on-goto-page', pg.meta);
|
||
|
},
|
||
|
updatePerpage: function(e) {
|
||
|
e.preventDefault();
|
||
|
// if (Plugin.getOption('layout.height') === null) {
|
||
|
// fix white space, when perpage is set from many records to less records
|
||
|
// $('html, body').animate({scrollTop: $(datatable).position().top});
|
||
|
// }
|
||
|
|
||
|
// hide dropdown after select
|
||
|
$(this).selectpicker('toggle');
|
||
|
|
||
|
pg.pager = $(datatable.table).siblings('.' + pfx + 'datatable-pager').removeClass(pfx + 'datatable-paging-loaded');
|
||
|
|
||
|
// on change select page size
|
||
|
if (e.originalEvent) {
|
||
|
pg.meta.perpage = parseInt($(this).val());
|
||
|
}
|
||
|
|
||
|
$(pg.pager).find('select.' + pfx + 'datatable-pager-size').val(pg.meta.perpage).attr('data-selected', pg.meta.perpage);
|
||
|
|
||
|
// update datasource params
|
||
|
Plugin.setDataSourceParam('pagination', {
|
||
|
page: pg.meta.page,
|
||
|
pages: pg.meta.pages,
|
||
|
perpage: pg.meta.perpage,
|
||
|
total: pg.meta.total,
|
||
|
});
|
||
|
|
||
|
// update page callback function
|
||
|
$(pg.pager).trigger(pfx + 'datatable-on-update-perpage', pg.meta);
|
||
|
$(datatable).trigger(pg.paginateEvent, pg.meta);
|
||
|
pg.callback(pg, pg.meta);
|
||
|
|
||
|
// update pagination info
|
||
|
pg.updateInfo.call();
|
||
|
},
|
||
|
addPaginateEvent: function(e) {
|
||
|
// pagination event
|
||
|
$(datatable).off(pg.paginateEvent).on(pg.paginateEvent, function(e, meta) {
|
||
|
Plugin.spinnerCallback(true);
|
||
|
|
||
|
pg.pager = $(datatable.table).siblings('.' + pfx + 'datatable-pager');
|
||
|
var pagerNumber = $(pg.pager).find('.' + pfx + 'datatable-pager-nav');
|
||
|
|
||
|
// set sync active page class
|
||
|
$(pagerNumber).find('.' + pfx + 'datatable-pager-link-active').removeClass(pfx + 'datatable-pager-link-active');
|
||
|
$(pagerNumber).find('.' + pfx + 'datatable-pager-link-number[data-page="' + meta.page + '"]').addClass(pfx + 'datatable-pager-link-active');
|
||
|
|
||
|
// set next and previous link page number
|
||
|
$(pagerNumber).find('.' + pfx + 'datatable-pager-link-prev').attr('data-page', Math.max(meta.page - 1, 1));
|
||
|
$(pagerNumber).find('.' + pfx + 'datatable-pager-link-next').attr('data-page', Math.min(meta.page + 1, meta.pages));
|
||
|
|
||
|
// current page input value sync
|
||
|
$(pg.pager).each(function() {
|
||
|
$(this).find('.' + pfx + 'datatable-pager-input[type="text"]').prop('value', meta.page);
|
||
|
});
|
||
|
|
||
|
// if only 1 page, should hide page?
|
||
|
// $(pg.pager).find('.' + pfx + 'datatable-pager-nav').show();
|
||
|
// if (meta.pages <= 1) {
|
||
|
// // hide pager if has 1 page
|
||
|
// $(pg.pager).find('.' + pfx + 'datatable-pager-nav').hide();
|
||
|
// }
|
||
|
|
||
|
// update datasource params
|
||
|
Plugin.setDataSourceParam('pagination', {
|
||
|
page: pg.meta.page,
|
||
|
pages: pg.meta.pages,
|
||
|
perpage: pg.meta.perpage,
|
||
|
total: pg.meta.total,
|
||
|
});
|
||
|
|
||
|
$(pg.pager).find('select.' + pfx + 'datatable-pager-size').val(meta.perpage).attr('data-selected', meta.perpage);
|
||
|
|
||
|
// clear active rows
|
||
|
$(datatable.table).find('.' + pfx + 'checkbox > [type="checkbox"]').prop('checked', false);
|
||
|
$(datatable.table).find('.' + pfx + 'datatable-row-active').removeClass(pfx + 'datatable-row-active');
|
||
|
|
||
|
pg.updateInfo.call();
|
||
|
pg.pagingBreakpoint.call();
|
||
|
// Plugin.resetScroll();
|
||
|
});
|
||
|
},
|
||
|
updateInfo: function() {
|
||
|
var start = Math.max(pg.meta.perpage * (pg.meta.page - 1) + 1, 1);
|
||
|
var end = Math.min(start + pg.meta.perpage - 1, pg.meta.total);
|
||
|
// page info update
|
||
|
$(pg.pager).find('.' + pfx + 'datatable-pager-info').find('.' + pfx + 'datatable-pager-detail').html(Plugin.dataPlaceholder(
|
||
|
Plugin.getOption('translate.toolbar.pagination.items.info'), {
|
||
|
// set start page 0 if the is no records. eg. Showing 0 - 0 of 0
|
||
|
start: pg.meta.total === 0 ? 0 : start,
|
||
|
end: pg.meta.perpage === -1 ? pg.meta.total : end,
|
||
|
pageSize: pg.meta.perpage === -1 ||
|
||
|
pg.meta.perpage >= pg.meta.total
|
||
|
? pg.meta.total
|
||
|
: pg.meta.perpage,
|
||
|
total: pg.meta.total,
|
||
|
}));
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Update pagination layout breakpoint
|
||
|
*/
|
||
|
pagingBreakpoint: function() {
|
||
|
// keep page links reference
|
||
|
var pagerNumber = $(datatable.table).siblings('.' + pfx + 'datatable-pager').find('.' + pfx + 'datatable-pager-nav');
|
||
|
if ($(pagerNumber).length === 0) return;
|
||
|
|
||
|
var currentPage = Plugin.getCurrentPage();
|
||
|
var pagerInput = $(pagerNumber).find('.' + pfx + 'datatable-pager-input').closest('li');
|
||
|
|
||
|
// reset
|
||
|
$(pagerNumber).find('li').show();
|
||
|
|
||
|
// pagination update
|
||
|
$.each(Plugin.getOption('toolbar.items.pagination.pages'),
|
||
|
function(mode, option) {
|
||
|
if (util.isInResponsiveRange(mode)) {
|
||
|
switch (mode) {
|
||
|
case 'desktop':
|
||
|
case 'tablet':
|
||
|
var end = Math.ceil(currentPage / option.pagesNumber) * option.pagesNumber;
|
||
|
var start = end - option.pagesNumber;
|
||
|
$(pagerInput).hide();
|
||
|
pg.meta = Plugin.getDataSourceParam('pagination');
|
||
|
pg.paginationUpdate();
|
||
|
break;
|
||
|
|
||
|
case 'mobile':
|
||
|
$(pagerInput).show();
|
||
|
$(pagerNumber).find('.' + pfx + 'datatable-pager-link-more-prev').closest('li').hide();
|
||
|
$(pagerNumber).find('.' + pfx + 'datatable-pager-link-more-next').closest('li').hide();
|
||
|
$(pagerNumber).find('.' + pfx + 'datatable-pager-link-number').closest('li').hide();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Update pagination number and button display
|
||
|
*/
|
||
|
paginationUpdate: function() {
|
||
|
var pager = $(datatable.table).siblings('.' + pfx + 'datatable-pager').find('.' + pfx + 'datatable-pager-nav'),
|
||
|
pagerMorePrev = $(pager).find('.' + pfx + 'datatable-pager-link-more-prev'),
|
||
|
pagerMoreNext = $(pager).find('.' + pfx + 'datatable-pager-link-more-next'),
|
||
|
pagerFirst = $(pager).find('.' + pfx + 'datatable-pager-link-first'),
|
||
|
pagerPrev = $(pager).find('.' + pfx + 'datatable-pager-link-prev'),
|
||
|
pagerNext = $(pager).find('.' + pfx + 'datatable-pager-link-next'),
|
||
|
pagerLast = $(pager).find('.' + pfx + 'datatable-pager-link-last');
|
||
|
|
||
|
// get visible page
|
||
|
var pagerNumber = $(pager).find('.' + pfx + 'datatable-pager-link-number');
|
||
|
// get page before of first visible
|
||
|
var morePrevPage = Math.max($(pagerNumber).first().data('page') - 1, 1);
|
||
|
$(pagerMorePrev).each(function(i, prev) {
|
||
|
$(prev).attr('data-page', morePrevPage);
|
||
|
});
|
||
|
// show/hide <li>
|
||
|
if (morePrevPage === 1) {
|
||
|
$(pagerMorePrev).parent().hide();
|
||
|
} else {
|
||
|
$(pagerMorePrev).parent().show();
|
||
|
}
|
||
|
|
||
|
// get page after of last visible
|
||
|
var moreNextPage = Math.min($(pagerNumber).last().data('page') + 1,
|
||
|
pg.meta.pages);
|
||
|
$(pagerMoreNext).each(function(i, prev) {
|
||
|
$(pagerMoreNext).attr('data-page', moreNextPage).show();
|
||
|
});
|
||
|
|
||
|
// show/hide <li>
|
||
|
if (moreNextPage === pg.meta.pages
|
||
|
// missing dot fix when last hidden page is one left
|
||
|
&& moreNextPage === $(pagerNumber).last().data('page')) {
|
||
|
$(pagerMoreNext).parent().hide();
|
||
|
} else {
|
||
|
$(pagerMoreNext).parent().show();
|
||
|
}
|
||
|
|
||
|
// begin/end of pages
|
||
|
if (pg.meta.page === 1) {
|
||
|
$(pagerFirst).attr('disabled', true).addClass(pfx + 'datatable-pager-link-disabled');
|
||
|
$(pagerPrev).attr('disabled', true).addClass(pfx + 'datatable-pager-link-disabled');
|
||
|
} else {
|
||
|
$(pagerFirst).removeAttr('disabled').removeClass(pfx + 'datatable-pager-link-disabled');
|
||
|
$(pagerPrev).removeAttr('disabled').removeClass(pfx + 'datatable-pager-link-disabled');
|
||
|
}
|
||
|
if (pg.meta.page === pg.meta.pages) {
|
||
|
$(pagerNext).attr('disabled', true).addClass(pfx + 'datatable-pager-link-disabled');
|
||
|
$(pagerLast).attr('disabled', true).addClass(pfx + 'datatable-pager-link-disabled');
|
||
|
} else {
|
||
|
$(pagerNext).removeAttr('disabled').removeClass(pfx + 'datatable-pager-link-disabled');
|
||
|
$(pagerLast).removeAttr('disabled').removeClass(pfx + 'datatable-pager-link-disabled');
|
||
|
}
|
||
|
|
||
|
// display more buttons
|
||
|
var nav = Plugin.getOption('toolbar.items.pagination.navigation');
|
||
|
if (!nav.first) $(pagerFirst).remove();
|
||
|
if (!nav.prev) $(pagerPrev).remove();
|
||
|
if (!nav.next) $(pagerNext).remove();
|
||
|
if (!nav.last) $(pagerLast).remove();
|
||
|
if (!nav.more) {
|
||
|
$(pagerMorePrev).remove();
|
||
|
$(pagerMoreNext).remove();
|
||
|
}
|
||
|
},
|
||
|
};
|
||
|
pg.init(meta);
|
||
|
return pg;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Hide/show table cell defined by
|
||
|
* options[columns][i][responsive][visible/hidden]
|
||
|
*/
|
||
|
columnHide: function() {
|
||
|
var screen = util.getViewPort().width;
|
||
|
// foreach columns setting
|
||
|
$.each(options.columns, function(i, column) {
|
||
|
if (typeof column.responsive !== 'undefined' || typeof column.visible !== 'undefined') {
|
||
|
var field = column.field;
|
||
|
var tds = $.grep($(datatable.table).find('.' + pfx + 'datatable-cell'), function(n, i) {
|
||
|
return field === $(n).data('field');
|
||
|
});
|
||
|
|
||
|
setTimeout(function () {
|
||
|
// hide by force
|
||
|
if (Plugin.getObject('visible', column) === false) {
|
||
|
$(tds).hide();
|
||
|
} else {
|
||
|
// show/hide by responsive breakpoint
|
||
|
if (util.getBreakpoint(Plugin.getObject('responsive.hidden', column)) >= screen) {
|
||
|
$(tds).hide();
|
||
|
} else {
|
||
|
$(tds).show();
|
||
|
}
|
||
|
if (util.getBreakpoint(Plugin.getObject('responsive.visible', column)) <= screen) {
|
||
|
$(tds).show();
|
||
|
} else {
|
||
|
$(tds).hide();
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Setup sub datatable
|
||
|
*/
|
||
|
setupSubDatatable: function() {
|
||
|
var subTableCallback = Plugin.getOption('detail.content');
|
||
|
if (typeof subTableCallback !== 'function') return;
|
||
|
|
||
|
// subtable already exist
|
||
|
if ($(datatable.table).find('.' + pfx + 'datatable-subtable').length > 0) return;
|
||
|
|
||
|
$(datatable.wrap).addClass(pfx + 'datatable-subtable');
|
||
|
|
||
|
options.columns[0]['subtable'] = true;
|
||
|
|
||
|
// toggle on open sub table
|
||
|
var toggleSubTable = function(e) {
|
||
|
e.preventDefault();
|
||
|
// get parent row of this subtable
|
||
|
var parentRow = $(this).closest('.' + pfx + 'datatable-row');
|
||
|
|
||
|
// get subtable row for sub table
|
||
|
var subTableRow = $(parentRow).next('.' + pfx + 'datatable-row-subtable');
|
||
|
if ($(subTableRow).length === 0) {
|
||
|
// prepare DOM for sub table, each <tr> as parent and add <tr> as child table
|
||
|
subTableRow = $('<tr/>').
|
||
|
addClass(pfx + 'datatable-row-subtable ' + pfx + 'datatable-row-loading').
|
||
|
hide().
|
||
|
append($('<td/>').addClass(pfx + 'datatable-subtable').attr('colspan', Plugin.getTotalColumns()));
|
||
|
$(parentRow).after(subTableRow);
|
||
|
// add class to even row
|
||
|
if ($(parentRow).hasClass(pfx + 'datatable-row-even')) {
|
||
|
$(subTableRow).addClass(pfx + 'datatable-row-subtable-even');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$(subTableRow).toggle();
|
||
|
|
||
|
var subTable = $(subTableRow).find('.' + pfx + 'datatable-subtable');
|
||
|
|
||
|
// get id from first column of parent row
|
||
|
var primaryKey = $(this).closest('[data-field]:first-child').find('.' + pfx + 'datatable-toggle-subtable').data('value');
|
||
|
|
||
|
var icon = $(this).find('i').removeAttr('class');
|
||
|
|
||
|
// prevent duplicate datatable init
|
||
|
if ($(parentRow).hasClass(pfx + 'datatable-row-subtable-expanded')) {
|
||
|
$(icon).addClass(Plugin.getOption('layout.icons.rowDetail.collapse'));
|
||
|
// remove expand class from parent row
|
||
|
$(parentRow).removeClass(pfx + 'datatable-row-subtable-expanded');
|
||
|
// trigger event on collapse
|
||
|
$(datatable).trigger(pfx + 'datatable-on-collapse-subtable', [parentRow]);
|
||
|
} else {
|
||
|
// expand and run callback function
|
||
|
$(icon).addClass(Plugin.getOption('layout.icons.rowDetail.expand'));
|
||
|
// add expand class to parent row
|
||
|
$(parentRow).addClass(pfx + 'datatable-row-subtable-expanded');
|
||
|
// trigger event on expand
|
||
|
$(datatable).trigger(pfx + 'datatable-on-expand-subtable', [parentRow]);
|
||
|
}
|
||
|
|
||
|
// prevent duplicate datatable init
|
||
|
if ($(subTable).find('.' + pfx + 'datatable').length === 0) {
|
||
|
// get data by primary id
|
||
|
$.map(datatable.dataSet, function(n, i) {
|
||
|
// primary id must be at the first column, otherwise e.data will be undefined
|
||
|
if (primaryKey === n[options.columns[0].field]) {
|
||
|
e.data = n;
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
});
|
||
|
|
||
|
// deprecated in v5.0.6
|
||
|
e.detailCell = subTable;
|
||
|
|
||
|
e.parentRow = parentRow;
|
||
|
e.subTable = subTable;
|
||
|
|
||
|
// run callback with event
|
||
|
subTableCallback(e);
|
||
|
|
||
|
$(subTable).children('.' + pfx + 'datatable').on(pfx + 'datatable-on-init', function(e) {
|
||
|
$(subTableRow).removeClass(pfx + 'datatable-row-loading');
|
||
|
});
|
||
|
if (Plugin.getOption('data.type') === 'local') {
|
||
|
$(subTableRow).removeClass(pfx + 'datatable-row-loading');
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
var columns = options.columns;
|
||
|
$(datatable.tableBody).find('.' + pfx + 'datatable-row').each(function(tri, tr) {
|
||
|
$(tr).find('.' + pfx + 'datatable-cell').each(function(tdi, td) {
|
||
|
// get column settings by field
|
||
|
var column = $.grep(columns, function(n, i) {
|
||
|
return $(td).data('field') === n.field;
|
||
|
})[0];
|
||
|
if (typeof column !== 'undefined') {
|
||
|
var value = $(td).text();
|
||
|
// enable column subtable toggle
|
||
|
if (typeof column.subtable !== 'undefined' && column.subtable) {
|
||
|
// check if subtable toggle exist
|
||
|
if ($(td).find('.' + pfx + 'datatable-toggle-subtable').length > 0) return;
|
||
|
// append subtable toggle
|
||
|
$(td).
|
||
|
html($('<a/>').
|
||
|
addClass(pfx + 'datatable-toggle-subtable').
|
||
|
attr('href', '#').
|
||
|
attr('data-value', value).
|
||
|
attr('title', Plugin.getOption('detail.title')).
|
||
|
on('click', toggleSubTable).
|
||
|
append($('<i/>').css('width', $(td).data('width')).addClass(Plugin.getOption('layout.icons.rowDetail.collapse'))));
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
|
||
|
// $(datatable.tableHead).find('.'+pfx+'-datatable-row').first()
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Datasource mapping callback
|
||
|
*/
|
||
|
dataMapCallback: function(raw) {
|
||
|
// static dataset array
|
||
|
var dataSet = raw;
|
||
|
// dataset mapping callback
|
||
|
if (typeof Plugin.getOption('data.source.read.map') === 'function') {
|
||
|
return Plugin.getOption('data.source.read.map')(raw);
|
||
|
} else {
|
||
|
// default data mapping fallback
|
||
|
if (typeof raw !== 'undefined' && typeof raw.data !== 'undefined') {
|
||
|
dataSet = raw.data;
|
||
|
}
|
||
|
}
|
||
|
return dataSet;
|
||
|
},
|
||
|
|
||
|
isSpinning: false,
|
||
|
/**
|
||
|
* BlockUI spinner callback
|
||
|
* @param block
|
||
|
* @param target
|
||
|
*/
|
||
|
spinnerCallback: function(block, target) {
|
||
|
if (typeof target === 'undefined') target = datatable;
|
||
|
// get spinner options
|
||
|
var spinnerOptions = Plugin.getOption('layout.spinner');
|
||
|
// spinner is disabled
|
||
|
if (typeof spinnerOptions === 'undefined' || !spinnerOptions) {
|
||
|
return;
|
||
|
}
|
||
|
if (block) {
|
||
|
if (!Plugin.isSpinning) {
|
||
|
if (typeof spinnerOptions.message !== 'undefined' && spinnerOptions.message === true) {
|
||
|
// use default spinner message from translation
|
||
|
spinnerOptions.message = Plugin.getOption('translate.records.processing');
|
||
|
}
|
||
|
Plugin.isSpinning = true;
|
||
|
if (typeof app !== 'undefined') {
|
||
|
app.block(target, spinnerOptions);
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
Plugin.isSpinning = false;
|
||
|
if (typeof app !== 'undefined') {
|
||
|
app.unblock(target);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Default sort callback function
|
||
|
* @param data
|
||
|
* @param sort
|
||
|
* @param column
|
||
|
* @returns {*|Array.<T>|{sort, field}|{asc, desc}}
|
||
|
*/
|
||
|
sortCallback: function(data, sort, column) {
|
||
|
var type = column['type'] || 'string';
|
||
|
var format = column['format'] || '';
|
||
|
var field = column['field'];
|
||
|
|
||
|
return $(data).sort(function(a, b) {
|
||
|
var aField = a[field];
|
||
|
var bField = b[field];
|
||
|
|
||
|
switch (type) {
|
||
|
case 'date':
|
||
|
if (typeof moment === 'undefined') {
|
||
|
throw new Error('Moment.js is required.');
|
||
|
}
|
||
|
var diff = moment(aField, format).diff(moment(bField, format));
|
||
|
if (sort === 'asc') {
|
||
|
return diff > 0 ? 1 : diff < 0 ? -1 : 0;
|
||
|
} else {
|
||
|
return diff < 0 ? 1 : diff > 0 ? -1 : 0;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'number':
|
||
|
if (isNaN(parseFloat(aField)) && aField != null) {
|
||
|
aField = Number(aField.replace(/[^0-9\.-]+/g, ''));
|
||
|
}
|
||
|
if (isNaN(parseFloat(bField)) && bField != null) {
|
||
|
bField = Number(bField.replace(/[^0-9\.-]+/g, ''));
|
||
|
}
|
||
|
aField = parseFloat(aField);
|
||
|
bField = parseFloat(bField);
|
||
|
if (sort === 'asc') {
|
||
|
return aField > bField ? 1 : aField < bField ? -1 : 0;
|
||
|
} else {
|
||
|
return aField < bField ? 1 : aField > bField ? -1 : 0;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'html':
|
||
|
return $(data).sort(function(a, b) {
|
||
|
// get the text only from html
|
||
|
aField = $(a[field]).text();
|
||
|
bField = $(b[field]).text();
|
||
|
// sort
|
||
|
if (sort === 'asc') {
|
||
|
return aField > bField ? 1 : aField < bField ? -1 : 0;
|
||
|
} else {
|
||
|
return aField < bField ? 1 : aField > bField ? -1 : 0;
|
||
|
}
|
||
|
});
|
||
|
break;
|
||
|
|
||
|
case 'string':
|
||
|
default:
|
||
|
if (sort === 'asc') {
|
||
|
return aField > bField ? 1 : aField < bField ? -1 : 0;
|
||
|
} else {
|
||
|
return aField < bField ? 1 : aField > bField ? -1 : 0;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Custom debug log
|
||
|
* @param text
|
||
|
* @param obj
|
||
|
*/
|
||
|
log: function(text, obj) {
|
||
|
if (typeof obj === 'undefined') obj = '';
|
||
|
if (datatable.debug) {
|
||
|
console.log(text, obj);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Auto hide columnds overflow in row
|
||
|
*/
|
||
|
autoHide: function() {
|
||
|
var hiddenExist = false;
|
||
|
// force hide enabled
|
||
|
var hidDefault = $(datatable.table).find('[data-autohide-enabled]');
|
||
|
if (hidDefault.length) {
|
||
|
hiddenExist = true;
|
||
|
hidDefault.hide();
|
||
|
}
|
||
|
|
||
|
var toggleHiddenColumns = function(e) {
|
||
|
e.preventDefault();
|
||
|
|
||
|
var row = $(this).closest('.' + pfx + 'datatable-row');
|
||
|
var detailRow = $(row).next();
|
||
|
|
||
|
if (!$(detailRow).hasClass(pfx + 'datatable-row-detail')) {
|
||
|
$(this).find('i').removeClass(Plugin.getOption('layout.icons.rowDetail.collapse')).addClass(Plugin.getOption('layout.icons.rowDetail.expand'));
|
||
|
|
||
|
var hiddenCells = $(row).find('.' + pfx + 'datatable-cell:hidden');
|
||
|
var clonedCells = hiddenCells.clone().show();
|
||
|
|
||
|
detailRow = $('<tr/>').addClass(pfx + 'datatable-row-detail').insertAfter(row);
|
||
|
var detailRowTd = $('<td/>').addClass(pfx + 'datatable-detail').attr('colspan', Plugin.getTotalColumns()).appendTo(detailRow);
|
||
|
|
||
|
var detailSubTable = $('<table/>');
|
||
|
$(clonedCells).each(function() {
|
||
|
var field = $(this).data('field');
|
||
|
var column = $.grep(options.columns, function(n, i) {
|
||
|
return field === n.field;
|
||
|
})[0];
|
||
|
if (typeof column === 'undefined' || column.visible !== false) {
|
||
|
$(detailSubTable).
|
||
|
append($('<tr class="' + pfx + 'datatable-row"></tr>').
|
||
|
append($('<td class="' + pfx + 'datatable-cell"></td>').append($('<span/>').append(column.title))).
|
||
|
append(this));
|
||
|
}
|
||
|
});
|
||
|
$(detailRowTd).append(detailSubTable);
|
||
|
|
||
|
} else {
|
||
|
$(this).find('i').removeClass(Plugin.getOption('layout.icons.rowDetail.expand')).addClass(Plugin.getOption('layout.icons.rowDetail.collapse'));
|
||
|
$(detailRow).remove();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
setTimeout(function () {
|
||
|
$(datatable.table).find('.' + pfx + 'datatable-cell').show();
|
||
|
$(datatable.tableBody).each(function() {
|
||
|
var recursive = 0;
|
||
|
while ($(this)[0].offsetWidth < $(this)[0].scrollWidth && recursive < options.columns.length) {
|
||
|
$(datatable.table).find('.' + pfx + 'datatable-row').each(function(i) {
|
||
|
var cell = $(this).find('.' + pfx + 'datatable-cell:not(:hidden):not([data-autohide-disabled])').last();
|
||
|
$(cell).hide();
|
||
|
hiddenExist = true;
|
||
|
});
|
||
|
recursive++;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
if (hiddenExist) {
|
||
|
// toggle show hidden columns
|
||
|
$(datatable.tableBody).find('.' + pfx + 'datatable-row').each(function() {
|
||
|
// if no toggle yet
|
||
|
if($(this).find('.' + pfx + 'datatable-toggle-detail').length === 0) {
|
||
|
// add toggle
|
||
|
$(this).prepend($('<td/>').
|
||
|
addClass(pfx + 'datatable-cell ' + pfx + 'datatable-toggle-detail').
|
||
|
append($('<a/>').
|
||
|
addClass(pfx + 'datatable-toggle-detail').
|
||
|
attr('href', '').
|
||
|
on('click', toggleHiddenColumns).
|
||
|
append('<i class="' + Plugin.getOption('layout.icons.rowDetail.collapse') + '"></i>')));
|
||
|
}
|
||
|
|
||
|
// check if subtable toggle exist
|
||
|
if ($(datatable.tableHead).find('.' + pfx + 'datatable-toggle-detail').length === 0) {
|
||
|
// add empty column to the header and footer
|
||
|
$(datatable.tableHead).
|
||
|
find('.' + pfx + 'datatable-row').
|
||
|
first().
|
||
|
prepend('<th class="' + pfx + 'datatable-cell ' + pfx + 'datatable-toggle-detail"><span></span></th>');
|
||
|
$(datatable.tableFoot).
|
||
|
find('.' + pfx + 'datatable-row').
|
||
|
first().
|
||
|
prepend('<th class="' + pfx + 'datatable-cell ' + pfx + 'datatable-toggle-detail"><span></span></th>');
|
||
|
} else {
|
||
|
$(datatable.tableHead).find('.' + pfx + 'datatable-toggle-detail').find('span');
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
Plugin.adjustCellsWidth.call();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* To enable auto columns features for remote data source
|
||
|
*/
|
||
|
setAutoColumns: function() {
|
||
|
if (Plugin.getOption('data.autoColumns')) {
|
||
|
$.each(datatable.dataSet[0], function(k, v) {
|
||
|
var found = $.grep(options.columns, function(n, i) {
|
||
|
return k === n.field;
|
||
|
});
|
||
|
if (found.length === 0) {
|
||
|
options.columns.push({field: k, title: k});
|
||
|
}
|
||
|
});
|
||
|
$(datatable.tableHead).find('.' + pfx + 'datatable-row').remove();
|
||
|
Plugin.setHeadTitle();
|
||
|
if (Plugin.getOption('layout.footer')) {
|
||
|
$(datatable.tableFoot).find('.' + pfx + 'datatable-row').remove();
|
||
|
Plugin.setHeadTitle(datatable.tableFoot);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/********************
|
||
|
** HELPERS
|
||
|
********************/
|
||
|
|
||
|
/**
|
||
|
* Check if table is a locked colums table
|
||
|
*/
|
||
|
isLocked: function() {
|
||
|
var isLocked = Plugin.lockEnabledColumns();
|
||
|
return isLocked.left.length > 0 || isLocked.right.length > 0;
|
||
|
},
|
||
|
|
||
|
isSubtable: function() {
|
||
|
return util.hasClass(datatable.wrap[0], pfx + 'datatable-subtable') || false;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get total extra space of an element for width calculation,
|
||
|
* including padding, margin, border
|
||
|
* @param element
|
||
|
* @returns {number}
|
||
|
*/
|
||
|
getExtraSpace: function(element) {
|
||
|
var padding = parseInt($(element).css('paddingRight')) +
|
||
|
parseInt($(element).css('paddingLeft'));
|
||
|
var margin = parseInt($(element).css('marginRight')) +
|
||
|
parseInt($(element).css('marginLeft'));
|
||
|
var border = Math.ceil(
|
||
|
$(element).css('border-right-width').replace('px', ''));
|
||
|
return padding + margin + border;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Insert data of array into {{ }} template placeholder
|
||
|
* @param template
|
||
|
* @param data
|
||
|
* @returns {*}
|
||
|
*/
|
||
|
dataPlaceholder: function(template, data) {
|
||
|
var result = template;
|
||
|
$.each(data, function(key, val) {
|
||
|
result = result.replace('{{' + key + '}}', val);
|
||
|
});
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get table unique ID
|
||
|
* Note: table unique change each time refreshed
|
||
|
* @param suffix
|
||
|
* @returns {*}
|
||
|
*/
|
||
|
getTableId: function(suffix) {
|
||
|
if (typeof suffix === 'undefined') suffix = '';
|
||
|
var id = $(datatable).attr('id');
|
||
|
if (typeof id === 'undefined') {
|
||
|
id = $(datatable).attr('class').split(' ')[0];
|
||
|
}
|
||
|
return id + suffix;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get table prefix with depth number
|
||
|
*/
|
||
|
getTablePrefix: function(suffix) {
|
||
|
if (typeof suffix !== 'undefined') suffix = '-' + suffix;
|
||
|
return Plugin.getTableId() + '-' + Plugin.getDepth() + suffix;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get current table depth of sub table
|
||
|
* @returns {number}
|
||
|
*/
|
||
|
getDepth: function() {
|
||
|
var depth = 0;
|
||
|
var table = datatable.table;
|
||
|
do {
|
||
|
table = $(table).parents('.' + pfx + 'datatable-table');
|
||
|
depth++;
|
||
|
} while ($(table).length > 0);
|
||
|
return depth;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Keep state item
|
||
|
* @param key
|
||
|
* @param value
|
||
|
*/
|
||
|
stateKeep: function(key, value) {
|
||
|
key = Plugin.getTablePrefix(key);
|
||
|
if (Plugin.getOption('data.saveState') === false) return;
|
||
|
if (localStorage) {
|
||
|
localStorage.setItem(key, JSON.stringify(value));
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get state item
|
||
|
* @param key
|
||
|
* @param defValue
|
||
|
*/
|
||
|
stateGet: function(key, defValue) {
|
||
|
key = Plugin.getTablePrefix(key);
|
||
|
if (Plugin.getOption('data.saveState') === false) return;
|
||
|
var value = null;
|
||
|
if (localStorage) {
|
||
|
value = localStorage.getItem(key);
|
||
|
}
|
||
|
if (typeof value !== 'undefined' && value !== null) {
|
||
|
return JSON.parse(value);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Update data in state without clear existing
|
||
|
* @param key
|
||
|
* @param value
|
||
|
*/
|
||
|
stateUpdate: function(key, value) {
|
||
|
var ori = Plugin.stateGet(key);
|
||
|
if (typeof ori === 'undefined' || ori === null) ori = {};
|
||
|
Plugin.stateKeep(key, $.extend({}, ori, value));
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Remove state item
|
||
|
* @param key
|
||
|
*/
|
||
|
stateRemove: function(key) {
|
||
|
key = Plugin.getTablePrefix(key);
|
||
|
if (localStorage) {
|
||
|
localStorage.removeItem(key);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get total columns.
|
||
|
*/
|
||
|
getTotalColumns: function(tablePart) {
|
||
|
if (typeof tablePart === 'undefined') tablePart = datatable.tableBody;
|
||
|
return $(tablePart).find('.' + pfx + 'datatable-row').first().find('.' + pfx + 'datatable-cell').length;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get table row. Useful to get row when current table is in lock
|
||
|
* mode. Can be used for both lock and normal table mode. By
|
||
|
* default, returning result will be in a list of <td>.
|
||
|
* @param tablePart
|
||
|
* @param row 1-based index
|
||
|
* @param tdOnly Optional. Default true
|
||
|
* @returns {*}
|
||
|
*/
|
||
|
getOneRow: function(tablePart, row, tdOnly) {
|
||
|
if (typeof tdOnly === 'undefined') tdOnly = true;
|
||
|
// get list of <tr>
|
||
|
var result = $(tablePart).find('.' + pfx + 'datatable-row:not(.' + pfx + 'datatable-row-detail):nth-child(' + row + ')');
|
||
|
if (tdOnly) {
|
||
|
// get list of <td> or <th>
|
||
|
result = result.find('.' + pfx + 'datatable-cell');
|
||
|
}
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Sort table row at HTML level by column index.
|
||
|
* todo; Not in use.
|
||
|
* @param header Header sort clicked
|
||
|
* @param sort asc|desc. Optional. Default asc
|
||
|
* @param int Boolean. Optional. Comparison value parse to integer.
|
||
|
* Default false
|
||
|
*/
|
||
|
sortColumn: function(header, sort, int) {
|
||
|
if (typeof sort === 'undefined') sort = 'asc'; // desc
|
||
|
if (typeof int === 'undefined') int = false;
|
||
|
|
||
|
var column = $(header).index();
|
||
|
var rows = $(datatable.tableBody).find('.' + pfx + 'datatable-row');
|
||
|
var hIndex = $(header).closest('.' + pfx + 'datatable-lock').index();
|
||
|
if (hIndex !== -1) {
|
||
|
rows = $(datatable.tableBody).find('.' + pfx + 'datatable-lock:nth-child(' + (hIndex + 1) + ')').find('.' + pfx + 'datatable-row');
|
||
|
}
|
||
|
|
||
|
var container = $(rows).parent();
|
||
|
$(rows).sort(function(a, b) {
|
||
|
var tda = $(a).find('td:nth-child(' + column + ')').text();
|
||
|
var tdb = $(b).find('td:nth-child(' + column + ')').text();
|
||
|
|
||
|
if (int) {
|
||
|
// useful for integer type sorting
|
||
|
tda = parseInt(tda);
|
||
|
tdb = parseInt(tdb);
|
||
|
}
|
||
|
|
||
|
if (sort === 'asc') {
|
||
|
return tda > tdb ? 1 : tda < tdb ? -1 : 0;
|
||
|
} else {
|
||
|
return tda < tdb ? 1 : tda > tdb ? -1 : 0;
|
||
|
}
|
||
|
}).appendTo(container);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Perform sort remote and local
|
||
|
*/
|
||
|
sorting: function() {
|
||
|
var sortObj = {
|
||
|
init: function() {
|
||
|
if (options.sortable) {
|
||
|
$(datatable.tableHead).
|
||
|
find('.' + pfx + 'datatable-cell:not(.' + pfx + 'datatable-cell-check)').
|
||
|
addClass(pfx + 'datatable-cell-sort').
|
||
|
off('click').
|
||
|
on('click', sortObj.sortClick);
|
||
|
// first init
|
||
|
sortObj.setIcon();
|
||
|
}
|
||
|
},
|
||
|
setIcon: function() {
|
||
|
var meta = Plugin.getDataSourceParam('sort');
|
||
|
if ($.isEmptyObject(meta)) return;
|
||
|
|
||
|
var column = Plugin.getColumnByField(meta.field);
|
||
|
// sort is disabled for this column
|
||
|
if (typeof column === 'undefined') return;
|
||
|
if (typeof column.sortable !== 'undefined' && column.sortable === false) return;
|
||
|
if (typeof column.selector !== 'undefined' && column.selector === true) return;
|
||
|
|
||
|
// sort icon beside column header
|
||
|
var td = $(datatable.tableHead).find('.' + pfx + 'datatable-cell[data-field="' + meta.field + '"]').attr('data-sort', meta.sort);
|
||
|
var sorting = $(td).find('span');
|
||
|
var icon = $(sorting).find('i');
|
||
|
|
||
|
var icons = Plugin.getOption('layout.icons.sort');
|
||
|
// update sort icon; desc & asc
|
||
|
if ($(icon).length > 0) {
|
||
|
$(icon).removeAttr('class').addClass(icons[meta.sort]);
|
||
|
} else {
|
||
|
$(sorting).append($('<i/>').addClass(icons[meta.sort]));
|
||
|
}
|
||
|
|
||
|
// set sorted class to header on init
|
||
|
$(td).addClass(pfx + 'datatable-cell-sorted');
|
||
|
},
|
||
|
sortClick: function(e) {
|
||
|
var meta = Plugin.getDataSourceParam('sort');
|
||
|
var field = $(this).data('field');
|
||
|
var column = Plugin.getColumnByField(field);
|
||
|
// sort is disabled for this column
|
||
|
if (typeof column === 'undefined') return;
|
||
|
if (typeof column.sortable !== 'undefined' && column.sortable === false) return;
|
||
|
if (typeof column.selector !== 'undefined' && column.selector === true) return;
|
||
|
|
||
|
// set sorted class to header
|
||
|
$(datatable.tableHead).find('th').removeClass(pfx + 'datatable-cell-sorted');
|
||
|
util.addClass(this, pfx + 'datatable-cell-sorted');
|
||
|
|
||
|
$(datatable.tableHead).find('.' + pfx + 'datatable-cell > span > i').remove();
|
||
|
|
||
|
if (options.sortable) {
|
||
|
Plugin.spinnerCallback(true);
|
||
|
|
||
|
var sort = 'desc';
|
||
|
if (Plugin.getObject('field', meta) === field) {
|
||
|
sort = Plugin.getObject('sort', meta);
|
||
|
}
|
||
|
|
||
|
// toggle sort
|
||
|
sort = typeof sort === 'undefined' || sort === 'desc'
|
||
|
? 'asc'
|
||
|
: 'desc';
|
||
|
|
||
|
// update field and sort params
|
||
|
meta = {field: field, sort: sort};
|
||
|
Plugin.setDataSourceParam('sort', meta);
|
||
|
|
||
|
sortObj.setIcon();
|
||
|
|
||
|
setTimeout(function() {
|
||
|
Plugin.dataRender('sort');
|
||
|
$(datatable).trigger(pfx + 'datatable-on-sort', meta);
|
||
|
}, 300);
|
||
|
}
|
||
|
},
|
||
|
};
|
||
|
sortObj.init();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Update JSON data list linked with sort, filter and pagination.
|
||
|
* Call this method, before using dataSet variable.
|
||
|
* @returns {*|null}
|
||
|
*/
|
||
|
localDataUpdate: function() {
|
||
|
var params = Plugin.getDataSourceParam();
|
||
|
if (typeof datatable.originalDataSet === 'undefined') {
|
||
|
datatable.originalDataSet = datatable.dataSet;
|
||
|
}
|
||
|
|
||
|
var field = Plugin.getObject('sort.field', params);
|
||
|
var sort = Plugin.getObject('sort.sort', params);
|
||
|
var column = Plugin.getColumnByField(field);
|
||
|
if (typeof column !== 'undefined' && Plugin.getOption('data.serverSorting') !== true) {
|
||
|
if (typeof column.sortCallback === 'function') {
|
||
|
datatable.dataSet = column.sortCallback(datatable.originalDataSet, sort, column);
|
||
|
} else {
|
||
|
datatable.dataSet = Plugin.sortCallback(datatable.originalDataSet, sort, column);
|
||
|
}
|
||
|
} else {
|
||
|
datatable.dataSet = datatable.originalDataSet;
|
||
|
}
|
||
|
|
||
|
// if server filter enable, don't pass local filter
|
||
|
if (typeof params.query === 'object' && !Plugin.getOption('data.serverFiltering')) {
|
||
|
params.query = params.query || {};
|
||
|
|
||
|
var nestedSearch = function(obj) {
|
||
|
for (var field in obj) {
|
||
|
if (!obj.hasOwnProperty(field)) continue;
|
||
|
if (typeof obj[field] === 'string') {
|
||
|
if (obj[field].toLowerCase() == search || obj[field].toLowerCase().indexOf(search) !== -1) {
|
||
|
return true;
|
||
|
}
|
||
|
} else if (typeof obj[field] === 'number') {
|
||
|
if (obj[field] === search) {
|
||
|
return true;
|
||
|
}
|
||
|
} else if (typeof obj[field] === 'object') {
|
||
|
if (nestedSearch(obj[field])) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
var search = $(Plugin.getOption('search.input')).val();
|
||
|
if (typeof search !== 'undefined' && search !== '') {
|
||
|
search = search.toLowerCase();
|
||
|
datatable.dataSet = $.grep(datatable.dataSet, nestedSearch);
|
||
|
// remove generalSearch as we don't need this for next columns filter
|
||
|
delete params.query[Plugin.getGeneralSearchKey()];
|
||
|
}
|
||
|
|
||
|
// remove empty element from array
|
||
|
$.each(params.query, function(k, v) {
|
||
|
if (v === '') {
|
||
|
delete params.query[k];
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// filter array by query
|
||
|
datatable.dataSet = Plugin.filterArray(datatable.dataSet, params.query);
|
||
|
|
||
|
// reset array index
|
||
|
datatable.dataSet = datatable.dataSet.filter(function() {
|
||
|
return true;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
return datatable.dataSet;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Utility helper to filter array by object pair of {key:value}
|
||
|
* @param list
|
||
|
* @param args
|
||
|
* @param operator
|
||
|
* @returns {*}
|
||
|
*/
|
||
|
filterArray: function(list, args, operator) {
|
||
|
if (typeof list !== 'object') {
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
if (typeof operator === 'undefined') operator = 'AND';
|
||
|
|
||
|
if (typeof args !== 'object') {
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
operator = operator.toUpperCase();
|
||
|
|
||
|
if ($.inArray(operator, ['AND', 'OR', 'NOT']) === -1) {
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
var count = Object.keys(args).length;
|
||
|
var filtered = [];
|
||
|
|
||
|
$.each(list, function(key, obj) {
|
||
|
var to_match = obj;
|
||
|
|
||
|
var matched = 0;
|
||
|
$.each(args, function(m_key, m_value) {
|
||
|
m_value = m_value instanceof Array ? m_value : [m_value];
|
||
|
var match_property = Plugin.getObject(m_key, to_match);
|
||
|
if (typeof match_property !== 'undefined' && match_property) {
|
||
|
var lhs = match_property.toString().toLowerCase();
|
||
|
m_value.forEach(function(item, index) {
|
||
|
if (item.toString().toLowerCase() == lhs || lhs.indexOf(item.toString().toLowerCase()) !== -1) {
|
||
|
matched++;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
if (('AND' == operator && matched == count) ||
|
||
|
('OR' == operator && matched > 0) ||
|
||
|
('NOT' == operator && 0 == matched)) {
|
||
|
filtered[key] = obj;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
list = filtered;
|
||
|
|
||
|
return list;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Reset lock column scroll to 0 when resize
|
||
|
*/
|
||
|
resetScroll: function() {
|
||
|
if (typeof options.detail === 'undefined' && Plugin.getDepth() === 1) {
|
||
|
$(datatable.table).find('.' + pfx + 'datatable-row').css('left', 0);
|
||
|
$(datatable.table).find('.' + pfx + 'datatable-lock').css('top', 0);
|
||
|
$(datatable.tableBody).scrollTop(0);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get column options by field
|
||
|
* @param field
|
||
|
* @returns {boolean}
|
||
|
*/
|
||
|
getColumnByField: function(field) {
|
||
|
if (typeof field === 'undefined') return;
|
||
|
var result;
|
||
|
$.each(options.columns, function(i, column) {
|
||
|
if (field === column.field) {
|
||
|
result = column;
|
||
|
return false;
|
||
|
}
|
||
|
});
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get default sort column
|
||
|
*/
|
||
|
getDefaultSortColumn: function() {
|
||
|
var result;
|
||
|
$.each(options.columns, function(i, column) {
|
||
|
if (typeof column.sortable !== 'undefined'
|
||
|
&& $.inArray(column.sortable, ['asc', 'desc']) !== -1) {
|
||
|
result = {sort: column.sortable, field: column.field};
|
||
|
return false;
|
||
|
}
|
||
|
});
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Helper to get element dimensions, when the element is hidden
|
||
|
* @param element
|
||
|
* @param includeMargin
|
||
|
* @returns {{width: number, height: number, innerWidth: number,
|
||
|
* innerHeight: number, outerWidth: number, outerHeight:
|
||
|
* number}}
|
||
|
*/
|
||
|
getHiddenDimensions: function(element, includeMargin) {
|
||
|
var props = {
|
||
|
position: 'absolute',
|
||
|
visibility: 'hidden',
|
||
|
display: 'block',
|
||
|
},
|
||
|
dim = {
|
||
|
width: 0,
|
||
|
height: 0,
|
||
|
innerWidth: 0,
|
||
|
innerHeight: 0,
|
||
|
outerWidth: 0,
|
||
|
outerHeight: 0,
|
||
|
},
|
||
|
hiddenParents = $(element).parents().addBack().not(':visible');
|
||
|
includeMargin = (typeof includeMargin === 'boolean')
|
||
|
? includeMargin
|
||
|
: false;
|
||
|
|
||
|
var oldProps = [];
|
||
|
hiddenParents.each(function() {
|
||
|
var old = {};
|
||
|
|
||
|
for (var name in props) {
|
||
|
old[name] = this.style[name];
|
||
|
this.style[name] = props[name];
|
||
|
}
|
||
|
|
||
|
oldProps.push(old);
|
||
|
});
|
||
|
|
||
|
dim.width = $(element).width();
|
||
|
dim.outerWidth = $(element).outerWidth(includeMargin);
|
||
|
dim.innerWidth = $(element).innerWidth();
|
||
|
dim.height = $(element).height();
|
||
|
dim.innerHeight = $(element).innerHeight();
|
||
|
dim.outerHeight = $(element).outerHeight(includeMargin);
|
||
|
|
||
|
hiddenParents.each(function(i) {
|
||
|
var old = oldProps[i];
|
||
|
for (var name in props) {
|
||
|
this.style[name] = old[name];
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return dim;
|
||
|
},
|
||
|
|
||
|
getGeneralSearchKey: function() {
|
||
|
var searchInput = $(Plugin.getOption('search.input'));
|
||
|
return Plugin.getOption('search.key') || $(searchInput).prop('name');
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get value by dot notation path string and to prevent undefined
|
||
|
* errors
|
||
|
* @param path String Dot notation path in string
|
||
|
* @param object Object to iterate
|
||
|
* @returns {*}
|
||
|
*/
|
||
|
getObject: function(path, object) {
|
||
|
return path.split('.').reduce(function(obj, i) {
|
||
|
return obj !== null && typeof obj[i] !== 'undefined' ? obj[i] : null;
|
||
|
}, object);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Extend object
|
||
|
* @param obj
|
||
|
* @param path
|
||
|
* @param value
|
||
|
* @returns {*}
|
||
|
*/
|
||
|
extendObj: function(obj, path, value) {
|
||
|
var levels = path.split('.'),
|
||
|
i = 0;
|
||
|
|
||
|
function createLevel(child) {
|
||
|
var name = levels[i++];
|
||
|
if (typeof child[name] !== 'undefined' && child[name] !== null) {
|
||
|
if (typeof child[name] !== 'object' &&
|
||
|
typeof child[name] !== 'function') {
|
||
|
child[name] = {};
|
||
|
}
|
||
|
} else {
|
||
|
child[name] = {};
|
||
|
}
|
||
|
if (i === levels.length) {
|
||
|
child[name] = value;
|
||
|
} else {
|
||
|
createLevel(child[name]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
createLevel(obj);
|
||
|
return obj;
|
||
|
},
|
||
|
|
||
|
rowEvenOdd: function() {
|
||
|
// row even class
|
||
|
$(datatable.tableBody).find('.' + pfx + 'datatable-row').removeClass(pfx + 'datatable-row-even');
|
||
|
if ($(datatable.wrap).hasClass(pfx + 'datatable-subtable')) {
|
||
|
$(datatable.tableBody).find('.' + pfx + 'datatable-row:not(.' + pfx + 'datatable-row-detail):even').addClass(pfx + 'datatable-row-even');
|
||
|
} else {
|
||
|
$(datatable.tableBody).find('.' + pfx + 'datatable-row:nth-child(even)').addClass(pfx + 'datatable-row-even');
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/********************
|
||
|
** PUBLIC API METHODS
|
||
|
********************/
|
||
|
|
||
|
// delay timer
|
||
|
timer: 0,
|
||
|
|
||
|
/**
|
||
|
* Redraw datatable by recalculating its DOM elements, etc.
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
redraw: function() {
|
||
|
Plugin.adjustCellsWidth.call();
|
||
|
if (Plugin.isLocked()) {
|
||
|
// fix hiding cell width issue
|
||
|
Plugin.scrollbar();
|
||
|
Plugin.resetScroll();
|
||
|
Plugin.adjustCellsHeight.call();
|
||
|
}
|
||
|
Plugin.adjustLockContainer.call();
|
||
|
Plugin.initHeight.call();
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Shortcode to reload
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
load: function() {
|
||
|
Plugin.reload();
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Datasource reload
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
reload: function() {
|
||
|
var delay = (function() {
|
||
|
return function(callback, ms) {
|
||
|
clearTimeout(Plugin.timer);
|
||
|
Plugin.timer = setTimeout(callback, ms);
|
||
|
};
|
||
|
})();
|
||
|
delay(function() {
|
||
|
// local only. remote pagination will skip this block
|
||
|
if (!options.data.serverFiltering) {
|
||
|
Plugin.localDataUpdate();
|
||
|
}
|
||
|
Plugin.dataRender();
|
||
|
$(datatable).trigger(pfx + 'datatable-on-reloaded');
|
||
|
}, Plugin.getOption('search.delay'));
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get record by record ID
|
||
|
* @param id
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
getRecord: function(id) {
|
||
|
if (typeof datatable.tableBody === 'undefined') datatable.tableBody = $(datatable.table).children('tbody');
|
||
|
$(datatable.tableBody).find('.' + pfx + 'datatable-cell:first-child').each(function(i, cell) {
|
||
|
if (id == $(cell).text()) {
|
||
|
var rowNumber = $(cell).closest('.' + pfx + 'datatable-row').index() + 1;
|
||
|
datatable.API.record = datatable.API.value = Plugin.getOneRow(datatable.tableBody, rowNumber);
|
||
|
return datatable;
|
||
|
}
|
||
|
});
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @deprecated in v5.0.6
|
||
|
* Get column of current record ID
|
||
|
* @param columnName
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
getColumn: function(columnName) {
|
||
|
Plugin.setSelectedRecords();
|
||
|
datatable.API.value = $(datatable.API.record).find('[data-field="' + columnName + '"]');
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Destroy datatable to original DOM state before datatable was
|
||
|
* initialized
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
destroy: function() {
|
||
|
$(datatable).parent().find('.' + pfx + 'datatable-pager').remove();
|
||
|
var initialDatatable = $(datatable.initialDatatable).addClass(pfx + 'datatable-destroyed').show();
|
||
|
$(datatable).replaceWith(initialDatatable);
|
||
|
datatable = initialDatatable;
|
||
|
$(datatable).trigger(pfx + 'datatable-on-destroy');
|
||
|
Plugin.isInit = false;
|
||
|
initialDatatable = null;
|
||
|
return initialDatatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Sort by column field
|
||
|
* @param field
|
||
|
* @param sort
|
||
|
*/
|
||
|
sort: function(field, sort) {
|
||
|
// toggle sort
|
||
|
sort = typeof sort === 'undefined' ? 'asc' : sort;
|
||
|
|
||
|
Plugin.spinnerCallback(true);
|
||
|
|
||
|
// update field and sort params
|
||
|
var meta = {field: field, sort: sort};
|
||
|
Plugin.setDataSourceParam('sort', meta);
|
||
|
|
||
|
setTimeout(function() {
|
||
|
Plugin.dataRender('sort');
|
||
|
$(datatable).trigger(pfx + 'datatable-on-sort', meta);
|
||
|
$(datatable.tableHead).find('.' + pfx + 'datatable-cell > span > i').remove();
|
||
|
}, 300);
|
||
|
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @deprecated in v5.0.6
|
||
|
* Get current selected column value
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
getValue: function() {
|
||
|
return $(datatable.API.value).text();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Set checkbox active
|
||
|
* @param cell JQuery selector or checkbox ID
|
||
|
*/
|
||
|
setActive: function(cell) {
|
||
|
if (typeof cell === 'string') {
|
||
|
// set by checkbox id
|
||
|
cell = $(datatable.tableBody).find('.' + pfx + 'checkbox-single > [type="checkbox"][value="' + cell + '"]');
|
||
|
}
|
||
|
|
||
|
$(cell).prop('checked', true);
|
||
|
|
||
|
var ids = [];
|
||
|
$(cell).each(function(i, td) {
|
||
|
// normal table
|
||
|
var row = $(td).closest('tr').addClass(pfx + 'datatable-row-active');
|
||
|
|
||
|
var id = $(td).attr('value');
|
||
|
if (typeof id !== 'undefined') {
|
||
|
ids.push(id);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
$(datatable).trigger(pfx + 'datatable-on-check', [ids]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Set checkbox inactive
|
||
|
* @param cell JQuery selector or checkbox ID
|
||
|
*/
|
||
|
setInactive: function(cell) {
|
||
|
if (typeof cell === 'string') {
|
||
|
// set by checkbox id
|
||
|
cell = $(datatable.tableBody).find('.' + pfx + 'checkbox-single > [type="checkbox"][value="' + cell + '"]');
|
||
|
}
|
||
|
|
||
|
$(cell).prop('checked', false);
|
||
|
|
||
|
var ids = [];
|
||
|
$(cell).each(function(i, td) {
|
||
|
// normal table
|
||
|
var row = $(td).closest('tr').removeClass(pfx + 'datatable-row-active');
|
||
|
|
||
|
var id = $(td).attr('value');
|
||
|
if (typeof id !== 'undefined') {
|
||
|
ids.push(id);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
$(datatable).trigger(pfx + 'datatable-on-uncheck', [ids]);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Set all checkboxes active or inactive
|
||
|
* @param active
|
||
|
*/
|
||
|
setActiveAll: function(active) {
|
||
|
var checkboxes = $(datatable.table).
|
||
|
find('> tbody, > thead').
|
||
|
find('tr').not('.' + pfx + 'datatable-row-subtable').
|
||
|
find('.' + pfx + 'datatable-cell-check [type="checkbox"]');
|
||
|
if (active) {
|
||
|
Plugin.setActive(checkboxes);
|
||
|
} else {
|
||
|
Plugin.setInactive(checkboxes);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @deprecated in v5.0.6
|
||
|
* Get selected rows which are active
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
setSelectedRecords: function() {
|
||
|
datatable.API.record = $(datatable.tableBody).find('.' + pfx + 'datatable-row-active');
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get selected records
|
||
|
* @returns {null}
|
||
|
*/
|
||
|
getSelectedRecords: function() {
|
||
|
// support old method
|
||
|
Plugin.setSelectedRecords();
|
||
|
datatable.API.record = datatable.rows('.' + pfx + 'datatable-row-active').nodes();
|
||
|
return datatable.API.record;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get options by dots notation path
|
||
|
* @param path String Dot notation path in string
|
||
|
* @returns {*}
|
||
|
*/
|
||
|
getOption: function(path) {
|
||
|
return Plugin.getObject(path, options);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Set global options nodes by dots notation path
|
||
|
* @param path
|
||
|
* @param object
|
||
|
*/
|
||
|
setOption: function(path, object) {
|
||
|
options = Plugin.extendObj(options, path, object);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Search filter for local & remote
|
||
|
* @param value
|
||
|
* @param columns. Optional list of columns to be filtered.
|
||
|
*/
|
||
|
search: function(value, columns) {
|
||
|
if (typeof columns !== 'undefined') columns = $.makeArray(columns);
|
||
|
var delay = (function() {
|
||
|
return function(callback, ms) {
|
||
|
clearTimeout(Plugin.timer);
|
||
|
Plugin.timer = setTimeout(callback, ms);
|
||
|
};
|
||
|
})();
|
||
|
|
||
|
delay(function() {
|
||
|
// get query parameters
|
||
|
var query = Plugin.getDataSourceQuery();
|
||
|
|
||
|
// search not by columns
|
||
|
if (typeof columns === 'undefined' && typeof value !== 'undefined') {
|
||
|
var key = Plugin.getGeneralSearchKey();
|
||
|
query[key] = value;
|
||
|
}
|
||
|
|
||
|
// search by columns, support multiple columns
|
||
|
if (typeof columns === 'object') {
|
||
|
$.each(columns, function(k, column) {
|
||
|
query[column] = value;
|
||
|
});
|
||
|
// remove empty element from arrays
|
||
|
$.each(query, function(k, v) {
|
||
|
if (v === '' || $.isEmptyObject(v)) {
|
||
|
delete query[k];
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
Plugin.setDataSourceQuery(query);
|
||
|
|
||
|
// reset pagination to 1 when doing seearching
|
||
|
datatable.setDataSourceParam('pagination', Object.assign({}, datatable.getDataSourceParam('pagination'), {page: 1}));
|
||
|
|
||
|
// local filter only. remote pagination will skip this block
|
||
|
if (!options.data.serverFiltering) {
|
||
|
Plugin.localDataUpdate();
|
||
|
}
|
||
|
Plugin.dataRender('search');
|
||
|
}, Plugin.getOption('search.delay'));
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Set datasource params extract
|
||
|
* @param param
|
||
|
* @param value
|
||
|
*/
|
||
|
setDataSourceParam: function(param, value) {
|
||
|
datatable.API.params = $.extend({}, {
|
||
|
pagination: {page: 1, perpage: Plugin.getOption('data.pageSize')},
|
||
|
sort: Plugin.getDefaultSortColumn(),
|
||
|
query: {},
|
||
|
}, datatable.API.params, Plugin.stateGet(Plugin.stateId));
|
||
|
|
||
|
datatable.API.params = Plugin.extendObj(datatable.API.params, param, value);
|
||
|
|
||
|
Plugin.stateKeep(Plugin.stateId, datatable.API.params);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get datasource params
|
||
|
* @param param
|
||
|
*/
|
||
|
getDataSourceParam: function(param) {
|
||
|
datatable.API.params = $.extend({}, {
|
||
|
pagination: {page: 1, perpage: Plugin.getOption('data.pageSize')},
|
||
|
sort: Plugin.getDefaultSortColumn(),
|
||
|
query: {},
|
||
|
}, datatable.API.params, Plugin.stateGet(Plugin.stateId));
|
||
|
|
||
|
if (typeof param === 'string') {
|
||
|
return Plugin.getObject(param, datatable.API.params);
|
||
|
}
|
||
|
|
||
|
return datatable.API.params;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Shortcode to datatable.getDataSourceParam('query');
|
||
|
* @returns {*}
|
||
|
*/
|
||
|
getDataSourceQuery: function() {
|
||
|
return Plugin.getDataSourceParam('query') || {};
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Shortcode to datatable.setDataSourceParam('query', query);
|
||
|
* @param query
|
||
|
*/
|
||
|
setDataSourceQuery: function(query) {
|
||
|
Plugin.setDataSourceParam('query', query);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get current page number
|
||
|
* @returns {number}
|
||
|
*/
|
||
|
getCurrentPage: function() {
|
||
|
return $(datatable.table).
|
||
|
siblings('.' + pfx + 'datatable-pager').
|
||
|
last().
|
||
|
find('.' + pfx + 'datatable-pager-nav').
|
||
|
find('.' + pfx + 'datatable-pager-link.' + pfx + 'datatable-pager-link-active').
|
||
|
data('page') || 1;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get selected dropdown page size
|
||
|
* @returns {*|number}
|
||
|
*/
|
||
|
getPageSize: function() {
|
||
|
return $(datatable.table).siblings('.' + pfx + 'datatable-pager').last().find('select.' + pfx + 'datatable-pager-size').val() || 10;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get total rows
|
||
|
*/
|
||
|
getTotalRows: function() {
|
||
|
return datatable.API.params.pagination.total;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get full dataset in grid
|
||
|
* @returns {*|null|Array}
|
||
|
*/
|
||
|
getDataSet: function() {
|
||
|
return datatable.originalDataSet;
|
||
|
},
|
||
|
|
||
|
nodeTr: [],
|
||
|
nodeTd: [],
|
||
|
nodeCols: [],
|
||
|
recentNode: [],
|
||
|
|
||
|
table: function() {
|
||
|
if (typeof datatable.table !== 'undefined') {
|
||
|
return datatable.table;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Select a single row from the table
|
||
|
* @param selector
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
row: function(selector) {
|
||
|
Plugin.rows(selector);
|
||
|
Plugin.nodeTr = Plugin.recentNode = $(Plugin.nodeTr).first();
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Select multiple rows from the table
|
||
|
* @param selector
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
rows: function(selector) {
|
||
|
if (Plugin.isLocked()) {
|
||
|
Plugin.nodeTr = Plugin.recentNode = $(datatable.tableBody).find(selector).filter('.' + pfx + 'datatable-lock-scroll > .' + pfx + 'datatable-row');
|
||
|
} else {
|
||
|
Plugin.nodeTr = Plugin.recentNode = $(datatable.tableBody).find(selector).filter('.' + pfx + 'datatable-row');
|
||
|
}
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Select a single column from the table
|
||
|
* @param index zero-based index
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
column: function(index) {
|
||
|
Plugin.nodeCols = Plugin.recentNode = $(datatable.tableBody).find('.' + pfx + 'datatable-cell:nth-child(' + (index + 1) + ')');
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Select multiple columns from the table
|
||
|
* @param selector
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
columns: function(selector) {
|
||
|
var context = datatable.table;
|
||
|
if (Plugin.nodeTr === Plugin.recentNode) {
|
||
|
context = Plugin.nodeTr;
|
||
|
}
|
||
|
var columns = $(context).find('.' + pfx + 'datatable-cell[data-field="' + selector + '"]');
|
||
|
if (columns.length > 0) {
|
||
|
Plugin.nodeCols = Plugin.recentNode = columns;
|
||
|
} else {
|
||
|
Plugin.nodeCols = Plugin.recentNode = $(context).find(selector).filter('.' + pfx + 'datatable-cell');
|
||
|
}
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
cell: function(selector) {
|
||
|
Plugin.cells(selector);
|
||
|
Plugin.nodeTd = Plugin.recentNode = $(Plugin.nodeTd).first();
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
cells: function(selector) {
|
||
|
var cells = $(datatable.tableBody).find('.' + pfx + 'datatable-cell');
|
||
|
if (typeof selector !== 'undefined') {
|
||
|
cells = $(cells).filter(selector);
|
||
|
}
|
||
|
Plugin.nodeTd = Plugin.recentNode = cells;
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Delete the selected row from the table
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
remove: function() {
|
||
|
if ($(Plugin.nodeTr.length) && Plugin.nodeTr === Plugin.recentNode) {
|
||
|
$(Plugin.nodeTr).remove();
|
||
|
}
|
||
|
Plugin.layoutUpdate();
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Show or hide the columns or rows
|
||
|
*/
|
||
|
visible: function(bool) {
|
||
|
if ($(Plugin.recentNode.length)) {
|
||
|
var locked = Plugin.lockEnabledColumns();
|
||
|
if (Plugin.recentNode === Plugin.nodeCols) {
|
||
|
var index = Plugin.recentNode.index();
|
||
|
|
||
|
if (Plugin.isLocked()) {
|
||
|
var scrollColumns = $(Plugin.recentNode).closest('.' + pfx + 'datatable-lock-scroll').length;
|
||
|
if (scrollColumns) {
|
||
|
// is at center of scrollable area
|
||
|
index += locked.left.length + 1;
|
||
|
} else if ($(Plugin.recentNode).closest('.' + pfx + 'datatable-lock-right').length) {
|
||
|
// is at the right locked table
|
||
|
index += locked.left.length + scrollColumns + 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bool) {
|
||
|
if (Plugin.recentNode === Plugin.nodeCols) {
|
||
|
delete options.columns[index].visible;
|
||
|
}
|
||
|
$(Plugin.recentNode).show();
|
||
|
} else {
|
||
|
if (Plugin.recentNode === Plugin.nodeCols) {
|
||
|
Plugin.setOption('columns.' + (index) + '.visible', false);
|
||
|
}
|
||
|
$(Plugin.recentNode).hide();
|
||
|
}
|
||
|
Plugin.columnHide();
|
||
|
Plugin.redraw();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get the the DOM element for the selected rows or columns
|
||
|
* @returns {Array}
|
||
|
*/
|
||
|
nodes: function() {
|
||
|
return Plugin.recentNode;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* will be implemented soon
|
||
|
* @returns {jQuery}
|
||
|
*/
|
||
|
dataset: function() {
|
||
|
return datatable;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Open page by number
|
||
|
* @param page number
|
||
|
*/
|
||
|
gotoPage: function (page) {
|
||
|
if (typeof Plugin.pagingObject !== 'undefined') {
|
||
|
Plugin.isInit = true;
|
||
|
Plugin.pagingObject.openPage(page);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Public API methods can be used directly by datatable
|
||
|
*/
|
||
|
$.each(Plugin, function(funcName, func) {
|
||
|
datatable[funcName] = func;
|
||
|
});
|
||
|
|
||
|
// initialize main datatable plugin
|
||
|
if (typeof options !== 'undefined') {
|
||
|
if (typeof options === 'string') {
|
||
|
var method = options;
|
||
|
datatable = $(this).data(pluginName);
|
||
|
if (typeof datatable !== 'undefined') {
|
||
|
options = datatable.options;
|
||
|
Plugin[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
||
|
}
|
||
|
} else {
|
||
|
if (!datatable.data(pluginName) && !$(this).hasClass(pfx + 'datatable-loaded')) {
|
||
|
datatable.dataSet = null;
|
||
|
datatable.textAlign = {
|
||
|
left: pfx + 'datatable-cell-left',
|
||
|
center: pfx + 'datatable-cell-center',
|
||
|
right: pfx + 'datatable-cell-right',
|
||
|
};
|
||
|
|
||
|
// merge default and user defined options
|
||
|
options = $.extend(true, {}, $.fn[pluginName].defaults, options);
|
||
|
|
||
|
datatable.options = options;
|
||
|
|
||
|
// init plugin process
|
||
|
Plugin.init.apply(this, [options]);
|
||
|
|
||
|
$(datatable.wrap).data(pluginName, datatable);
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
// get existing instance datatable
|
||
|
datatable = $(this).data(pluginName);
|
||
|
if (typeof datatable === 'undefined') {
|
||
|
$.error(pluginName + ' not initialized');
|
||
|
}
|
||
|
options = datatable.options;
|
||
|
}
|
||
|
|
||
|
return datatable;
|
||
|
};
|
||
|
|
||
|
// default options
|
||
|
$.fn[pluginName].defaults = {
|
||
|
// datasource definition
|
||
|
data: {
|
||
|
type: 'local',
|
||
|
source: null,
|
||
|
pageSize: 10, // display records per page
|
||
|
saveState: true,
|
||
|
|
||
|
serverPaging: false,
|
||
|
serverFiltering: false,
|
||
|
serverSorting: false,
|
||
|
|
||
|
autoColumns: false,
|
||
|
attr: {
|
||
|
rowProps: [],
|
||
|
},
|
||
|
},
|
||
|
|
||
|
// layout definition
|
||
|
layout: {
|
||
|
theme: 'default', // datatable will support multiple themes and designs
|
||
|
class: pfx + 'datatable-primary', // custom wrapper class
|
||
|
scroll: false, // enable/disable datatable scroll both horizontal and vertical when needed.
|
||
|
height: null, // datatable's body's fixed height
|
||
|
minHeight: null,
|
||
|
footer: false, // display/hide footer
|
||
|
header: true, // display/hide header
|
||
|
customScrollbar: true, // set false to disable custom scrollbar
|
||
|
|
||
|
// datatable spinner
|
||
|
spinner: {
|
||
|
overlayColor: '#000000',
|
||
|
opacity: 0,
|
||
|
type: 'loader',
|
||
|
state: 'primary',
|
||
|
message: true,
|
||
|
},
|
||
|
|
||
|
// datatable UI icons
|
||
|
icons: {
|
||
|
sort: {asc: 'flaticon2-arrow-up', desc: 'flaticon2-arrow-down'},
|
||
|
pagination: {
|
||
|
next: 'flaticon2-next',
|
||
|
prev: 'flaticon2-back',
|
||
|
first: 'flaticon2-fast-back',
|
||
|
last: 'flaticon2-fast-next',
|
||
|
more: 'flaticon-more-1',
|
||
|
},
|
||
|
rowDetail: {expand: 'fa fa-caret-down', collapse: 'fa fa-caret-right'},
|
||
|
},
|
||
|
},
|
||
|
|
||
|
// column sorting
|
||
|
sortable: true,
|
||
|
|
||
|
// resize column size with mouse drag coming soon)
|
||
|
resizable: false,
|
||
|
|
||
|
// column based filtering (coming soon)
|
||
|
filterable: false,
|
||
|
|
||
|
pagination: true,
|
||
|
|
||
|
// inline and bactch editing (cooming soon)
|
||
|
editable: false,
|
||
|
|
||
|
// columns definition
|
||
|
columns: [],
|
||
|
|
||
|
search: {
|
||
|
// enable trigger search by keyup enter
|
||
|
onEnter: false,
|
||
|
// input text for search
|
||
|
input: null,
|
||
|
// search delay in milliseconds
|
||
|
delay: 400,
|
||
|
// remote server search key value
|
||
|
key: null
|
||
|
},
|
||
|
|
||
|
rows: {
|
||
|
// deprecated
|
||
|
callback: function() {
|
||
|
},
|
||
|
// call before row template
|
||
|
beforeTemplate: function() {
|
||
|
},
|
||
|
// call after row template
|
||
|
afterTemplate: function() {
|
||
|
},
|
||
|
autoHide: true,
|
||
|
},
|
||
|
|
||
|
// toolbar
|
||
|
toolbar: {
|
||
|
// place pagination and displayInfo blocks according to the array order
|
||
|
layout: ['pagination', 'info'],
|
||
|
|
||
|
// toolbar placement can be at top or bottom or both top and bottom repeated
|
||
|
placement: ['bottom'], //'top', 'bottom'
|
||
|
|
||
|
// toolbar items
|
||
|
items: {
|
||
|
// pagination
|
||
|
pagination: {
|
||
|
// pagination type(default or scroll)
|
||
|
type: 'default',
|
||
|
|
||
|
// number of pages to display by breakpoints
|
||
|
pages: {
|
||
|
desktop: {
|
||
|
layout: 'default',
|
||
|
pagesNumber: 5,
|
||
|
},
|
||
|
tablet: {
|
||
|
layout: 'default',
|
||
|
pagesNumber: 3,
|
||
|
},
|
||
|
mobile: {
|
||
|
layout: 'compact',
|
||
|
},
|
||
|
},
|
||
|
|
||
|
// navigation buttons
|
||
|
navigation: {
|
||
|
prev: true, // display prev button
|
||
|
next: true, // display next button
|
||
|
first: true, // display first button
|
||
|
last: true, // display last button
|
||
|
more: false // display more button
|
||
|
},
|
||
|
|
||
|
// page size select
|
||
|
pageSizeSelect: [], // display dropdown to select pagination size. -1 is used for "ALl" option
|
||
|
},
|
||
|
|
||
|
// records info
|
||
|
info: true,
|
||
|
},
|
||
|
},
|
||
|
|
||
|
// here we will keep all strings and message used by datatable UI so developer can easiliy translate to any language.
|
||
|
// By default the stirngs will be in the plugin source and here can override it
|
||
|
translate: {
|
||
|
records: {
|
||
|
processing: 'Please wait...',
|
||
|
noRecords: 'No records found',
|
||
|
},
|
||
|
toolbar: {
|
||
|
pagination: {
|
||
|
items: {
|
||
|
default: {
|
||
|
first: 'First',
|
||
|
prev: 'Previous',
|
||
|
next: 'Next',
|
||
|
last: 'Last',
|
||
|
more: 'More pages',
|
||
|
input: 'Page number',
|
||
|
select: 'Select page size',
|
||
|
all: 'all',
|
||
|
},
|
||
|
info: 'Showing {{start}} - {{end}} of {{total}}',
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
|
||
|
extensions: {},
|
||
|
};
|
||
|
|
||
|
}(jQuery));
|
||
|
|
||
|
"use strict";
|
||
|
(function($) {
|
||
|
|
||
|
var pluginName = 'KTDatatable';
|
||
|
var pfx = '';
|
||
|
|
||
|
$.fn[pluginName] = $.fn[pluginName] || {};
|
||
|
|
||
|
/**
|
||
|
* @param datatable Main datatable plugin instance
|
||
|
* @param options Extension options
|
||
|
* @returns {*}
|
||
|
*/
|
||
|
$.fn[pluginName].checkbox = function(datatable, options) {
|
||
|
var Extension = {
|
||
|
selectedAllRows: false,
|
||
|
selectedRows: [],
|
||
|
unselectedRows: [],
|
||
|
|
||
|
init: function() {
|
||
|
if (Extension.selectorEnabled()) {
|
||
|
// reset
|
||
|
datatable.setDataSourceParam(options.vars.selectedAllRows, false);
|
||
|
datatable.stateRemove('checkbox');
|
||
|
|
||
|
// requestIds is not null
|
||
|
if (options.vars.requestIds) {
|
||
|
// request ids in response
|
||
|
datatable.setDataSourceParam(options.vars.requestIds, true);
|
||
|
}
|
||
|
|
||
|
// remove selected checkbox on datatable reload
|
||
|
$(datatable).on(pfx + 'datatable-on-reloaded', function() {
|
||
|
datatable.stateRemove('checkbox');
|
||
|
datatable.setDataSourceParam(options.vars.selectedAllRows, false);
|
||
|
Extension.selectedAllRows = false;
|
||
|
Extension.selectedRows = [];
|
||
|
Extension.unselectedRows = [];
|
||
|
});
|
||
|
|
||
|
// select all on extension init
|
||
|
Extension.selectedAllRows = datatable.getDataSourceParam(options.vars.selectedAllRows);
|
||
|
|
||
|
$(datatable).on(pfx + 'datatable-on-layout-updated', function(e, args) {
|
||
|
if (args.table != $(datatable.wrap).attr('id')) {
|
||
|
return;
|
||
|
}
|
||
|
datatable.ready(function() {
|
||
|
Extension.initVars();
|
||
|
Extension.initEvent();
|
||
|
Extension.initSelect();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
$(datatable).on(pfx + 'datatable-on-check', function(e, ids) {
|
||
|
ids.forEach(function(id) {
|
||
|
Extension.selectedRows.push(id);
|
||
|
// // remove from unselected rows
|
||
|
Extension.unselectedRows = Extension.remove(Extension.unselectedRows, id);
|
||
|
});
|
||
|
var storage = {};
|
||
|
storage['selectedRows'] = $.unique(Extension.selectedRows);
|
||
|
storage['unselectedRows'] = $.unique(Extension.unselectedRows);
|
||
|
datatable.stateKeep('checkbox', storage);
|
||
|
});
|
||
|
$(datatable).on(pfx + 'datatable-on-uncheck', function(e, ids) {
|
||
|
ids.forEach(function(id) {
|
||
|
Extension.unselectedRows.push(id);
|
||
|
// // remove from selected rows
|
||
|
Extension.selectedRows = Extension.remove(Extension.selectedRows, id);
|
||
|
});
|
||
|
var storage = {};
|
||
|
storage['selectedRows'] = $.unique(Extension.selectedRows);
|
||
|
storage['unselectedRows'] = $.unique(Extension.unselectedRows);
|
||
|
datatable.stateKeep('checkbox', storage);
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Init checkbox clicks event
|
||
|
*/
|
||
|
initEvent: function() {
|
||
|
// select all checkbox click
|
||
|
$(datatable.tableHead).find('.' + pfx + 'checkbox-all > [type="checkbox"]').click(function(e) {
|
||
|
// clear selected and unselected rows
|
||
|
Extension.selectedRows = Extension.unselectedRows = [];
|
||
|
datatable.stateRemove('checkbox');
|
||
|
|
||
|
// select all rows
|
||
|
Extension.selectedAllRows = !!$(this).is(':checked');
|
||
|
|
||
|
// local select all current page rows
|
||
|
if (!options.vars.requestIds) {
|
||
|
if ($(this).is(':checked')) {
|
||
|
Extension.selectedRows = $.makeArray($(datatable.tableBody).find('.' + pfx + 'checkbox-single > [type="checkbox"]').map(function(i, chk) {
|
||
|
return $(chk).val();
|
||
|
}));
|
||
|
}
|
||
|
var storage = {};
|
||
|
storage['selectedRows'] = $.unique(Extension.selectedRows);
|
||
|
datatable.stateKeep('checkbox', storage);
|
||
|
}
|
||
|
|
||
|
// keep selectedAllRows in datasource params
|
||
|
datatable.setDataSourceParam(options.vars.selectedAllRows, Extension.selectedAllRows);
|
||
|
|
||
|
$(datatable).trigger(pfx + 'datatable-on-click-checkbox', [$(this)]);
|
||
|
});
|
||
|
|
||
|
// single row checkbox click
|
||
|
$(datatable.tableBody).find('.' + pfx + 'checkbox-single > [type="checkbox"]').click(function(e) {
|
||
|
var id = $(this).val();
|
||
|
if ($(this).is(':checked')) {
|
||
|
Extension.selectedRows.push(id);
|
||
|
// remove from unselected rows
|
||
|
Extension.unselectedRows = Extension.remove(Extension.unselectedRows, id);
|
||
|
}
|
||
|
else {
|
||
|
Extension.unselectedRows.push(id);
|
||
|
// remove from selected rows
|
||
|
Extension.selectedRows = Extension.remove(Extension.selectedRows, id);
|
||
|
}
|
||
|
|
||
|
// local checkbox header check
|
||
|
if (!options.vars.requestIds && Extension.selectedRows.length < 1) {
|
||
|
// remove select all checkbox, if there is no checked checkbox left
|
||
|
$(datatable.tableHead).find('.' + pfx + 'checkbox-all > [type="checkbox"]').prop('checked', false);
|
||
|
}
|
||
|
|
||
|
var storage = {};
|
||
|
storage['selectedRows'] = Extension.selectedRows.filter(Extension.unique);
|
||
|
storage['unselectedRows'] = Extension.unselectedRows.filter(Extension.unique);
|
||
|
datatable.stateKeep('checkbox', storage);
|
||
|
|
||
|
$(datatable).trigger(pfx + 'datatable-on-click-checkbox', [$(this)]);
|
||
|
});
|
||
|
},
|
||
|
|
||
|
unique: function(value, index, self) {
|
||
|
return self.indexOf(value) === index;
|
||
|
},
|
||
|
|
||
|
initSelect: function() {
|
||
|
// selected all rows from server
|
||
|
if (Extension.selectedAllRows && options.vars.requestIds) {
|
||
|
if (!datatable.hasClass(pfx + 'datatable-error')) {
|
||
|
// set header select all checkbox checked
|
||
|
$(datatable.tableHead).find('.' + pfx + 'checkbox-all > [type="checkbox"]').prop('checked', true);
|
||
|
}
|
||
|
|
||
|
// set all checkbox in table body
|
||
|
datatable.setActiveAll(true);
|
||
|
|
||
|
// remove unselected rows
|
||
|
Extension.unselectedRows.forEach(function(id) {
|
||
|
datatable.setInactive(id);
|
||
|
});
|
||
|
|
||
|
}
|
||
|
else {
|
||
|
// single check for server and local
|
||
|
Extension.selectedRows.forEach(function(id) {
|
||
|
datatable.setActive(id);
|
||
|
});
|
||
|
|
||
|
// local checkbox; check if all checkboxes of currect page are checked
|
||
|
if (!datatable.hasClass(pfx + 'datatable-error') && $(datatable.tableBody).find('.' + pfx + 'checkbox-single > [type="checkbox"]').not(':checked').length < 1) {
|
||
|
// set header select all checkbox checked
|
||
|
$(datatable.tableHead).find('.' + pfx + 'checkbox-all > [type="checkbox"]').prop('checked', true);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Check if selector is enabled from options
|
||
|
*/
|
||
|
selectorEnabled: function() {
|
||
|
return $.grep(datatable.options.columns, function(n, i) {
|
||
|
return n.selector || false;
|
||
|
})[0];
|
||
|
},
|
||
|
|
||
|
initVars: function() {
|
||
|
// get single select/unselect from localstorage
|
||
|
var storage = datatable.stateGet('checkbox');
|
||
|
if (typeof storage !== 'undefined') {
|
||
|
Extension.selectedRows = storage['selectedRows'] || [];
|
||
|
Extension.unselectedRows = storage['unselectedRows'] || [];
|
||
|
}
|
||
|
},
|
||
|
|
||
|
getSelectedId: function(path) {
|
||
|
Extension.initVars();
|
||
|
|
||
|
// server selected all rows
|
||
|
if (Extension.selectedAllRows && options.vars.requestIds) {
|
||
|
if (typeof path === 'undefined') {
|
||
|
path = options.vars.rowIds;
|
||
|
}
|
||
|
|
||
|
// if selected all rows, return id from response meta
|
||
|
var selectedAllRows = datatable.getObject(path, datatable.lastResponse) || [];
|
||
|
|
||
|
if (selectedAllRows.length > 0) {
|
||
|
// remove single unselected rows from selectedAllRows ids from server response emta
|
||
|
Extension.unselectedRows.forEach(function(id) {
|
||
|
selectedAllRows = Extension.remove(selectedAllRows, parseInt(id));
|
||
|
});
|
||
|
}
|
||
|
return $.unique(selectedAllRows);
|
||
|
}
|
||
|
|
||
|
// else return single checked selected rows
|
||
|
return Extension.selectedRows;
|
||
|
},
|
||
|
|
||
|
remove: function(array, element) {
|
||
|
return array.filter(function(e) {
|
||
|
return e !== element;
|
||
|
});
|
||
|
},
|
||
|
};
|
||
|
|
||
|
// make the extension accessible from datatable init
|
||
|
datatable.checkbox = function() {
|
||
|
return Extension;
|
||
|
};
|
||
|
|
||
|
if (typeof options === 'object') {
|
||
|
options = $.extend(true, {}, $.fn[pluginName].checkbox.default, options);
|
||
|
Extension.init.apply(this, [options]);
|
||
|
}
|
||
|
|
||
|
return datatable;
|
||
|
};
|
||
|
|
||
|
$.fn[pluginName].checkbox.default = {
|
||
|
vars: {
|
||
|
// select all rows flag to be sent to the server
|
||
|
selectedAllRows: 'selectedAllRows',
|
||
|
// request id parameter's name
|
||
|
requestIds: 'requestIds',
|
||
|
// response path to all rows id
|
||
|
rowIds: 'meta.rowIds',
|
||
|
},
|
||
|
};
|
||
|
|
||
|
}(jQuery));
|
||
|
|
||
|
var defaults = {
|
||
|
layout: {
|
||
|
icons: {
|
||
|
pagination: {
|
||
|
next: 'flaticon2-next',
|
||
|
prev: 'flaticon2-back',
|
||
|
first: 'flaticon2-fast-back',
|
||
|
last: 'flaticon2-fast-next',
|
||
|
more: 'flaticon-more-1',
|
||
|
},
|
||
|
rowDetail: {expand: 'fa fa-caret-down', collapse: 'fa fa-caret-right'},
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
if (KTUtil.isRTL()) {
|
||
|
defaults = {
|
||
|
layout: {
|
||
|
icons: {
|
||
|
pagination: {
|
||
|
next: 'flaticon2-back',
|
||
|
prev: 'flaticon2-next',
|
||
|
first: 'flaticon2-fast-next',
|
||
|
last: 'flaticon2-fast-back',
|
||
|
},
|
||
|
rowDetail: {collapse: 'fa fa-caret-down', expand: 'fa fa-caret-right'},
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$.extend(true, $.fn.KTDatatable.defaults, defaults);
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
// Initialization
|
||
|
KTUtil.ready(function() {
|
||
|
////////////////////////////////////////////////////
|
||
|
// Layout Base Partials(mandatory for core layout)//
|
||
|
////////////////////////////////////////////////////
|
||
|
|
||
|
// Init Desktop & Mobile Headers
|
||
|
KTLayoutHeader.init('kt_header', 'kt_header_mobile');
|
||
|
|
||
|
// Init Header Topbar For Mobile Mode
|
||
|
KTLayoutHeaderTopbar.init('kt_header_mobile_topbar_toggle');
|
||
|
|
||
|
// Init Aside
|
||
|
KTLayoutAside.init('kt_aside');
|
||
|
|
||
|
// Init Aside Menu
|
||
|
KTLayoutAsideMenu.init('kt_aside_menu');
|
||
|
|
||
|
// Init Subheader
|
||
|
KTLayoutSubheader.init('kt_subheader');
|
||
|
|
||
|
// Init Content
|
||
|
KTLayoutContent.init('kt_content');
|
||
|
|
||
|
// Init Footer
|
||
|
KTLayoutFooter.init('kt_footer');
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////
|
||
|
// Layout Extended Partials(optional to use)//
|
||
|
//////////////////////////////////////////////
|
||
|
|
||
|
// Init Scrolltop
|
||
|
KTLayoutScrolltop.init('kt_scrolltop');
|
||
|
|
||
|
// Init Sticky Card
|
||
|
KTLayoutStickyCard.init('kt_page_sticky_card');
|
||
|
|
||
|
// Init Stretched Card
|
||
|
KTLayoutStretchedCard.init('kt_page_stretched_card');
|
||
|
|
||
|
// Init Code Highlighter & Preview Blocks(used to demonstrate the theme features)
|
||
|
KTLayoutExamples.init();
|
||
|
|
||
|
// Init Demo Selection Panel
|
||
|
KTLayoutDemoPanel.init('kt_demo_panel');
|
||
|
|
||
|
// Init Chat App(quick modal chat)
|
||
|
KTLayoutChat.init();
|
||
|
|
||
|
// Init Quick Actions Offcanvas Panel
|
||
|
KTLayoutQuickActions.init('kt_quick_actions');
|
||
|
|
||
|
// Init Quick Notifications Offcanvas Panel
|
||
|
KTLayoutQuickNotifications.init('kt_quick_notifications');
|
||
|
|
||
|
// Init Quick Offcanvas Panel
|
||
|
KTLayoutQuickPanel.init('kt_quick_panel');
|
||
|
|
||
|
// Init Quick User Panel
|
||
|
KTLayoutQuickUser.init('kt_quick_user');
|
||
|
|
||
|
// Init Search Inline Dropdown For Desktop Mode
|
||
|
KTLayoutSearchInline().init('kt_quick_search_inline');
|
||
|
|
||
|
// Init Search Dropdown For Tablet & Mobile Mode
|
||
|
KTLayoutSearch().init('kt_quick_search_dropdown');
|
||
|
});
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutAsideMenu = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
var _menuObject;
|
||
|
|
||
|
// Initialize
|
||
|
var _init = function() {
|
||
|
|
||
|
_menuObject = new KTMenu(_element, {
|
||
|
// Submenu setup
|
||
|
submenu: {
|
||
|
desktop: 'accordion',
|
||
|
tablet: 'accordion', // menu set to accordion in tablet mode
|
||
|
mobile: 'accordion' // menu set to accordion in mobile mode
|
||
|
},
|
||
|
|
||
|
// Accordion setup
|
||
|
accordion: {
|
||
|
expandAll: false // allow having multiple expanded accordions in the menu
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
|
||
|
if (!_element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Initialize menu
|
||
|
_init();
|
||
|
},
|
||
|
|
||
|
getElement: function() {
|
||
|
return _element;
|
||
|
},
|
||
|
|
||
|
getMenu: function() {
|
||
|
return _menuObject;
|
||
|
},
|
||
|
|
||
|
pauseDropdownHover: function(time) {
|
||
|
if (_menuObject) {
|
||
|
_menuObject.pauseDropdownHover(time);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
closeMobileOffcanvas: function() {
|
||
|
if (_menuObject && KTUtil.isMobileDevice()) {
|
||
|
_menuObject.hide();
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutAsideMenu;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutAside = function() {
|
||
|
// Private properties
|
||
|
var _body;
|
||
|
var _element;
|
||
|
var _asideMenuWrapperElement;
|
||
|
var _offcanvasObject;
|
||
|
|
||
|
// Private functions
|
||
|
// Initialize
|
||
|
var _init = function() {
|
||
|
var offcanvasClass = KTUtil.hasClass(_element, 'aside-offcanvas-default') ? 'aside-offcanvas-default' : 'aside';
|
||
|
|
||
|
// Initialize mobile aside offcanvas
|
||
|
_offcanvasObject = new KTOffcanvas(_element, {
|
||
|
baseClass: offcanvasClass,
|
||
|
overlay: true,
|
||
|
closeBy: 'kt_aside_close_btn',
|
||
|
toggleBy: ['kt_aside_desktop_toggle', 'kt_aside_tablet_and_mobile_toggle']
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var _initScroll = function() {
|
||
|
KTUtil.scrollInit(_asideMenuWrapperElement, {
|
||
|
disableForMobile: true,
|
||
|
resetHeightOnDestroy: true,
|
||
|
handleWindowResize: true,
|
||
|
height: function() {
|
||
|
var height = parseInt(KTUtil.getViewPort().height);
|
||
|
|
||
|
height = height - (parseInt(KTUtil.css(_asideMenuWrapperElement , 'marginBottom')) + parseInt(KTUtil.css(_asideMenuWrapperElement, 'marginTop')));
|
||
|
|
||
|
return height;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
_asideMenuWrapperElement = KTUtil.getById('kt_aside_menu_wrapper');
|
||
|
_body = KTUtil.getBody();
|
||
|
|
||
|
if (!_element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Initialize
|
||
|
_init();
|
||
|
_initScroll();
|
||
|
},
|
||
|
|
||
|
getElement: function() {
|
||
|
return _element;
|
||
|
},
|
||
|
|
||
|
getOffcanvas: function() {
|
||
|
return _offcanvasObject;
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutAside;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutContent = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
|
||
|
// Private functions
|
||
|
var _getHeight = function() {
|
||
|
var height;
|
||
|
|
||
|
height = KTUtil.getViewPort().height;
|
||
|
|
||
|
if (_element) {
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingTop')) - parseInt(KTUtil.css(_element, 'paddingBottom'));
|
||
|
}
|
||
|
|
||
|
height = height - KTLayoutHeader.getHeight();
|
||
|
height = height - KTLayoutSubheader.getHeight();
|
||
|
height = height - KTLayoutFooter.getHeight();
|
||
|
|
||
|
return height;
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
},
|
||
|
|
||
|
getHeight: function() {
|
||
|
return _getHeight();
|
||
|
},
|
||
|
|
||
|
getElement: function() {
|
||
|
return _element;
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutContent;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutFooter = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
|
||
|
// Private functions
|
||
|
var _getHeight = function() {
|
||
|
var height = 0;
|
||
|
|
||
|
if (_element) {
|
||
|
height = KTUtil.actualHeight(_element);
|
||
|
}
|
||
|
|
||
|
return height;
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
},
|
||
|
|
||
|
getHeight: function() {
|
||
|
return _getHeight();
|
||
|
},
|
||
|
|
||
|
getElement: function() {
|
||
|
return _element;
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutFooter;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutHeaderTopbar = function() {
|
||
|
// Private properties
|
||
|
var _toggleElement;
|
||
|
var _toggleObject;
|
||
|
|
||
|
// Private functions
|
||
|
var _init = function() {
|
||
|
_toggleObject = new KTToggle(_toggleElement, {
|
||
|
target: KTUtil.getBody(),
|
||
|
targetState: 'topbar-mobile-on',
|
||
|
toggleState: 'active'
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_toggleElement = KTUtil.getById(id);
|
||
|
|
||
|
if (!_toggleElement) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Initialize
|
||
|
_init();
|
||
|
},
|
||
|
|
||
|
getToggleElement: function() {
|
||
|
return _toggleElement;
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutHeaderTopbar;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutHeader = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
var _elementForMobile;
|
||
|
var _object;
|
||
|
|
||
|
// Private functions
|
||
|
|
||
|
// Get height
|
||
|
var _getHeight = function() {
|
||
|
var height = 0;
|
||
|
|
||
|
if (_element) {
|
||
|
height = KTUtil.actualHeight(_element) + 1;
|
||
|
}
|
||
|
|
||
|
return height;
|
||
|
}
|
||
|
|
||
|
// Get height
|
||
|
var _getHeightForMobile = function() {
|
||
|
var height;
|
||
|
|
||
|
height = KTUtil.actualHeight(_elementForMobile);
|
||
|
|
||
|
return height;
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id, idForMobile) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
_elementForMobile = KTUtil.getById(idForMobile);
|
||
|
|
||
|
if (!_element) {
|
||
|
return;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
isFixed: function() {
|
||
|
return KTUtil.hasClass(KTUtil.getBody(), 'header-fixed')
|
||
|
},
|
||
|
|
||
|
isFixedForMobile: function() {
|
||
|
return KTUtil.hasClass(KTUtil.getBody(), 'header-mobile-fixed')
|
||
|
},
|
||
|
|
||
|
getElement: function() {
|
||
|
return _element;
|
||
|
},
|
||
|
|
||
|
getElementForMobile: function() {
|
||
|
return _elementForMobile;
|
||
|
},
|
||
|
|
||
|
getHeader: function() {
|
||
|
return _object;
|
||
|
},
|
||
|
|
||
|
getHeight: function() {
|
||
|
return _getHeight();
|
||
|
},
|
||
|
|
||
|
getHeightForMobile: function() {
|
||
|
return _getHeightForMobile();
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutHeader;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutStickyCard = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
var _object;
|
||
|
|
||
|
// Private functions
|
||
|
var _init = function() {
|
||
|
var offset = 300;
|
||
|
|
||
|
if (typeof KTLayoutHeader !== 'undefined') {
|
||
|
offset = KTLayoutHeader.getHeight();
|
||
|
}
|
||
|
|
||
|
_object = new KTCard(_element, {
|
||
|
sticky: {
|
||
|
offset: offset,
|
||
|
zIndex: 90,
|
||
|
position: {
|
||
|
top: function() {
|
||
|
var pos = 0;
|
||
|
var body = KTUtil.getBody();
|
||
|
|
||
|
if (KTUtil.isBreakpointUp('lg')) {
|
||
|
if (typeof KTLayoutHeader !== 'undefined' && KTLayoutHeader.isFixed()) {
|
||
|
pos = pos + KTLayoutHeader.getHeight();
|
||
|
}
|
||
|
|
||
|
if (typeof KTLayoutSubheader !== 'undefined' && KTLayoutSubheader.isFixed()) {
|
||
|
pos = pos + KTLayoutSubheader.getHeight();
|
||
|
}
|
||
|
} else {
|
||
|
if (typeof KTLayoutHeader !== 'undefined' && KTLayoutHeader.isFixedForMobile()) {
|
||
|
pos = pos + KTLayoutHeader.getHeightForMobile();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pos = pos - 1; // remove header border width
|
||
|
|
||
|
return pos;
|
||
|
},
|
||
|
left: function(card) {
|
||
|
return KTUtil.offset(_element).left;
|
||
|
},
|
||
|
right: function(card) {
|
||
|
var body = KTUtil.getBody();
|
||
|
|
||
|
var cardWidth = parseInt(KTUtil.css(_element, 'width'));
|
||
|
var bodyWidth = parseInt(KTUtil.css(body, 'width'));
|
||
|
var cardOffsetLeft = KTUtil.offset(_element).left;
|
||
|
|
||
|
return bodyWidth - cardWidth - cardOffsetLeft;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
_object.initSticky();
|
||
|
|
||
|
KTUtil.addResizeHandler(function() {
|
||
|
_object.updateSticky();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
|
||
|
if (!_element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Initialize
|
||
|
_init();
|
||
|
},
|
||
|
|
||
|
update: function() {
|
||
|
if (_object) {
|
||
|
_object.updateSticky();
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutStickyCard;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutStretchedCard = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
|
||
|
// Private functions
|
||
|
var _init = function() {
|
||
|
var scroll = KTUtil.find(_element, '.card-scroll');
|
||
|
var cardBody = KTUtil.find(_element, '.card-body');
|
||
|
var cardHeader = KTUtil.find(_element, '.card-header');
|
||
|
|
||
|
var height = KTLayoutContent.getHeight();
|
||
|
|
||
|
height = height - parseInt(KTUtil.actualHeight(cardHeader));
|
||
|
|
||
|
height = height - parseInt(KTUtil.css(_element, 'marginTop')) - parseInt(KTUtil.css(_element, 'marginBottom'));
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingTop')) - parseInt(KTUtil.css(_element, 'paddingBottom'));
|
||
|
|
||
|
height = height - parseInt(KTUtil.css(cardBody, 'paddingTop')) - parseInt(KTUtil.css(cardBody, 'paddingBottom'));
|
||
|
height = height - parseInt(KTUtil.css(cardBody, 'marginTop')) - parseInt(KTUtil.css(cardBody, 'marginBottom'));
|
||
|
|
||
|
height = height - 3;
|
||
|
|
||
|
KTUtil.css(scroll, 'height', height + 'px');
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
|
||
|
if (!_element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Initialize
|
||
|
_init();
|
||
|
|
||
|
// Re-calculate on window resize
|
||
|
KTUtil.addResizeHandler(function() {
|
||
|
_init();
|
||
|
});
|
||
|
},
|
||
|
|
||
|
update: function() {
|
||
|
_init();
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutStretchedCard;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutSubheader = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
|
||
|
// Private functions
|
||
|
var _getHeight = function() {
|
||
|
var height = 0;
|
||
|
|
||
|
if (_element) {
|
||
|
height = KTUtil.actualHeight(_element);
|
||
|
}
|
||
|
|
||
|
return height;
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
|
||
|
if (!_element) {
|
||
|
return;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
isFixed: function() {
|
||
|
return KTUtil.hasClass(KTUtil.getBody(), 'subheader-fixed');
|
||
|
},
|
||
|
|
||
|
getElement: function() {
|
||
|
return _element;
|
||
|
},
|
||
|
|
||
|
getHeight: function() {
|
||
|
return _getHeight();
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutSubheader;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
// Class definition
|
||
|
var KTLayoutChat = function () {
|
||
|
// Private functions
|
||
|
var _init = function (element) {
|
||
|
var scrollEl = KTUtil.find(element, '.scroll');
|
||
|
var cardBodyEl = KTUtil.find(element, '.card-body');
|
||
|
var cardHeaderEl = KTUtil.find(element, '.card-header');
|
||
|
var cardFooterEl = KTUtil.find(element, '.card-footer');
|
||
|
|
||
|
if (!scrollEl) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// initialize perfect scrollbar(see: https://github.com/utatti/perfect-scrollbar)
|
||
|
KTUtil.scrollInit(scrollEl, {
|
||
|
windowScroll: false, // allow browser scroll when the scroll reaches the end of the side
|
||
|
mobileNativeScroll: true, // enable native scroll for mobile
|
||
|
desktopNativeScroll: false, // disable native scroll and use custom scroll for desktop
|
||
|
resetHeightOnDestroy: true, // reset css height on scroll feature destroyed
|
||
|
handleWindowResize: true, // recalculate hight on window resize
|
||
|
rememberPosition: true, // remember scroll position in cookie
|
||
|
height: function() { // calculate height
|
||
|
var height;
|
||
|
|
||
|
if (KTUtil.isBreakpointDown('lg')) { // Mobile mode
|
||
|
return KTUtil.hasAttr(scrollEl, 'data-mobile-height') ? parseInt(KTUtil.attr(scrollEl, 'data-mobile-height')) : 400;
|
||
|
} else if (KTUtil.isBreakpointUp('lg') && KTUtil.hasAttr(scrollEl, 'data-height')) { // Desktop Mode
|
||
|
return parseInt(KTUtil.attr(scrollEl, 'data-height'));
|
||
|
} else {
|
||
|
height = KTLayoutContent.getHeight();
|
||
|
|
||
|
if (scrollEl) {
|
||
|
height = height - parseInt(KTUtil.css(scrollEl, 'margin-top')) - parseInt(KTUtil.css(scrollEl, 'margin-bottom'));
|
||
|
}
|
||
|
|
||
|
if (cardHeaderEl) {
|
||
|
height = height - parseInt(KTUtil.css(cardHeaderEl, 'height'));
|
||
|
height = height - parseInt(KTUtil.css(cardHeaderEl, 'margin-top')) - parseInt(KTUtil.css(cardHeaderEl, 'margin-bottom'));
|
||
|
}
|
||
|
|
||
|
if (cardBodyEl) {
|
||
|
height = height - parseInt(KTUtil.css(cardBodyEl, 'padding-top')) - parseInt(KTUtil.css(cardBodyEl, 'padding-bottom'));
|
||
|
}
|
||
|
|
||
|
if (cardFooterEl) {
|
||
|
height = height - parseInt(KTUtil.css(cardFooterEl, 'height'));
|
||
|
height = height - parseInt(KTUtil.css(cardFooterEl, 'margin-top')) - parseInt(KTUtil.css(cardFooterEl, 'margin-bottom'));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Remove additional space
|
||
|
height = height - 2;
|
||
|
|
||
|
return height;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// attach events
|
||
|
KTUtil.on(element, '.card-footer textarea', 'keydown', function(e) {
|
||
|
if (e.keyCode == 13) {
|
||
|
_handeMessaging(element);
|
||
|
e.preventDefault();
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
KTUtil.on(element, '.card-footer .chat-send', 'click', function(e) {
|
||
|
_handeMessaging(element);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var _handeMessaging = function(element) {
|
||
|
var messagesEl = KTUtil.find(element, '.messages');
|
||
|
var scrollEl = KTUtil.find(element, '.scroll');
|
||
|
var textarea = KTUtil.find(element, 'textarea');
|
||
|
|
||
|
if (textarea.value.length === 0 ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var node = document.createElement("DIV");
|
||
|
KTUtil.addClass(node, 'd-flex flex-column mb-5 align-items-end');
|
||
|
|
||
|
var html = '';
|
||
|
html += '<div class="d-flex align-items-center">';
|
||
|
html += ' <div>';
|
||
|
html += ' <span class="text-muted font-size-sm">2 Hours</span>';
|
||
|
html += ' <a href="#" class="text-dark-75 text-hover-primary font-weight-bold font-size-h6">You</a>';
|
||
|
html += ' </div>';
|
||
|
html += ' <div class="symbol symbol-circle symbol-40 ml-3">';
|
||
|
html += ' <img alt="Pic" src="assets/media/users/300_12.jpg"/>';
|
||
|
html += ' </div>';
|
||
|
html += '</div>';
|
||
|
html += '<div class="mt-2 rounded p-5 bg-light-primary text-dark-50 font-weight-bold font-size-lg text-right max-w-400px">' + textarea.value + '</div>';
|
||
|
|
||
|
KTUtil.setHTML(node, html);
|
||
|
messagesEl.appendChild(node);
|
||
|
textarea.value = '';
|
||
|
scrollEl.scrollTop = parseInt(KTUtil.css(messagesEl, 'height'));
|
||
|
|
||
|
var ps;
|
||
|
if (ps = KTUtil.data(scrollEl).get('ps')) {
|
||
|
ps.update();
|
||
|
}
|
||
|
|
||
|
setTimeout(function() {
|
||
|
var node = document.createElement("DIV");
|
||
|
KTUtil.addClass(node, 'd-flex flex-column mb-5 align-items-start');
|
||
|
|
||
|
var html = '';
|
||
|
html += '<div class="d-flex align-items-center">';
|
||
|
html += ' <div class="symbol symbol-circle symbol-40 mr-3">';
|
||
|
html += ' <img alt="Pic" src="assets/media/users/300_12.jpg"/>';
|
||
|
html += ' </div>';
|
||
|
html += ' <div>';
|
||
|
html += ' <a href="#" class="text-dark-75 text-hover-primary font-weight-bold font-size-h6">Matt Pears</a>';
|
||
|
html += ' <span class="text-muted font-size-sm">Just now</span>';
|
||
|
html += ' </div>';
|
||
|
html += '</div>';
|
||
|
html += '<div class="mt-2 rounded p-5 bg-light-success text-dark-50 font-weight-bold font-size-lg text-left max-w-400px">';
|
||
|
html += 'Right before vacation season we have the next Big Deal for you.';
|
||
|
html += '</div>';
|
||
|
|
||
|
KTUtil.setHTML(node, html);
|
||
|
messagesEl.appendChild(node);
|
||
|
textarea.value = '';
|
||
|
scrollEl.scrollTop = parseInt(KTUtil.css(messagesEl, 'height'));
|
||
|
|
||
|
var ps;
|
||
|
if (ps = KTUtil.data(scrollEl).get('ps')) {
|
||
|
ps.update();
|
||
|
}
|
||
|
}, 2000);
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function() {
|
||
|
// init modal chat example
|
||
|
_init(KTUtil.getById('kt_chat_modal'));
|
||
|
|
||
|
// trigger click to show popup modal chat on page load
|
||
|
if (encodeURI(window.location.hostname) == 'keenthemes.com' || encodeURI(window.location.hostname) == 'www.keenthemes.com') {
|
||
|
setTimeout(function() {
|
||
|
if (!KTCookie.getCookie('kt_app_chat_shown')) {
|
||
|
var expires = new Date(new Date().getTime() + 60 * 60 * 1000); // expire in 60 minutes from now
|
||
|
|
||
|
KTCookie.setCookie('kt_app_chat_shown', 1, { expires: expires });
|
||
|
|
||
|
if (KTUtil.getById('kt_app_chat_launch_btn')) {
|
||
|
KTUtil.getById('kt_app_chat_launch_btn').click();
|
||
|
}
|
||
|
}
|
||
|
}, 2000);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
setup: function(element) {
|
||
|
_init(element);
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutChat;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutDemoPanel = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
var _offcanvasObject;
|
||
|
|
||
|
// Private functions
|
||
|
var _init = function() {
|
||
|
_offcanvasObject = new KTOffcanvas(_element, {
|
||
|
overlay: true,
|
||
|
baseClass: 'offcanvas',
|
||
|
placement: 'right',
|
||
|
closeBy: 'kt_demo_panel_close',
|
||
|
toggleBy: 'kt_demo_panel_toggle'
|
||
|
});
|
||
|
|
||
|
var header = KTUtil.find(_element, '.offcanvas-header');
|
||
|
var content = KTUtil.find(_element, '.offcanvas-content');
|
||
|
var wrapper = KTUtil.find(_element, '.offcanvas-wrapper');
|
||
|
var footer = KTUtil.find(_element, '.offcanvas-footer');
|
||
|
|
||
|
KTUtil.scrollInit(wrapper, {
|
||
|
disableForMobile: true,
|
||
|
resetHeightOnDestroy: true,
|
||
|
handleWindowResize: true,
|
||
|
height: function() {
|
||
|
var height = parseInt(KTUtil.getViewPort().height);
|
||
|
|
||
|
if (header) {
|
||
|
height = height - parseInt(KTUtil.actualHeight(header));
|
||
|
height = height - parseInt(KTUtil.css(header, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(header, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
if (content) {
|
||
|
height = height - parseInt(KTUtil.css(content, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(content, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
if (wrapper) {
|
||
|
height = height - parseInt(KTUtil.css(wrapper, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(wrapper, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
if (footer) {
|
||
|
height = height - parseInt(KTUtil.actualHeight(footer));
|
||
|
height = height - parseInt(KTUtil.css(footer, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(footer, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingTop'));
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingBottom'));
|
||
|
|
||
|
height = height - 2;
|
||
|
|
||
|
return height;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
if (typeof offcanvas !== 'undefined' && offcanvas.length === 0) {
|
||
|
offcanvas.on('hide', function() {
|
||
|
var expires = new Date(new Date().getTime() + 60 * 60 * 1000); // expire in 60 minutes from now
|
||
|
KTCookie.setCookie('kt_demo_panel_shown', 1, {expires: expires});
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var _remind = function() {
|
||
|
if (!(encodeURI(window.location.hostname) == 'keenthemes.com' || encodeURI(window.location.hostname) == 'www.keenthemes.com')) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
setTimeout(function() {
|
||
|
if (!KTCookie.getCookie('kt_demo_panel_shown')) {
|
||
|
var expires = new Date(new Date().getTime() + 15 * 60 * 1000); // expire in 15 minutes from now
|
||
|
KTCookie.setCookie('kt_demo_panel_shown', 1, { expires: expires });
|
||
|
if (typeof _offcanvasObject !== 'undefined') {
|
||
|
_offcanvasObject.show();
|
||
|
}
|
||
|
}
|
||
|
}, 4000);
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
|
||
|
if (!_element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Initialize
|
||
|
_init();
|
||
|
|
||
|
// Remind
|
||
|
_remind();
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutDemoPanel;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutExamples = function() {
|
||
|
|
||
|
var initDefaultMode = function(element) {
|
||
|
var elements = element;
|
||
|
if (typeof elements === 'undefined') {
|
||
|
elements = document.querySelectorAll('.example:not(.example-compact):not(.example-hover):not(.example-basic)');
|
||
|
}
|
||
|
|
||
|
for (var i = 0; i < elements.length; ++i) {
|
||
|
var example = elements[i];
|
||
|
var copy = KTUtil.find(example, '.example-copy');
|
||
|
|
||
|
var clipboard = new ClipboardJS(copy, {
|
||
|
target: function(trigger) {
|
||
|
var example = trigger.closest('.example');
|
||
|
var el = KTUtil.find(example, '.example-code .tab-pane.active');
|
||
|
|
||
|
if (!el) {
|
||
|
el = KTUtil.find(example, '.example-code');
|
||
|
}
|
||
|
|
||
|
return el;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
clipboard.on('success', function(e) {
|
||
|
KTUtil.addClass(e.trigger, 'example-copied');
|
||
|
e.clearSelection();
|
||
|
|
||
|
setTimeout(function() {
|
||
|
KTUtil.removeClass(e.trigger, 'example-copied');
|
||
|
}, 2000);
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var initCompactMode = function(element) {
|
||
|
var example,code,toggle,copy, clipboard;
|
||
|
var elements = element;
|
||
|
if (typeof elements === 'undefined') {
|
||
|
var elements = document.querySelectorAll('.example.example-compact');
|
||
|
}
|
||
|
|
||
|
for (var i = 0; i < elements.length; ++i) {
|
||
|
var example = elements[i];
|
||
|
var toggle = KTUtil.find(example, '.example-toggle');
|
||
|
var copy = KTUtil.find(example, '.example-copy');
|
||
|
|
||
|
// Handle toggle
|
||
|
KTUtil.addEvent(toggle, 'click', function() {
|
||
|
var example = this.closest('.example');
|
||
|
var code = KTUtil.find(example, '.example-code');
|
||
|
var the = this;
|
||
|
|
||
|
if (KTUtil.hasClass(this, 'example-toggled')) {
|
||
|
KTUtil.slideUp(code, 300, function() {
|
||
|
KTUtil.removeClass(the, 'example-toggled');
|
||
|
KTUtil.removeClass(code, 'example-code-on');
|
||
|
KTUtil.hide(code);
|
||
|
});
|
||
|
} else {
|
||
|
KTUtil.addClass(code, 'example-code-on');
|
||
|
KTUtil.addClass(this, 'example-toggled');
|
||
|
KTUtil.slideDown(code, 300, function() {
|
||
|
KTUtil.show(code);
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Handle copy
|
||
|
var clipboard = new ClipboardJS(copy, {
|
||
|
target: function(trigger) {
|
||
|
var example = trigger.closest('.example');
|
||
|
var el = KTUtil.find(example, '.example-code .tab-pane.active');
|
||
|
|
||
|
if (!el) {
|
||
|
el = KTUtil.find(example, '.example-code');
|
||
|
}
|
||
|
|
||
|
return el;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
clipboard.on('success', function(e) {
|
||
|
KTUtil.addClass(e.trigger, 'example-copied');
|
||
|
e.clearSelection();
|
||
|
|
||
|
setTimeout(function() {
|
||
|
KTUtil.removeClass(e.trigger, 'example-copied');
|
||
|
}, 2000);
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
init: function(element, options) {
|
||
|
initDefaultMode(element);
|
||
|
initCompactMode(element);
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// webpack support
|
||
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||
|
module.exports = KTLayoutExamples;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutQuickActions = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
var _offcanvasObject;
|
||
|
|
||
|
// Private functions
|
||
|
var _init = function() {
|
||
|
var header = KTUtil.find(_element, '.offcanvas-header');
|
||
|
var content = KTUtil.find(_element, '.offcanvas-content');
|
||
|
|
||
|
_offcanvasObject = new KTOffcanvas(_element, {
|
||
|
overlay: true,
|
||
|
baseClass: 'offcanvas',
|
||
|
placement: 'right',
|
||
|
closeBy: 'kt_quick_actions_close',
|
||
|
toggleBy: 'kt_quick_actions_toggle'
|
||
|
});
|
||
|
|
||
|
KTUtil.scrollInit(content, {
|
||
|
disableForMobile: true,
|
||
|
resetHeightOnDestroy: true,
|
||
|
handleWindowResize: true,
|
||
|
height: function() {
|
||
|
var height = parseInt(KTUtil.getViewPort().height);
|
||
|
|
||
|
if (header) {
|
||
|
height = height - parseInt(KTUtil.actualHeight(header));
|
||
|
height = height - parseInt(KTUtil.css(header, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(header, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
if (content) {
|
||
|
height = height - parseInt(KTUtil.css(content, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(content, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingTop'));
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingBottom'));
|
||
|
|
||
|
height = height - 2;
|
||
|
|
||
|
return height;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
|
||
|
if (!_element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Initialize
|
||
|
_init();
|
||
|
},
|
||
|
|
||
|
getElement: function() {
|
||
|
return _element;
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutQuickActions;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutQuickCartPanel = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
var _offcanvasObject;
|
||
|
|
||
|
// Private functions
|
||
|
var _init = function() {
|
||
|
_offcanvasObject = new KTOffcanvas(_element, {
|
||
|
overlay: true,
|
||
|
baseClass: 'offcanvas',
|
||
|
placement: 'right',
|
||
|
closeBy: 'kt_quick_cart_close',
|
||
|
toggleBy: 'kt_quick_cart_toggle'
|
||
|
});
|
||
|
|
||
|
var header = KTUtil.find(_element, '.offcanvas-header');
|
||
|
var content = KTUtil.find(_element, '.offcanvas-content');
|
||
|
var wrapper = KTUtil.find(_element, '.offcanvas-wrapper');
|
||
|
var footer = KTUtil.find(_element, '.offcanvas-footer');
|
||
|
|
||
|
KTUtil.scrollInit(wrapper, {
|
||
|
disableForMobile: true,
|
||
|
resetHeightOnDestroy: true,
|
||
|
handleWindowResize: true,
|
||
|
height: function() {
|
||
|
var height = parseInt(KTUtil.getViewPort().height);
|
||
|
|
||
|
if (header) {
|
||
|
height = height - parseInt(KTUtil.actualHeight(header));
|
||
|
height = height - parseInt(KTUtil.css(header, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(header, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
if (content) {
|
||
|
height = height - parseInt(KTUtil.css(content, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(content, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
if (wrapper) {
|
||
|
height = height - parseInt(KTUtil.css(wrapper, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(wrapper, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
if (footer) {
|
||
|
height = height - parseInt(KTUtil.actualHeight(footer));
|
||
|
height = height - parseInt(KTUtil.css(footer, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(footer, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingTop'));
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingBottom'));
|
||
|
|
||
|
height = height - 2;
|
||
|
|
||
|
return height;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
|
||
|
if (!_element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Initialize
|
||
|
_init();
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutQuickCartPanel;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutQuickNotifications = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
var _offcanvasObject;
|
||
|
|
||
|
// Private functions
|
||
|
var _init = function() {
|
||
|
var header = KTUtil.find(_element, '.offcanvas-header');
|
||
|
var content = KTUtil.find(_element, '.offcanvas-content');
|
||
|
|
||
|
_offcanvasObject = new KTOffcanvas(_element, {
|
||
|
overlay: true,
|
||
|
baseClass: 'offcanvas',
|
||
|
placement: 'right',
|
||
|
closeBy: 'kt_quick_notifications_close',
|
||
|
toggleBy: 'kt_quick_notifications_toggle'
|
||
|
});
|
||
|
|
||
|
KTUtil.scrollInit(content, {
|
||
|
disableForMobile: true,
|
||
|
resetHeightOnDestroy: true,
|
||
|
handleWindowResize: true,
|
||
|
height: function() {
|
||
|
var height = parseInt(KTUtil.getViewPort().height);
|
||
|
|
||
|
if (header) {
|
||
|
height = height - parseInt(KTUtil.actualHeight(header));
|
||
|
height = height - parseInt(KTUtil.css(header, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(header, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
if (content) {
|
||
|
height = height - parseInt(KTUtil.css(content, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(content, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingTop'));
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingBottom'));
|
||
|
|
||
|
height = height - 2;
|
||
|
|
||
|
return height;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
|
||
|
if (!_element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Initialize
|
||
|
_init();
|
||
|
},
|
||
|
|
||
|
getElement: function() {
|
||
|
return _element;
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutQuickNotifications;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutQuickPanel = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
var _offcanvasObject;
|
||
|
var _notificationsElement;
|
||
|
var _logsElement;
|
||
|
var _settingsElement;
|
||
|
|
||
|
// Private functions
|
||
|
var _getContentHeight = function() {
|
||
|
var height;
|
||
|
|
||
|
var header = KTUtil.find(_element, '.offcanvas-header');
|
||
|
var content = KTUtil.find(_element, '.offcanvas-content');
|
||
|
|
||
|
var height = parseInt(KTUtil.getViewPort().height);
|
||
|
|
||
|
if (header) {
|
||
|
height = height - parseInt(KTUtil.actualHeight(header));
|
||
|
height = height - parseInt(KTUtil.css(header, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(header, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
if (content) {
|
||
|
height = height - parseInt(KTUtil.css(content, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(content, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingTop'));
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingBottom'));
|
||
|
|
||
|
height = height - 2;
|
||
|
|
||
|
return height;
|
||
|
}
|
||
|
|
||
|
var _init = function() {
|
||
|
_offcanvasObject = new KTOffcanvas(_element, {
|
||
|
overlay: true,
|
||
|
baseClass: 'offcanvas',
|
||
|
placement: 'right',
|
||
|
closeBy: 'kt_quick_panel_close',
|
||
|
toggleBy: 'kt_quick_panel_toggle'
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var _initNotifications = function() {
|
||
|
KTUtil.scrollInit(_notificationsElement, {
|
||
|
mobileNativeScroll: true,
|
||
|
resetHeightOnDestroy: true,
|
||
|
handleWindowResize: true,
|
||
|
height: function() {
|
||
|
return _getContentHeight();
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var _initLogs = function() {
|
||
|
KTUtil.scrollInit(_logsElement, {
|
||
|
mobileNativeScroll: true,
|
||
|
resetHeightOnDestroy: true,
|
||
|
handleWindowResize: true,
|
||
|
height: function() {
|
||
|
return _getContentHeight();
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var _initSettings = function() {
|
||
|
KTUtil.scrollInit(_settingsElement, {
|
||
|
mobileNativeScroll: true,
|
||
|
resetHeightOnDestroy: true,
|
||
|
handleWindowResize: true,
|
||
|
height: function() {
|
||
|
return _getContentHeight();
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var _updateScrollbars = function() {
|
||
|
$(_element).find('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||
|
KTUtil.scrollUpdate(_notificationsElement);
|
||
|
KTUtil.scrollUpdate(_logsElement);
|
||
|
KTUtil.scrollUpdate(_settingsElement);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
_notificationsElement = KTUtil.getById('kt_quick_panel_notifications');
|
||
|
_logsElement = KTUtil.getById('kt_quick_panel_logs');
|
||
|
_settingsElement = KTUtil.getById('kt_quick_panel_settings');
|
||
|
|
||
|
_init();
|
||
|
_initNotifications();
|
||
|
_initLogs();
|
||
|
_initSettings();
|
||
|
|
||
|
_updateScrollbars();
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutQuickPanel;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutQuickSearch = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
var _offcanvasObject;
|
||
|
|
||
|
// Private functions
|
||
|
var _init = function() {
|
||
|
var header = KTUtil.find(_element, '.offcanvas-header');
|
||
|
var content = KTUtil.find(_element, '.offcanvas-content');
|
||
|
var form = KTUtil.find(_element, '.quick-search-form');
|
||
|
var results = KTUtil.find(_element, '.quick-search-wrapper');
|
||
|
|
||
|
_offcanvasObject = new KTOffcanvas(_element, {
|
||
|
overlay: true,
|
||
|
baseClass: 'offcanvas',
|
||
|
placement: 'right',
|
||
|
closeBy: 'kt_quick_search_close',
|
||
|
toggleBy: 'kt_quick_search_toggle'
|
||
|
});
|
||
|
|
||
|
KTUtil.scrollInit(results, {
|
||
|
disableForMobile: true,
|
||
|
resetHeightOnDestroy: true,
|
||
|
handleWindowResize: true,
|
||
|
height: function() {
|
||
|
var height = parseInt(KTUtil.getViewPort().height);
|
||
|
|
||
|
if (header) {
|
||
|
height = height - parseInt(KTUtil.actualHeight(header));
|
||
|
height = height - parseInt(KTUtil.css(header, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(header, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
if (content) {
|
||
|
height = height - parseInt(KTUtil.css(content, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(content, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
if (results) {
|
||
|
height = height - parseInt(KTUtil.actualHeight(form));
|
||
|
height = height - parseInt(KTUtil.css(form, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(form, 'marginBottom'));
|
||
|
|
||
|
height = height - parseInt(KTUtil.css(results, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(results, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingTop'));
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingBottom'));
|
||
|
|
||
|
height = height - 2;
|
||
|
|
||
|
return height;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
|
||
|
if (!_element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Initialize
|
||
|
_init();
|
||
|
},
|
||
|
|
||
|
getElement: function() {
|
||
|
return _element;
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutQuickSearch;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutQuickUser = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
var _offcanvasObject;
|
||
|
|
||
|
// Private functions
|
||
|
var _init = function() {
|
||
|
var header = KTUtil.find(_element, '.offcanvas-header');
|
||
|
var content = KTUtil.find(_element, '.offcanvas-content');
|
||
|
|
||
|
_offcanvasObject = new KTOffcanvas(_element, {
|
||
|
overlay: true,
|
||
|
baseClass: 'offcanvas',
|
||
|
placement: 'right',
|
||
|
closeBy: 'kt_quick_user_close',
|
||
|
toggleBy: 'kt_quick_user_toggle'
|
||
|
});
|
||
|
|
||
|
KTUtil.scrollInit(content, {
|
||
|
disableForMobile: true,
|
||
|
resetHeightOnDestroy: true,
|
||
|
handleWindowResize: true,
|
||
|
height: function() {
|
||
|
var height = parseInt(KTUtil.getViewPort().height);
|
||
|
|
||
|
if (header) {
|
||
|
height = height - parseInt(KTUtil.actualHeight(header));
|
||
|
height = height - parseInt(KTUtil.css(header, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(header, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
if (content) {
|
||
|
height = height - parseInt(KTUtil.css(content, 'marginTop'));
|
||
|
height = height - parseInt(KTUtil.css(content, 'marginBottom'));
|
||
|
}
|
||
|
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingTop'));
|
||
|
height = height - parseInt(KTUtil.css(_element, 'paddingBottom'));
|
||
|
|
||
|
height = height - 2;
|
||
|
|
||
|
return height;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
|
||
|
if (!_element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Initialize
|
||
|
_init();
|
||
|
},
|
||
|
|
||
|
getElement: function() {
|
||
|
return _element;
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutQuickUser;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var KTLayoutScrolltop = function() {
|
||
|
// Private properties
|
||
|
var _element;
|
||
|
var _object;
|
||
|
|
||
|
// Private functions
|
||
|
var _init = function() {
|
||
|
_object = new KTScrolltop(_element, {
|
||
|
offset: 300,
|
||
|
speed: 600,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_element = KTUtil.getById(id);
|
||
|
|
||
|
if (!_element) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Initialize
|
||
|
_init();
|
||
|
},
|
||
|
|
||
|
getElement: function() {
|
||
|
return _element;
|
||
|
}
|
||
|
};
|
||
|
}();
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutScrolltop;
|
||
|
}
|
||
|
|
||
|
"use strict";
|
||
|
//
|
||
|
// Handle User Quick Search For Dropdown, Inline and Offcanvas Search Panels
|
||
|
//
|
||
|
|
||
|
var KTLayoutSearch = function() {
|
||
|
// Private properties
|
||
|
var _target;
|
||
|
var _form;
|
||
|
var _input;
|
||
|
var _closeIcon;
|
||
|
var _resultWrapper;
|
||
|
var _resultDropdown;
|
||
|
var _resultDropdownToggle;
|
||
|
var _closeIconContainer;
|
||
|
var _inputGroup;
|
||
|
var _query = '';
|
||
|
|
||
|
var _hasResult = false;
|
||
|
var _timeout = false;
|
||
|
var _isProcessing = false;
|
||
|
var _requestTimeout = 200; // ajax request fire timeout in milliseconds
|
||
|
var _spinnerClass = 'spinner spinner-sm spinner-primary';
|
||
|
var _resultClass = 'quick-search-has-result';
|
||
|
var _minLength = 2;
|
||
|
|
||
|
// Private functions
|
||
|
var _showProgress = function() {
|
||
|
_isProcessing = true;
|
||
|
KTUtil.addClass(_closeIconContainer, _spinnerClass);
|
||
|
|
||
|
if (_closeIcon) {
|
||
|
KTUtil.hide(_closeIcon);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var _hideProgress = function() {
|
||
|
_isProcessing = false;
|
||
|
KTUtil.removeClass(_closeIconContainer, _spinnerClass);
|
||
|
|
||
|
if (_closeIcon) {
|
||
|
if (_input.value.length < _minLength) {
|
||
|
KTUtil.hide(_closeIcon);
|
||
|
} else {
|
||
|
KTUtil.show(_closeIcon, 'flex');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var _showDropdown = function() {
|
||
|
if (_resultDropdownToggle && !KTUtil.hasClass(_resultDropdown, 'show')) {
|
||
|
$(_resultDropdownToggle).dropdown('toggle');
|
||
|
$(_resultDropdownToggle).dropdown('update');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var _hideDropdown = function() {
|
||
|
if (_resultDropdownToggle && KTUtil.hasClass(_resultDropdown, 'show')) {
|
||
|
$(_resultDropdownToggle).dropdown('toggle');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var _processSearch = function() {
|
||
|
if (_hasResult && _query === _input.value) {
|
||
|
_hideProgress();
|
||
|
KTUtil.addClass(_target, _resultClass);
|
||
|
_showDropdown();
|
||
|
KTUtil.scrollUpdate(_resultWrapper);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
_query = _input.value;
|
||
|
|
||
|
KTUtil.removeClass(_target, _resultClass);
|
||
|
_showProgress();
|
||
|
_hideDropdown();
|
||
|
|
||
|
setTimeout(function() {
|
||
|
$.ajax({
|
||
|
url: HOST_URL + '/api/quick_search.php',
|
||
|
data: {
|
||
|
query: _query
|
||
|
},
|
||
|
dataType: 'html',
|
||
|
success: function(res) {
|
||
|
_hasResult = true;
|
||
|
_hideProgress();
|
||
|
KTUtil.addClass(_target, _resultClass);
|
||
|
KTUtil.setHTML(_resultWrapper, res);
|
||
|
_showDropdown();
|
||
|
KTUtil.scrollUpdate(_resultWrapper);
|
||
|
},
|
||
|
error: function(res) {
|
||
|
_hasResult = false;
|
||
|
_hideProgress();
|
||
|
KTUtil.addClass(_target, _resultClass);
|
||
|
KTUtil.setHTML(_resultWrapper, '<span class="font-weight-bold text-muted">Connection error. Please try again later..</div>');
|
||
|
_showDropdown();
|
||
|
KTUtil.scrollUpdate(_resultWrapper);
|
||
|
}
|
||
|
});
|
||
|
}, 1000);
|
||
|
}
|
||
|
|
||
|
var _handleCancel = function(e) {
|
||
|
_input.value = '';
|
||
|
_query = '';
|
||
|
_hasResult = false;
|
||
|
KTUtil.hide(_closeIcon);
|
||
|
KTUtil.removeClass(_target, _resultClass);
|
||
|
_hideDropdown();
|
||
|
}
|
||
|
|
||
|
var _handleSearch = function() {
|
||
|
if (_input.value.length < _minLength) {
|
||
|
_hideProgress();
|
||
|
_hideDropdown();
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (_isProcessing == true) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (_timeout) {
|
||
|
clearTimeout(_timeout);
|
||
|
}
|
||
|
|
||
|
_timeout = setTimeout(function() {
|
||
|
_processSearch();
|
||
|
}, _requestTimeout);
|
||
|
}
|
||
|
|
||
|
// Public methods
|
||
|
return {
|
||
|
init: function(id) {
|
||
|
_target = KTUtil.getById(id);
|
||
|
|
||
|
if (!_target) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
_form = KTUtil.find(_target, '.quick-search-form');
|
||
|
_input = KTUtil.find(_target, '.form-control');
|
||
|
_closeIcon = KTUtil.find(_target, '.quick-search-close');
|
||
|
_resultWrapper = KTUtil.find(_target, '.quick-search-wrapper');
|
||
|
_resultDropdown = KTUtil.find(_target, '.dropdown-menu');
|
||
|
_resultDropdownToggle = KTUtil.find(_target, '[data-toggle="dropdown"]');
|
||
|
_inputGroup = KTUtil.find(_target, '.input-group');
|
||
|
_closeIconContainer = KTUtil.find(_target, '.input-group .input-group-append');
|
||
|
|
||
|
// Attach input keyup handler
|
||
|
KTUtil.addEvent(_input, 'keyup', _handleSearch);
|
||
|
KTUtil.addEvent(_input, 'focus', _handleSearch);
|
||
|
|
||
|
// Prevent enter click
|
||
|
_form.onkeypress = function(e) {
|
||
|
var key = e.charCode || e.keyCode || 0;
|
||
|
if (key == 13) {
|
||
|
e.preventDefault();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
KTUtil.addEvent(_closeIcon, 'click', _handleCancel);
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// Webpack support
|
||
|
if (typeof module !== 'undefined') {
|
||
|
module.exports = KTLayoutSearch;
|
||
|
}
|
||
|
|
||
|
var KTLayoutSearchInline = KTLayoutSearch;
|
||
|
var KTLayoutSearchOffcanvas = KTLayoutSearch;
|