@syncfusion/ej2-navigations
Version:
A package of Essential JS 2 navigation components such as Tree-view, Tab, Toolbar, Context-menu, and Accordion which is used to navigate from one page to another
20,595 lines • 876 kB
JavaScript
import { Component, Browser, getUniqueID, Touch, EventHandler, isNullOrUndefined, selectAll, detach, classList, Property, NotifyPropertyChanges, createElement, removeClass, select, ChildProperty, Collection, Event, Complex, Animation, getValue, setValue, append, closest, addClass, isBlazor, rippleEffect, KeyboardEvents, getInstance, isVisible, SanitizeHtmlHelper, formatUnit, setStyleAttribute, attributes, compile, isRippleEnabled, animationMode, remove, getRandomId, L10n, Draggable, isUndefined, getElement, Droppable, matches, extend, merge, initializeCSPTemplate } from '@syncfusion/ej2-base';
import { ListBase } from '@syncfusion/ej2-lists';
import { getScrollableParent, Popup, getZindexPartial, fit, isCollide, calculatePosition, createSpinner, showSpinner, hideSpinner, Tooltip } from '@syncfusion/ej2-popups';
import { Button, createCheckBox, rippleMouseHandler } from '@syncfusion/ej2-buttons';
import { DataManager, Query } from '@syncfusion/ej2-data';
import { Input } from '@syncfusion/ej2-inputs';
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const CLS_ROOT = 'e-hscroll';
const CLS_RTL = 'e-rtl';
const CLS_DISABLE = 'e-overlay';
const CLS_HSCROLLBAR = 'e-hscroll-bar';
const CLS_HSCROLLCON = 'e-hscroll-content';
const CLS_NAVARROW = 'e-nav-arrow';
const CLS_NAVRIGHTARROW = 'e-nav-right-arrow';
const CLS_NAVLEFTARROW = 'e-nav-left-arrow';
const CLS_HSCROLLNAV = 'e-scroll-nav';
const CLS_HSCROLLNAVRIGHT = 'e-scroll-right-nav';
const CLS_HSCROLLNAVLEFT = 'e-scroll-left-nav';
const CLS_DEVICE = 'e-scroll-device';
const CLS_OVERLAY = 'e-scroll-overlay';
const CLS_RIGHTOVERLAY = 'e-scroll-right-overlay';
const CLS_LEFTOVERLAY = 'e-scroll-left-overlay';
const OVERLAY_MAXWID = 40;
/**
* HScroll module is introduces horizontal scroller when content exceeds the current viewing area.
* It can be useful for the components like Toolbar, Tab which needs horizontal scrolling alone.
* Hidden content can be view by touch moving or icon click.
* ```html
* <div id="scroll"/>
* <script>
* var scrollObj = new HScroll();
* scrollObj.appendTo("#scroll");
* </script>
* ```
*/
let HScroll = class HScroll extends Component {
/**
* Initializes a new instance of the HScroll class.
*
* @param {HScrollModel} options - Specifies HScroll model properties as options.
* @param {string | HTMLElement} element - Specifies the element for which horizontal scrolling applies.
*/
constructor(options, element) {
super(options, element);
}
/**
* Initialize the event handler
*
* @private
* @returns {void}
*/
preRender() {
this.browser = Browser.info.name;
this.browserCheck = this.browser === 'mozilla';
this.isDevice = Browser.isDevice;
this.customStep = true;
const element = this.element;
this.ieCheck = this.browser === 'edge' || this.browser === 'msie';
this.initialize();
if (element.id === '') {
element.id = getUniqueID('hscroll');
this.uniqueId = true;
}
element.style.display = 'block';
if (this.enableRtl) {
element.classList.add(CLS_RTL);
}
}
/**
* To Initialize the horizontal scroll rendering
*
* @private
* @returns {void}
*/
render() {
this.touchModule = new Touch(this.element, { scroll: this.touchHandler.bind(this), swipe: this.swipeHandler.bind(this) });
EventHandler.add(this.scrollEle, 'scroll', this.scrollHandler, this);
if (!this.isDevice) {
this.createNavIcon(this.element);
}
else {
this.element.classList.add(CLS_DEVICE);
this.createOverlay(this.element);
}
this.setScrollState();
}
setScrollState() {
if (isNullOrUndefined(this.scrollStep) || this.scrollStep < 0) {
this.scrollStep = this.scrollEle.offsetWidth;
this.customStep = false;
}
else {
this.customStep = true;
}
}
initialize() {
const scrollEle = this.createElement('div', { className: CLS_HSCROLLCON });
const scrollDiv = this.createElement('div', { className: CLS_HSCROLLBAR });
scrollDiv.setAttribute('tabindex', '-1');
const ele = this.element;
const innerEle = [].slice.call(ele.children);
for (const ele of innerEle) {
scrollEle.appendChild(ele);
}
scrollDiv.appendChild(scrollEle);
ele.appendChild(scrollDiv);
scrollDiv.style.overflowX = 'hidden';
this.scrollEle = scrollDiv;
this.scrollItems = scrollEle;
}
getPersistData() {
const keyEntity = ['scrollStep'];
return this.addOnPersist(keyEntity);
}
/**
* Returns the current module name.
*
* @returns {string} - It returns the current module name.
* @private
*/
getModuleName() {
return 'hScroll';
}
/**
* Removes the control from the DOM and also removes all its related events.
*
* @returns {void}
*/
destroy() {
const ele = this.element;
ele.style.display = '';
ele.classList.remove(CLS_ROOT);
ele.classList.remove(CLS_DEVICE);
ele.classList.remove(CLS_RTL);
const nav = selectAll('.e-' + ele.id + '_nav.' + CLS_HSCROLLNAV, ele);
const overlay = selectAll('.' + CLS_OVERLAY, ele);
[].slice.call(overlay).forEach((ele) => {
detach(ele);
});
for (const elem of [].slice.call(this.scrollItems.children)) {
ele.appendChild(elem);
}
if (this.uniqueId) {
this.element.removeAttribute('id');
}
detach(this.scrollEle);
if (nav.length > 0) {
detach(nav[0]);
if (!isNullOrUndefined(nav[1])) {
detach(nav[1]);
}
}
EventHandler.remove(this.scrollEle, 'scroll', this.scrollHandler);
this.touchModule.destroy();
this.touchModule = null;
super.destroy();
}
/**
* Specifies the value to disable/enable the HScroll component.
* When set to `true` , the component will be disabled.
*
* @param {boolean} value - Based on this Boolean value, HScroll will be enabled (false) or disabled (true).
* @returns {void}.
*/
disable(value) {
const navEles = selectAll('.e-scroll-nav:not(.' + CLS_DISABLE + ')', this.element);
if (value) {
this.element.classList.add(CLS_DISABLE);
}
else {
this.element.classList.remove(CLS_DISABLE);
}
[].slice.call(navEles).forEach((el) => {
el.setAttribute('tabindex', !value ? '0' : '-1');
});
}
createOverlay(element) {
const id = element.id.concat('_nav');
const rightOverlayEle = this.createElement('div', { className: CLS_OVERLAY + ' ' + CLS_RIGHTOVERLAY });
const clsRight = 'e-' + element.id.concat('_nav ' + CLS_HSCROLLNAV + ' ' + CLS_HSCROLLNAVRIGHT);
const rightEle = this.createElement('div', { id: id.concat('_right'), className: clsRight });
const navItem = this.createElement('div', { className: CLS_NAVRIGHTARROW + ' ' + CLS_NAVARROW + ' e-icons' });
rightEle.appendChild(navItem);
const leftEle = this.createElement('div', { className: CLS_OVERLAY + ' ' + CLS_LEFTOVERLAY });
if (this.ieCheck) {
rightEle.classList.add('e-ie-align');
}
element.appendChild(rightOverlayEle);
element.appendChild(rightEle);
element.insertBefore(leftEle, element.firstChild);
this.eventBinding([rightEle]);
}
createNavIcon(element) {
const id = element.id.concat('_nav');
const clsRight = 'e-' + element.id.concat('_nav ' + CLS_HSCROLLNAV + ' ' + CLS_HSCROLLNAVRIGHT);
const rightAttributes = { 'role': 'button', 'id': id.concat('_right'), 'aria-label': 'Scroll right' };
const nav = this.createElement('div', { className: clsRight, attrs: rightAttributes });
nav.setAttribute('aria-disabled', 'false');
const navItem = this.createElement('div', { className: CLS_NAVRIGHTARROW + ' ' + CLS_NAVARROW + ' e-icons' });
const clsLeft = 'e-' + element.id.concat('_nav ' + CLS_HSCROLLNAV + ' ' + CLS_HSCROLLNAVLEFT);
const leftAttributes = { 'role': 'button', 'id': id.concat('_left'), 'aria-label': 'Scroll left' };
const navEle = this.createElement('div', { className: clsLeft + ' ' + CLS_DISABLE, attrs: leftAttributes });
navEle.setAttribute('aria-disabled', 'true');
const navLeftItem = this.createElement('div', { className: CLS_NAVLEFTARROW + ' ' + CLS_NAVARROW + ' e-icons' });
navEle.appendChild(navLeftItem);
nav.appendChild(navItem);
element.appendChild(nav);
element.insertBefore(navEle, element.firstChild);
if (this.ieCheck) {
nav.classList.add('e-ie-align');
navEle.classList.add('e-ie-align');
}
this.eventBinding([nav, navEle]);
}
onKeyPress(e) {
if (e.key === 'Enter') {
const timeoutFun = () => {
this.keyTimeout = true;
this.eleScrolling(10, e.target, true);
};
this.keyTimer = window.setTimeout(() => {
timeoutFun();
}, 100);
}
}
onKeyUp(e) {
if (e.key !== 'Enter') {
return;
}
if (this.keyTimeout) {
this.keyTimeout = false;
}
else {
e.target.click();
}
clearTimeout(this.keyTimer);
}
eventBinding(ele) {
[].slice.call(ele).forEach((el) => {
new Touch(el, { tapHold: this.tabHoldHandler.bind(this), tapHoldThreshold: 500 });
el.addEventListener('keydown', this.onKeyPress.bind(this));
el.addEventListener('keyup', this.onKeyUp.bind(this));
el.addEventListener('mouseup', this.repeatScroll.bind(this));
el.addEventListener('touchend', this.repeatScroll.bind(this));
el.addEventListener('contextmenu', (e) => {
e.preventDefault();
});
EventHandler.add(el, 'click', this.clickEventHandler, this);
});
}
repeatScroll() {
clearInterval(this.timeout);
}
tabHoldHandler(e) {
let trgt = e.originalEvent.target;
trgt = this.contains(trgt, CLS_HSCROLLNAV) ? trgt.firstElementChild : trgt;
const scrollDis = 10;
const timeoutFun = () => {
this.eleScrolling(scrollDis, trgt, true);
};
this.timeout = window.setInterval(() => {
timeoutFun();
}, 50);
}
contains(ele, className) {
return ele.classList.contains(className);
}
eleScrolling(scrollDis, trgt, isContinuous) {
const rootEle = this.element;
let classList = trgt.classList;
if (classList.contains(CLS_HSCROLLNAV)) {
classList = trgt.querySelector('.' + CLS_NAVARROW).classList;
}
if (this.contains(rootEle, CLS_RTL) && this.browserCheck) {
scrollDis = -scrollDis;
}
if ((!this.contains(rootEle, CLS_RTL) || this.browserCheck) || this.ieCheck) {
if (classList.contains(CLS_NAVRIGHTARROW)) {
this.frameScrollRequest(scrollDis, 'add', isContinuous);
}
else {
this.frameScrollRequest(scrollDis, '', isContinuous);
}
}
else {
if (classList.contains(CLS_NAVLEFTARROW)) {
this.frameScrollRequest(scrollDis, 'add', isContinuous);
}
else {
this.frameScrollRequest(scrollDis, '', isContinuous);
}
}
}
clickEventHandler(e) {
this.eleScrolling(this.scrollStep, e.target, false);
}
swipeHandler(e) {
const swipeEle = this.scrollEle;
let distance;
if (e.velocity <= 1) {
distance = e.distanceX / (e.velocity * 10);
}
else {
distance = e.distanceX / e.velocity;
}
let start = 0.5;
const animate = () => {
const step = Math.sin(start);
if (step <= 0) {
window.cancelAnimationFrame(step);
}
else {
if (e.swipeDirection === 'Left') {
swipeEle.scrollLeft += distance * step;
}
else if (e.swipeDirection === 'Right') {
swipeEle.scrollLeft -= distance * step;
}
start -= 0.5;
window.requestAnimationFrame(animate);
}
};
animate();
}
scrollUpdating(scrollVal, action) {
if (action === 'add') {
this.scrollEle.scrollLeft += scrollVal;
}
else {
this.scrollEle.scrollLeft -= scrollVal;
}
if (this.enableRtl && this.scrollEle.scrollLeft > 0) {
this.scrollEle.scrollLeft = 0;
}
}
frameScrollRequest(scrollVal, action, isContinuous) {
const step = 10;
if (isContinuous) {
this.scrollUpdating(scrollVal, action);
return;
}
if (!this.customStep) {
[].slice.call(selectAll('.' + CLS_OVERLAY, this.element)).forEach((el) => {
scrollVal -= el.offsetWidth;
});
}
const animate = () => {
let scrollValue;
let scrollStep;
if (this.contains(this.element, CLS_RTL) && this.browserCheck) {
scrollValue = -scrollVal;
scrollStep = -step;
}
else {
scrollValue = scrollVal;
scrollStep = step;
}
if (scrollValue < step) {
window.cancelAnimationFrame(scrollStep);
}
else {
this.scrollUpdating(scrollStep, action);
scrollVal -= scrollStep;
window.requestAnimationFrame(animate);
}
};
animate();
}
touchHandler(e) {
const ele = this.scrollEle;
let distance = e.distanceX;
if ((this.ieCheck) && this.contains(this.element, CLS_RTL)) {
distance = -distance;
}
if (e.scrollDirection === 'Left') {
ele.scrollLeft = ele.scrollLeft + distance;
}
else if (e.scrollDirection === 'Right') {
ele.scrollLeft = ele.scrollLeft - distance;
}
}
arrowDisabling(addDisable, removeDisable) {
if (this.isDevice) {
const arrowEle = isNullOrUndefined(addDisable) ? removeDisable : addDisable;
const arrowIcon = arrowEle.querySelector('.' + CLS_NAVARROW);
if (isNullOrUndefined(addDisable)) {
classList(arrowIcon, [CLS_NAVRIGHTARROW], [CLS_NAVLEFTARROW]);
}
else {
classList(arrowIcon, [CLS_NAVLEFTARROW], [CLS_NAVRIGHTARROW]);
}
}
else if (addDisable && removeDisable) {
addDisable.classList.add(CLS_DISABLE);
addDisable.setAttribute('aria-disabled', 'true');
addDisable.removeAttribute('tabindex');
removeDisable.classList.remove(CLS_DISABLE);
removeDisable.setAttribute('aria-disabled', 'false');
removeDisable.setAttribute('tabindex', '0');
}
this.repeatScroll();
}
scrollHandler(e) {
const target = e.target;
const width = target.offsetWidth;
const rootEle = this.element;
const navLeftEle = this.element.querySelector('.' + CLS_HSCROLLNAVLEFT);
const navRightEle = this.element.querySelector('.' + CLS_HSCROLLNAVRIGHT);
let leftOverlay = this.element.querySelector('.' + CLS_LEFTOVERLAY);
let rightOverlay = this.element.querySelector('.' + CLS_RIGHTOVERLAY);
let scrollLeft = target.scrollLeft;
if (scrollLeft <= 0) {
scrollLeft = -scrollLeft;
}
if (this.isDevice) {
if (this.enableRtl && !(this.browserCheck || this.ieCheck)) {
leftOverlay = this.element.querySelector('.' + CLS_RIGHTOVERLAY);
rightOverlay = this.element.querySelector('.' + CLS_LEFTOVERLAY);
}
if (scrollLeft < OVERLAY_MAXWID) {
leftOverlay.style.width = scrollLeft + 'px';
}
else {
leftOverlay.style.width = '40px';
}
if ((target.scrollWidth - Math.ceil(width + scrollLeft)) < OVERLAY_MAXWID) {
rightOverlay.style.width = (target.scrollWidth - Math.ceil(width + scrollLeft)) + 'px';
}
else {
rightOverlay.style.width = '40px';
}
}
if (scrollLeft === 0) {
this.arrowDisabling(navLeftEle, navRightEle);
}
else if (Math.ceil(width + scrollLeft + .1) >= target.scrollWidth) {
this.arrowDisabling(navRightEle, navLeftEle);
}
else {
const disEle = this.element.querySelector('.' + CLS_HSCROLLNAV + '.' + CLS_DISABLE);
if (disEle) {
disEle.classList.remove(CLS_DISABLE);
disEle.setAttribute('aria-disabled', 'false');
disEle.setAttribute('tabindex', '0');
}
}
}
/**
* Gets called when the model property changes.The data that describes the old and new values of property that changed.
*
* @param {HScrollModel} newProp - It contains the new value of data.
* @param {HScrollModel} oldProp - It contains the old value of data.
* @returns {void}
* @private
*/
onPropertyChanged(newProp, oldProp) {
for (const prop of Object.keys(newProp)) {
switch (prop) {
case 'scrollStep':
this.setScrollState();
break;
case 'enableRtl':
newProp.enableRtl ? this.element.classList.add(CLS_RTL) : this.element.classList.remove(CLS_RTL);
break;
}
}
}
};
__decorate([
Property(null)
], HScroll.prototype, "scrollStep", void 0);
HScroll = __decorate([
NotifyPropertyChanges
], HScroll);
var __decorate$1 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const CLS_ROOT$1 = 'e-vscroll';
const CLS_RTL$1 = 'e-rtl';
const CLS_DISABLE$1 = 'e-overlay';
const CLS_VSCROLLBAR = 'e-vscroll-bar';
const CLS_VSCROLLCON = 'e-vscroll-content';
const CLS_NAVARROW$1 = 'e-nav-arrow';
const CLS_NAVUPARROW = 'e-nav-up-arrow';
const CLS_NAVDOWNARROW = 'e-nav-down-arrow';
const CLS_VSCROLLNAV = 'e-scroll-nav';
const CLS_VSCROLLNAVUP = 'e-scroll-up-nav';
const CLS_VSCROLLNAVDOWN = 'e-scroll-down-nav';
const CLS_DEVICE$1 = 'e-scroll-device';
const CLS_OVERLAY$1 = 'e-scroll-overlay';
const CLS_UPOVERLAY = 'e-scroll-up-overlay';
const CLS_DOWNOVERLAY = 'e-scroll-down-overlay';
const OVERLAY_MAXWID$1 = 40;
/**
* VScroll module is introduces vertical scroller when content exceeds the current viewing area.
* It can be useful for the components like Toolbar, Tab which needs vertical scrolling alone.
* Hidden content can be view by touch moving or icon click.
* ```html
* <div id="scroll"/>
* <script>
* var scrollObj = new VScroll();
* scrollObj.appendTo("#scroll");
* </script>
* ```
*/
let VScroll = class VScroll extends Component {
/**
* Initializes a new instance of the VScroll class.
*
* @param {VScrollModel} options - Specifies VScroll model properties as options.
* @param {string | HTMLElement} element - Specifies the element for which vertical scrolling applies.
*/
constructor(options, element) {
super(options, element);
}
/**
* Initialize the event handler
*
* @private
* @returns {void}
*/
preRender() {
this.browser = Browser.info.name;
this.browserCheck = this.browser === 'mozilla';
this.isDevice = Browser.isDevice;
this.customStep = true;
const ele = this.element;
this.ieCheck = this.browser === 'edge' || this.browser === 'msie';
this.initialize();
if (ele.id === '') {
ele.id = getUniqueID('vscroll');
this.uniqueId = true;
}
ele.style.display = 'block';
if (this.enableRtl) {
ele.classList.add(CLS_RTL$1);
}
}
/**
* To Initialize the vertical scroll rendering
*
* @private
* @returns {void}
*/
render() {
this.touchModule = new Touch(this.element, { scroll: this.touchHandler.bind(this), swipe: this.swipeHandler.bind(this) });
EventHandler.add(this.scrollEle, 'scroll', this.scrollEventHandler, this);
if (!this.isDevice) {
this.createNavIcon(this.element);
}
else {
this.element.classList.add(CLS_DEVICE$1);
this.createOverlayElement(this.element);
}
this.setScrollState();
EventHandler.add(this.element, 'wheel', this.wheelEventHandler, this);
}
setScrollState() {
if (isNullOrUndefined(this.scrollStep) || this.scrollStep < 0) {
this.scrollStep = this.scrollEle.offsetHeight;
this.customStep = false;
}
else {
this.customStep = true;
}
}
initialize() {
const scrollCnt = createElement('div', { className: CLS_VSCROLLCON });
const scrollBar = createElement('div', { className: CLS_VSCROLLBAR });
scrollBar.setAttribute('tabindex', '-1');
const ele = this.element;
const innerEle = [].slice.call(ele.children);
for (const ele of innerEle) {
scrollCnt.appendChild(ele);
}
scrollBar.appendChild(scrollCnt);
ele.appendChild(scrollBar);
scrollBar.style.overflow = 'hidden';
this.scrollEle = scrollBar;
this.scrollItems = scrollCnt;
}
getPersistData() {
const keyEntity = ['scrollStep'];
return this.addOnPersist(keyEntity);
}
/**
* Returns the current module name.
*
* @returns {string} - It returns the current module name.
* @private
*/
getModuleName() {
return 'vScroll';
}
/**
* Removes the control from the DOM and also removes all its related events.
*
* @returns {void}
*/
destroy() {
const el = this.element;
el.style.display = '';
removeClass([this.element], [CLS_ROOT$1, CLS_DEVICE$1, CLS_RTL$1]);
const navs = selectAll('.e-' + el.id + '_nav.' + CLS_VSCROLLNAV, el);
const overlays = selectAll('.' + CLS_OVERLAY$1, el);
[].slice.call(overlays).forEach((ele) => {
detach(ele);
});
for (const elem of [].slice.call(this.scrollItems.children)) {
el.appendChild(elem);
}
if (this.uniqueId) {
this.element.removeAttribute('id');
}
detach(this.scrollEle);
if (navs.length > 0) {
detach(navs[0]);
if (!isNullOrUndefined(navs[1])) {
detach(navs[1]);
}
}
EventHandler.remove(this.scrollEle, 'scroll', this.scrollEventHandler);
this.touchModule.destroy();
this.touchModule = null;
super.destroy();
}
/**
* Specifies the value to disable/enable the VScroll component.
* When set to `true` , the component will be disabled.
*
* @param {boolean} value - Based on this Boolean value, VScroll will be enabled (false) or disabled (true).
* @returns {void}.
*/
disable(value) {
const navEle = selectAll('.e-scroll-nav:not(.' + CLS_DISABLE$1 + ')', this.element);
if (value) {
this.element.classList.add(CLS_DISABLE$1);
}
else {
this.element.classList.remove(CLS_DISABLE$1);
}
[].slice.call(navEle).forEach((el) => {
el.setAttribute('tabindex', !value ? '0' : '-1');
});
}
createOverlayElement(element) {
const id = element.id.concat('_nav');
const downOverlayEle = createElement('div', { className: CLS_OVERLAY$1 + ' ' + CLS_DOWNOVERLAY });
const clsDown = 'e-' + element.id.concat('_nav ' + CLS_VSCROLLNAV + ' ' + CLS_VSCROLLNAVDOWN);
const downEle = createElement('div', { id: id.concat('down'), className: clsDown });
const navItem = createElement('div', { className: CLS_NAVDOWNARROW + ' ' + CLS_NAVARROW$1 + ' e-icons' });
downEle.appendChild(navItem);
const upEle = createElement('div', { className: CLS_OVERLAY$1 + ' ' + CLS_UPOVERLAY });
if (this.ieCheck) {
downEle.classList.add('e-ie-align');
}
element.appendChild(downOverlayEle);
element.appendChild(downEle);
element.insertBefore(upEle, element.firstChild);
this.eventBinding([downEle]);
}
createNavIcon(element) {
const id = element.id.concat('_nav');
const clsDown = 'e-' + element.id.concat('_nav ' + CLS_VSCROLLNAV + ' ' + CLS_VSCROLLNAVDOWN);
const nav = createElement('div', { id: id.concat('_down'), className: clsDown });
nav.setAttribute('aria-disabled', 'false');
const navItem = createElement('div', { className: CLS_NAVDOWNARROW + ' ' + CLS_NAVARROW$1 + ' e-icons' });
const clsUp = 'e-' + element.id.concat('_nav ' + CLS_VSCROLLNAV + ' ' + CLS_VSCROLLNAVUP);
const navElement = createElement('div', { id: id.concat('_up'), className: clsUp + ' ' + CLS_DISABLE$1 });
navElement.setAttribute('aria-disabled', 'true');
const navUpItem = createElement('div', { className: CLS_NAVUPARROW + ' ' + CLS_NAVARROW$1 + ' e-icons' });
navElement.appendChild(navUpItem);
nav.appendChild(navItem);
nav.setAttribute('tabindex', '0');
element.appendChild(nav);
element.insertBefore(navElement, element.firstChild);
if (this.ieCheck) {
nav.classList.add('e-ie-align');
navElement.classList.add('e-ie-align');
}
this.eventBinding([nav, navElement]);
}
onKeyPress(ev) {
if (ev.key === 'Enter') {
const timeoutFun = () => {
this.keyTimeout = true;
this.eleScrolling(10, ev.target, true);
};
this.keyTimer = window.setTimeout(() => {
timeoutFun();
}, 100);
}
}
onKeyUp(ev) {
if (ev.key !== 'Enter') {
return;
}
if (this.keyTimeout) {
this.keyTimeout = false;
}
else {
ev.target.click();
}
clearTimeout(this.keyTimer);
}
eventBinding(element) {
[].slice.call(element).forEach((ele) => {
new Touch(ele, { tapHold: this.tabHoldHandler.bind(this), tapHoldThreshold: 500 });
ele.addEventListener('keydown', this.onKeyPress.bind(this));
ele.addEventListener('keyup', this.onKeyUp.bind(this));
ele.addEventListener('mouseup', this.repeatScroll.bind(this));
ele.addEventListener('touchend', this.repeatScroll.bind(this));
ele.addEventListener('contextmenu', (e) => {
e.preventDefault();
});
EventHandler.add(ele, 'click', this.clickEventHandler, this);
});
}
repeatScroll() {
clearInterval(this.timeout);
}
tabHoldHandler(ev) {
let trgt = ev.originalEvent.target;
trgt = this.contains(trgt, CLS_VSCROLLNAV) ? trgt.firstElementChild : trgt;
const scrollDistance = 10;
const timeoutFun = () => {
this.eleScrolling(scrollDistance, trgt, true);
};
this.timeout = window.setInterval(() => {
timeoutFun();
}, 50);
}
contains(element, className) {
return element.classList.contains(className);
}
eleScrolling(scrollDis, trgt, isContinuous) {
let classList = trgt.classList;
if (classList.contains(CLS_VSCROLLNAV)) {
classList = trgt.querySelector('.' + CLS_NAVARROW$1).classList;
}
if (classList.contains(CLS_NAVDOWNARROW)) {
this.frameScrollRequest(scrollDis, 'add', isContinuous);
}
else if (classList.contains(CLS_NAVUPARROW)) {
this.frameScrollRequest(scrollDis, '', isContinuous);
}
}
clickEventHandler(event) {
this.eleScrolling(this.scrollStep, event.target, false);
}
wheelEventHandler(e) {
e.preventDefault();
this.frameScrollRequest(this.scrollStep, (e.deltaY > 0 ? 'add' : ''), false);
}
swipeHandler(e) {
const swipeElement = this.scrollEle;
let distance;
if (e.velocity <= 1) {
distance = e.distanceY / (e.velocity * 10);
}
else {
distance = e.distanceY / e.velocity;
}
let start = 0.5;
const animate = () => {
const step = Math.sin(start);
if (step <= 0) {
window.cancelAnimationFrame(step);
}
else {
if (e.swipeDirection === 'Up') {
swipeElement.scrollTop += distance * step;
}
else if (e.swipeDirection === 'Down') {
swipeElement.scrollTop -= distance * step;
}
start -= 0.02;
window.requestAnimationFrame(animate);
}
};
animate();
}
scrollUpdating(scrollVal, action) {
if (action === 'add') {
this.scrollEle.scrollTop += scrollVal;
}
else {
this.scrollEle.scrollTop -= scrollVal;
}
}
frameScrollRequest(scrollValue, action, isContinuous) {
const step = 10;
if (isContinuous) {
this.scrollUpdating(scrollValue, action);
return;
}
if (!this.customStep) {
[].slice.call(selectAll('.' + CLS_OVERLAY$1, this.element)).forEach((el) => {
scrollValue -= el.offsetHeight;
});
}
const animate = () => {
if (scrollValue < step) {
window.cancelAnimationFrame(step);
}
else {
this.scrollUpdating(step, action);
scrollValue -= step;
window.requestAnimationFrame(animate);
}
};
animate();
}
touchHandler(e) {
const el = this.scrollEle;
const distance = e.distanceY;
if (e.scrollDirection === 'Up') {
el.scrollTop = el.scrollTop + distance;
}
else if (e.scrollDirection === 'Down') {
el.scrollTop = el.scrollTop - distance;
}
}
arrowDisabling(addDisableCls, removeDisableCls) {
if (this.isDevice) {
const arrowEle = isNullOrUndefined(addDisableCls) ? removeDisableCls : addDisableCls;
const arrowIcon = arrowEle.querySelector('.' + CLS_NAVARROW$1);
if (isNullOrUndefined(addDisableCls)) {
classList(arrowIcon, [CLS_NAVDOWNARROW], [CLS_NAVUPARROW]);
}
else {
classList(arrowIcon, [CLS_NAVUPARROW], [CLS_NAVDOWNARROW]);
}
}
else {
addDisableCls.classList.add(CLS_DISABLE$1);
addDisableCls.setAttribute('aria-disabled', 'true');
addDisableCls.removeAttribute('tabindex');
removeDisableCls.classList.remove(CLS_DISABLE$1);
removeDisableCls.setAttribute('aria-disabled', 'false');
removeDisableCls.setAttribute('tabindex', '0');
}
this.repeatScroll();
}
scrollEventHandler(e) {
const target = e.target;
const height = target.offsetHeight;
const navUpEle = this.element.querySelector('.' + CLS_VSCROLLNAVUP);
const navDownEle = this.element.querySelector('.' + CLS_VSCROLLNAVDOWN);
const upOverlay = this.element.querySelector('.' + CLS_UPOVERLAY);
const downOverlay = this.element.querySelector('.' + CLS_DOWNOVERLAY);
let scrollTop = target.scrollTop;
if (scrollTop <= 0) {
scrollTop = -scrollTop;
}
if (this.isDevice) {
if (scrollTop < OVERLAY_MAXWID$1) {
upOverlay.style.height = scrollTop + 'px';
}
else {
upOverlay.style.height = '40px';
}
if ((target.scrollHeight - Math.ceil(height + scrollTop)) < OVERLAY_MAXWID$1) {
downOverlay.style.height = (target.scrollHeight - Math.ceil(height + scrollTop)) + 'px';
}
else {
downOverlay.style.height = '40px';
}
}
if (scrollTop === 0) {
this.arrowDisabling(navUpEle, navDownEle);
}
else if (Math.ceil(height + scrollTop + .1) >= target.scrollHeight) {
this.arrowDisabling(navDownEle, navUpEle);
}
else {
const disEle = this.element.querySelector('.' + CLS_VSCROLLNAV + '.' + CLS_DISABLE$1);
if (disEle) {
disEle.classList.remove(CLS_DISABLE$1);
disEle.setAttribute('aria-disabled', 'false');
disEle.setAttribute('tabindex', '0');
}
}
}
/**
* Gets called when the model property changes.The data that describes the old and new values of property that changed.
*
* @param {VScrollModel} newProp - It contains the new value of data.
* @param {VScrollModel} oldProp - It contains the old value of data.
* @returns {void}
* @private
*/
onPropertyChanged(newProp, oldProp) {
for (const prop of Object.keys(newProp)) {
switch (prop) {
case 'scrollStep':
this.setScrollState();
break;
case 'enableRtl':
if (newProp.enableRtl) {
this.element.classList.add(CLS_RTL$1);
}
else {
this.element.classList.remove(CLS_RTL$1);
}
break;
}
}
}
};
__decorate$1([
Property(null)
], VScroll.prototype, "scrollStep", void 0);
VScroll = __decorate$1([
NotifyPropertyChanges
], VScroll);
/**
* Used to add scroll in menu.
*
* @param {createElementType} createElement - Specifies the create element model
* @param {HTMLElement} container - Specifies the element container
* @param {HTMLElement} content - Specifies the content element
* @param {string} scrollType - Specifies the scroll type
* @param {boolean} enableRtl - Specifies the enable RTL property
* @param {boolean} offset - Specifies the offset value
* @returns {HTMLElement} - Element
* @hidden
*/
function addScrolling(createElement, container, content, scrollType, enableRtl, offset) {
let containerOffset;
let contentOffset;
const parentElem = container.parentElement;
if (scrollType === 'vscroll') {
containerOffset = offset || container.getBoundingClientRect().height;
contentOffset = content.getBoundingClientRect().height;
}
else {
containerOffset = container.getBoundingClientRect().width;
contentOffset = content.getBoundingClientRect().width;
}
if (containerOffset < contentOffset) {
return createScrollbar(createElement, container, content, scrollType, enableRtl, offset);
}
else if (parentElem) {
const width = parentElem.getBoundingClientRect().width;
if (width < containerOffset && scrollType === 'hscroll') {
contentOffset = width;
container.style.maxWidth = width + 'px';
return createScrollbar(createElement, container, content, scrollType, enableRtl, offset);
}
return content;
}
else {
return content;
}
}
/**
* Used to create scroll bar in menu.
*
* @param {createElementType} createElement - Specifies the create element model
* @param {HTMLElement} container - Specifies the element container
* @param {HTMLElement} content - Specifies the content element
* @param {string} scrollType - Specifies the scroll type
* @param {boolean} enableRtl - Specifies the enable RTL property
* @param {boolean} offset - Specifies the offset value
* @returns {HTMLElement} - Element
* @hidden
*/
function createScrollbar(createElement, container, content, scrollType, enableRtl, offset) {
const scrollEle = createElement('div', { className: 'e-menu-' + scrollType });
container.appendChild(scrollEle);
scrollEle.appendChild(content);
if (offset) {
scrollEle.style.overflow = 'hidden';
scrollEle.style.height = offset + 'px';
}
else {
scrollEle.style.maxHeight = container.style.maxHeight;
container.style.overflow = 'hidden';
}
let scrollObj;
if (scrollType === 'vscroll') {
scrollObj = new VScroll({ enableRtl: enableRtl }, scrollEle);
scrollObj.scrollStep = select('.e-' + scrollType + '-bar', container).offsetHeight / 2;
}
else {
scrollObj = new HScroll({ enableRtl: enableRtl }, scrollEle);
scrollObj.scrollStep = select('.e-' + scrollType + '-bar', container).offsetWidth;
}
return scrollEle;
}
/**
* Used to destroy the scroll option.
*
* @param {VScroll | HScroll} scrollObj - Specifies the scroller object
* @param {Element} element - Specifies the element
* @param {HTMLElement} skipEle - Specifies the skip element
* @returns {void}
* @hidden
*/
function destroyScroll(scrollObj, element, skipEle) {
if (scrollObj) {
const menu = select('.e-menu-parent', element);
if (menu) {
if (!skipEle || skipEle === menu) {
scrollObj.destroy();
element.parentElement.appendChild(menu);
detach(element);
}
}
else {
scrollObj.destroy();
detach(element);
}
}
}
var __decorate$2 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const ENTER = 'enter';
const ESCAPE = 'escape';
const FOCUSED = 'e-focused';
const HEADER = 'e-menu-header';
const SELECTED = 'e-selected';
const SEPARATOR = 'e-separator';
const UPARROW = 'uparrow';
const DOWNARROW = 'downarrow';
const LEFTARROW = 'leftarrow';
const RIGHTARROW = 'rightarrow';
const HOME = 'home';
const END = 'end';
const TAB = 'tab';
const CARET = 'e-caret';
const ITEM = 'e-menu-item';
const DISABLED = 'e-disabled';
const HIDE = 'e-menu-hide';
const ICONS = 'e-icons';
const RTL = 'e-rtl';
const POPUP = 'e-menu-popup';
const TEMPLATE_PROPERTY = 'Template';
/**
* Configures the field options of the Menu.
*/
class FieldSettings extends ChildProperty {
}
__decorate$2([
Property('id')
], FieldSettings.prototype, "itemId", void 0);
__decorate$2([
Property('parentId')
], FieldSettings.prototype, "parentId", void 0);
__decorate$2([
Property('text')
], FieldSettings.prototype, "text", void 0);
__decorate$2([
Property('iconCss')
], FieldSettings.prototype, "iconCss", void 0);
__decorate$2([
Property('url')
], FieldSettings.prototype, "url", void 0);
__decorate$2([
Property('separator')
], FieldSettings.prototype, "separator", void 0);
__decorate$2([
Property('items')
], FieldSettings.prototype, "children", void 0);
/**
* Specifies menu items.
*/
class MenuItem extends ChildProperty {
}
__decorate$2([
Property(null)
], MenuItem.prototype, "iconCss", void 0);
__decorate$2([
Property('')
], MenuItem.prototype, "id", void 0);
__decorate$2([
Property(false)
], MenuItem.prototype, "separator", void 0);
__decorate$2([
Collection([], MenuItem)
], MenuItem.prototype, "items", void 0);
__decorate$2([
Property('')
], MenuItem.prototype, "text", void 0);
__decorate$2([
Property('')
], MenuItem.prototype, "url", void 0);
__decorate$2([
Property()
], MenuItem.prototype, "htmlAttributes", void 0);
/**
* Animation configuration settings.
*/
class MenuAnimationSettings extends ChildProperty {
}
__decorate$2([
Property('SlideDown')
], MenuAnimationSettings.prototype, "effect", void 0);
__decorate$2([
Property(400)
], MenuAnimationSettings.prototype, "duration", void 0);
__decorate$2([
Property('ease')
], MenuAnimationSettings.prototype, "easing", void 0);
/**
* Base class for Menu and ContextMenu components.
*
* @private
*/
let MenuBase = class MenuBase extends Component {
/**
* Constructor for creating the widget.
*
* @private
* @param {MenuBaseModel} options - Specifies the menu base model
* @param {string | HTMLUListElement} element - Specifies the element
*/
constructor(options, element) {
super(options, element);
this.navIdx = [];
this.animation = new Animation({});
this.isTapHold = false;
this.tempItem = [];
this.showSubMenuOn = 'Auto';
this.isOpenCalled = false;
this.isAnimationNone = false;
this.isKBDAction = false;
}
/**
* Initialized third party configuration settings.
*
* @private
* @returns {void}
*/
preRender() {
if (!this.isMenu) {
let ul;
if (this.element.tagName === 'EJS-CONTEXTMENU') {
ul = this.createElement('ul', {
id: getUniqueID(this.getModuleName()), className: 'e-control e-lib e-' + this.getModuleName()
});
const ejInst = getValue('ej2_instances', this.element);
removeClass([this.element], ['e-control', 'e-lib', 'e-' + this.getModuleName()]);
this.clonedElement = this.element;
this.element = ul;
setValue('ej2_instances', ejInst, this.element);
}
else {
ul = this.createElement('ul', { id: getUniqueID(this.getModuleName()) });
append([].slice.call(this.element.cloneNode(true).children), ul);
const refEle = this.element.nextElementSibling;
if (refEle) {
this.element.parentElement.insertBefore(ul, refEle);
}
else {
this.element.parentElement.appendChild(ul);
}
this.clonedElement = ul;
}
this.clonedElement.style.display = 'none';
}
if (this.element.tagName === 'EJS-MENU') {
let ele = this.element;
const ejInstance = getValue('ej2_instances', ele);
const ul = this.createElement('ul');
const wrapper = this.createElement('EJS-MENU', { className: 'e-' + this.getModuleName() + '-wrapper' });
for (let idx = 0, len = ele.attributes.length; idx < len; idx++) {
ul.setAttribute(ele.attributes[idx].nodeName, ele.attributes[idx].nodeValue);
}
ele.parentNode.insertBefore(wrapper, ele);
detach(ele);
ele = ul;
wrapper.appendChild(ele);
setValue('ej2_instances', ejInstance, ele);
this.clonedElement = wrapper;
this.element = ele;
if (!this.element.id) {
this.element.id = getUniqueID(this.getModuleName());
}
}
}
/**
* Initialize the control rendering.
*
* @private
* @returns {void}
*/
render() {
this.initialize();
this.renderItems();
this.wireEvents();
this.renderComplete();
const wrapper = this.getWrapper();
// eslint-disable-next-line
if (this.template && this.enableScrolling && (this.isReact || this.isAngular)) {
requestAnimationFrame(() => {
addScrolling(this.createElement, wrapper, this.element, 'hscroll', this.enableRtl);
});
}
}
enableTouchScroll(scrollList) {
let touchStartY = 0;
this.touchStartFn = (e) => {
touchStartY = e.touches[0].clientY;
};
this.touchMoveFn = (e) => {
const touchEndY = e.touches[0].clientY;
const touchDiff = touchStartY - touchEndY;
const atTop = scrollList.scrollTop === 0;
const atBottom = scrollList.scrollTop + scrollList.clientHeight === scrollList.scrollHeight;
if ((atTop && touchDiff < 0) || (atBottom && touchDiff > 0)) {
e.preventDefault();
}
touchStartY = touchEndY;
};
scrollList.addEventListener('touchstart', this.touchStartFn, { passive: false });
scrollList.addEventListener('touchmove', this.touchMoveFn, { passive: false });
}
touchOutsideHandler(e) {
const target = e.target;
if (!closest(target, '.e-' + this.getModuleName() + '-wrapper')) {
this.closeMenu();
}
}
initialize() {
let wrapper = this.getWrapper();
if (!wrapper) {
wrapper = this.createElement('div', { className: 'e-' + this.getModuleName() + '-wrapper' });
if (this.isMenu) {
this.element.parentElement.insertBefore(wrapper, this.element);
}
else {
document.body.appendChild(wrapper);
}
}
if (this.cssClass) {
addClass([wrapper], this.cssClass.replace(/\s+/g, ' ').trim().split(' '));
}
if (this.enableRtl) {
wrapper.classList.add(RTL);
}
wrapper.appendChild(this.element);
if (this.isMenu && this.hamburgerMode) {
if (!this.target) {
this.createHeaderContainer(wrapper);
}
}
this.defaultOption = this.showItemOnClick;
}
renderItems() {
if (!this.items.length) {
const items = ListBase.createJsonFromElement(this.element, { fields: { child: 'items' } });
this.setProperties({ items: items }, true);
if (isBlazor() && !this.isMenu) {
this.element = this.removeChildElement(this.element);
}
else {
this.element.innerHTML = '';
}
}
const ul = this.createItems(this.items);
append(Array.prototype.slice.call(ul.children), this.element);
this.element.classList.add('e-menu-parent');
if (this.isMenu) {
if (!this.hamburgerMode && this.element.classList.contains('e-vertical')) {
this.setBlankIconStyle(this.element);
}
if (this.enableScrolling) {
const wrapper = this.getWrapper();
if (this.element.classList.contains('e-vertical')) {
addScrolling(this.createElement, wrapper, this.element, 'vscroll', this.enableRtl);
}
else {
addScrolling(this.createElement, wrapper, this.element, 'hscroll', this.enableRtl);
}
}
}
else {
this.element.parentElement.setAttribute('role', 'dialog');
this.element.parentElement.setAttribute('aria-label', 'context menu');
}
}
wireEvents() {
const wrapper = this.getWrapper();
if (this.target) {
let target;
const targetElems = selectAll(this.target);
for (let i = 0, len = targetElems.length; i < len; i++) {
target = targetElems[i];
if (this.isMenu) {
EventHandler.add(target, 'click', this.menuHeaderClickHandler, this);
}
else {
if (Browser.isIos) {
new Touch(target, { tapHold: this.touchHandler.bind(this) });
}
else {
EventHandler.add(target, 'contextmenu', this.cmenuHandler, this);
}
}
}
this.targetElement = target;
if (!this.isMenu) {
EventHandler.add(this.targetElement, 'scroll', this.scrollHandler, this);
for (const parent of getScrollableParent(this.targetElement)) {
EventHandler.add(parent, 'scroll', this.scrollHandler, this);
}
}
}
if (!Browser.isDevice) {
this.delegateMoverHandler = this.moverHandler.bind(this);
this.delegateMouseDownHandler = this.mouseDownHandler.bind(this);
EventHandler.add(this.isMenu ? document : wrapper, 'mouseover', this.delegateMoverHandler, this);
EventHandler.add(document, 'mousedown', this.delegateMouseDownHandler, this);
EventHandler.add(document, 'keydown', this.domKeyHandler, this);
if (!this.isMenu && !this.target) {
EventHandler.add(document, 'scroll', this.scrollHandler, this);
}
}
this.delegateClickHandler = this.clickHandler.bind(this);
EventHandler.add(document, 'click', this.delegateClickHandler, this);
this.wireKeyboardEvent(wrapper);
this.rippleFn = rippleEffect(wrapper, { selector: '.' + ITEM });
if (!this.isMenu && this.enableScrolling) {
this.enableTouchScroll(wrapper);
document.addEventListener('touchstart', this.touchOutsideHandler.bind(this), { passive: true });
}
}
wireKeyboardEvent(element) {
const keyConfigs = {
downarrow: DOWNARROW,
uparrow: UPARROW,
enter: ENTER,
leftarrow: LEFTARROW,
rightarrow: RIGHTARROW,
escape: ESCAPE
};
if (this.isMenu) {
keyConfigs.home = HOME;
keyConfigs.end = END;
keyConfigs.tab = TAB;
}
new KeyboardEvents(element, {
keyAction: this.keyBoardHandler.bind(this),
keyConfigs: keyConfigs
});
}
mouseDownHandler(e) {
if (closest(e.target, '.e-' + this.getModuleName() + '-wrapper') !== this.getWrapper()
&& (!closest(e.target, '.e-' + this.getModuleName() + '-popup'))) {
this.closeMenu(this.isMenu ? null : this.navIdx.length, e);
}
}
keyHandler(e) {
if (e.keyCode === 38 || e.keyCode === 40) {
if (e.target && (e.target.classList.contains('e-contextmenu') || e.target.classList.contains('e-menu-item'))) {
e.preventDefault();
}
}
}
domKeyHandler(e) {
if (e.keyCode === 27) {
if (this.isMenuVisible()) {
e.stopImmediatePropagation();
}
e.action = ESCAPE;
this.leftEscKeyHandler(e);
}
}
keyBoardHandler(e) {
let actionName = '';
const trgt = e.target;
let actionNeeded = this.isMenu && !this.hamburgerMode && !this.element.classList.contains('e-vertical')
&& this.navIdx.length < 1;
e.preventDefault();
if (this.enableScrolling && e.keyCode === 13 && trgt.classList.contains('e-scroll-nav')) {
this.removeLIStateByClass([FOCUSED, SELECTED], [closest(trgt, '.e-' + this.getModuleName() + '-wrapper')]);
}
this.isKBDAction = true;
if (actionNeeded) {
switch (e.action) {
case RIGHTARROW:
actionName = RIGHTARROW;
e.action = DOWNARROW;
break;
case LEFTARROW:
actionName = LEFTARROW;
e.action = UPARROW;
break;
case DOWNARROW:
actionName = DOWNARROW;
e.action = RIGHTARROW;
break;
case UPARROW:
actionName = UPARROW;
e.action = '';
break;
}
}
else if (this.enableRtl) {
switch (e.action) {
case LEFTARROW:
actionNeeded = true;
actionName = LEFTARROW;
e.action = RIGHTARROW;
break;
case RIGHTARROW:
actionNeeded = true;
actionName = RIGHTARROW;
e.action = LEFTARROW;
break;
}
}
switch (e.action) {
case DOWNARROW:
case UPARROW:
case END:
case HOME:
case TAB:
this.upDownKeyHandler(e);
break;
case RIGHTARROW:
this.rightEnterKeyHandler(e);
break;
case LEFTARROW:
this.leftEscKeyHandler(e);
break;
case ENTER:
if (this.hamburgerMode && trgt.tagName === 'SPAN' && trgt.classList.contains('e-menu-icon')) {
this.menuHeaderClickHandler(e);
}
else {
this.rightEnterKeyHandler(e);
}
break;
}
if (this.isAnimationNone) {
this.isKBDAction = false;
}
if (actionNeeded) {
e.action = actionName;
}
}
upDownKeyHandler(e) {
const cul = this.getUlByNavIdx();
const defaultIdx = (e.action === DOWNARROW || e.action === HOME || e.action === TAB) ? 0 : cul.childElementCount - 1;
let fliIdx = defaultIdx;
const fli = this.getLIByClass(cul, FOCUSED);
if (fli) {
if (e.action !== END && e.action !== HOME) {
fliIdx = this.getIdx(cul, fli);
}
fli.classList.remove(FOCUSED);
if (e.action !== END && e.action !== HOME) {
if (e.action === DOWNARROW) {
fliIdx++;
}
else {
fliIdx--;
}
if (fliIdx === (e.action === DOWNARROW ? cul.childElementCount : -1)) {
fliIdx = defaultIdx;
}
}
}
const cli = cul.children[fliIdx];
fliIdx = this.isValidLI(cli, fliIdx, e.action);
cul.children[fliIdx].classList.add(FOCUSED);
cul.children[fliIdx].focus();
}
isValidLI(cli, index, action) {
const cul = this.getUlByNavIdx();
const defaultIdx = (action === DOWNARROW || action === HOME || action === TAB) ? 0 : cul.childElementCount - 1;
if (cli.classList.contains(SEPARATOR) || cli.classList.contains(DISABLED) || cli.classList.contains(HIDE)) {
if (action === DOWNARROW && index === cul.childElementCount - 1) {
index = defaultIdx;
}
else if (action === UPARROW && index === 0) {
index = defaultIdx;
}
else if ((action === DOWNARROW) || (action === RIGHTARROW)) {
index++;
}
else if (action === 'tab' && cli.classList.contains(SEPARATOR)) {
index++;
}
else {
index--;
}
}
cli = cul.children[index];
if (cli && (cli.classList.contains(SEPARATOR) || cli.classList.contains(DISABLED) || cli.classList.contains(HIDE))) {
index = this.isValidLI(cli, index, action);
}
return index;
}
getUlByNavIdx(navIdxLen = this.navIdx.length) {
if (this.isMenu) {
let popup = [this.getWrapper()].concat([].slice.call(selectAll('.' + POPUP)))[navIdxLen];
const popups = [];
const allPopup = selectAll('.' + POPUP);
allPopup.forEach((elem) => {
if (this.element.id === elem.id.split('-')[2] || elem.id.split('-')[2] + '-' + elem.id.split('-')[3]) {
popups.push(elem);
}
});
popup = [this.getWrapper()].concat([].slice.call(popups))[navIdxLen];
return isNullOrUndefined(popup) ? null : select('.e-menu-parent', popup);
}
else {
if (!document.body.contains(this.element) && navIdxLen === 0) {
return null;
}
return this.getWrapper().children[navIdxLen];
}
}
rightEnterKeyHandler(e) {
let eventArgs;
const cul = this.getUlByNavIdx();
const fli = this.getLIByClass(cul, FOCUSED);
if (fli) {
const fliIdx = this.getIdx(cul, fli);
const navIdx = this.navIdx.concat(fliIdx);
const item = this.getItem(navIdx);
if (item.items.length) {
this.navIdx.push(fliIdx);
this.keyType = 'right';
this.action = e.action;
this.openMenu(fli, item, -1, -1, e);
}
else {
if (e.action === ENTER) {
if (this.isMenu && this.navIdx.length === 0) {
this.removeLIStateByClass([SELECTED], [this.getWrapper()]);
}
else {
fli.classList.remove(FOCUSED);
}
fli.classList.add(SELECTED);
eventArgs = { element: fli, item: item, event: e };
this.trigger('select', eventArgs);
const aEle = fli.querySelector('.e-menu-url');
if (item.url && aEle) {
switch (aEle.getAttribute('target')) {
case '_blank':
window.open(item.url, '_blank');
break;
case '_parent':
window.parent.location.href = item.url;
break;
default:
window.location.href = item.url;
}
}
this.closeMenu(null, e);
const sli = this.getLIByClass(this.getUlByNavIdx(), SELECTED);
if (sli) {
sli.classList.add(FOCUSED);
sli.focus();
}
}
}
}
}
leftEscKeyHandler(e) {
if (this.navIdx.length) {
this.keyType = 'left';
this.closeMenu(this.navIdx.length, e);
}
else {
if (e.action === ESCAPE) {
this.closeMenu(null, e);
}
}
}
scrollHandler(e) {
this.closeMenu(null, e);
}
touchHandler(e) {
this.isTapHold = true;
this.cmenuHandler(e.originalEvent);
}
cmenuHandler(e) {
e.preventDefault();
this.currentTarget = e.target;
this.isCMenu = true;
this.pageX = e.changedTouches ? e.changedTouches[0].pageX + 1 : e.pageX + 1;
this.pageY = e.changedTouches ? e.changedTouches[0].pageY + 1 : e.pageY + 1;
this.closeMenu(null, e);
if (this.isCMenu) {
if (this.canOpen(e.target)) {
this.openMenu(null, null, this.pageY, this.pageX, e);
}
this.isCMenu = false;
}
}
// eslint:disable-next-line:max-func-body-length
closeMenu(ulIndex = 0, e = null, isIterated) {
if (this.isMenuVisible()) {
let sli;
let item;
const wrapper = this.getWrapper();
let beforeCloseArgs;
let items;
const popups = this.getPopups();
let isClose = false;
const cnt = this.isMenu ? popups.length + 1 : wrapper.childElementCount;
const ul = this.isMenu && cnt !== 1 ? select('.e-ul', popups[cnt - 2])
: selectAll('.e-menu-parent', wrapper)[cnt - 1];
if (this.isMenu && ul.classList.contains('e-menu')) {
sli = this.getLIByClass(ul, SELECTED);
if (sli) {
sli.classList.remove(SELECTED);
}
isClose = true;
}
if (!isClose) {
const liElem = e && e.target && this.getLI(e.target);
if (liElem) {
this.cli = liElem;
}
else {
this.cli = ul.children[0];
}
item = this.navIdx.length ? this.getItem(this.navIdx) : null;
items = item ? item.items : this.items;
beforeCloseArgs = { element: ul, parentItem: item, items: items, event: e, cancel: false, isFocused: true };
this.trigger('beforeClose', beforeCloseArgs, (observedCloseArgs) => {
let popupEle;
let closeArgs;
let popupId = '';
let popupObj;
const isOpen = !observedCloseArgs.cancel;
if (isOpen || this.isCMenu) {
if (this.isMenu) {
popupEle = closest(ul, '.' + POPUP);
if (this.hamburgerMode) {
popupEle.parentElement.style.minHeight = '';
closest(ul, '.e-menu-item').setAttribute('aria-expanded', 'false');
}
this.unWireKeyboardEvent(popupEle);
destroyScroll(getInstance(popupEle.children[0], VScroll), popupEle.children[0]);
popupObj = getInstance(popupEle, Popup);
popupObj.hide();
popupId = popupEle.id;
popupObj.destroy();
detach(popupEle);
}
else {
this.isContextMenuClosed = false;
this.toggleAnimation(ul, false);
}
closeArgs = { element: ul, parentItem: item, items: items };
this.trigger('onClose', closeArgs);
this.navIdx.pop();
if (this.navIdx.length === 0 && e && e.type === 'keyup') {
this.showSubMenu = false;
}
if (!this.isMenu) {
EventHandler.remove(ul, 'keydown', this.keyHandler);
if (this.keyType === 'right') {
this.keyType = '';
}
}
}
this.updateReactTemplate();
let trgtliId;
let closedLi;
let trgtLi;
const trgtpopUp = this.getWrapper() && this.getUlByNavIdx();
if (this.isCMenu) {
if (this.canOpen(e.target)) {
this.openMenu(null, null, this.pageY, this.pageX, e);
}
this.isCMenu = false;
}
if (this.isMenu && trgtpopUp && popupId.length) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const regExp = RegExp;
trgtliId = new regExp('(.*)-ej2menu-' + this.element.id + '-popup').exec(popupId)[1];
closedLi = trgtpopUp.querySelector('[id="' + trgtliId + '"]');
trgtLi = (liElem && trgtpopUp.querySelector('[id="' + liElem.id + '"]'));
}
else if (trgtpopUp) {
closedLi = trgtpopUp.querySelector('.e-menu-item.e-selected');
trgtLi = (liElem && trgtpopUp.querySelector('[id="' + liElem.id + '"]'));
}
const submenus = liElem && liElem.querySelectorAll('.e-menu-item');
if (isOpen && this.hamburgerMode && ulIndex && !(submenus.length)) {
this.afterCloseMenu(e);
}
else if (isOpen && !this.hamburgerMode && closedLi && !trgtLi && this.keyType !== 'left' && (this.navIdx.length || !this.isMenu && this.navIdx.length === 0)) {
let ele = (e && e.target.classList && (e.target.classList.contains('e-vscroll') || e.target.classList.contains('e-scroll-nav')))
? closest(e.target, '.e-menu-wrapper') : null;
if (ele) {
ele = ele.querySelector('.e-menu-item');
if (this.showItemOnClick || (ele && this.getIndex(ele.id, true).length <= this.navIdx.length)) {
this.closeMenu(this.navIdx[this.navIdx.length - 1], e, true);
}
}
else {
if (!(e && e.target.classList && e.target.classList.contains('e-nav-arrow'))) {
this.closeMenu(this.navIdx[this.navIdx.length - 1], e);
}
}
}
else if (isOpen && !isIterated && !ulIndex && ((this.hamburgerMode && this.navIdx.length) ||
this.navIdx.length === 1 && liElem && trgtpopUp !== liElem.parentElement)) {
this.closeMenu(null, e);
}
else if (isOpen && isNullOrUndefined(ulIndex) && this.navIdx.length) {
this.closeMenu(null, e);
}
else if (isOpen && !this.isMenu && !ulIndex && this.navIdx.length === 0 &&
!this.isMenusClosed && !this.isCmenuHover) {
this.isMenusClosed = true;
this.closeMenu(0, e);
}
else if (isOpen && this.isMenu && e && e.target &&
this.navIdx.length !== 0 && closest(e.target, '.e-menu-parent.e-control')) {
this.closeMenu(0, e);
}
else if (isOpen && !this.isMenu && selectAll('.e-menu-parent', wrapper)[ulIndex - 1] && e.which === 3) {
this.closeMenu(null, e);
}
else {
if (isOpen && (this.keyType === 'right' || this.keyType === 'click')) {
this.afterCloseMenu(e);
}
else {
const cul = this.getUlByNavIdx();
const sli = this.getLIByClass(cul, SELECTED);
if (sli) {
sli.setAttribute('aria-expanded', 'false');
sli.classList.remove(SELECTED);
if (observedCloseArgs.isFocused && liElem || this.keyType === 'left') {
sli.classList.add(FOCUSED);
if (!e.target || !e.target.classList.contains('e-edit-template')) {
sli.focus();
}
}
}
if (!isOpen && this.hamburgerMode && liElem && liElem.getAttribute('aria-expanded') === 'false' &&
liElem.getAttribute('aria-haspopup') === 'true') {
if (closest(liElem, '.e-menu-parent.e-control')) {
this.navIdx = [];
}
else {
this.navIdx.pop();
}
this.navIdx.push(this.cliIdx);
const item = this.getItem(this.navIdx);
liElem.setAttribute('aria-expanded', 'true');
this.openMenu(liElem, item, -1, -1, e);
}
}
if (this.navIdx.length < 1) {
if (this.showSubMenuOn === 'Hover' || this.showSubMenuOn === 'Click') {
this.showItemOnClick = this.defaultOption;
this.showSubMenuOn = 'Auto';
}
}
}
this.removeStateWrapper();
});
}
}
}
updateReactTemplate() {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (this.isReact && this.template && this.navIdx.length === 0) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let portals;
if (this.portals) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
portals = this.portals.splice(0, this.items.length);
}
this.clearTemplate(['template']);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.portals = portals;
this.renderReactTemplates();
}
}
getMenuItemModel(item, level) {
if (isNullOrUndefined(item)) {
return null;
}
if (isNullOrUndefined(level)) {
level = 0;
}
const fields = this.getFields(level);
return { text: item[fields.text], id: item[fields.id], items: item[fields.child], separator: item[fields.separator],
iconCss: item[fields.iconCss], url: item[fields.url] };
}
getPopups() {
const popups = [];
[].slice.call(document.querySelectorAll('.' + POPUP)).forEach((elem) => {
if (!isNullOrUndefined(elem.querySelector('.' + ITEM)) && this.getIndex(elem.querySelector('.' + ITEM).id, true).length) {
popups.push(elem);
}
});
return popups;
}
isMenuVisible() {
return (this.navIdx.length > 0 || (this.element.classList.contains('e-contextmenu') && isVisible(this.element).valueOf()));
}
canOpen(target) {
let canOpen = true;
if (this.filter) {
canOpen = false;
const filter = this.filter.split(' ');
for (let i = 0, len = filter.length; i < len; i++) {
if (closest(target, '.' + filter[i])) {
canOpen = true;
break;
}
}
}
return canOpen;
}
openMenu(li, item, top = 0, left = 0, e = null, target = this.targetElement) {
const wrapper = this.getWrapper();
this.lItem = li;
const elemId = this.element.id !== '' ? this.element.id : 'menu';
this.isMenusClosed = false;
if (isNullOrUndefined(top)) {
top = -1;
}
if (isNullOrUndefined(left)) {
left = -1;
}
if (li) {
this.uList = this.createItems(item[this.getField('children', this.navIdx.length - 1)]);
if (!this.isMenu && Browser.isDevice) {
wrapper.lastChild.style.display = 'none';
const data = {
text: item[this.getField('text')].toString(), iconCss: ICONS + ' e-previous'
};
if (this.template) {
item.iconCss = (item.iconCss || '') + ICONS + ' e-previous';
}
const hdata = new MenuItem(this.items[0], 'items', this.template ? item : data, true);
const hli = this.createItems([hdata]).children[0];
hli.classList.add(HEADER);
this.uList.insertBefore(hli, this.uList.children[0]);
}
if (this.isMenu) {
this.popupWrapper = this.createElement('div', {
className: 'e-' + this.getModuleName() + '-wrapper ' + POPUP, id: li.id + '-ej2menu-' + elemId + '-popup'
});
this.popupWrapper.setAttribute('role', 'navigation');
this.popupWrapper.setAttribute('aria-label', item.text + '-menu-popup');
if (this.hamburgerMode) {
top = li.offsetHeight;
li.appendChild(this.popupWrapper);
}
else {
document.body.appendChild(this.popupWrapper);
}
this.isNestedOrVertical = this.element.classList.contains('e-vertical') || this.navIdx.length !== 1;
this.popupObj = this.generatePopup(this.popupWrapper, this.uList, li, this.isNestedOrVertical);
if (this.template) {
this.renderReactTemplates();
}
if (this.hamburgerMode) {
this.calculateIndentSize(this.uList, li);
}
else {
if (this.cssClass) {
addClass([this.popupWrapper], this.cssClass.replace(/\s+/g, ' ').trim().split(' '));
}
this.popupObj.hide();
}
if (!this.hamburgerMode && !this.showItemOnClick && this.hoverDelay) {
window.clearInterval(this.timer);
this.timer = window.setTimeout(() => { this.triggerBeforeOpen(li, this.uList, item, e, 0, 0, 'menu'); }, this.hoverDelay);
}
else {
this.triggerBeforeOpen(li, this.uList, item, e, 0, 0, 'menu');
}
}
else {
this.uList.style.zIndex = this.element.style.zIndex;
wrapper.appendChild(this.uList);
if (!this.showItemOnClick && this.hoverDelay) {
window.clearInterval(this.timer);
this.timer = window.setTimeout(() => { this.triggerBeforeOpen(li, this.uList, item, e, top, left, 'none'); }, this.hoverDelay);
}
else {
this.triggerBeforeOpen(li, this.uList, item, e, top, left, 'none');
}
}
}
else {
this.uList = this.element;
this.uList.style.zIndex = getZindexPartial(target ? target : this.element).toString();
if (isNullOrUndefined(e)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const ev = document.createEvent('MouseEvents');
ev.initEvent('click', true, false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const targetEvent = this.copyObject(ev, {});
targetEvent.target = targetEvent.srcElement = target;
targetEvent.currentTarget = target;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.triggerBeforeOpen(li, this.uList, item, targetEvent, top, left, 'none');
}
else {
this.triggerBeforeOpen(li, this.uList, item, e, top, left, 'none');
}
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
copyObject(source, destination) {
// eslint-disable-next-line guard-for-in
for (const prop in source) {
destination[`${prop}`] = source[`${prop}`];
}
return destination;
}
calculateIndentSize(ul, li) {
const liStyle = getComputedStyle(li);
let liIndent = parseInt(liStyle.textIndent, 10);
if (this.navIdx.length < 2 && !li.classList.contains('e-blankicon')) {
liIndent *= 2;
}
else {
liIndent += (liIndent / 4);
}
ul.style.textIndent = liIndent + 'px';
const blankIconElem = ul.querySelectorAll('.e-blankicon');
if (blankIconElem && blankIconElem.length) {
const menuIconElem = ul.querySelector('.e-menu-icon');
const menuIconElemStyle = getComputedStyle(menuIconElem);
const blankIconIndent = (parseInt(menuIconElemStyle.marginRight, 10) + menuIconElem.offsetWidth + liIndent);
for (let i = 0; i < blankIconElem.length; i++) {
blankIconElem[i].style.textIndent = blankIconIndent + 'px';
}
}
}
generatePopup(popupWrapper, ul, li, isNestedOrVertical) {
const popupObj = new Popup(popupWrapper, {
actionOnScroll: this.hamburgerMode ? 'none' : 'reposition',
relateTo: li,
collision: this.hamburgerMode ? { X: 'none', Y: 'none' } : { X: isNestedOrVertical ||
this.enableRtl ? 'none' : 'flip', Y: 'fit' },
position: (isNestedOrVertical && !this.hamburgerMode) ? { X: 'right', Y: 'top' } : { X: 'left', Y: 'bottom' },
targetType: 'relative',
enableRtl: this.enableRtl,
content: ul,
open: () => {
const scrollEle = select('.e-menu-vscroll', popupObj.element);
if (scrollEle) {
scrollEle.style.height = 'inherit';
scrollEle.style.maxHeight = '';
}
const ul = select('.e-ul', popupObj.element);
popupObj.element.style.maxHeight = '';
ul.focus();
this.triggerOpen(ul);
}
});
return popupObj;
}
createHeaderContainer(wrapper) {
wrapper = wrapper || this.getWrapper();
const spanElem = this.createElement('span', { className: 'e-' + this.getModuleName() + '-header' });
const tempTitle = (this.enableHtmlSanitizer) ? SanitizeHtmlHelper.sanitize(this.title) : this.title;
const spanTitle = this.createElement('span', {
className: 'e-' + this.getModuleName() + '-title', innerHTML: tempTitle
});
const spanIcon = this.createElement('span', {
className: 'e-icons e-' + this.getModuleName() + '-icon', attrs: { 'tabindex': '0' }
});
spanElem.appendChild(spanTitle);
spanElem.appendChild(spanIcon);
wrapper.insertBefore(spanElem, this.element);
}
openHamburgerMenu(e) {
if (this.hamburgerMode) {
this.triggerBeforeOpen(null, this.element, null, e, 0, 0, 'hamburger');
}
}
closeHamburgerMenu(e) {
const beforeCloseArgs = { element: this.element, parentItem: null, event: e,
items: this.items, cancel: false };
this.trigger('beforeClose', beforeCloseArgs, (observedHamburgerCloseArgs) => {
if (!observedHamburgerCloseArgs.cancel) {
this.closeMenu(null, e);
this.element.classList.add('e-hide-menu');
this.trigger('onClose', { element: this.element, parentItem: null, items: this.items });
}
});
}
callFit(element, x, y, top, left) {
return fit(element, null, { X: x, Y: y }, { top: top, left: left });
}
triggerBeforeOpen(li, ul, item, e, top, left, type) {
const items = li ? item[this.getField('children', this.navIdx.length - 1)] : this.items;
const eventArgs = {
element: ul, items: items, parentItem: item, event: e, cancel: false, top: top, left: left, showSubMenuOn: 'Auto'
};
const menuType = type;
let observedElement;
this.trigger('beforeOpen', eventArgs, (observedOpenArgs) => {
switch (menuType) {
case 'menu':
if (!this.hamburgerMode) {
if (observedOpenArgs.showSubMenuOn !== 'Auto') {
this.showItemOnClick = !this.defaultOption;
this.showSubMenuOn = observedOpenArgs.showSubMenuOn;
}
this.top = observedOpenArgs.top;
this.left = observedOpenArgs.left;
}
this.popupWrapper.style.display = 'block';
if (!this.hamburgerMode) {
this.popupWrapper.style.maxHeight = this.popupWrapper.getBoundingClientRect().height + 'px';
if (this.enableScrolling) {
addScrolling(this.createElement, this.popupWrapper, this.uList, 'vscroll', this.enableRtl);
}
this.checkScrollOffset(e);
}
if (!this.hamburgerMode && !this.left && !this.top) {
this.popupObj.refreshPosition(this.lItem, true);
this.left = parseInt(this.popupWrapper.style.left, 10);
this.top = parseInt(this.popupWrapper.style.top, 10);
if (this.enableRtl) {
this.left =
this.isNestedOrVertical ? this.left - this.popupWrapper.offsetWidth - this.lItem.parentElement.offsetWidth + 2
: this.left - this.popupWrapper.offsetWidth + this.lItem.offsetWidth;
}
// eslint-disable-next-line
if (this.template && (this.isReact || this.isAngular)) {
requestAnimationFrame(() => {
this.collision();
this.popupWrapper.style.display = '';
});
}
else {
this.collision();
this.popupWrapper.style.display = '';
}
}
else {
this.popupObj.collision = { X: 'none', Y: 'none' };
this.popupWrapper.style.display = '';
}
break;
case 'none':
this.top = observedOpenArgs.top;
this.left = observedOpenArgs.left;
this.isContextMenuClosed = true;
observedElement = observedOpenArgs.element;
if (this.enableScrolling && this.isCMenu && observedElement && observedElement.parentElement) {
observedElement.style.height = observedElement.parentElement.style.height;
}
break;
case 'hamburger':
if (!observedOpenArgs.cancel) {
this.element.classList.remove('e-hide-menu');
this.triggerOpen(this.element);
}
break;
}
if (menuType !== 'hamburger') {
if (observedOpenArgs.cancel) {
if (this.isMenu) {
this.popupObj.destroy();
detach(this.popupWrapper);
}
else if (ul.className.indexOf('e-ul') > -1) {
detach(ul);
}
this.navIdx.pop();
}
else {
if (this.isMenu) {
if (this.hamburgerMode) {
this.popupWrapper.style.top = this.top + 'px';
this.popupWrapper.style.left = 0 + 'px';
this.toggleAnimation(this.popupWrapper);
}
else {
this.setBlankIconStyle(this.popupWrapper);
this.wireKeyboardEvent(this.popupWrapper);
rippleEffect(this.popupWrapper, { selector: '.' + ITEM });
this.popupWrapper.style.left = this.left + 'px';
this.popupWrapper.style.top = this.top + 'px';
const animationOptions = this.animationSettings.effect !== 'None' ? {
name: this.animationSettings.effect, duration: this.animationSettings.duration,
timingFunction: this.animationSettings.easing
} : null;
this.popupObj.show(animationOptions, this.lItem);
if (Browser.isDevice) {
this.popupWrapper.style.left = this.left + 'px';
}
}
}
else {
this.setBlankIconStyle(this.uList);
this.setPosition(this.lItem, this.uList, this.top, this.left);
this.toggleAnimation(this.uList);
}
}
}
if (this.keyType === 'right') {
let cul = this.getUlByNavIdx();
li.classList.remove(FOCUSED);
if (this.isMenu && this.navIdx.length === 1) {
this.removeLIStateByClass([SELECTED], [this.getWrapper()]);
}
li.classList.add(SELECTED);
if (this.action === ENTER) {
const eventArgs = { element: li, item: item, event: e };
this.trigger('select', eventArgs);
}
li.focus();
cul = this.getUlByNavIdx();
const index = this.isValidLI(cul.children[0], 0, this.action);
cul.children[index].classList.add(FOCUSED);
cul.children[index].focus();
}
});
}
collision() {
let collide;
collide = isCollide(this.popupWrapper, null, this.left, this.top);
if ((this.isNestedOrVertical || this.enableRtl) && (collide.indexOf('right') > -1
|| collide.indexOf('left') > -1)) {
this.popupObj.collision.X = 'none';
const offWidth = closest(this.lItem, '.e-' + this.getModuleName() + '-wrapper').offsetWidth;
this.left =
this.enableRtl ? calculatePosition(this.lItem, this.isNestedOrVertical ? 'right' : 'left', 'top').left
: this.left - this.popupWrapper.offsetWidth - offWidth + 2;
}
collide = isCollide(this.popupWrapper, null, this.left, this.top);
if (collide.indexOf('left') > -1 || collide.indexOf('right') > -1) {
this.left = this.callFit(this.popupWrapper, true, false, this.top, this.left).left;
}
this.popupWrapper.style.left = this.left + 'px';
}
setBlankIconStyle(menu) {
const blankIconList = [].slice.call(menu.getElementsByClassName('e-blankicon'));
if (!blankIconList.length) {
return;
}
const iconLi = menu.querySelector('.e-menu-item:not(.e-blankicon):not(.e-separator)');
if (!iconLi) {
return;
}
const icon = iconLi.querySelector('.e-menu-icon');
if (!icon) {
return;
}
const cssProp = this.enableRtl ? { padding: 'paddingRight', margin: 'marginLeft' } :
{ padding: 'paddingLeft', margin: 'marginRight' };
const iconCssProps = getComputedStyle(icon);
let iconSize = parseInt(iconCssProps.fontSize, 10);
if (!!parseInt(iconCssProps.width, 10) && parseInt(iconCssProps.width, 10) > iconSize) {
iconSize = parseInt(iconCssProps.width, 10);
}
// eslint:disable
const size = `${iconSize + parseInt(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
iconCssProps[cssProp.margin], 10) + parseInt(getComputedStyle(iconLi)[cssProp.padding], 10)}px`;
blankIconList.forEach((li) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
li.style[cssProp.padding] = size;
});
// eslint:enable
}
checkScrollOffset(e) {
const wrapper = this.getWrapper();
if (wrapper.children[0].classList.contains('e-menu-hscroll') && this.navIdx.length === 1) {
const trgt = isNullOrUndefined(e) ? this.element : closest(e.target, '.' + ITEM);
const offsetEle = select('.e-hscroll-bar', wrapper);
if (offsetEle.scrollLeft > trgt.offsetLeft) {
offsetEle.scrollLeft -= (offsetEle.scrollLeft - trgt.offsetLeft);
}
const offsetLeft = offsetEle.scrollLeft + offsetEle.offsetWidth;
const offsetRight = trgt.offsetLeft + trgt.offsetWidth;
if (offsetLeft < offsetRight) {
offsetEle.scrollLeft += (offsetRight - offsetLeft);
}
}
}
setPosition(li, ul, top, left, isOpen = false) {
const px = 'px';
this.toggleVisiblity(ul);
if (ul === this.element || (left > -1 && top > -1)) {
let collide = isCollide(ul, null, left, top);
if (collide.indexOf('right') > -1) {
left = left - ul.offsetWidth;
}
if (collide.indexOf('bottom') > -1) {
const offset = this.callFit(ul, false, true, top, left);
top = offset.top - 20;
if (top < 0) {
const newTop = (pageYOffset + document.documentElement.clientHeight) - ul.getBoundingClientRect().height;
if (newTop > -1) {
top = newTop;
}
}
}
collide = isCollide(ul, null, left, top);
if (collide.indexOf('left') > -1) {
const offset = this.callFit(ul, true, false, top, left);
left = offset.left;
}
}
else {
if (Browser.isDevice) {
if (!this.isMenu && this.enableScrolling) {
const menuScrollElement = document.querySelector('.e-menu-vscroll');
top = Number(menuScrollElement.style.top.replace('px', ''));
left = Number(menuScrollElement.style.left.replace('px', ''));
}
else {
top = Number(this.element.style.top.replace(px, ''));
left = Number(this.element.style.left.replace(px, ''));
}
}
else {
const x = this.enableRtl ? 'left' : 'right';
let offset = calculatePosition(li, x, 'top');
top = offset.top;
left = offset.left;
const collide = isCollide(ul, null, this.enableRtl ? left - ul.offsetWidth : left, top);
const xCollision = collide.indexOf('left') > -1 || collide.indexOf('right') > -1;
if (xCollision) {
offset = calculatePosition(li, this.enableRtl ? 'right' : 'left', 'top');
left = offset.left;
}
if (this.enableRtl || xCollision) {
left = (this.enableRtl && xCollision) ? left : left - ul.offsetWidth;
}
if (collide.indexOf('bottom') > -1 && (this.isMenu || !this.enableScrolling)) {
offset = this.callFit(ul, false, true, top, left);
top = offset.top;
}
}
}
this.toggleVisiblity(ul, false);
if ((this.isCMenu || this.isOpenCalled) && this.enableScrolling && ul) {
ul.style.height = '';
ul.style.top = '';
ul.style.left = '';
ul.style.width = '';
ul.style.position = '';
}
const wrapper = closest(this.element, '.e-' + this.getModuleName() + '-wrapper');
if (!this.isMenu && this.enableScrolling && ul && wrapper && wrapper.offsetHeight > 0) {
const menuVScroll = closest(ul, '.e-menu-vscroll');
ul.style.display = 'block';
if (menuVScroll) {
destroyScroll(getInstance(menuVScroll, VScroll), menuVScroll);
}
const cmenuWidth = Math.ceil(this.getMenuWidth(ul, ul.offsetWidth, this.enableRtl));
const cmenu = addScrolling(this.createElement, wrapper, ul, 'vscroll', this.enableRtl, wrapper.offsetHeight);
const newOffset = this.callFit(cmenu, false, true, top, left);
top = newOffset.top;
Object.assign(cmenu.style, {
top: `${top}px`,
left: `${left}px`,
width: `${cmenuWidth}px`,
position: 'absolute',
display: !isOpen ? 'none' : 'block'
});
}
else {
ul.style.top = top + px;
ul.style.left = left + px;
}
}
getMenuWidth(menuElement, width, isRtl) {
const caretIcon = menuElement.getElementsByClassName(CARET)[0];
if (caretIcon) {
width += parseInt(getComputedStyle(caretIcon)[isRtl ? 'marginRight' : 'marginLeft'], 10);
}
return width < 120 ? 120 : width;
}
toggleVisiblity(ul, isVisible = true) {
ul.style.visibility = isVisible ? 'hidden' : '';
ul.style.display = isVisible ? 'block' : 'none';
}
createItems(items) {
const level = this.navIdx ? this.navIdx.length : 0;
const fields = this.getFields(level);
const showIcon = this.hasField(items, this.getField('iconCss', level));
const listBaseOptions = {
showIcon: showIcon,
moduleName: 'menu',
fields: fields,
template: this.template,
itemNavigable: true,
itemCreating: (args) => {
if (!args.curData[args.fields[fields.id]]) {
args.curData[args.fields[fields.id]] = getUniqueID('menuitem');
}
if (isNullOrUndefined(args.curData.htmlAttributes)) {
Object.defineProperty(args.curData, 'htmlAttributes', {
value: {},
writable: true,
enumerable: true,
configurable: true
});
}
if (Browser.isIE) {
if (!args.curData.htmlAttributes.role) {
args.curData.htmlAttributes.role = 'menuitem';
}
if (!args.curData.htmlAttributes.tabindex) {
args.curData.htmlAttributes.tabindex = '-1';
}
}
else {
Object.assign(args.curData.htmlAttributes, {
role: args.curData.htmlAttributes.role || 'menuitem',
tabindex: args.curData.htmlAttributes.tabindex || '-1'
});
}
if (this.isMenu && !args.curData[this.getField('separator', level)]) {
if (!args.curData.htmlAttributes['aria-label']) {
args.curData.htmlAttributes['aria-label'] = args.curData[args.fields.text] ?
args.curData[args.fields.text] : args.curData[args.fields.id];
}
}
if (args.curData[args.fields[fields.iconCss]] === '') {
args.curData[args.fields[fields.iconCss]] = null;
}
},
itemCreated: (args) => {
if (args.curData[this.getField('separator', level)]) {
args.item.classList.add(SEPARATOR);
if (!args.curData.htmlAttributes.role) {
args.item.setAttribute('role', 'separator');
}
if (!args.curData.htmlAttributes.ariaLabel) {
args.item.setAttribute('aria-label', 'separator');
}
}
if (showIcon && !args.curData[args.fields.iconCss]
&& !args.curData[this.getField('separator', level)]) {
args.item.classList.add('e-blankicon');
}
if (args.curData[args.fields.child]
&& args.curData[args.fields.child].length) {
const span = this.createElement('span', { className: ICONS + ' ' + CARET });
args.item.appendChild(span);
args.item.setAttribute('aria-haspopup', 'true');
args.item.setAttribute('aria-expanded', 'false');
args.item.classList.add('e-menu-caret-icon');
}
if (this.template) {
args.item.setAttribute('id', args.curData[args.fields.id].toString());
args.item.removeAttribute('data-uid');
if (args.item.classList.contains('e-level-1')) {
args.item.classList.remove('e-level-1');
}
if (args.item.classList.contains('e-has-child')) {
args.item.classList.remove('e-has-child');
}
args.item.removeAttribute('aria-level');
}
const eventArgs = { item: args.curData, element: args.item };
this.trigger('beforeItemRender', eventArgs);
}
};
this.setProperties({ 'items': this.items }, true);
if (this.isMenu) {
listBaseOptions.templateID = this.element.id + TEMPLATE_PROPERTY;
}
const ul = ListBase.createList(this.createElement, items, listBaseOptions, !this.template, this);
ul.setAttribute('tabindex', '0');
if (this.isMenu) {
ul.setAttribute('role', 'menu');
}
else {
ul.setAttribute('role', 'menubar');
}
return ul;
}
moverHandler(e) {
const trgt = e.target;
this.liTrgt = trgt;
if (!this.isMenu) {
this.isCmenuHover = true;
}
const cli = this.getLI(trgt);
const wrapper = cli ? closest(cli, '.e-' + this.getModuleName() + '-wrapper') : this.getWrapper();
const hdrWrapper = this.getWrapper();
const regex = new RegExp('-ej2menu-(.*)-popup');
let ulId;
let isDifferentElem = false;
if (!wrapper) {
return;
}
if (wrapper.id !== '') {
ulId = regex.exec(wrapper.id)[1];
}
else {
ulId = wrapper.querySelector('ul').id;
}
if (ulId !== this.element.id) {
this.removeLIStateByClass([FOCUSED, SELECTED], [this.getWrapper()]);
if (this.navIdx.length) {
isDifferentElem = true;
}
else {
return;
}
}
if (cli && closest(cli, '.e-' + this.getModuleName() + '-wrapper') && !isDifferentElem) {
this.removeLIStateByClass([FOCUSED], this.isMenu ? [wrapper].concat(this.getPopups()) : [wrapper]);
this.removeLIStateByClass([FOCUSED], this.isMenu ? [hdrWrapper].concat(this.getPopups()) : [hdrWrapper]);
cli.classList.add(FOCUSED);
if (!this.showItemOnClick) {
this.clickHandler(e);
}
}
else if (this.isMenu && this.showItemOnClick && !isDifferentElem) {
this.removeLIStateByClass([FOCUSED], [wrapper].concat(this.getPopups()));
}
if (this.isMenu) {
if (!this.showItemOnClick && (trgt.parentElement !== wrapper && !closest(trgt, '.e-' + this.getModuleName() + '-popup'))
&& (!cli || (cli && !this.getIndex(cli.id, true).length)) && this.showSubMenuOn !== 'Hover') {
this.removeLIStateByClass([FOCUSED], [wrapper]);
if (this.navIdx.length) {
this.isClosed = true;
this.closeMenu(null, e);
}
}
else if (isDifferentElem && !this.showItemOnClick) {
if (this.navIdx.length) {
this.isClosed = true;
this.closeMenu(null, e);
}
}
if (!this.isClosed) {
this.removeStateWrapper();
}
this.isClosed = false;
}
if (!this.isMenu) {
this.isCmenuHover = false;
}
}
removeStateWrapper() {
if (this.liTrgt) {
const wrapper = closest(this.liTrgt, '.e-menu-vscroll');
if (this.liTrgt.tagName === 'DIV' && wrapper) {
this.removeLIStateByClass([FOCUSED, SELECTED], [wrapper]);
}
}
}
removeLIStateByClass(classList, element) {
let li;
for (let i = 0; i < element.length; i++) {
classList.forEach((className) => {
li = select('.' + className, element[i]);
if (li) {
li.classList.remove(className);
}
});
}
}
getField(propName, level = 0) {
const fieldName = this.fields[`${propName}`];
return typeof fieldName === 'string' ? fieldName :
(!fieldName[level] ? fieldName[fieldName.length - 1].toString()
: fieldName[level].toString());
}
getFields(level = 0) {
return {
id: this.getField('itemId', level),
iconCss: this.getField('iconCss', level),
text: this.getField('text', level),
url: this.getField('url', level),
child: this.getField('children', level),
separator: this.getField('separator', level)
};
}
hasField(items, field) {
for (let i = 0, len = items.length; i < len; i++) {
if (items[i][`${field}`]) {
return true;
}
}
return false;
}
menuHeaderClickHandler(e) {
const menuWrapper = closest(e.target, '.e-menu-wrapper');
if (menuWrapper && menuWrapper.querySelector('ul.e-menu-parent').id !== this.element.id) {
return;
}
if (this.element.className.indexOf('e-hide-menu') > -1) {
this.openHamburgerMenu(e);
}
else {
this.closeHamburgerMenu(e);
}
}
clickHandler(e) {
this.isTapHold = this.isTapHold ? false : this.isTapHold;
const wrapper = this.getWrapper();
const trgt = e.target;
const cli = this.cli = this.getLI(trgt);
const regex = new RegExp('-ej2menu-(.*)-popup');
const cliWrapper = cli ? closest(cli, '.e-' + this.getModuleName() + '-wrapper') : null;
const isInstLI = cli && cliWrapper && (this.isMenu ? this.getIndex(cli.id, true).length > 0
: wrapper.firstElementChild.id === cliWrapper.firstElementChild.id);
if (Browser.isDevice && this.isMenu) {
this.removeLIStateByClass([FOCUSED], [wrapper].concat(this.getPopups()));
this.mouseDownHandler(e);
}
if (cli && cliWrapper && this.isMenu) {
const cliWrapperId = cliWrapper.id ? regex.exec(cliWrapper.id)[1] : cliWrapper.querySelector('.e-menu-parent').id;
if (this.element.id !== cliWrapperId) {
return;
}
}
if (isInstLI && e.type === 'click' && !cli.classList.contains(HEADER)) {
this.setLISelected(cli);
const navIdx = this.getIndex(cli.id, true);
const item = this.getItem(navIdx);
const eventArgs = { element: cli, item: item, event: e };
this.trigger('select', eventArgs);
}
if (isInstLI && (e.type === 'mouseover' || Browser.isDevice || this.showItemOnClick)) {
let ul;
if (cli.classList.contains(HEADER)) {
ul = wrapper.children[this.navIdx.length - 1];
this.toggleAnimation(ul);
const sli = this.getLIByClass(ul, SELECTED);
if (sli) {
sli.classList.remove(SELECTED);
}
const scrollMenu = this.enableScrolling && !this.isMenu ? closest(cli.parentElement, '.e-menu-vscroll') : null;
if (scrollMenu) {
destroyScroll(getInstance(scrollMenu, VScroll), scrollMenu);
}
detach(cli.parentNode);
this.navIdx.pop();
}
else {
if (!cli.classList.contains(SEPARATOR)) {
this.showSubMenu = true;
const cul = cli.parentNode;
if (isNullOrUndefined(cul)) {
return;
}
this.cliIdx = this.getIdx(cul, cli);
if (this.isMenu || !Browser.isDevice) {
const culIdx = this.isMenu ? Array.prototype.indexOf.call([wrapper].concat(this.getPopups()), closest(cul, '.' + 'e-' + this.getModuleName() + '-wrapper'))
: this.getIdx(wrapper, cul);
if (this.navIdx[culIdx] === this.cliIdx) {
this.showSubMenu = false;
}
if (culIdx !== this.navIdx.length && (e.type !== 'mouseover' || this.showSubMenu)) {
const sli = this.getLIByClass(cul, SELECTED);
if (sli) {
sli.classList.remove(SELECTED);
}
this.isClosed = true;
this.keyType = 'click';
if (this.showItemOnClick) {
this.setLISelected(cli);
if (!this.isMenu) {
this.isCmenuHover = true;
}
}
this.closeMenu(culIdx + 1, e);
if (this.showItemOnClick) {
this.setLISelected(cli);
if (!this.isMenu) {
this.isCmenuHover = false;
}
}
}
}
if (!this.isClosed) {
this.afterCloseMenu(e);
}
this.isClosed = false;
}
}
}
else {
if (trgt.tagName === 'DIV' && closest(trgt, '.e-menu-vscroll') && (this.navIdx.length || !this.isMenu && this.enableScrolling && this.navIdx.length === 0)) {
const popupEle = this.isMenu ? closest(trgt, '.' + POPUP) : closest(trgt, '.e-menu-vscroll');
const cIdx = this.isMenu ? Array.prototype.indexOf.call(this.getPopups(), popupEle) + 1
: this.getIdx(wrapper, select('ul.e-menu-parent', popupEle));
if (cIdx < this.navIdx.length) {
this.closeMenu(cIdx + 1, e);
if (popupEle) {
this.removeLIStateByClass([FOCUSED, SELECTED], [popupEle]);
}
}
}
else if (this.isMenu && this.hamburgerMode && trgt.tagName === 'SPAN'
&& trgt.classList.contains('e-menu-icon')) {
this.menuHeaderClickHandler(e);
}
else {
if (trgt.tagName !== 'UL' || (this.isMenu ? trgt.parentElement.classList.contains('e-menu-wrapper') &&
!this.getIndex(trgt.querySelector('.' + ITEM).id, true).length : trgt.parentElement !== wrapper)) {
if (!cli && !isNullOrUndefined(wrapper)) {
this.removeLIStateByClass([SELECTED], [wrapper]);
}
if (!this.isAnimationNone && !cli || (cli && !cli.querySelector('.' + CARET))) {
if (navigator.platform.toUpperCase().indexOf('MAC') < 0 || (navigator.platform.toUpperCase().indexOf('MAC') >= 0 && !e.ctrlKey)) {
this.closeMenu(null, e);
}
}
}
}
}
}
afterCloseMenu(e) {
if (isNullOrUndefined(e)) {
return;
}
let isHeader;
if (this.showSubMenu) {
if (this.showItemOnClick && this.navIdx.length === 0) {
isHeader = closest(e.target, '.e-menu-parent.e-control');
}
else {
isHeader = closest(this.element, '.e-menu-parent.e-control');
}
const idx = this.navIdx.concat(this.cliIdx);
const item = this.getItem(idx);
if (item && item[this.getField('children', idx.length - 1)] &&
item[this.getField('children', idx.length - 1)].length) {
if (e.type === 'mouseover' || (Browser.isDevice && this.isMenu)) {
this.setLISelected(this.cli);
}
if ((!this.hamburgerMode && isHeader) || (this.hamburgerMode && this.cli.getAttribute('aria-expanded') === 'false')) {
this.cli.setAttribute('aria-expanded', 'true');
this.navIdx.push(this.cliIdx);
this.openMenu(this.cli, item, null, null, e);
}
}
else {
if (e.type !== 'mouseover') {
this.closeMenu(null, e);
}
}
if (!isHeader) {
const cul = this.getUlByNavIdx();
const sli = this.getLIByClass(cul, SELECTED);
if (sli) {
sli.setAttribute('aria-expanded', 'false');
sli.classList.remove(SELECTED);
}
}
}
this.keyType = '';
}
setLISelected(li) {
const sli = this.getLIByClass(li.parentElement, SELECTED);
if (sli) {
sli.classList.remove(SELECTED);
}
if (!this.isMenu) {
li.classList.remove(FOCUSED);
}
li.classList.add(SELECTED);
}
getLIByClass(ul, classname) {
if (ul && ul.children) {
for (let i = 0, len = ul.children.length; i < len; i++) {
if (ul.children[i].classList.contains(classname)) {
return ul.children[i];
}
}
}
return null;
}
/**
* This method is used to get the index of the menu item in the Menu based on the argument.
*
* @param {MenuItem | string} item - item be passed to get the index | id to be passed to get the item index.
* @param {boolean} isUniqueId - Set `true` if it is a unique id.
* @returns {void}
*/
getItemIndex(item, isUniqueId) {
let idx;
if (typeof item === 'string') {
idx = item;
}
else {
idx = item.id;
}
const isText = (isUniqueId === false) ? false : true;
const navIdx = this.getIndex(idx, isText);
return navIdx;
}
/**
* This method is used to set the menu item in the Menu based on the argument.
*
* @param {MenuItem} item - item need to be updated.
* @param {string} id - id / text to be passed to update the item.
* @param {boolean} isUniqueId - Set `true` if it is a unique id.
* @returns {void}
*/
setItem(item, id, isUniqueId) {
let idx;
if (isUniqueId) {
idx = id ? id : item.id;
}
else {
idx = id ? id : item.text;
}
const navIdx = this.getIndex(idx, isUniqueId);
const newItem = this.getItem(navIdx);
Object.assign(newItem, item);
}
getItem(navIdx) {
navIdx = navIdx.slice();
const idx = navIdx.pop();
const items = this.getItems(navIdx);
return items[idx];
}
getItems(navIdx) {
let items = this.items;
for (let i = 0; i < navIdx.length; i++) {
items = items[navIdx[i]][this.getField('children', i)];
}
return items;
}
setItems(newItems, navIdx) {
const items = this.getItems(navIdx);
items.splice(0, items.length);
for (let i = 0; i < newItems.length; i++) {
items.splice(i, 0, newItems[i]);
}
}
getIdx(ul, li, skipHdr = true) {
const ulElem = !this.isMenu && this.enableScrolling && select('.e-menu-vscroll', ul)
? selectAll('.e-menu-parent', ul) : Array.from(ul.children);
let idx = Array.prototype.indexOf.call(ulElem, li);
if (skipHdr && ul.children[0].classList.contains(HEADER)) {
idx--;
}
return idx;
}
getLI(elem) {
if (elem.tagName === 'LI' && elem.classList.contains('e-menu-item')) {
return elem;
}
return closest(elem, 'li.e-menu-item');
}
updateItemsByNavIdx() {
let items = this.items;
let count = 0;
for (let index = 0; index < this.navIdx.length; index++) {
items = items[index].items;
if (!items) {
break;
}
count++;
const ul = this.getUlByNavIdx(count);
if (!ul) {
break;
}
this.updateItem(ul, items);
}
}
removeChildElement(elem) {
while (elem.firstElementChild) {
elem.removeChild(elem.firstElementChild);
}
return elem;
}
/**
* Called internally if any of the property value changed.
*
* @private
* @param {MenuBaseModel} newProp - Specifies the new properties
* @param {MenuBaseModel} oldProp - Specifies the old properties
* @returns {void}
*/
onPropertyChanged(newProp, oldProp) {
const wrapper = this.getWrapper();
for (const prop of Object.keys(newProp)) {
switch (prop) {
case 'cssClass':
if (oldProp.cssClass) {
removeClass([wrapper], oldProp.cssClass.split(' '));
}
if (newProp.cssClass) {
addClass([wrapper], newProp.cssClass.replace(/\s+/g, ' ').trim().split(' '));
}
break;
case 'enableRtl':
if (this.enableRtl) {
wrapper.classList.add(RTL);
}
else {
wrapper.classList.remove(RTL);
}
break;
case 'showItemOnClick':
this.unWireEvents();
this.showItemOnClick = newProp.showItemOnClick;
this.wireEvents();
break;
case 'enableScrolling':
if (newProp.enableScrolling) {
let ul;
if (this.element.classList.contains('e-vertical')) {
addScrolling(this.createElement, wrapper, this.element, 'vscroll', this.enableRtl);
}
else {
addScrolling(this.createElement, wrapper, this.element, 'hscroll', this.enableRtl);
}
this.getPopups().forEach((wrapper) => {
ul = select('.e-ul', wrapper);
addScrolling(this.createElement, wrapper, ul, 'vscroll', this.enableRtl);
});
}
else {
let ul = wrapper.children[0];
if (this.element.classList.contains('e-vertical') || !this.isMenu) {
destroyScroll(getInstance(ul, VScroll), ul);
}
else {
destroyScroll(getInstance(ul, HScroll), ul);
}
wrapper.style.overflow = '';
wrapper.appendChild(this.element);
this.getPopups().forEach((wrapper) => {
ul = wrapper.children[0];
destroyScroll(getInstance(ul, VScroll), ul);
wrapper.style.overflow = '';
});
}
break;
case 'items': {
let idx;
let navIdx;
let item;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (this.isReact && this.template) {
this.clearTemplate(['template']);
}
if (!Object.keys(oldProp.items).length) {
this.updateItem(this.element, this.items);
if (this.enableScrolling && this.element.parentElement.classList.contains('e-custom-scroll')) {
if (this.element.classList.contains('e-vertical')) {
addScrolling(this.createElement, wrapper, this.element, 'vscroll', this.enableRtl);
}
else {
addScrolling(this.createElement, wrapper, this.element, 'hscroll', this.enableRtl);
}
}
if (this.enableScrolling && this.element.classList.contains('e-contextmenu')) {
this.isCMenu = true;
this.setPosition(this.lItem, this.uList, this.top, this.left, true);
this.isCMenu = false;
}
if (!this.hamburgerMode) {
for (let i = 1, count = wrapper.childElementCount; i < count; i++) {
detach(wrapper.lastElementChild);
}
}
this.navIdx = [];
}
else {
const keys = Object.keys(newProp.items);
for (let i = 0; i < keys.length; i++) {
navIdx = this.getChangedItemIndex(newProp, [], Number(keys[i]));
if (navIdx.length <= this.getWrapper().children.length) {
idx = navIdx.pop();
item = this.getItems(navIdx);
this.insertAfter([item[idx]], item[idx].text);
this.removeItem(item, navIdx, idx);
this.setItems(item, navIdx);
}
navIdx.length = 0;
}
}
break;
}
}
}
}
updateItem(ul, items) {
if (isBlazor() && !this.isMenu) {
ul = this.removeChildElement(ul);
}
else {
if (this.enableScrolling) {
const wrapper1 = this.getWrapper();
const ul1 = wrapper1.children[0];
if (this.element.classList.contains('e-vertical')) {
destroyScroll(getInstance(ul1, VScroll), ul1);
}
else {
destroyScroll(getInstance(ul1, HScroll), ul1);
}
}
ul.innerHTML = '';
}
const lis = [].slice.call(this.createItems(items).children);
lis.forEach((li) => {
ul.appendChild(li);
});
}
getChangedItemIndex(newProp, index, idx) {
index.push(idx);
const key = Object.keys(newProp.items[idx]).pop();
if (key === 'items') {
const item = newProp.items[idx];
const popStr = Object.keys(item.items).pop();
if (popStr) {
this.getChangedItemIndex(item, index, Number(popStr));
}
}
else {
if (key === 'isParentArray' && index.length > 1) {
index.pop();
}
}
return index;
}
removeItem(item, navIdx, idx) {
item.splice(idx, 1);
const uls = this.getWrapper().children;
if (navIdx.length < uls.length) {
if (this.enableScrolling && !uls[navIdx.length].classList.contains('e-menu-parent')) {
const ul = uls[navIdx.length].querySelector('.e-menu-parent');
detach(ul.children[idx]);
}
else {
detach(uls[navIdx.length].children[idx]);
}
}
}
/**
* Used to unwire the bind events.
*
* @private
* @param {string} targetSelctor - Specifies the target selector
* @returns {void}
*/
unWireEvents(targetSelctor = this.target) {
const wrapper = this.getWrapper();
if (targetSelctor) {
let target;
let touchModule;
const targetElems = selectAll(targetSelctor);
for (let i = 0, len = targetElems.length; i < len; i++) {
target = targetElems[i];
if (this.isMenu) {
EventHandler.remove(target, 'click', this.menuHeaderClickHandler);
}
else {
if (Browser.isIos) {
touchModule = getInstance(target, Touch);
if (touchModule) {
touchModule.destroy();
}
}
else {
EventHandler.remove(target, 'contextmenu', this.cmenuHandler);
}
}
}
if (!this.isMenu) {
EventHandler.remove(this.targetElement, 'scroll', this.scrollHandler);
for (const parent of getScrollableParent(this.targetElement)) {
EventHandler.remove(parent, 'scroll', this.scrollHandler);
}
}
}
if (!Browser.isDevice) {
EventHandler.remove(this.isMenu ? document : wrapper, 'mouseover', this.delegateMoverHandler);
EventHandler.remove(document, 'mousedown', this.delegateMouseDownHandler);
EventHandler.remove(document, 'keydown', this.domKeyHandler);
if (!this.isMenu && !this.target) {
EventHandler.remove(document, 'scroll', this.scrollHandler);
}
}
EventHandler.remove(document, 'click', this.delegateClickHandler);
this.unWireKeyboardEvent(wrapper);
this.rippleFn();
if (!this.isMenu && this.enableScrolling) {
wrapper.removeEventListener('touchstart', this.touchStartFn);
wrapper.removeEventListener('touchmove', this.touchMoveFn);
document.removeEventListener('touchstart', this.touchOutsideHandler);
}
}
unWireKeyboardEvent(element) {
const keyboardModule = getInstance(element, KeyboardEvents);
if (keyboardModule) {
keyboardModule.destroy();
}
}
toggleAnimation(ul, isMenuOpen = true) {
const menuWrapper = this.getWrapper();
if (menuWrapper) {
const activeMenuElements = menuWrapper.querySelectorAll('.e-menu-parent');
activeMenuElements.forEach((menuElement) => {
Animation.stop(menuElement);
});
}
let pUlHeight;
let pElement;
const animateElement = (this.enableScrolling && !this.isMenu && closest(ul, '.e-menu-vscroll'))
? closest(ul, '.e-menu-vscroll') : ul;
Animation.stop(animateElement);
if (this.animationSettings.effect === 'None' || !isMenuOpen) {
if (this.hamburgerMode && ul) {
ul.style.top = '0px';
}
this.isAnimationNone = this.animationSettings.effect === 'None';
this.end(ul, isMenuOpen);
}
else {
animateElement.style.maxHeight = '';
this.animation.animate(animateElement, {
name: this.animationSettings.effect,
duration: this.animationSettings.duration,
timingFunction: this.animationSettings.easing,
begin: (options) => {
if (this.hamburgerMode) {
pElement = options.element.parentElement;
options.element.style.position = 'absolute';
if (pElement) {
pUlHeight = pElement.offsetHeight;
}
options.element.style.maxHeight = options.element.offsetHeight + 'px';
if (pElement) {
pElement.style.maxHeight = '';
}
}
else {
options.element.style.display = 'block';
options.element.style.maxHeight = options.element.getBoundingClientRect().height + 'px';
}
},
progress: (options) => {
if (this.hamburgerMode && pElement) {
pElement.style.minHeight = (pUlHeight + options.element.offsetHeight) + 'px';
}
},
end: (options) => {
if (this.hamburgerMode) {
options.element.style.position = '';
options.element.style.maxHeight = '';
if (pElement) {
pElement.style.minHeight = '';
}
options.element.style.top = 0 + 'px';
options.element.children[0].focus();
this.triggerOpen(options.element.children[0]);
}
else {
this.end(options.element, isMenuOpen);
}
this.isKBDAction = false;
}
});
}
}
triggerOpen(ul) {
const item = this.navIdx.length ? this.getItem(this.navIdx) : null;
const eventArgs = {
element: ul, parentItem: item, items: item ? item.items : this.items
};
this.trigger('onOpen', eventArgs);
if (!this.isMenu) {
EventHandler.add(ul, 'keydown', this.keyHandler, this);
}
}
end(ul, isMenuOpen) {
if (isMenuOpen && this.isContextMenuClosed) {
if (this.isMenu || !Browser.isDevice || (!this.isMenu && this.isAnimationNone && Browser.isDevice)) {
ul.style.display = 'block';
}
ul.style.maxHeight = '';
const scrollMenu = this.enableScrolling && !this.isMenu ? closest(ul, '.e-menu-vscroll') : null;
if (scrollMenu) {
scrollMenu.style.display = 'block';
}
this.triggerOpen(ul);
if (ul.querySelector('.' + FOCUSED) && this.isKBDAction) {
ul.querySelector('.' + FOCUSED).focus();
}
else {
const ele = this.getWrapper().children[this.getIdx(this.getWrapper(), ul) - 1];
if (this.currentTarget) {
if (!(this.currentTarget.classList.contains('e-numerictextbox') || this.currentTarget.classList.contains('e-textbox') || this.currentTarget.tagName === 'INPUT')) {
if (ele && this.isKBDAction) {
ele.querySelector('.' + SELECTED).focus();
}
else {
this.element.focus();
}
}
}
else {
if (ele && this.isKBDAction) {
ele.querySelector('.' + SELECTED).focus();
}
else {
this.element.focus();
}
}
}
}
else {
const scrollMenu = this.enableScrolling && !this.isMenu ? closest(ul, '.e-menu-vscroll') : null;
if (scrollMenu) {
destroyScroll(getInstance(scrollMenu, VScroll), scrollMenu);
}
if (ul === this.element) {
const fli = this.getLIByClass(this.element, FOCUSED);
if (fli) {
fli.classList.remove(FOCUSED);
}
const sli = this.getLIByClass(this.element, SELECTED);
if (sli) {
sli.classList.remove(SELECTED);
}
ul.style.display = 'none';
this.isAnimationNone = false;
}
else {
detach(ul);
}
}
}
/**
* Get the properties to be maintained in the persisted state.
*
* @returns {string} - Persist data
*/
getPersistData() {
return '';
}
/**
* Get wrapper element.
*
* @returns {Element} - Wrapper element
* @private
*/
getWrapper() {
return closest(this.element, '.e-' + this.getModuleName() + '-wrapper');
}
getIndex(data, isUniqueId, items = this.items, nIndex = [], isCallBack = false, level = 0) {
let item;
level = isCallBack ? level + 1 : 0;
for (let i = 0, len = items.length; i < len; i++) {
item = items[i];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const currentField = isUniqueId ? item[this.getField('itemId', level)] : item[this.getField('text', level)];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const itemId = (item.htmlAttributes && 'id' in item.htmlAttributes) ? item.htmlAttributes.id : currentField;
if (itemId === data) {
nIndex.push(i);
break;
}
else if (item[this.getField('children', level)]
&& item[this.getField('children', level)].length) {
nIndex = this.getIndex(data, isUniqueId, item[this.getField('children', level)], nIndex, true, level);
if (nIndex[nIndex.length - 1] === -1) {
if (i !== len - 1) {
nIndex.pop();
}
}
else {
nIndex.unshift(i);
break;
}
}
else {
if (i === len - 1) {
nIndex.push(-1);
}
}
}
return (!isCallBack && nIndex[0] === -1) ? [] : nIndex;
}
/**
* This method is used to enable or disable the menu items in the Menu based on the items and enable argument.
*
* @param {string[]} items - Text items that needs to be enabled/disabled.
* @param {boolean} enable - Set `true`/`false` to enable/disable the list items.
* @param {boolean} isUniqueId - Set `true` if it is a unique id.
* @returns {void}
*/
enableItems(items, enable = true, isUniqueId) {
let ul;
let idx;
let navIdx;
const disabled = DISABLED;
let skipItem;
for (let i = 0; i < items.length; i++) {
navIdx = this.getIndex(items[i], isUniqueId);
if (this.navIdx.length) {
if (navIdx.length !== 1) {
skipItem = false;
for (let i = 0, len = navIdx.length - 1; i < len; i++) {
if (navIdx[i] !== this.navIdx[i]) {
skipItem = true;
break;
}
}
if (skipItem) {
continue;
}
}
}
else {
if (navIdx.length !== 1) {
continue;
}
}
idx = navIdx.pop();
ul = this.getUlByNavIdx(navIdx.length);
if (ul && !isNullOrUndefined(idx)) {
if (enable) {
if (this.isMenu) {
ul.children[idx].classList.remove(disabled);
ul.children[idx].removeAttribute('aria-disabled');
}
else {
if (Browser.isDevice && !ul.classList.contains('e-contextmenu')) {
ul.children[idx + 1].classList.remove(disabled);
}
else if (this.enableScrolling && !ul.classList.contains('e-menu-parent')) {
const mainUl = ul.querySelector('.e-menu-parent');
mainUl.children[idx].classList.remove(disabled);
}
else {
ul.children[idx].classList.remove(disabled);
}
}
}
else {
if (this.isMenu) {
ul.children[idx].classList.add(disabled);
ul.children[idx].setAttribute('aria-disabled', 'true');
}
else {
if (Browser.isDevice && !ul.classList.contains('e-contextmenu')) {
ul.children[idx + 1].classList.add(disabled);
}
else {
if (this.enableScrolling && !ul.classList.contains('e-menu-parent')) {
const mainUl = ul.querySelector('.e-menu-parent');
mainUl.children[idx].classList.add(disabled);
}
else {
ul.children[idx].classList.add(disabled);
}
}
}
}
}
}
}
/**
* This method is used to show the menu items in the Menu based on the items text.
*
* @param {string[]} items - Text items that needs to be shown.
* @param {boolean} isUniqueId - Set `true` if it is a unique id.
* @returns {void}
*/
showItems(items, isUniqueId) {
this.showHideItems(items, false, isUniqueId);
}
/**
* This method is used to hide the menu items in the Menu based on the items text.
*
* @param {string[]} items - Text items that needs to be hidden.
* @param {boolean} isUniqueId - Set `true` if it is a unique id.
* @returns {void}
*/
hideItems(items, isUniqueId) {
this.showHideItems(items, true, isUniqueId);
}
showHideItems(items, ishide, isUniqueId) {
let ul;
let index;
let navIdx;
let item;
for (let i = 0; i < items.length; i++) {
navIdx = this.getIndex(items[i], isUniqueId);
index = navIdx.pop();
ul = this.getUlByNavIdx(navIdx.length);
item = this.getItems(navIdx);
if (ul) {
if (this.enableScrolling && !ul.classList.contains('e-menu-parent')) {
ul = ul.querySelector('.e-menu-parent');
}
const validUl = isUniqueId ? ul.children[index].id : item[index].text.toString();
if (ishide && validUl === items[i]) {
ul.children[index].classList.add(HIDE);
}
else if (!ishide && validUl === items[i]) {
ul.children[index].classList.remove(HIDE);
}
}
}
}
/**
* It is used to remove the menu items from the Menu based on the items text.
*
* @param {string[]} items Text items that needs to be removed.
* @param {boolean} isUniqueId - Set `true` if it is a unique id.
* @returns {void}
*/
removeItems(items, isUniqueId) {
let idx;
let navIdx;
let iitems;
for (let i = 0; i < items.length; i++) {
navIdx = this.getIndex(items[i], isUniqueId);
idx = navIdx.pop();
iitems = this.getItems(navIdx);
if (!isNullOrUndefined(idx)) {
this.removeItem(iitems, navIdx, idx);
}
}
}
/**
* It is used to insert the menu items after the specified menu item text.
*
* @param {MenuItemModel[]} items - Items that needs to be inserted.
* @param {string} text - Text item after that the element to be inserted.
* @param {boolean} isUniqueId - Set `true` if it is a unique id.
* @returns {void}
*/
insertAfter(items, text, isUniqueId) {
this.insertItems(items, text, isUniqueId);
}
/**
* It is used to insert the menu items before the specified menu item text.
*
* @param {MenuItemModel[]} items - Items that needs to be inserted.
* @param {string} text - Text item before that the element to be inserted.
* @param {boolean} isUniqueId - Set `true` if it is a unique id.
* @returns {void}
*/
insertBefore(items, text, isUniqueId) {
this.insertItems(items, text, isUniqueId, false);
}
insertItems(items, text, isUniqueId, isAfter = true) {
let li;
let idx;
let navIdx;
let iitems;
let menuitem;
let parentUl;
for (let i = 0; i < items.length; i++) {
navIdx = this.getIndex(text, isUniqueId);
idx = navIdx.pop();
iitems = this.getItems(navIdx);
menuitem = new MenuItem(iitems[0], 'items', items[i], true);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
menuitem.parentObj = iitems[0].parentObj;
iitems.splice(isAfter ? idx + 1 : idx, 0, menuitem);
const uls = this.isMenu ? [this.getWrapper()].concat(this.getPopups()) : [].slice.call(this.getWrapper().children);
if (!isNullOrUndefined(idx) && navIdx.length < uls.length) {
idx = isAfter ? idx + 1 : idx;
li = this.createItems(iitems).children[idx];
let ul = parentUl = this.isMenu ? select('.e-menu-parent', uls[navIdx.length]) : uls[navIdx.length];
if (this.enableScrolling && !ul.classList.contains('e-menu-parent')) {
ul = ul.querySelector('.e-menu-parent');
}
ul.insertBefore(li, ul.children[idx]);
if (i === items.length - 1 && !this.isMenu && ul.style.display === 'block') {
if (this.enableScrolling) {
this.setPosition(null, ul, parseFloat(parentUl.style.top), parseFloat(parentUl.style.left));
const scrollElem = closest(ul, '.e-vscroll');
if (scrollElem) {
scrollElem.style.display = 'block';
}
}
else {
this.setPosition(null, ul, parseFloat(ul.style.top), parseFloat(ul.style.left));
ul.style.display = 'block';
}
}
}
}
}
removeAttributes() {
['top', 'left', 'display', 'z-index'].forEach((key) => {
this.element.style.removeProperty(key);
});
['role', 'tabindex', 'class', 'style'].forEach((key) => {
if (key === 'class' && this.element.classList.contains('e-menu-parent')) {
this.element.classList.remove('e-menu-parent');
}
if (['class', 'style'].indexOf(key) === -1 || !this.element.getAttribute(key)) {
this.element.removeAttribute(key);
}
if (this.isMenu && key === 'class' && this.element.classList.contains('e-vertical')) {
this.element.classList.remove('e-vertical');
}
});
}
/**
* Destroys the widget.
*
* @returns {void}
*/
destroy() {
const wrapper = this.getWrapper();
if (wrapper) {
this.unWireEvents();
if (!this.isMenu) {
this.clonedElement.style.display = '';
if (this.clonedElement.tagName === 'EJS-CONTEXTMENU') {
addClass([this.clonedElement], ['e-control', 'e-lib', 'e-' + this.getModuleName()]);
this.element = this.clonedElement;
}
else {
if (this.refreshing && this.clonedElement.childElementCount && this.clonedElement.children[0].tagName === 'LI') {
this.setProperties({ 'items': [] }, true);
}
if (document.getElementById(this.clonedElement.id)) {
const refEle = this.clonedElement.nextElementSibling;
if (refEle && refEle !== wrapper) {
this.clonedElement.parentElement.insertBefore(this.element, refEle);
}
else {
this.clonedElement.parentElement.appendChild(this.element);
}
if (isBlazor() && !this.isMenu) {
this.element = this.removeChildElement(this.element);
}
else {
this.element.innerHTML = '';
}
append([].slice.call(this.clonedElement.children), this.element);
detach(this.clonedElement);
this.removeAttributes();
}
}
this.clonedElement = null;
}
else {
this.closeMenu();
if (isBlazor() && !this.isMenu) {
this.element = this.removeChildElement(this.element);
}
else {
this.element.innerHTML = '';
}
this.removeAttributes();
wrapper.parentNode.insertBefore(this.element, wrapper);
this.clonedElement = null;
}
detach(wrapper);
super.destroy();
if (this.template) {
this.clearTemplate(['template']);
}
}
this.rippleFn = null;
}
};
__decorate$2([
Event()
], MenuBase.prototype, "beforeItemRender", void 0);
__decorate$2([
Event()
], MenuBase.prototype, "beforeOpen", void 0);
__decorate$2([
Event()
], MenuBase.prototype, "onOpen", void 0);
__decorate$2([
Event()
], MenuBase.prototype, "beforeClose", void 0);
__decorate$2([
Event()
], MenuBase.prototype, "onClose", void 0);
__decorate$2([
Event()
], MenuBase.prototype, "select", void 0);
__decorate$2([
Event()
], MenuBase.prototype, "created", void 0);
__decorate$2([
Property('')
], MenuBase.prototype, "cssClass", void 0);
__decorate$2([
Property(0)
], MenuBase.prototype, "hoverDelay", void 0);
__decorate$2([
Property(false)
], MenuBase.prototype, "showItemOnClick", void 0);
__decorate$2([
Property('')
], MenuBase.prototype, "target", void 0);
__decorate$2([
Property('')
], MenuBase.prototype, "filter", void 0);
__decorate$2([
Property(null)
], MenuBase.prototype, "template", void 0);
__decorate$2([
Property(false)
], MenuBase.prototype, "enableScrolling", void 0);
__decorate$2([
Property(true)
], MenuBase.prototype, "enableHtmlSanitizer", void 0);
__decorate$2([
Complex({ itemId: 'id', text: 'text', parentId: 'parentId', iconCss: 'iconCss', url: 'url', separator: 'separator', children: 'items' }, FieldSettings)
], MenuBase.prototype, "fields", void 0);
__decorate$2([
Collection([], MenuItem)
], MenuBase.prototype, "items", void 0);
__decorate$2([
Complex({ duration: 400, easing: 'ease', effect: 'SlideDown' }, MenuAnimationSettings)
], MenuBase.prototype, "animationSettings", void 0);
MenuBase = __decorate$2([
NotifyPropertyChanges
], MenuBase);
var __decorate$3 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const CLS_VERTICAL = 'e-vertical';
const CLS_ITEMS = 'e-toolbar-items';
const CLS_ITEM = 'e-toolbar-item';
const CLS_RTL$2 = 'e-rtl';
const CLS_SEPARATOR = 'e-separator';
const CLS_POPUPICON = 'e-popup-up-icon';
const CLS_POPUPDOWN = 'e-popup-down-icon';
const CLS_POPUPOPEN = 'e-popup-open';
const CLS_TEMPLATE = 'e-template';
const CLS_DISABLE$2 = 'e-overlay';
const CLS_POPUPTEXT = 'e-toolbar-text';
const CLS_TBARTEXT = 'e-popup-text';
const CLS_TBAROVERFLOW = 'e-overflow-show';
const CLS_POPOVERFLOW = 'e-overflow-hide';
const CLS_TBARBTN = 'e-tbar-btn';
const CLS_TBARNAV = 'e-hor-nav';
const CLS_TBARSCRLNAV = 'e-scroll-nav';
const CLS_TBARRIGHT = 'e-toolbar-right';
const CLS_TBARLEFT = 'e-toolbar-left';
const CLS_TBARCENTER = 'e-toolbar-center';
const CLS_TBARPOS = 'e-tbar-pos';
const CLS_HSCROLLCNT = 'e-hscroll-content';
const CLS_VSCROLLCNT = 'e-vscroll-content';
const CLS_HSCROLLBAR$1 = 'e-hscroll-bar';
const CLS_POPUPNAV = 'e-hor-nav';
const CLS_POPUPCLASS = 'e-toolbar-pop';
const CLS_POPUP = 'e-toolbar-popup';
const CLS_TBARBTNTEXT = 'e-tbar-btn-text';
const CLS_TBARNAVACT = 'e-nav-active';
const CLS_TBARIGNORE = 'e-ignore';
const CLS_POPPRI = 'e-popup-alone';
const CLS_HIDDEN = 'e-hidden';
const CLS_MULTIROW = 'e-toolbar-multirow';
const CLS_MULTIROWPOS = 'e-multirow-pos';
const CLS_MULTIROW_SEPARATOR = 'e-multirow-separator';
const CLS_EXTENDABLE_SEPARATOR = 'e-extended-separator';
const CLS_EXTEANDABLE_TOOLBAR = 'e-extended-toolbar';
const CLS_EXTENDABLECLASS = 'e-toolbar-extended';
const CLS_EXTENDPOPUP = 'e-expended-nav';
const CLS_EXTENDEDPOPOPEN = 'e-tbar-extended';
/**
* An item object that is used to configure Toolbar commands.
*/
class Item extends ChildProperty {
}
__decorate$3([
Property('')
], Item.prototype, "id", void 0);
__decorate$3([
Property('')
], Item.prototype, "text", void 0);
__decorate$3([
Property('auto')
], Item.prototype, "width", void 0);
__decorate$3([
Property('')
], Item.prototype, "cssClass", void 0);
__decorate$3([
Property(false)
], Item.prototype, "showAlwaysInPopup", void 0);
__decorate$3([
Property(false)
], Item.prototype, "disabled", void 0);
__decorate$3([
Property('')
], Item.prototype, "prefixIcon", void 0);
__decorate$3([
Property('')
], Item.prototype, "suffixIcon", void 0);
__decorate$3([
Property(true)
], Item.prototype, "visible", void 0);
__decorate$3([
Property('None')
], Item.prototype, "overflow", void 0);
__decorate$3([
Property('')
], Item.prototype, "template", void 0);
__decorate$3([
Property('Button')
], Item.prototype, "type", void 0);
__decorate$3([
Property('Both')
], Item.prototype, "showTextOn", void 0);
__decorate$3([
Property(null)
], Item.prototype, "htmlAttributes", void 0);
__decorate$3([
Property('')
], Item.prototype, "tooltipText", void 0);
__decorate$3([
Property('Left')
], Item.prototype, "align", void 0);
__decorate$3([
Event()
], Item.prototype, "click", void 0);
__decorate$3([
Property(-1)
], Item.prototype, "tabIndex", void 0);
/**
* The Toolbar control contains a group of commands that are aligned horizontally.
* ```html
* <div id="toolbar"/>
* <script>
* var toolbarObj = new Toolbar();
* toolbarObj.appendTo("#toolbar");
* </script>
* ```
*/
let Toolbar = class Toolbar extends Component {
/**
* Initializes a new instance of the Toolbar class.
*
* @param {ToolbarModel} options - Specifies Toolbar model properties as options.
* @param { string | HTMLElement} element - Specifies the element that is rendered as a Toolbar.
*/
constructor(options, element) {
super(options, element);
this.resizeContext = this.resize.bind(this);
this.orientationChangeContext = this.orientationChange.bind(this);
/**
* Contains the keyboard configuration of the Toolbar.
*/
this.keyConfigs = {
moveLeft: 'leftarrow',
moveRight: 'rightarrow',
moveUp: 'uparrow',
moveDown: 'downarrow',
popupOpen: 'enter',
popupClose: 'escape',
tab: 'tab',
home: 'home',
end: 'end'
};
}
/**
* Removes the control from the DOM and also removes all its related events.
*
* @returns {void}.
*/
destroy() {
if (this.isReact || this.isAngular) {
this.clearTemplate();
}
const btnItems = this.element.querySelectorAll('.e-control.e-btn');
[].slice.call(btnItems).forEach((el) => {
if (!isNullOrUndefined(el) && !isNullOrUndefined(el.ej2_instances) && !isNullOrUndefined(el.ej2_instances[0]) && !(el.ej2_instances[0].isDestroyed)) {
el.ej2_instances[0].destroy();
}
});
this.unwireEvents();
this.tempId.forEach((ele) => {
if (!isNullOrUndefined(this.element.querySelector(ele))) {
document.body.appendChild(this.element.querySelector(ele)).style.display = 'none';
}
});
this.destroyItems();
while (this.element.lastElementChild) {
this.element.removeChild(this.element.lastElementChild);
}
if (this.trgtEle) {
this.element.appendChild(this.ctrlTem);
this.trgtEle = null;
this.ctrlTem = null;
}
if (this.popObj) {
this.popObj.destroy();
detach(this.popObj.element);
}
if (this.activeEle) {
this.activeEle = null;
}
this.popObj = null;
this.tbarAlign = null;
this.tbarItemsCol = [];
this.remove(this.element, 'e-toolpop');
if (this.cssClass) {
removeClass([this.element], this.cssClass.split(' '));
}
this.element.removeAttribute('style');
['aria-disabled', 'aria-orientation', 'role'].forEach((attrb) => this.element.removeAttribute(attrb));
super.destroy();
}
/**
* Initialize the event handler
*
* @private
* @returns {void}
*/
preRender() {
const eventArgs = { enableCollision: this.enableCollision, scrollStep: this.scrollStep };
this.trigger('beforeCreate', eventArgs);
this.enableCollision = eventArgs.enableCollision;
this.scrollStep = eventArgs.scrollStep;
this.scrollModule = null;
this.popObj = null;
this.tempId = [];
this.tbarItemsCol = this.items;
this.isVertical = this.element.classList.contains(CLS_VERTICAL) ? true : false;
this.isExtendedOpen = false;
this.popupPriCount = 0;
if (this.enableRtl) {
this.add(this.element, CLS_RTL$2);
}
}
wireEvents() {
EventHandler.add(this.element, 'click', this.clickHandler, this);
window.addEventListener('resize', this.resizeContext);
window.addEventListener('orientationchange', this.orientationChangeContext);
if (this.allowKeyboard) {
this.wireKeyboardEvent();
}
}
wireKeyboardEvent() {
this.keyModule = new KeyboardEvents(this.element, {
keyAction: this.keyActionHandler.bind(this),
keyConfigs: this.keyConfigs
});
EventHandler.add(this.element, 'keydown', this.docKeyDown, this);
this.updateTabIndex('0');
}
updateTabIndex(tabIndex) {
const ele = this.element.querySelector('.' + CLS_ITEM + ':not(.' + CLS_DISABLE$2 + ' ):not(.' + CLS_SEPARATOR + ' ):not(.' + CLS_HIDDEN + ' )');
if (!isNullOrUndefined(ele) && !isNullOrUndefined(ele.firstElementChild)) {
const dataTabIndex = ele.firstElementChild.getAttribute('data-tabindex');
if (dataTabIndex && dataTabIndex === '-1' && ele.firstElementChild.tagName !== 'INPUT') {
ele.firstElementChild.setAttribute('tabindex', tabIndex);
}
}
}
unwireKeyboardEvent() {
if (this.keyModule) {
EventHandler.remove(this.element, 'keydown', this.docKeyDown);
this.keyModule.destroy();
this.keyModule = null;
}
}
docKeyDown(e) {
if (e.target.tagName === 'INPUT') {
return;
}
const popCheck = !isNullOrUndefined(this.popObj) && isVisible(this.popObj.element) && this.overflowMode !== 'Extended';
if (e.keyCode === 9 && e.target.classList.contains('e-hor-nav') === true && popCheck) {
this.popObj.hide({ name: 'FadeOut', duration: 100 });
}
const keyCheck = (e.keyCode === 40 || e.keyCode === 38 || e.keyCode === 35 || e.keyCode === 36);
if (keyCheck) {
e.preventDefault();
}
}
unwireEvents() {
EventHandler.remove(this.element, 'click', this.clickHandler);
this.destroyScroll();
this.unwireKeyboardEvent();
window.removeEventListener('resize', this.resizeContext);
window.removeEventListener('orientationchange', this.orientationChangeContext);
document.removeEventListener('scroll', this.clickEvent);
document.removeEventListener('click', this.scrollEvent);
this.scrollEvent = null;
this.clickEvent = null;
}
clearProperty() {
this.tbarEle = [];
this.tbarAlgEle = { lefts: [], centers: [], rights: [] };
}
docEvent(e) {
const popEle = closest(e.target, '.e-popup');
if (this.popupTriggeredByToolbar) {
this.popupTriggeredByToolbar = false;
return;
}
if (this.popObj && isVisible(this.popObj.element) && !popEle && this.overflowMode === 'Popup') {
this.popObj.hide({ name: 'FadeOut', duration: 100 });
}
}
destroyScroll() {
if (this.scrollModule) {
if (this.tbarAlign) {
this.add(this.scrollModule.element, CLS_TBARPOS);
}
this.scrollModule.destroy();
this.scrollModule = null;
}
}
destroyItems() {
if (this.element) {
[].slice.call(this.element.querySelectorAll('.' + CLS_ITEM)).forEach((el) => { detach(el); });
}
if (this.tbarAlign) {
const tbarItems = this.element.querySelector('.' + CLS_ITEMS);
if (tbarItems) {
if (tbarItems.children) {
[].slice.call(tbarItems.children).forEach((el) => {
detach(el);
});
}
this.remove(tbarItems, CLS_TBARPOS);
}
this.tbarAlign = false;
}
this.clearProperty();
}
destroyMode() {
if (this.scrollModule) {
this.remove(this.scrollModule.element, CLS_RTL$2);
this.destroyScroll();
}
this.remove(this.element, CLS_EXTENDEDPOPOPEN);
this.remove(this.element, CLS_EXTEANDABLE_TOOLBAR);
const tempEle = this.element.querySelector('.e-toolbar-multirow');
if (tempEle) {
this.remove(tempEle, CLS_MULTIROW);
}
if (this.popObj) {
this.popupRefresh(this.popObj.element, true);
}
}
add(ele, val) {
ele.classList.add(val);
}
remove(ele, val) {
ele.classList.remove(val);
}
elementFocus(ele) {
const fChild = ele.firstElementChild;
if (fChild) {
fChild.focus();
this.activeEleSwitch(ele);
}
else {
ele.focus();
}
}
clstElement(tbrNavChk, trgt) {
let clst;
if (tbrNavChk && this.popObj && isVisible(this.popObj.element)) {
clst = this.popObj.element.querySelector('.' + CLS_ITEM);
}
else if (this.element === trgt || tbrNavChk) {
clst = this.element.querySelector('.' + CLS_ITEM + ':not(.' + CLS_DISABLE$2 + ' ):not(.' + CLS_SEPARATOR + ' ):not(.' + CLS_HIDDEN + ' )');
}
else {
clst = closest(trgt, '.' + CLS_ITEM);
}
return clst;
}
getNextFocusableItem(currentItem, action) {
const selector = `.${CLS_ITEM}:not(.${CLS_DISABLE$2}):not(.${CLS_SEPARATOR}):not(.${CLS_HIDDEN})`;
const items = Array.from(this.element.querySelectorAll(selector));
const currentIndex = items.indexOf(currentItem);
if (currentIndex < 0) {
return null;
}
let nextIndex;
switch (action) {
case 'moveRight':
case 'moveDown':
case 'tab':
nextIndex = (currentIndex + 1) % items.length;
break;
case 'moveLeft':
case 'moveUp':
nextIndex = (currentIndex - 1 + items.length) % items.length;
break;
case 'home':
nextIndex = 0;
break;
case 'end':
nextIndex = items.length - 1;
break;
default:
nextIndex = currentIndex;
}
if (nextIndex >= 0 && nextIndex < items.length) {
return items[parseInt(nextIndex.toString(), 10)];
}
return null;
}
keyHandling(clst, e, trgt, navChk, scrollChk) {
const popObj = this.popObj;
const rootEle = this.element;
const popAnimate = { name: 'FadeOut', duration: 100 };
const value = e.action === 'moveUp' ? 'previous' : 'next';
let ele;
let nodes;
switch (e.action) {
case 'moveRight':
if (this.isVertical) {
return;
}
if (rootEle === trgt) {
this.elementFocus(clst);
}
else if (!navChk) {
this.eleFocus(clst, 'next');
}
break;
case 'moveLeft':
if (this.isVertical) {
return;
}
if (!navChk) {
this.eleFocus(clst, 'previous');
}
break;
case 'home':
case 'end':
if (clst) {
let popupCheck = closest(clst, '.e-popup');
const extendedPopup = this.element.querySelector('.' + CLS_EXTENDABLECLASS);
if (this.overflowMode === 'Extended' && extendedPopup && extendedPopup.classList.contains('e-popup-open')) {
popupCheck = e.action === 'end' ? extendedPopup : null;
}
if (popupCheck) {
if (isVisible(this.popObj.element)) {
nodes = [].slice.call(popupCheck.children);
if (e.action === 'home') {
ele = this.focusFirstVisibleEle(nodes);
}
else {
ele = this.focusLastVisibleEle(nodes);
}
}
}
else {
nodes = this.element.querySelectorAll('.' + CLS_ITEMS + ' .' + CLS_ITEM + ':not(.' + CLS_SEPARATOR + ')');
if (e.action === 'home') {
ele = this.focusFirstVisibleEle(nodes);
}
else {
ele = this.focusLastVisibleEle(nodes);
}
}
if (ele) {
this.elementFocus(ele);
}
}
break;
case 'moveUp':
case 'moveDown':
if (!this.isVertical) {
if (popObj && closest(trgt, '.e-popup')) {
const popEle = popObj.element;
if ((value === 'previous' && popEle.firstElementChild === clst)) {
const lastVisibleEle = this.focusLastVisibleEle([].slice.call(popEle.children));
if (lastVisibleEle) {
this.elementFocus(lastVisibleEle);
}
}
else if (value === 'next' && popEle.lastElementChild === clst) {
const firstVisibleEle = this.focusFirstVisibleEle([].slice.call(popEle.children));
if (firstVisibleEle) {
this.elementFocus(firstVisibleEle);
}
}
else {
this.eleFocus(clst, value);
}
}
else if (e.action === 'moveDown' && popObj && isVisible(popObj.element)) {
const skipEle = this.eleContains(clst);
if (skipEle) {
this.eleFocus(clst, value);
}
else {
this.elementFocus(clst);
}
}
}
else {
if (e.action === 'moveUp') {
this.eleFocus(clst, 'previous');
}
else {
this.eleFocus(clst, 'next');
}
}
break;
case 'tab':
if (!scrollChk && !navChk) {
const ele = clst.firstElementChild;
if (rootEle === trgt) {
if (this.activeEle) {
this.activeEle.focus();
}
else {
this.activeEleRemove(ele);
ele.focus();
}
}
}
break;
case 'popupClose':
if (popObj && this.overflowMode !== 'Extended') {
popObj.hide(popAnimate);
}
break;
case 'popupOpen':
if (!navChk) {
return;
}
if (popObj && !isVisible(popObj.element)) {
popObj.element.style.top = rootEle.offsetHeight + 'px';
popObj.show({ name: 'FadeIn', duration: 100 });
}
else {
popObj.hide(popAnimate);
}
break;
}
}
keyActionHandler(e) {
const trgt = e.target;
if ((e.action === 'home' || e.action === 'end' || e.action === 'moveRight' || e.action === 'moveLeft' || e.action === 'moveUp' || e.action === 'moveDown')
&& (trgt.tagName === 'INPUT' || trgt.tagName === 'TEXTAREA' || this.element.classList.contains(CLS_DISABLE$2))) {
return;
}
e.preventDefault();
const tbrNavChk = trgt.classList.contains(CLS_TBARNAV);
const tbarScrollChk = trgt.classList.contains(CLS_TBARSCRLNAV);
const clst = this.clstElement(tbrNavChk, trgt);
if (clst || tbarScrollChk) {
const currentItem = clst;
const nextItem = this.getNextFocusableItem(currentItem, e.action);
const keyDownEventArgs = {
originalEvent: e,
currentItem: currentItem,
nextItem: nextItem,
cancel: false
};
this.trigger('keyDown', keyDownEventArgs, (keyDownArgs) => {
if (!keyDownArgs.cancel) {
this.keyHandling(clst, e, trgt, tbrNavChk, tbarScrollChk);
}
});
}
}
/**
* Specifies the value to disable/enable the Toolbar component.
* When set to `true`, the component will be disabled.
*
* @param {boolean} value - Based on this Boolean value, Toolbar will be enabled (false) or disabled (true).
* @returns {void}.
*/
disable(value) {
const rootEle = this.element;
if (value) {
rootEle.classList.add(CLS_DISABLE$2);
}
else {
rootEle.classList.remove(CLS_DISABLE$2);
}
if (this.activeEle) {
this.activeEle.setAttribute('tabindex', this.activeEle.getAttribute('data-tabindex'));
}
if (this.scrollModule) {
this.scrollModule.disable(value);
}
if (this.popObj) {
if (isVisible(this.popObj.element) && this.overflowMode !== 'Extended') {
this.popObj.hide();
}
rootEle.querySelector('#' + rootEle.id + '_nav').setAttribute('tabindex', !value ? '0' : '-1');
}
}
eleContains(el) {
return el.classList.contains(CLS_SEPARATOR) || el.classList.contains(CLS_DISABLE$2) || el.getAttribute('disabled') || el.classList.contains(CLS_HIDDEN) || !isVisible(el) || !el.classList.contains(CLS_ITEM);
}
focusFirstVisibleEle(nodes) {
let element;
let index = 0;
while (index < nodes.length) {
const ele = nodes[parseInt(index.toString(), 10)];
if (!ele.classList.contains(CLS_SEPARATOR) && !ele.classList.contains(CLS_HIDDEN) && !ele.classList.contains(CLS_DISABLE$2)) {
return ele;
}
index++;
}
return element;
}
focusLastVisibleEle(nodes) {
let element;
let index = nodes.length - 1;
while (index >= 0) {
const ele = nodes[parseInt(index.toString(), 10)];
if (!ele.classList.contains(CLS_SEPARATOR) && !ele.classList.contains(CLS_HIDDEN) && !ele.classList.contains(CLS_DISABLE$2)) {
return ele;
}
index--;
}
return element;
}
eleFocus(closest, pos) {
const sib = Object(closest)[pos + 'ElementSibling'];
if (sib) {
const skipEle = this.eleContains(sib);
if (skipEle) {
this.eleFocus(sib, pos);
return;
}
this.elementFocus(sib);
}
else if (this.tbarAlign) {
let elem = Object(closest.parentElement)[pos + 'ElementSibling'];
if (!isNullOrUndefined(elem) && elem.children.length === 0) {
elem = Object(elem)[pos + 'ElementSibling'];
}
if (!isNullOrUndefined(elem) && elem.children.length > 0) {
if (pos === 'next') {
const el = elem.querySelector('.' + CLS_ITEM);
if (this.eleContains(el)) {
this.eleFocus(el, pos);
}
else {
el.firstElementChild.focus();
this.activeEleSwitch(el);
}
}
else {
const el = elem.lastElementChild;
if (this.eleContains(el)) {
this.eleFocus(el, pos);
}
else {
this.elementFocus(el);
}
}
}
}
else if (!isNullOrUndefined(closest)) {
const tbrItems = this.element.querySelectorAll('.' + CLS_ITEMS + ' .' + CLS_ITEM + ':not(.' + CLS_SEPARATOR + ')' + ':not(.' + CLS_DISABLE$2 + ')' + ':not(.' + CLS_HIDDEN + ')');
if (pos === 'next' && tbrItems) {
this.elementFocus(tbrItems[0]);
}
else if (pos === 'previous' && tbrItems) {
this.elementFocus(tbrItems[tbrItems.length - 1]);
}
}
}
clickHandler(e) {
const trgt = e.target;
const ele = this.element;
const isPopupElement = !isNullOrUndefined(closest(trgt, '.' + CLS_POPUPCLASS));
let clsList = trgt.classList;
let popupNav = closest(trgt, ('.' + CLS_TBARNAV));
const popupDownIcon = closest(trgt, ('.' + CLS_POPUPDOWN));
if (popupDownIcon || popupNav) {
this.popupTriggeredByToolbar = true;
}
if (!popupNav) {
popupNav = trgt;
}
if (!ele.children[0].classList.contains('e-hscroll') && !ele.children[0].classList.contains('e-vscroll')
&& (clsList.contains(CLS_TBARNAV))) {
clsList = trgt.querySelector('.e-icons').classList;
}
if (clsList.contains(CLS_POPUPICON) || clsList.contains(CLS_POPUPDOWN)) {
this.popupClickHandler(ele, popupNav, CLS_RTL$2);
}
let itemObj;
const clst = closest(e.target, '.' + CLS_ITEM);
if ((isNullOrUndefined(clst) || clst.classList.contains(CLS_DISABLE$2)) && !popupNav.classList.contains(CLS_TBARNAV)) {
return;
}
if (clst) {
const tempItem = this.items[this.tbarEle.indexOf(clst)];
itemObj = tempItem;
}
const eventArgs = { originalEvent: e, item: itemObj };
const isClickBinded = itemObj && !isNullOrUndefined(itemObj.click) && typeof itemObj.click == 'object' ?
!isNullOrUndefined(itemObj.click.observers) && itemObj.click.observers.length > 0 :
!isNullOrUndefined(itemObj) && !isNullOrUndefined(itemObj.click);
if (isClickBinded) {
this.trigger('items[' + this.tbarEle.indexOf(clst) + '].click', eventArgs);
}
if (!eventArgs.cancel) {
this.trigger('clicked', eventArgs, (clickedArgs) => {
if (!isNullOrUndefined(this.popObj) && isPopupElement && !clickedArgs.cancel && this.overflowMode === 'Popup' &&
clickedArgs.item && clickedArgs.item.type !== 'Input') {
this.popObj.hide({ name: 'FadeOut', duration: 100 });
}
});
}
}
popupClickHandler(ele, popupNav, CLS_RTL) {
const popObj = this.popObj;
if (isVisible(popObj.element)) {
popupNav.classList.remove(CLS_TBARNAVACT);
popObj.hide({ name: 'FadeOut', duration: 100 });
}
else {
if (ele.classList.contains(CLS_RTL)) {
popObj.enableRtl = true;
popObj.position = { X: 'left', Y: 'top' };
}
if (popObj.offsetX === 0 && !ele.classList.contains(CLS_RTL)) {
popObj.enableRtl = false;
popObj.position = { X: 'right', Y: 'top' };
}
if (this.overflowMode === 'Extended') {
popObj.element.style.minHeight = '0px';
popObj.width = this.getToolbarPopupWidth(this.element);
}
popObj.dataBind();
popObj.refreshPosition();
popObj.element.style.top = this.getElementOffsetY() + 'px';
popupNav.classList.add(CLS_TBARNAVACT);
popObj.show({ name: 'FadeIn', duration: 100 });
}
}
getToolbarPopupWidth(ele) {
const eleStyles = window.getComputedStyle(ele);
return parseFloat(eleStyles.width) + ((parseFloat(eleStyles.borderRightWidth)) * 2);
}
/**
* To Initialize the control rendering
*
* @private
* @returns {void}
*/
render() {
this.initialize();
this.clickEvent = this.docEvent.bind(this);
this.scrollEvent = this.docEvent.bind(this);
this.renderControl();
this.wireEvents();
this.renderComplete();
if (this.isReact && this.portals && this.portals.length > 0) {
this.renderReactTemplates(() => {
this.refreshOverflow();
});
}
}
initialize() {
const width = formatUnit(this.width);
const height = formatUnit(this.height);
if (Browser.info.name !== 'msie' || this.height !== 'auto' || this.overflowMode === 'MultiRow') {
setStyleAttribute(this.element, { 'height': height });
}
setStyleAttribute(this.element, { 'width': width });
const ariaAttr = {
'role': 'toolbar', 'aria-disabled': 'false',
'aria-orientation': !this.isVertical ? 'horizontal' : 'vertical'
};
attributes(this.element, ariaAttr);
if (this.cssClass) {
addClass([this.element], this.cssClass.split(' '));
}
}
renderControl() {
const ele = this.element;
this.trgtEle = (ele.children.length > 0) ? ele.querySelector('div') : null;
this.tbarAlgEle = { lefts: [], centers: [], rights: [] };
this.renderItems();
this.renderLayout();
}
renderLayout() {
this.renderOverflowMode();
if (this.tbarAlign) {
this.itemPositioning();
}
if (this.popObj && this.popObj.element.childElementCount > 1 && this.checkPopupRefresh(this.element, this.popObj.element)) {
this.popupRefresh(this.popObj.element, false);
}
this.separator();
}
itemsAlign(items, itemEleDom) {
let innerItem;
let innerPos;
if (!this.tbarEle) {
this.tbarEle = [];
}
for (let i = 0; i < items.length; i++) {
innerItem = this.renderSubComponent(items[parseInt(i.toString(), 10)], i);
if (this.tbarEle.indexOf(innerItem) === -1) {
this.tbarEle.push(innerItem);
}
if (!this.tbarAlign) {
this.tbarItemAlign(items[parseInt(i.toString(), 10)], itemEleDom, i);
}
innerPos = itemEleDom.querySelector('.e-toolbar-' + items[parseInt(i.toString(), 10)].align.toLowerCase());
if (innerPos) {
if (!(items[parseInt(i.toString(), 10)].showAlwaysInPopup && items[parseInt(i.toString(), 10)].overflow !== 'Show')) {
this.tbarAlgEle[(items[parseInt(i.toString(), 10)].align + 's').toLowerCase()].push(innerItem);
}
innerPos.appendChild(innerItem);
}
else {
itemEleDom.appendChild(innerItem);
}
}
if (this.isReact) {
const portals = 'portals';
this.notify('render-react-toolbar-template', this[`${portals}`]);
this.renderReactTemplates();
}
}
/**
* @hidden
* @returns {void}
*/
changeOrientation() {
const ele = this.element;
if (this.isVertical) {
ele.classList.remove(CLS_VERTICAL);
this.isVertical = false;
if (this.height === 'auto' || this.height === '100%') {
ele.style.height = this.height;
}
ele.setAttribute('aria-orientation', 'horizontal');
}
else {
ele.classList.add(CLS_VERTICAL);
this.isVertical = true;
ele.setAttribute('aria-orientation', 'vertical');
setStyleAttribute(this.element, { 'height': formatUnit(this.height), 'width': formatUnit(this.width) });
}
this.destroyMode();
this.refreshOverflow();
}
initScroll(element, innerItems) {
if (!this.scrollModule && this.checkOverflow(element, innerItems[0])) {
if (this.tbarAlign) {
this.element.querySelector('.' + CLS_ITEMS + ' .' + CLS_TBARCENTER).removeAttribute('style');
}
if (this.isVertical) {
this.scrollModule = new VScroll({ scrollStep: this.scrollStep, enableRtl: this.enableRtl }, innerItems[0]);
}
else {
this.scrollModule = new HScroll({ scrollStep: this.scrollStep, enableRtl: this.enableRtl }, innerItems[0]);
}
if (this.cssClass) {
addClass([innerItems[0]], this.cssClass.split(' '));
}
const scrollEle = this.scrollModule.element.querySelector('.' + CLS_HSCROLLBAR$1 + ', .' + 'e-vscroll-bar');
if (scrollEle) {
scrollEle.removeAttribute('tabindex');
}
this.remove(this.scrollModule.element, CLS_TBARPOS);
setStyleAttribute(this.element, { overflow: 'hidden' });
}
}
itemWidthCal(items) {
let width = 0;
let style;
[].slice.call(selectAll('.' + CLS_ITEM, items)).forEach((el) => {
if (isVisible(el)) {
style = window.getComputedStyle(el);
width += this.isVertical ? el.offsetHeight : el.offsetWidth;
width += parseFloat(this.isVertical ? style.marginTop : style.marginRight);
width += parseFloat(this.isVertical ? style.marginBottom : style.marginLeft);
}
});
return width;
}
getScrollCntEle(innerItem) {
const trgClass = (this.isVertical) ? '.e-vscroll-content' : '.e-hscroll-content';
return innerItem.querySelector(trgClass);
}
checkOverflow(element, innerItem) {
if (isNullOrUndefined(element) || isNullOrUndefined(innerItem) || !isVisible(element)) {
return false;
}
const eleWidth = this.isVertical ? element.offsetHeight : element.offsetWidth;
let itemWidth = this.isVertical ? innerItem.offsetHeight : innerItem.offsetWidth;
if (this.tbarAlign || this.scrollModule || (eleWidth === itemWidth)) {
itemWidth = this.itemWidthCal(this.scrollModule ? this.getScrollCntEle(innerItem) : innerItem);
}
const popNav = element.querySelector('.' + CLS_TBARNAV);
const scrollNav = element.querySelector('.' + CLS_TBARSCRLNAV);
let navEleWidth = 0;
if (popNav) {
navEleWidth = this.isVertical ? popNav.offsetHeight : popNav.offsetWidth;
}
else if (scrollNav) {
navEleWidth = this.isVertical ? (scrollNav.offsetHeight * (2)) : (scrollNav.offsetWidth * 2);
}
if (eleWidth >= itemWidth && scrollNav) {
return false;
}
else if (itemWidth > eleWidth - navEleWidth) {
return true;
}
else {
return false;
}
}
/**
* Refresh the whole Toolbar component without re-rendering.
* - It is used to manually refresh the Toolbar overflow modes such as scrollable, popup, multi row, and extended.
* - It will refresh the Toolbar component after loading items dynamically.
*
* @returns {void}.
*/
refreshOverflow() {
this.resize();
}
toolbarAlign(innerItems) {
if (this.tbarAlign) {
this.add(innerItems, CLS_TBARPOS);
this.itemPositioning();
}
}
renderOverflowMode() {
const ele = this.element;
const innerItems = ele.querySelector('.' + CLS_ITEMS);
const priorityCheck = this.popupPriCount > 0;
if (ele && ele.children.length > 0) {
this.offsetWid = ele.offsetWidth;
this.remove(this.element, 'e-toolpop');
if (Browser.info.name === 'msie' && this.height === 'auto') {
ele.style.height = '';
}
switch (this.overflowMode) {
case 'Scrollable':
if (isNullOrUndefined(this.scrollModule)) {
this.initScroll(ele, [].slice.call(ele.getElementsByClassName(CLS_ITEMS)));
}
break;
case 'Popup':
this.add(this.element, 'e-toolpop');
if (this.tbarAlign) {
this.removePositioning();
}
if (this.checkOverflow(ele, innerItems) || priorityCheck) {
this.setOverflowAttributes(ele);
}
this.toolbarAlign(innerItems);
break;
case 'MultiRow':
this.add(innerItems, CLS_MULTIROW);
if (this.checkOverflow(ele, innerItems) && this.tbarAlign) {
this.removePositioning();
this.add(innerItems, CLS_MULTIROWPOS);
}
if (ele.style.overflow === 'hidden') {
ele.style.overflow = '';
}
if (Browser.info.name === 'msie' || ele.style.height !== 'auto') {
ele.style.height = 'auto';
}
break;
case 'Extended':
this.add(this.element, CLS_EXTEANDABLE_TOOLBAR);
if (this.checkOverflow(ele, innerItems) || priorityCheck) {
if (this.tbarAlign) {
this.removePositioning();
}
this.setOverflowAttributes(ele);
}
this.toolbarAlign(innerItems);
}
}
}
setOverflowAttributes(ele) {
this.createPopupEle(ele, [].slice.call(selectAll('.' + CLS_ITEMS + ' .' + CLS_ITEM, ele)));
const ariaAttr = {
'tabindex': '0', 'role': 'button', 'aria-haspopup': 'true',
'aria-label': 'overflow'
};
attributes(this.element.querySelector('.' + CLS_TBARNAV), ariaAttr);
}
separator() {
const element = this.element;
const eleItem = [].slice.call(element.querySelectorAll('.' + CLS_SEPARATOR));
const multiVar = element.querySelector('.' + CLS_MULTIROW_SEPARATOR);
const extendVar = element.querySelector('.' + CLS_EXTENDABLE_SEPARATOR);
const eleInlineItem = this.overflowMode === 'MultiRow' ? multiVar : extendVar;
if (eleInlineItem !== null) {
if (this.overflowMode === 'MultiRow') {
eleInlineItem.classList.remove(CLS_MULTIROW_SEPARATOR);
}
else if (this.overflowMode === 'Extended') {
eleInlineItem.classList.remove(CLS_EXTENDABLE_SEPARATOR);
}
}
for (let i = 0; i <= eleItem.length - 1; i++) {
if (eleItem[parseInt(i.toString(), 10)].offsetLeft < 30 && eleItem[parseInt(i.toString(), 10)].offsetLeft !== 0) {
if (this.overflowMode === 'MultiRow') {
eleItem[parseInt(i.toString(), 10)].classList.add(CLS_MULTIROW_SEPARATOR);
}
else if (this.overflowMode === 'Extended') {
eleItem[parseInt(i.toString(), 10)].classList.add(CLS_EXTENDABLE_SEPARATOR);
}
}
}
}
createPopupEle(ele, innerEle) {
let innerNav = ele.querySelector('.' + CLS_TBARNAV);
const vertical = this.isVertical;
if (!innerNav) {
this.createPopupIcon(ele);
}
innerNav = ele.querySelector('.' + CLS_TBARNAV);
const innerNavDom = (vertical ? innerNav.offsetHeight : innerNav.offsetWidth);
const eleWidth = ((vertical ? ele.offsetHeight : ele.offsetWidth) - (innerNavDom));
this.element.classList.remove('e-rtl');
setStyleAttribute(this.element, { direction: 'initial' });
this.checkPriority(ele, innerEle, eleWidth, true);
if (this.enableRtl) {
this.element.classList.add('e-rtl');
}
this.element.style.removeProperty('direction');
this.createPopup();
}
pushingPoppedEle(tbarObj, popupPri, ele, eleHeight, sepHeight) {
const element = tbarObj.element;
const poppedEle = [].slice.call(selectAll('.' + CLS_POPUP, element.querySelector('.' + CLS_ITEMS)));
let nodes = selectAll('.' + CLS_TBAROVERFLOW, ele);
let nodeIndex = 0;
let nodePri = 0;
poppedEle.forEach((el, index) => {
nodes = selectAll('.' + CLS_TBAROVERFLOW, ele);
if (el.classList.contains(CLS_TBAROVERFLOW) && nodes.length > 0) {
if (tbarObj.tbResize && nodes.length > index) {
ele.insertBefore(el, nodes[parseInt(index.toString(), 10)]);
++nodePri;
}
else {
ele.insertBefore(el, ele.children[nodes.length]);
++nodePri;
}
}
else if (el.classList.contains(CLS_TBAROVERFLOW)) {
ele.insertBefore(el, ele.firstChild);
++nodePri;
}
else if (tbarObj.tbResize && el.classList.contains(CLS_POPOVERFLOW) && ele.children.length > 0 && nodes.length === 0) {
ele.insertBefore(el, ele.firstChild);
++nodePri;
}
else if (el.classList.contains(CLS_POPOVERFLOW)) {
popupPri.push(el);
}
else if (tbarObj.tbResize) {
ele.insertBefore(el, ele.childNodes[nodeIndex + nodePri]);
++nodeIndex;
}
else {
const children = Array.prototype.slice.call(ele.children);
const insertionNode = children.slice(index)
.find((child) => !child.classList.contains(CLS_POPPRI));
ele.insertBefore(el, insertionNode || null);
}
if (el.classList.contains(CLS_SEPARATOR)) {
setStyleAttribute(el, { display: '', height: sepHeight + 'px' });
}
else {
setStyleAttribute(el, { display: '', height: eleHeight + 'px' });
}
});
popupPri.forEach((el) => {
ele.appendChild(el);
});
const tbarEle = selectAll('.' + CLS_ITEM, element.querySelector('.' + CLS_ITEMS));
for (let i = tbarEle.length - 1; i >= 0; i--) {
const tbarElement = tbarEle[parseInt(i.toString(), 10)];
if (tbarElement.classList.contains(CLS_SEPARATOR) && this.overflowMode !== 'Extended') {
setStyleAttribute(tbarElement, { display: 'none' });
}
else {
break;
}
}
}
createPopup() {
const element = this.element;
let sepHeight;
let sepItem;
if (this.overflowMode === 'Extended') {
sepItem = element.querySelector('.' + CLS_SEPARATOR);
sepHeight =
(element.style.height === 'auto' || element.style.height === '') ? null : (sepItem && sepItem.offsetHeight);
}
const eleItem = element.querySelector('.' + CLS_ITEM + ':not(.' + CLS_SEPARATOR + '):not(.' + CLS_POPUP + ')');
const eleHeight = (element.style.height === 'auto' || element.style.height === '') ? null : (eleItem && eleItem.offsetHeight);
let ele;
const popupPri = [];
if (select('#' + element.id + '_popup.' + CLS_POPUPCLASS, element)) {
ele = select('#' + element.id + '_popup.' + CLS_POPUPCLASS, element);
}
else {
const extendEle = this.createElement('div', {
id: element.id + '_popup', className: CLS_POPUPCLASS + ' ' + CLS_EXTENDABLECLASS
});
const popupEle = this.createElement('div', { id: element.id + '_popup', className: CLS_POPUPCLASS });
ele = this.overflowMode === 'Extended' ? extendEle : popupEle;
}
this.pushingPoppedEle(this, popupPri, ele, eleHeight, sepHeight);
this.popupInit(element, ele);
}
getElementOffsetY() {
return (this.overflowMode === 'Extended' && window.getComputedStyle(this.element).getPropertyValue('box-sizing') === 'border-box' ?
this.element.clientHeight : this.element.offsetHeight);
}
popupInit(element, ele) {
if (!this.popObj) {
element.appendChild(ele);
if (this.cssClass) {
addClass([ele], this.cssClass.split(' '));
}
setStyleAttribute(this.element, { overflow: '' });
const popup = new Popup(null, {
relateTo: this.element,
offsetY: (this.isVertical) ? 0 : this.getElementOffsetY(),
enableRtl: this.enableRtl,
open: this.popupOpen.bind(this),
close: this.popupClose.bind(this),
collision: { Y: this.enableCollision ? 'flip' : 'none' },
position: this.enableRtl ? { X: 'left', Y: 'top' } : { X: 'right', Y: 'top' }
});
if (this.overflowMode === 'Extended') {
popup.width = this.getToolbarPopupWidth(this.element);
popup.offsetX = 0;
}
popup.appendTo(ele);
document.addEventListener('scroll', this.clickEvent);
document.addEventListener('click', this.scrollEvent);
if (this.overflowMode !== 'Extended') {
popup.element.style.maxHeight = popup.element.offsetHeight + 'px';
}
if (this.isVertical) {
popup.element.style.visibility = 'hidden';
}
if (this.isExtendedOpen) {
const popupNav = this.element.querySelector('.' + CLS_TBARNAV);
popupNav.classList.add(CLS_TBARNAVACT);
classList(popupNav.firstElementChild, [CLS_POPUPICON], [CLS_POPUPDOWN]);
this.element.querySelector('.' + CLS_EXTENDABLECLASS).classList.add(CLS_POPUPOPEN);
}
else {
popup.hide();
}
this.popObj = popup;
}
else if (this.overflowMode !== 'Extended') {
const popupEle = this.popObj.element;
setStyleAttribute(popupEle, { maxHeight: '', display: 'block' });
setStyleAttribute(popupEle, { maxHeight: popupEle.offsetHeight + 'px', display: '' });
}
}
tbarPopupHandler(isOpen) {
if (this.overflowMode === 'Extended') {
if (isOpen) {
this.add(this.element, CLS_EXTENDEDPOPOPEN);
}
else {
this.remove(this.element, CLS_EXTENDEDPOPOPEN);
}
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
popupOpen(e) {
const popObj = this.popObj;
if (!this.isVertical) {
popObj.offsetY = this.getElementOffsetY();
popObj.dataBind();
}
const popupEle = this.popObj.element;
const toolEle = this.popObj.element.parentElement;
const popupNav = toolEle.querySelector('.' + CLS_TBARNAV);
popupNav.setAttribute('aria-expanded', 'true');
if (this.overflowMode === 'Extended') {
popObj.element.style.minHeight = '';
}
else {
setStyleAttribute(popObj.element, { height: 'auto', maxHeight: '' });
popObj.element.style.maxHeight = popObj.element.offsetHeight + 'px';
}
const popupElePos = popupEle.offsetTop + popupEle.offsetHeight + calculatePosition(toolEle).top;
const popIcon = popupNav.firstElementChild;
popupNav.classList.add(CLS_TBARNAVACT);
classList(popIcon, [CLS_POPUPICON], [CLS_POPUPDOWN]);
this.tbarPopupHandler(true);
const scrollVal = isNullOrUndefined(window.scrollY) ? 0 : window.scrollY;
if (!this.isVertical && ((window.innerHeight + scrollVal) < popupElePos) && (this.element.offsetTop < popupEle.offsetHeight)) {
let overflowHeight = (popupEle.offsetHeight - ((popupElePos - window.innerHeight - scrollVal) + 5));
popObj.height = overflowHeight + 'px';
for (let i = 0; i <= popupEle.childElementCount; i++) {
const ele = popupEle.children[parseInt(i.toString(), 10)];
if (ele.offsetTop + ele.offsetHeight > overflowHeight) {
overflowHeight = ele.offsetTop;
break;
}
}
if (this.overflowMode !== 'Extended') {
setStyleAttribute(popObj.element, { maxHeight: overflowHeight + 'px' });
}
}
else if (this.isVertical && this.overflowMode !== 'Extended') {
const tbEleData = this.element.getBoundingClientRect();
setStyleAttribute(popObj.element, { maxHeight: (tbEleData.top + this.element.offsetHeight) + 'px', bottom: 0, visibility: '' });
}
if (popObj) {
const popupOffset = popupEle.getBoundingClientRect();
if (popupOffset.right > document.documentElement.clientWidth && popupOffset.width > toolEle.getBoundingClientRect().width) {
popObj.collision = { Y: 'none' };
popObj.dataBind();
}
popObj.refreshPosition();
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
popupClose(e) {
const element = this.element;
const popupNav = element.querySelector('.' + CLS_TBARNAV);
popupNav.setAttribute('aria-expanded', 'false');
const popIcon = popupNav.firstElementChild;
popupNav.classList.remove(CLS_TBARNAVACT);
classList(popIcon, [CLS_POPUPDOWN], [CLS_POPUPICON]);
this.tbarPopupHandler(false);
}
checkPriority(ele, inEle, eleWidth, pre) {
const popPriority = this.popupPriCount > 0;
const len = inEle.length;
const eleWid = eleWidth;
let eleOffset;
let checkoffset;
let sepCheck = 0;
let itemCount = 0;
let itemPopCount = 0;
const checkClass = (ele, val) => {
let rVal = false;
val.forEach((cls) => {
if (ele.classList.contains(cls)) {
rVal = true;
}
});
return rVal;
};
for (let i = len - 1; i >= 0; i--) {
let mrgn;
const compuStyle = window.getComputedStyle(inEle[parseInt(i.toString(), 10)]);
if (this.isVertical) {
mrgn = parseFloat((compuStyle).marginTop);
mrgn += parseFloat((compuStyle).marginBottom);
}
else {
mrgn = parseFloat((compuStyle).marginRight);
mrgn += parseFloat((compuStyle).marginLeft);
}
const fstEleCheck = inEle[parseInt(i.toString(), 10)] === this.tbarEle[0];
if (fstEleCheck) {
this.tbarEleMrgn = mrgn;
}
eleOffset = this.isVertical ? inEle[parseInt(i.toString(), 10)].offsetHeight : inEle[parseInt(i.toString(), 10)].offsetWidth;
const eleWid = fstEleCheck ? (eleOffset + mrgn) : eleOffset;
if (checkClass(inEle[parseInt(i.toString(), 10)], [CLS_POPPRI]) && popPriority) {
inEle[parseInt(i.toString(), 10)].classList.add(CLS_POPUP);
if (this.isVertical) {
setStyleAttribute(inEle[parseInt(i.toString(), 10)], { display: 'none', minHeight: eleWid + 'px' });
}
else {
setStyleAttribute(inEle[parseInt(i.toString(), 10)], { display: 'none', minWidth: eleWid + 'px' });
}
itemPopCount++;
}
if (this.isVertical) {
checkoffset =
(inEle[parseInt(i.toString(), 10)].offsetTop + inEle[parseInt(i.toString(), 10)].offsetHeight + mrgn) > eleWidth;
}
else {
checkoffset =
(inEle[parseInt(i.toString(), 10)].offsetLeft + inEle[parseInt(i.toString(), 10)].offsetWidth + mrgn) > eleWidth;
}
if (checkoffset) {
if (inEle[parseInt(i.toString(), 10)].classList.contains(CLS_SEPARATOR)) {
if (this.overflowMode === 'Extended') {
const sepEle = inEle[parseInt(i.toString(), 10)];
if (checkClass(sepEle, [CLS_SEPARATOR, CLS_TBARIGNORE])) {
inEle[parseInt(i.toString(), 10)].classList.add(CLS_POPUP);
itemPopCount++;
}
itemCount++;
}
else if (this.overflowMode === 'Popup') {
if (sepCheck > 0 && itemCount === itemPopCount) {
const sepEle = inEle[i + itemCount + (sepCheck - 1)];
if (checkClass(sepEle, [CLS_SEPARATOR, CLS_TBARIGNORE])) {
setStyleAttribute(sepEle, { display: 'none' });
}
}
sepCheck++;
itemCount = 0;
itemPopCount = 0;
}
}
else {
itemCount++;
}
if (inEle[parseInt(i.toString(), 10)].classList.contains(CLS_TBAROVERFLOW) && pre) {
eleWidth -= ((this.isVertical ? inEle[parseInt(i.toString(), 10)].offsetHeight :
inEle[parseInt(i.toString(), 10)].offsetWidth) + (mrgn));
}
else if (!checkClass(inEle[parseInt(i.toString(), 10)], [CLS_SEPARATOR, CLS_TBARIGNORE])) {
inEle[parseInt(i.toString(), 10)].classList.add(CLS_POPUP);
if (this.isVertical) {
setStyleAttribute(inEle[parseInt(i.toString(), 10)], { display: 'none', minHeight: eleWid + 'px' });
}
else {
setStyleAttribute(inEle[parseInt(i.toString(), 10)], { display: 'none', minWidth: eleWid + 'px' });
}
itemPopCount++;
}
else {
eleWidth -= ((this.isVertical ? inEle[parseInt(i.toString(), 10)].offsetHeight :
inEle[parseInt(i.toString(), 10)].offsetWidth) + (mrgn));
}
}
}
if (pre) {
const popedEle = selectAll('.' + CLS_ITEM + ':not(.' + CLS_POPUP + ')', this.element);
this.checkPriority(ele, popedEle, eleWid, false);
}
}
createPopupIcon(element) {
const id = element.id.concat('_nav');
let className = 'e-' + element.id.concat('_nav ' + CLS_POPUPNAV);
className = this.overflowMode === 'Extended' ? className + ' ' + CLS_EXTENDPOPUP : className;
const nav = this.createElement('div', { id: id, className: className });
if (Browser.info.name === 'msie' || Browser.info.name === 'edge') {
nav.classList.add('e-ie-align');
}
const navItem = this.createElement('div', { className: CLS_POPUPDOWN + ' e-icons' });
nav.appendChild(navItem);
nav.setAttribute('tabindex', '0');
nav.setAttribute('role', 'button');
element.appendChild(nav);
}
// eslint-disable-next-line max-len
tbarPriRef(inEle, indx, sepPri, el, des, elWid, wid, ig, eleStyles) {
const ignoreCount = ig;
const popEle = this.popObj.element;
const query = '.' + CLS_ITEM + ':not(.' + CLS_SEPARATOR + '):not(.' + CLS_TBAROVERFLOW + ')';
const priEleCnt = selectAll('.' + CLS_POPUP + ':not(.' + CLS_TBAROVERFLOW + ')', popEle).length;
const checkClass = (ele, val) => {
return ele.classList.contains(val);
};
if (selectAll(query, inEle).length === 0) {
const eleSep = inEle.children[indx - (indx - sepPri) - 1];
const ignoreCheck = (!isNullOrUndefined(eleSep) && checkClass(eleSep, CLS_TBARIGNORE));
if ((!isNullOrUndefined(eleSep) && checkClass(eleSep, CLS_SEPARATOR) && !isVisible(eleSep)) || ignoreCheck) {
eleSep.style.display = 'unset';
const eleSepWidth = eleSep.offsetWidth + (parseFloat(window.getComputedStyle(eleSep).marginRight) * 2);
const prevSep = eleSep.previousElementSibling;
if ((elWid + eleSepWidth) < wid || des) {
inEle.insertBefore(el, inEle.children[(indx + ignoreCount) - (indx - sepPri)]);
if (!isNullOrUndefined(prevSep)) {
prevSep.style.display = '';
}
}
else {
setStyleAttribute(el, eleStyles);
if (prevSep.classList.contains(CLS_SEPARATOR)) {
prevSep.style.display = 'none';
}
}
eleSep.style.display = '';
}
else {
inEle.insertBefore(el, inEle.children[(indx + ignoreCount) - (indx - sepPri)]);
}
}
else {
inEle.insertBefore(el, inEle.children[(indx + ignoreCount) - priEleCnt]);
}
}
popupRefresh(popupEle, destroy) {
const ele = this.element;
const isVer = this.isVertical;
const innerEle = ele.querySelector('.' + CLS_ITEMS);
let popNav = ele.querySelector('.' + CLS_TBARNAV);
if (isNullOrUndefined(popNav)) {
return;
}
innerEle.removeAttribute('style');
popupEle.style.display = 'block';
let dimension;
if (isVer) {
dimension = ele.offsetHeight - (popNav.offsetHeight + innerEle.offsetHeight);
}
else {
dimension = ele.offsetWidth - (popNav.offsetWidth + innerEle.offsetWidth);
}
let popupEleWidth = 0;
[].slice.call(popupEle.children).forEach((el) => {
popupEleWidth += this.popupEleWidth(el);
setStyleAttribute(el, { 'position': '' });
});
if ((dimension + (isVer ? popNav.offsetHeight : popNav.offsetWidth)) > (popupEleWidth) && this.popupPriCount === 0) {
destroy = true;
}
this.popupEleRefresh(dimension, popupEle, destroy);
popupEle.style.display = '';
if (popupEle.children.length === 0 && popNav && this.popObj) {
detach(popNav);
popNav = null;
this.popObj.destroy();
detach(this.popObj.element);
this.popObj = null;
}
}
ignoreEleFetch(index, innerEle) {
const ignoreEle = [].slice.call(innerEle.querySelectorAll('.' + CLS_TBARIGNORE));
const ignoreInx = [];
let count = 0;
if (ignoreEle.length > 0) {
ignoreEle.forEach((ele) => {
ignoreInx.push([].slice.call(innerEle.children).indexOf(ele));
});
}
else {
return 0;
}
ignoreInx.forEach((val) => {
if (val <= index) {
count++;
}
});
return count;
}
checkPopupRefresh(root, popEle) {
popEle.style.display = 'block';
const elWid = this.popupEleWidth(popEle.firstElementChild);
popEle.firstElementChild.style.removeProperty('Position');
const tbarWidth = root.offsetWidth - root.querySelector('.' + CLS_TBARNAV).offsetWidth;
const tbarItemsWid = root.querySelector('.' + CLS_ITEMS).offsetWidth;
popEle.style.removeProperty('display');
if (tbarWidth > (elWid + tbarItemsWid)) {
return true;
}
return false;
}
popupEleWidth(el) {
el.style.position = 'absolute';
const style = window.getComputedStyle(el);
let elWidth = this.isVertical
? el.offsetHeight
: el.offsetWidth + parseFloat(style.marginLeft) + parseFloat(style.marginRight);
const btnText = el.querySelector('.' + CLS_TBARBTNTEXT);
if (el.classList.contains('e-tbtn-align') || el.classList.contains(CLS_TBARTEXT)) {
const btn = el.children[0];
if (!isNullOrUndefined(btnText) && el.classList.contains(CLS_TBARTEXT)) {
btnText.style.display = 'none';
}
else if (!isNullOrUndefined(btnText) && el.classList.contains(CLS_POPUPTEXT)) {
btnText.style.display = 'block';
}
btn.style.minWidth = '0%';
elWidth = parseFloat(!this.isVertical ? el.style.minWidth : el.style.minHeight);
btn.style.minWidth = '';
btn.style.minHeight = '';
if (!isNullOrUndefined(btnText)) {
btnText.style.display = '';
}
}
return elWidth;
}
popupEleRefresh(width, popupEle, destroy) {
const popPriority = this.popupPriCount > 0;
let eleSplice = this.tbarEle;
let priEleCnt;
let index;
let innerEle = this.element.querySelector('.' + CLS_ITEMS);
let ignoreCount = 0;
for (const el of [].slice.call(popupEle.children)) {
if (el.classList.contains(CLS_POPPRI) && popPriority && !destroy) {
continue;
}
let elWidth = this.popupEleWidth(el);
if (el === this.tbarEle[0]) {
elWidth += this.tbarEleMrgn;
}
el.style.position = '';
if (elWidth < width || destroy) {
const inlineStyles = {
minWidth: el.style.minWidth, height: el.style.height,
minHeight: el.style.minHeight
};
setStyleAttribute(el, { minWidth: '', height: '', minHeight: '' });
if (!el.classList.contains(CLS_POPOVERFLOW)) {
el.classList.remove(CLS_POPUP);
}
index = this.tbarEle.indexOf(el);
if (this.tbarAlign) {
const pos = this.items[parseInt(index.toString(), 10)].align;
index = this.tbarAlgEle[(pos + 's').toLowerCase()].indexOf(el);
eleSplice = this.tbarAlgEle[(pos + 's').toLowerCase()];
innerEle = this.element.querySelector('.' + CLS_ITEMS + ' .' + 'e-toolbar-' + pos.toLowerCase());
}
let sepBeforePri = 0;
if (this.overflowMode !== 'Extended') {
eleSplice.slice(0, index).forEach((el) => {
if (el.classList.contains(CLS_TBAROVERFLOW) || el.classList.contains(CLS_SEPARATOR)) {
if (el.classList.contains(CLS_SEPARATOR)) {
el.style.display = '';
width -= el.offsetWidth;
}
sepBeforePri++;
}
});
}
ignoreCount = this.ignoreEleFetch(index, innerEle);
if (el.classList.contains(CLS_TBAROVERFLOW)) {
this.tbarPriRef(innerEle, index, sepBeforePri, el, destroy, elWidth, width, ignoreCount, inlineStyles);
width -= el.offsetWidth;
}
else if (index === 0) {
innerEle.insertBefore(el, innerEle.firstChild);
width -= el.offsetWidth;
}
else {
priEleCnt = selectAll('.' + CLS_TBAROVERFLOW, this.popObj.element).length;
innerEle.insertBefore(el, innerEle.children[(index + ignoreCount) - priEleCnt]);
width -= el.offsetWidth;
}
el.style.height = '';
}
else {
break;
}
}
const checkOverflow = this.checkOverflow(this.element, this.element.getElementsByClassName(CLS_ITEMS)[0]);
if (checkOverflow && !destroy) {
this.renderOverflowMode();
}
}
removePositioning() {
const item = this.element.querySelector('.' + CLS_ITEMS);
if (isNullOrUndefined(item) || !item.classList.contains(CLS_TBARPOS)) {
return;
}
this.remove(item, CLS_TBARPOS);
const innerItem = [].slice.call(item.childNodes);
innerItem[1].removeAttribute('style');
innerItem[2].removeAttribute('style');
}
refreshPositioning() {
const item = this.element.querySelector('.' + CLS_ITEMS);
this.add(item, CLS_TBARPOS);
this.itemPositioning();
}
itemPositioning() {
const item = this.element.querySelector('.' + CLS_ITEMS);
let margin;
if (isNullOrUndefined(item) || !item.classList.contains(CLS_TBARPOS)) {
return;
}
const popupNav = this.element.querySelector('.' + CLS_TBARNAV);
let innerItem;
if (this.scrollModule) {
const trgClass = (this.isVertical) ? CLS_VSCROLLCNT : CLS_HSCROLLCNT;
innerItem = [].slice.call(item.querySelector('.' + trgClass).children);
}
else {
innerItem = [].slice.call(item.childNodes);
}
if (this.isVertical) {
margin = innerItem[0].offsetHeight + innerItem[2].offsetHeight;
}
else {
margin = innerItem[0].offsetWidth + innerItem[2].offsetWidth;
}
let tbarWid = this.isVertical ? this.element.offsetHeight : this.element.offsetWidth;
if (popupNav) {
tbarWid -= (this.isVertical ? popupNav.offsetHeight : popupNav.offsetWidth);
const popWid = (this.isVertical ? popupNav.offsetHeight : popupNav.offsetWidth) + 'px';
innerItem[2].removeAttribute('style');
if (this.isVertical) {
if (this.enableRtl) {
innerItem[2].style.top = popWid;
}
else {
innerItem[2].style.bottom = popWid;
}
}
else {
if (this.enableRtl) {
innerItem[2].style.left = popWid;
}
else {
innerItem[2].style.right = popWid;
}
}
}
if (tbarWid <= margin) {
return;
}
const value = (((tbarWid - margin)) - (!this.isVertical ? innerItem[1].offsetWidth : innerItem[1].offsetHeight)) / 2;
innerItem[1].removeAttribute('style');
const mrgn = ((!this.isVertical ? innerItem[0].offsetWidth : innerItem[0].offsetHeight) + value) + 'px';
if (this.isVertical) {
if (this.enableRtl) {
innerItem[1].style.marginBottom = mrgn;
}
else {
innerItem[1].style.marginTop = mrgn;
}
}
else {
if (this.enableRtl) {
innerItem[1].style.marginRight = mrgn;
}
else {
innerItem[1].style.marginLeft = mrgn;
}
}
}
tbarItemAlign(item, itemEle, pos) {
if (item.showAlwaysInPopup && item.overflow !== 'Show') {
return;
}
const alignDiv = [];
alignDiv.push(this.createElement('div', { className: CLS_TBARLEFT, attrs: { role: 'group' } }));
alignDiv.push(this.createElement('div', { className: CLS_TBARCENTER, attrs: { role: 'group' } }));
alignDiv.push(this.createElement('div', { className: CLS_TBARRIGHT, attrs: { role: 'group' } }));
if (pos === 0 && item.align !== 'Left') {
alignDiv.forEach((ele) => {
itemEle.appendChild(ele);
});
this.tbarAlign = true;
this.add(itemEle, CLS_TBARPOS);
}
else if (item.align !== 'Left') {
const alignEle = itemEle.childNodes;
const leftAlign = alignDiv[0];
[].slice.call(alignEle).forEach((el) => {
this.tbarAlgEle.lefts.push(el);
leftAlign.appendChild(el);
});
itemEle.appendChild(leftAlign);
itemEle.appendChild(alignDiv[1]);
itemEle.appendChild(alignDiv[2]);
this.tbarAlign = true;
this.add(itemEle, CLS_TBARPOS);
}
}
ctrlTemplate() {
this.ctrlTem = this.trgtEle.cloneNode(true);
this.add(this.trgtEle, CLS_ITEMS);
this.tbarEle = [];
const innerEle = [].slice.call(this.trgtEle.children);
innerEle.forEach((ele) => {
if (ele.tagName === 'DIV') {
this.tbarEle.push(ele);
if (!isNullOrUndefined(ele.firstElementChild)) {
ele.firstElementChild.setAttribute('aria-disabled', 'false');
}
this.add(ele, CLS_ITEM);
}
});
}
renderItems() {
const ele = this.element;
const items = this.items;
if (this.trgtEle != null) {
this.ctrlTemplate();
}
else if (ele && items.length > 0) {
let itemEleDom;
if (ele && ele.children.length > 0) {
itemEleDom = ele.querySelector('.' + CLS_ITEMS);
}
if (!itemEleDom) {
itemEleDom = this.createElement('div', { className: CLS_ITEMS });
}
this.itemsAlign(items, itemEleDom);
ele.appendChild(itemEleDom);
}
}
setAttr(attr, element) {
const key = Object.keys(attr);
let keyVal;
for (let i = 0; i < key.length; i++) {
keyVal = key[parseInt(i.toString(), 10)];
if (keyVal === 'class') {
this.add(element, attr[`${keyVal}`]);
}
else {
element.setAttribute(keyVal, attr[`${keyVal}`]);
}
}
}
/**
* Enables or disables the specified Toolbar item.
*
* @param {number|HTMLElement|NodeList} items - DOM element or an array of items to be enabled or disabled.
* @param {boolean} isEnable - Boolean value that determines whether the command should be enabled or disabled.
* By default, `isEnable` is set to true.
* @returns {void}.
*/
enableItems(items, isEnable) {
const elements = items;
const len = elements.length;
let ele;
if (isNullOrUndefined(isEnable)) {
isEnable = true;
}
const enable = (isEnable, ele) => {
if (isEnable) {
ele.classList.remove(CLS_DISABLE$2);
if (!isNullOrUndefined(ele.firstElementChild)) {
ele.firstElementChild.setAttribute('aria-disabled', 'false');
this.updateTabIndex('0');
}
}
else {
ele.classList.add(CLS_DISABLE$2);
if (!isNullOrUndefined(ele.firstElementChild)) {
ele.firstElementChild.setAttribute('aria-disabled', 'true');
ele.firstElementChild.setAttribute('tabindex', '-1');
this.updateTabIndex('0');
}
}
};
if (!isNullOrUndefined(len) && len >= 1) {
for (let a = 0, element = [].slice.call(elements); a < len; a++) {
const itemElement = element[parseInt(a.toString(), 10)];
if (typeof (itemElement) === 'number') {
ele = this.getElementByIndex(itemElement);
if (isNullOrUndefined(ele)) {
return;
}
else {
elements[parseInt(a.toString(), 10)] = ele;
}
}
else {
ele = itemElement;
}
enable(isEnable, ele);
}
if (isEnable) {
removeClass(elements, CLS_DISABLE$2);
}
else {
addClass(elements, CLS_DISABLE$2);
}
}
else {
if (typeof (elements) === 'number') {
ele = this.getElementByIndex(elements);
if (isNullOrUndefined(ele)) {
return;
}
}
else {
ele = items;
}
enable(isEnable, ele);
}
}
getElementByIndex(index) {
if (this.tbarEle[parseInt(index.toString(), 10)]) {
return this.tbarEle[parseInt(index.toString(), 10)];
}
return null;
}
/**
* Adds new items to the Toolbar that accepts an array as Toolbar items.
*
* @param {ItemModel[]} items - DOM element or an array of items to be added to the Toolbar.
* @param {number} index - Number value that determines where the command is to be added. By default, index is 0.
* @returns {void}.
*/
addItems(items, index) {
let innerItems;
this.extendedOpen();
const itemsDiv = this.element.querySelector('.' + CLS_ITEMS);
if (isNullOrUndefined(itemsDiv)) {
this.itemsRerender(items);
return;
}
let innerEle;
let itemAgn = 'Left';
if (isNullOrUndefined(index)) {
index = 0;
}
items.forEach((e) => {
if (!isNullOrUndefined(e.align) && e.align !== 'Left' && itemAgn === 'Left') {
itemAgn = e.align;
}
});
for (const item of items) {
if (isNullOrUndefined(item.type)) {
item.type = 'Button';
}
innerItems = selectAll('.' + CLS_ITEM, this.element);
item.align = itemAgn;
innerEle = this.renderSubComponent(item, index);
if (this.tbarEle.length >= index && innerItems.length >= 0) {
if (isNullOrUndefined(this.scrollModule)) {
this.destroyMode();
}
const algIndex = item.align[0] === 'L' ? 0 : item.align[0] === 'C' ? 1 : 2;
let ele;
if (!this.tbarAlign && itemAgn !== 'Left') {
this.tbarItemAlign(item, itemsDiv, 1);
this.tbarAlign = true;
ele = closest(innerItems[0], '.' + CLS_ITEMS).children[parseInt(algIndex.toString(), 10)];
ele.appendChild(innerEle);
this.tbarAlgEle[(item.align + 's').toLowerCase()].push(innerEle);
this.refreshPositioning();
}
else if (this.tbarAlign) {
ele = closest(innerItems[0], '.' + CLS_ITEMS).children[parseInt(algIndex.toString(), 10)];
ele.insertBefore(innerEle, ele.children[parseInt(index.toString(), 10)]);
this.tbarAlgEle[(item.align + 's').toLowerCase()].splice(index, 0, innerEle);
this.refreshPositioning();
}
else if (innerItems.length === 0) {
innerItems = selectAll('.' + CLS_ITEMS, this.element);
innerItems[0].appendChild(innerEle);
}
else {
innerItems[0].parentNode.insertBefore(innerEle, innerItems[parseInt(index.toString(), 10)]);
}
this.items.splice(index, 0, item);
if (item.template) {
this.tbarEle.splice(this.tbarEle.length - 1, 1);
}
this.tbarEle.splice(index, 0, innerEle);
index++;
this.offsetWid = itemsDiv.offsetWidth;
}
}
itemsDiv.style.width = '';
this.renderOverflowMode();
if (this.isReact) {
this.renderReactTemplates();
}
}
/**
* Removes the items from the Toolbar. Acceptable arguments are index of item/HTMLElement/node list.
*
* @param {number|HTMLElement|NodeList|HTMLElement[]} args
* Index or DOM element or an Array of item which is to be removed from the Toolbar.
* @returns {void}.
*/
removeItems(args) {
const elements = args;
let index;
let innerItems = [].slice.call(selectAll('.' + CLS_ITEM, this.element));
if (typeof (elements) === 'number') {
index = parseInt(args.toString(), 10);
this.removeItemByIndex(index, innerItems);
}
else {
if (elements && elements.length > 1) {
for (const ele of [].slice.call(elements)) {
index = this.tbarEle.indexOf(ele);
this.removeItemByIndex(index, innerItems);
innerItems = selectAll('.' + CLS_ITEM, this.element);
}
}
else {
const ele = (elements && elements.length && elements.length === 1) ? elements[0] : args;
index = innerItems.indexOf(ele);
this.removeItemByIndex(index, innerItems);
}
}
this.resize();
}
removeItemByIndex(index, innerItems) {
if (this.tbarEle[parseInt(index.toString(), 10)] && innerItems[parseInt(index.toString(), 10)]) {
const eleIdx = this.tbarEle.indexOf(innerItems[parseInt(index.toString(), 10)]);
if (this.tbarAlign) {
const indexAgn = this.tbarAlgEle[(this.items[parseInt(eleIdx.toString(), 10)].align + 's').toLowerCase()].indexOf(this.tbarEle[parseInt(eleIdx.toString(), 10)]);
this.tbarAlgEle[(this.items[parseInt(eleIdx.toString(), 10)].align + 's').toLowerCase()].splice(parseInt(indexAgn.toString(), 10), 1);
}
if (this.isReact) {
this.clearToolbarTemplate(innerItems[parseInt(index.toString(), 10)]);
}
const btnItem = innerItems[parseInt(index.toString(), 10)].querySelector('.e-control.e-btn');
if (!isNullOrUndefined(btnItem) && !isNullOrUndefined(btnItem.ej2_instances[0]) && !(btnItem.ej2_instances[0].isDestroyed)) {
btnItem.ej2_instances[0].destroy();
}
detach(innerItems[parseInt(index.toString(), 10)]);
this.items.splice(eleIdx, 1);
this.tbarEle.splice(eleIdx, 1);
}
}
templateRender(templateProp, innerEle, item, index) {
const itemType = item.type;
const eleObj = templateProp;
let isComponent;
if (typeof (templateProp) === 'object') {
isComponent = typeof (eleObj.appendTo) === 'function';
}
if (typeof (templateProp) === 'string' || !isComponent) {
let templateFn;
let val = templateProp;
const regEx = new RegExp(/<(?=.*? .*?\/ ?>|br|hr|input|!--|wbr)[a-z]+.*?>|<([a-z]+).*?<\/\1>/i);
val = (typeof (templateProp) === 'string') ? templateProp.trim() : templateProp;
try {
if (typeof (templateProp) === 'object' && !isNullOrUndefined(templateProp.tagName)) {
innerEle.appendChild(templateProp);
}
else if (typeof (templateProp) === 'string' && regEx.test(val)) {
innerEle.innerHTML = val;
}
else if (document.querySelectorAll(val).length) {
const ele = document.querySelector(val);
const tempStr = ele.outerHTML.trim();
innerEle.appendChild(ele);
ele.style.display = '';
if (!isNullOrUndefined(tempStr)) {
this.tempId.push(val);
}
}
else {
templateFn = compile(val);
}
}
catch (e) {
templateFn = compile(val);
}
let tempArray;
if (!isNullOrUndefined(templateFn)) {
const toolbarTemplateID = this.element.id + index + '_template';
tempArray = templateFn({}, this, 'template', toolbarTemplateID, this.isStringTemplate, undefined, undefined, this.root);
}
if (!isNullOrUndefined(tempArray) && tempArray.length > 0) {
[].slice.call(tempArray).forEach((ele) => {
if (!isNullOrUndefined(ele.tagName)) {
ele.style.display = '';
}
innerEle.appendChild(ele);
});
}
}
else if (itemType === 'Input') {
const ele = this.createElement('input');
if (item.id) {
ele.id = item.id;
}
else {
ele.id = getUniqueID('tbr-ipt');
}
innerEle.appendChild(ele);
eleObj.appendTo(ele);
}
this.add(innerEle, CLS_TEMPLATE);
const firstChild = innerEle.firstElementChild;
if (!isNullOrUndefined(firstChild)) {
firstChild.setAttribute('tabindex', isNullOrUndefined(firstChild.getAttribute('tabIndex')) ? '-1' : this.getDataTabindex(firstChild));
firstChild.setAttribute('data-tabindex', isNullOrUndefined(firstChild.getAttribute('tabIndex')) ? '-1' : this.getDataTabindex(firstChild));
}
this.tbarEle.push(innerEle);
}
buttonRendering(item, innerEle) {
const dom = this.createElement('button', { className: CLS_TBARBTN });
dom.setAttribute('type', 'button');
const textStr = item.text;
let iconCss;
let iconPos;
if (item.id) {
dom.id = item.id;
}
else {
dom.id = getUniqueID('e-tbr-btn');
}
const btnTxt = this.createElement('span', { className: 'e-tbar-btn-text' });
if (textStr) {
btnTxt.innerHTML = this.enableHtmlSanitizer ? SanitizeHtmlHelper.sanitize(textStr) : textStr;
dom.appendChild(btnTxt);
dom.classList.add('e-tbtn-txt');
}
else {
this.add(innerEle, 'e-tbtn-align');
}
if (item.prefixIcon || item.suffixIcon) {
if ((item.prefixIcon && item.suffixIcon) || item.prefixIcon) {
iconCss = item.prefixIcon + ' e-icons';
iconPos = 'Left';
}
else {
iconCss = item.suffixIcon + ' e-icons';
iconPos = 'Right';
}
}
const btnObj = new Button({ iconCss: iconCss, iconPosition: iconPos });
btnObj.createElement = this.createElement;
btnObj.appendTo(dom);
if (item.width) {
setStyleAttribute(dom, { 'width': formatUnit(item.width) });
}
return dom;
}
renderSubComponent(item, index) {
let dom;
const innerEle = this.createElement('div', { className: CLS_ITEM });
const tempDom = this.createElement('div', {
innerHTML: this.enableHtmlSanitizer && !isNullOrUndefined(item.tooltipText) ?
SanitizeHtmlHelper.sanitize(item.tooltipText) : item.tooltipText
});
if (!this.tbarEle) {
this.tbarEle = [];
}
if (item.htmlAttributes) {
this.setAttr(item.htmlAttributes, innerEle);
}
if (item.tooltipText) {
innerEle.setAttribute('title', tempDom.textContent);
}
if (item.cssClass) {
innerEle.className = innerEle.className + ' ' + item.cssClass;
}
if (item.template) {
this.templateRender(item.template, innerEle, item, index);
}
else {
switch (item.type) {
case 'Button':
dom = this.buttonRendering(item, innerEle);
dom.setAttribute('tabindex', isNullOrUndefined(item.tabIndex) ? '-1' : item.tabIndex.toString());
dom.setAttribute('data-tabindex', isNullOrUndefined(item.tabIndex) ? '-1' : item.tabIndex.toString());
dom.setAttribute('aria-label', (item.text || item.tooltipText));
dom.setAttribute('aria-disabled', 'false');
innerEle.appendChild(dom);
innerEle.addEventListener('click', this.itemClick.bind(this));
break;
case 'Separator':
this.add(innerEle, CLS_SEPARATOR);
break;
}
}
if (item.showTextOn) {
const sTxt = item.showTextOn;
if (sTxt === 'Toolbar') {
this.add(innerEle, CLS_POPUPTEXT);
this.add(innerEle, 'e-tbtn-align');
}
else if (sTxt === 'Overflow') {
this.add(innerEle, CLS_TBARTEXT);
}
}
if (item.overflow) {
const overflow = item.overflow;
if (overflow === 'Show') {
this.add(innerEle, CLS_TBAROVERFLOW);
}
else if (overflow === 'Hide') {
if (!innerEle.classList.contains(CLS_SEPARATOR)) {
this.add(innerEle, CLS_POPOVERFLOW);
}
}
}
if (item.overflow !== 'Show' && item.showAlwaysInPopup && !innerEle.classList.contains(CLS_SEPARATOR)) {
this.add(innerEle, CLS_POPPRI);
this.popupPriCount++;
}
if (item.disabled) {
this.add(innerEle, CLS_DISABLE$2);
}
if (item.visible === false) {
this.add(innerEle, CLS_HIDDEN);
}
return innerEle;
}
getDataTabindex(ele) {
return isNullOrUndefined(ele.getAttribute('data-tabindex')) ? '-1' : ele.getAttribute('data-tabindex');
}
itemClick(e) {
this.activeEleSwitch(e.currentTarget);
}
activeEleSwitch(ele) {
this.activeEleRemove(ele.firstElementChild);
this.activeEle.focus();
}
activeEleRemove(curEle) {
let previousEle = this.element.querySelector('.' + CLS_ITEM + ':not(.' + CLS_DISABLE$2 + ' ):not(.' + CLS_SEPARATOR + ' ):not(.' + CLS_HIDDEN + ' )');
if (!isNullOrUndefined(this.activeEle)) {
this.activeEle.setAttribute('tabindex', this.getDataTabindex(this.activeEle));
if (previousEle) {
previousEle.removeAttribute('tabindex');
}
previousEle = this.activeEle;
}
this.activeEle = curEle;
if (this.getDataTabindex(this.activeEle) === '-1') {
if (isNullOrUndefined(this.trgtEle) && !curEle.parentElement.classList.contains(CLS_TEMPLATE)) {
if (!isNullOrUndefined(this.element.querySelector('.e-hor-nav')) && this.element.querySelector('.e-hor-nav').classList.contains('e-nav-active')) {
this.updateTabIndex('0');
const tabindexValue = this.getDataTabindex(previousEle) === '-1' ? '0' : this.getDataTabindex(previousEle);
previousEle.setAttribute('tabindex', tabindexValue);
}
else {
this.updateTabIndex('-1');
}
curEle.removeAttribute('tabindex');
}
else {
const tabIndex = parseInt(this.getDataTabindex(this.activeEle), 10) + 1;
this.activeEle.setAttribute('tabindex', tabIndex.toString());
}
}
}
getPersistData() {
return this.addOnPersist([]);
}
/**
* Returns the current module name.
*
* @returns {string} - Returns the module name as string.
* @private
*/
getModuleName() {
return 'toolbar';
}
itemsRerender(newProp) {
this.items = this.tbarItemsCol;
if (this.isReact || this.isAngular) {
this.clearTemplate();
}
this.destroyMode();
this.destroyItems();
this.items = newProp;
this.tbarItemsCol = this.items;
this.renderItems();
this.renderOverflowMode();
if (this.isReact) {
this.renderReactTemplates();
}
}
resize() {
const ele = this.element;
this.tbResize = true;
if (this.tbarAlign) {
this.itemPositioning();
}
if (this.popObj && this.overflowMode === 'Popup') {
this.popObj.hide();
}
const checkOverflow = this.checkOverflow(ele, ele.getElementsByClassName(CLS_ITEMS)[0]);
if (!checkOverflow) {
this.destroyScroll();
const multirowele = ele.querySelector('.' + CLS_ITEMS);
if (!isNullOrUndefined(multirowele)) {
this.remove(multirowele, CLS_MULTIROWPOS);
if (this.tbarAlign) {
this.add(multirowele, CLS_TBARPOS);
}
}
}
if (checkOverflow && this.scrollModule && (this.offsetWid === ele.offsetWidth)) {
return;
}
if (this.offsetWid > ele.offsetWidth || checkOverflow) {
this.renderOverflowMode();
}
if (this.popObj) {
if (this.overflowMode === 'Extended') {
this.popObj.width = this.getToolbarPopupWidth(this.element);
}
if (this.tbarAlign) {
this.removePositioning();
}
this.popupRefresh(this.popObj.element, false);
if (this.tbarAlign) {
this.refreshPositioning();
}
}
if (this.element.querySelector('.' + CLS_HSCROLLBAR$1)) {
this.scrollStep = this.element.querySelector('.' + CLS_HSCROLLBAR$1).offsetWidth;
}
this.offsetWid = ele.offsetWidth;
this.tbResize = false;
this.separator();
}
orientationChange() {
setTimeout(() => {
this.resize();
}, 500);
}
extendedOpen() {
const sib = this.element.querySelector('.' + CLS_EXTENDABLECLASS);
if (this.overflowMode === 'Extended' && sib) {
this.isExtendedOpen = sib.classList.contains(CLS_POPUPOPEN);
}
}
updateHideEleTabIndex(ele, isHidden, isElement, eleIndex, innerItems) {
if (isElement) {
eleIndex = innerItems.indexOf(ele);
}
let nextEle = innerItems[++eleIndex];
while (nextEle) {
const skipEle = this.eleContains(nextEle);
if (!skipEle) {
const dataTabIndex = nextEle.firstElementChild.getAttribute('data-tabindex');
if (isHidden && dataTabIndex === '-1') {
nextEle.firstElementChild.setAttribute('tabindex', '0');
}
else if (dataTabIndex !== nextEle.firstElementChild.getAttribute('tabindex')) {
nextEle.firstElementChild.setAttribute('tabindex', dataTabIndex);
}
break;
}
nextEle = innerItems[++eleIndex];
}
}
clearToolbarTemplate(templateEle) {
if (this.registeredTemplate && this.registeredTemplate[`${'template'}`]) {
const registeredTemplates = this.registeredTemplate;
for (let index = 0; index < registeredTemplates[`${'template'}`].length; index++) {
const registeredItem = registeredTemplates[`${'template'}`][parseInt(index.toString(), 10)].rootNodes[0];
const closestItem = closest(registeredItem, '.' + CLS_ITEM);
if (!isNullOrUndefined(closestItem) && closestItem === templateEle) {
this.clearTemplate(['template'], [registeredTemplates[`${'template'}`][parseInt(index.toString(), 10)]]);
break;
}
}
}
else if (this.portals && this.portals.length > 0) {
const portals = this.portals;
for (let index = 0; index < portals.length; index++) {
const portalItem = portals[parseInt(index.toString(), 10)];
const closestItem = closest(portalItem.containerInfo, '.' + CLS_ITEM);
if (!isNullOrUndefined(closestItem) && closestItem === templateEle) {
this.clearTemplate(['template'], index);
break;
}
}
}
}
/**
* Gets called when the model property changes.The data that describes the old and new values of the property that changed.
*
* @param {ToolbarModel} newProp - It contains new value of the data.
* @param {ToolbarModel} oldProp - It contains old value of the data.
* @returns {void}
* @private
*/
onPropertyChanged(newProp, oldProp) {
const tEle = this.element;
this.extendedOpen();
for (const prop of Object.keys(newProp)) {
switch (prop) {
case 'items':
if (!(newProp.items instanceof Array && oldProp.items instanceof Array)) {
const changedProb = Object.keys(newProp.items);
for (let i = 0; i < changedProb.length; i++) {
const index = parseInt(Object.keys(newProp.items)[parseInt(i.toString(), 10)], 10);
const property = Object.keys(newProp.items[parseInt(index.toString(), 10)])[0];
const newProperty = Object(newProp.items[parseInt(index.toString(), 10)])[`${property}`];
if (this.tbarAlign || property === 'align') {
this.refresh();
this.trigger('created');
break;
}
const popupPriCheck = property === 'showAlwaysInPopup' && !newProperty;
const booleanCheck = property === 'overflow' && this.popupPriCount !== 0;
if ((popupPriCheck) || (this.items[parseInt(index.toString(), 10)].showAlwaysInPopup) && booleanCheck) {
--this.popupPriCount;
}
if (isNullOrUndefined(this.scrollModule)) {
this.destroyMode();
}
const itemCol = [].slice.call(selectAll('.' + CLS_ITEMS + ' .' + CLS_ITEM, tEle));
if (this.isReact && this.items[parseInt(index.toString(), 10)].template) {
this.clearToolbarTemplate(itemCol[parseInt(index.toString(), 10)]);
}
detach(itemCol[parseInt(index.toString(), 10)]);
this.tbarEle.splice(index, 1);
this.addItems([this.items[parseInt(index.toString(), 10)]], index);
this.items.splice(index, 1);
if (this.items[parseInt(index.toString(), 10)].template) {
this.tbarEle.splice(this.items.length, 1);
}
}
}
else {
this.itemsRerender(newProp.items);
}
break;
case 'width':
setStyleAttribute(tEle, { 'width': formatUnit(newProp.width) });
this.refreshOverflow();
break;
case 'height':
setStyleAttribute(this.element, { 'height': formatUnit(newProp.height) });
break;
case 'overflowMode':
this.destroyMode();
this.renderOverflowMode();
if (this.enableRtl) {
this.add(tEle, CLS_RTL$2);
}
this.refreshOverflow();
break;
case 'enableRtl':
if (newProp.enableRtl) {
this.add(tEle, CLS_RTL$2);
}
else {
this.remove(tEle, CLS_RTL$2);
}
if (!isNullOrUndefined(this.scrollModule)) {
if (newProp.enableRtl) {
this.add(this.scrollModule.element, CLS_RTL$2);
}
else {
this.remove(this.scrollModule.element, CLS_RTL$2);
}
}
if (!isNullOrUndefined(this.popObj)) {
if (newProp.enableRtl) {
this.add(this.popObj.element, CLS_RTL$2);
}
else {
this.remove(this.popObj.element, CLS_RTL$2);
}
}
if (this.tbarAlign) {
this.itemPositioning();
}
break;
case 'scrollStep':
if (this.scrollModule) {
this.scrollModule.scrollStep = this.scrollStep;
}
break;
case 'enableCollision':
if (this.popObj) {
this.popObj.collision = { Y: this.enableCollision ? 'flip' : 'none' };
}
break;
case 'cssClass':
if (oldProp.cssClass) {
removeClass([this.element], oldProp.cssClass.split(' '));
}
if (newProp.cssClass) {
addClass([this.element], newProp.cssClass.split(' '));
}
break;
case 'allowKeyboard':
this.unwireKeyboardEvent();
if (newProp.allowKeyboard) {
this.wireKeyboardEvent();
}
break;
}
}
}
/**
* Shows or hides the Toolbar item that is in the specified index.
*
* @param {number | HTMLElement} index - Index value of target item or DOM element of items to be hidden or shown.
* @param {boolean} value - Based on this Boolean value, item will be hide (true) or show (false). By default, value is false.
* @returns {void}.
*/
hideItem(index, value) {
const isElement = (typeof (index) === 'object') ? true : false;
const eleIndex = index;
let ele;
if (!isElement && isNullOrUndefined(eleIndex)) {
return;
}
const innerItems = [].slice.call(selectAll('.' + CLS_ITEM, this.element));
if (isElement) {
ele = index;
}
else if (this.tbarEle[parseInt(eleIndex.toString(), 10)]) {
const innerItems = [].slice.call(selectAll('.' + CLS_ITEM, this.element));
ele = innerItems[parseInt(eleIndex.toString(), 10)];
}
if (ele) {
if (value) {
ele.classList.add(CLS_HIDDEN);
if (!ele.classList.contains(CLS_SEPARATOR)) {
if (isNullOrUndefined(ele.firstElementChild.getAttribute('tabindex')) ||
ele.firstElementChild.getAttribute('tabindex') !== '-1') {
this.updateHideEleTabIndex(ele, value, isElement, eleIndex, innerItems);
}
}
}
else {
ele.classList.remove(CLS_HIDDEN);
if (!ele.classList.contains(CLS_SEPARATOR)) {
this.updateHideEleTabIndex(ele, value, isElement, eleIndex, innerItems);
}
}
this.refreshOverflow();
}
}
};
__decorate$3([
Collection([], Item)
], Toolbar.prototype, "items", void 0);
__decorate$3([
Property('auto')
], Toolbar.prototype, "width", void 0);
__decorate$3([
Property('auto')
], Toolbar.prototype, "height", void 0);
__decorate$3([
Property('')
], Toolbar.prototype, "cssClass", void 0);
__decorate$3([
Property('Scrollable')
], Toolbar.prototype, "overflowMode", void 0);
__decorate$3([
Property()
], Toolbar.prototype, "scrollStep", void 0);
__decorate$3([
Property(true)
], Toolbar.prototype, "enableCollision", void 0);
__decorate$3([
Property(true)
], Toolbar.prototype, "enableHtmlSanitizer", void 0);
__decorate$3([
Property(true)
], Toolbar.prototype, "allowKeyboard", void 0);
__decorate$3([
Event()
], Toolbar.prototype, "clicked", void 0);
__decorate$3([
Event()
], Toolbar.prototype, "created", void 0);
__decorate$3([
Event()
], Toolbar.prototype, "destroyed", void 0);
__decorate$3([
Event()
], Toolbar.prototype, "beforeCreate", void 0);
__decorate$3([
Event()
], Toolbar.prototype, "keyDown", void 0);
Toolbar = __decorate$3([
NotifyPropertyChanges
], Toolbar);
var __decorate$4 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const CLS_ACRDN_ROOT = 'e-acrdn-root';
const CLS_ROOT$2 = 'e-accordion';
const CLS_ITEM$1 = 'e-acrdn-item';
const CLS_ITEMFOCUS = 'e-item-focus';
const CLS_ITEMHIDE = 'e-hide';
const CLS_HEADER = 'e-acrdn-header';
const CLS_HEADERICN = 'e-acrdn-header-icon';
const CLS_HEADERCTN = 'e-acrdn-header-content';
const CLS_CONTENT = 'e-acrdn-panel';
const CLS_CTENT = 'e-acrdn-content';
const CLS_TOOGLEICN = 'e-toggle-icon';
const CLS_COLLAPSEICN = 'e-tgl-collapse-icon e-icons';
const CLS_EXPANDICN = 'e-expand-icon';
const CLS_RTL$3 = 'e-rtl';
const CLS_CTNHIDE = 'e-content-hide';
const CLS_SLCT = 'e-select';
const CLS_SLCTED = 'e-selected';
const CLS_ACTIVE = 'e-active';
const CLS_ANIMATE = 'e-animate';
const CLS_DISABLE$3 = 'e-overlay';
const CLS_TOGANIMATE = 'e-toggle-animation';
const CLS_NEST = 'e-nested';
const CLS_EXPANDSTATE = 'e-expand-state';
const CLS_CONTAINER = 'e-accordion-container';
/**
* Objects used for configuring the Accordion expanding item action properties.
*/
class AccordionActionSettings extends ChildProperty {
}
__decorate$4([
Property('SlideDown')
], AccordionActionSettings.prototype, "effect", void 0);
__decorate$4([
Property(400)
], AccordionActionSettings.prototype, "duration", void 0);
__decorate$4([
Property('linear')
], AccordionActionSettings.prototype, "easing", void 0);
/**
* Objects used for configuring the Accordion animation properties.
*/
class AccordionAnimationSettings extends ChildProperty {
}
__decorate$4([
Complex({ effect: 'SlideUp', duration: 400, easing: 'linear' }, AccordionActionSettings)
], AccordionAnimationSettings.prototype, "collapse", void 0);
__decorate$4([
Complex({ effect: 'SlideDown', duration: 400, easing: 'linear' }, AccordionActionSettings)
], AccordionAnimationSettings.prototype, "expand", void 0);
/**
* An item object that is used to configure Accordion items.
*/
class AccordionItem extends ChildProperty {
}
__decorate$4([
Property(null)
], AccordionItem.prototype, "content", void 0);
__decorate$4([
Property(null)
], AccordionItem.prototype, "header", void 0);
__decorate$4([
Property(null)
], AccordionItem.prototype, "cssClass", void 0);
__decorate$4([
Property(null)
], AccordionItem.prototype, "iconCss", void 0);
__decorate$4([
Property(false)
], AccordionItem.prototype, "expanded", void 0);
__decorate$4([
Property(true)
], AccordionItem.prototype, "visible", void 0);
__decorate$4([
Property(false)
], AccordionItem.prototype, "disabled", void 0);
__decorate$4([
Property()
], AccordionItem.prototype, "id", void 0);
/**
* The Accordion is a vertically collapsible content panel that displays one or more panels at a time within the available space.
* ```html
* <div id='accordion'/>
* <script>
* var accordionObj = new Accordion();
* accordionObj.appendTo('#accordion');
* </script>
* ```
*/
let Accordion = class Accordion extends Component {
/**
* Initializes a new instance of the Accordion class.
*
* @param {AccordionModel} options - Specifies Accordion model properties as options.
* @param {string | HTMLElement} element - Specifies the element that is rendered as an Accordion.
*/
constructor(options, element) {
super(options, element);
/**
* Contains the keyboard configuration of the Accordion.
*/
this.keyConfigs = {
moveUp: 'uparrow',
moveDown: 'downarrow',
enter: 'enter',
space: 'space',
home: 'home',
end: 'end'
};
}
/**
* Removes the control from the DOM and also removes all its related events.
*
* @returns {void}
*/
destroy() {
if (this.isReact || this.isAngular || this.isVue) {
this.clearTemplate();
}
const ele = this.element;
super.destroy();
this.unWireEvents();
this.isDestroy = true;
this.restoreContent(null);
[].slice.call(ele.children).forEach((el) => {
ele.removeChild(el);
});
if (this.trgtEle) {
this.trgtEle = null;
while (this.ctrlTem.firstElementChild) {
ele.appendChild(this.ctrlTem.firstElementChild);
}
this.ctrlTem = null;
}
ele.classList.remove(CLS_ACRDN_ROOT);
ele.removeAttribute('style');
this.element.removeAttribute('data-ripple');
if (!this.isNested && isRippleEnabled) {
this.removeRippleEffect();
}
}
preRender() {
const nested = closest(this.element, '.' + CLS_CONTENT);
this.isNested = false;
this.templateEle = [];
if (!this.isDestroy) {
this.isDestroy = false;
}
if (nested && nested.firstElementChild && nested.firstElementChild.firstElementChild) {
if (nested.firstElementChild.firstElementChild.classList.contains(CLS_ROOT$2)) {
nested.classList.add(CLS_NEST);
this.isNested = true;
}
}
else {
this.element.classList.add(CLS_ACRDN_ROOT);
}
if (this.enableRtl) {
this.add(this.element, CLS_RTL$3);
}
}
add(ele, val) {
ele.classList.add(val);
}
remove(ele, val) {
ele.classList.remove(val);
}
/**
* To initialize the control rendering
*
* @private
* @returns {void}
*/
render() {
this.initializeHeaderTemplate();
this.initializeItemTemplate();
this.initialize();
this.renderControl();
this.wireEvents();
this.renderComplete();
}
initialize() {
const width = formatUnit(this.width);
const height = formatUnit(this.height);
setStyleAttribute(this.element, { 'width': width, 'height': height });
if (isNullOrUndefined(this.initExpand)) {
this.initExpand = [];
}
if (!isNullOrUndefined(this.expandedIndices) && this.expandedIndices.length > 0) {
this.initExpand = this.expandedIndices;
}
}
renderControl() {
this.trgtEle = (this.element.children.length > 0) ? select('div', this.element) : null;
this.renderItems();
this.initItemExpand();
}
wireFocusEvents() {
const acrdItem = [].slice.call(this.element.querySelectorAll('.' + CLS_ITEM$1));
for (const item of acrdItem) {
const headerEle = item.querySelector('.' + CLS_HEADER);
if (item.childElementCount > 0 && headerEle) {
EventHandler.clearEvents(headerEle);
EventHandler.add(headerEle, 'focus', this.focusIn, this);
EventHandler.add(headerEle, 'blur', this.focusOut, this);
}
}
}
unWireEvents() {
EventHandler.remove(this.element, 'click', this.clickHandler);
if (!isNullOrUndefined(this.keyModule)) {
this.keyModule.destroy();
}
}
wireEvents() {
EventHandler.add(this.element, 'click', this.clickHandler, this);
if (!this.isNested && !this.isDestroy) {
this.removeRippleEffect = rippleEffect(this.element, { selector: '.' + CLS_HEADER });
}
if (!this.isNested) {
this.keyModule = new KeyboardEvents(this.element, {
keyAction: this.keyActionHandler.bind(this),
keyConfigs: this.keyConfigs,
eventName: 'keydown'
});
}
}
templateParser(template) {
if (template) {
try {
if (typeof template !== 'function' && document.querySelectorAll(template).length) {
return compile(document.querySelector(template).innerHTML.trim());
}
else {
return compile(template);
}
}
catch (error) {
return compile(template);
}
}
return undefined;
}
initializeHeaderTemplate() {
if (this.headerTemplate) {
this.headerTemplateFn = this.templateParser(this.headerTemplate);
}
}
initializeItemTemplate() {
if (this.itemTemplate) {
this.itemTemplateFn = this.templateParser(this.itemTemplate);
}
}
getHeaderTemplate() {
return this.headerTemplateFn;
}
getItemTemplate() {
return this.itemTemplateFn;
}
focusIn(e) {
e.target.parentElement.classList.add(CLS_ITEMFOCUS);
}
focusOut(e) {
e.target.parentElement.classList.remove(CLS_ITEMFOCUS);
}
ctrlTemplate() {
this.ctrlTem = this.element.cloneNode(true);
let innerEles;
const rootEle = select('.' + CLS_CONTAINER, this.element);
if (rootEle) {
innerEles = rootEle.children;
}
else {
innerEles = this.element.children;
}
const items = [];
[].slice.call(innerEles).forEach((el) => {
items.push({
header: (el.childElementCount > 0 && el.children[0]) ? (el.children[0]) : '',
content: (el.childElementCount > 1 && el.children[1]) ? (el.children[1]) : ''
});
el.parentNode.removeChild(el);
});
if (rootEle) {
this.element.removeChild(rootEle);
}
this.setProperties({ items: items }, true);
}
toggleIconGenerate() {
const tglIcon = this.createElement('div', { className: CLS_TOOGLEICN });
const hdrColIcon = this.createElement('span', { className: CLS_COLLAPSEICN });
tglIcon.appendChild(hdrColIcon);
return tglIcon;
}
initItemExpand() {
const len = this.initExpand.length;
if (len === 0) {
return;
}
if (this.expandMode === 'Single') {
this.expandItem(true, this.initExpand[len - 1]);
}
else {
for (let i = 0; i < len; i++) {
this.expandItem(true, this.initExpand[parseInt(i.toString(), 10)]);
}
}
if (this.isReact) {
this.renderReactTemplates();
}
}
renderItems() {
const ele = this.element;
let innerItem;
let innerDataSourceItem;
if (!isNullOrUndefined(this.trgtEle)) {
this.ctrlTemplate();
}
if (!isNullOrUndefined(this.dataSource) && this.dataSource.length > 0) {
this.dataSource.forEach((item, index) => {
innerDataSourceItem = this.renderInnerItem(item, index);
ele.appendChild(innerDataSourceItem);
if (innerDataSourceItem.childElementCount > 0) {
EventHandler.add(innerDataSourceItem.querySelector('.' + CLS_HEADER), 'focus', this.focusIn, this);
EventHandler.add(innerDataSourceItem.querySelector('.' + CLS_HEADER), 'blur', this.focusOut, this);
}
});
}
else {
const items = this.items;
if (ele && items.length > 0) {
items.forEach((item, index) => {
innerItem = this.renderInnerItem(item, index);
ele.appendChild(innerItem);
if (innerItem.childElementCount > 0) {
EventHandler.add(innerItem.querySelector('.' + CLS_HEADER), 'focus', this.focusIn, this);
EventHandler.add(innerItem.querySelector('.' + CLS_HEADER), 'blur', this.focusOut, this);
}
});
}
}
if (this.isReact) {
this.renderReactTemplates();
}
}
clickHandler(e) {
const trgt = e.target;
const items = this.getItems();
const eventArgs = {};
let tglIcon;
const acrdEle = closest(trgt, '.' + CLS_ROOT$2);
if (acrdEle !== this.element) {
return;
}
trgt.classList.add('e-target');
const acrdnItem = closest(trgt, '.' + CLS_ITEM$1);
let acrdnHdr = closest(trgt, '.' + CLS_HEADER);
let acrdnCtn = closest(trgt, '.' + CLS_CONTENT);
if (acrdnItem && (isNullOrUndefined(acrdnHdr) || isNullOrUndefined(acrdnCtn))) {
acrdnHdr = acrdnItem.children[0];
acrdnCtn = acrdnItem.children[1];
}
if (acrdnHdr) {
tglIcon = select('.' + CLS_TOOGLEICN, acrdnHdr);
}
let acrdnCtnItem;
if (acrdnHdr) {
acrdnCtnItem = closest(acrdnHdr, '.' + CLS_ITEM$1);
}
else if (acrdnCtn) {
acrdnCtnItem = closest(acrdnCtn, '.' + CLS_ITEM$1);
}
const index = this.getIndexByItem(acrdnItem);
if (acrdnCtnItem) {
eventArgs.item = items[this.getIndexByItem(acrdnCtnItem)];
}
eventArgs.originalEvent = e;
const ctnCheck = !isNullOrUndefined(tglIcon) && acrdnItem.childElementCount <= 1;
if (ctnCheck && (isNullOrUndefined(acrdnCtn) || !isNullOrUndefined(select('.' + CLS_HEADER + ' .' + CLS_TOOGLEICN, acrdnCtnItem)))) {
acrdnItem.appendChild(this.contentRendering(index));
this.ariaAttrUpdate(acrdnItem);
this.afterContentRender(trgt, eventArgs, acrdnItem, acrdnHdr, acrdnCtn, acrdnCtnItem);
}
else {
this.afterContentRender(trgt, eventArgs, acrdnItem, acrdnHdr, acrdnCtn, acrdnCtnItem);
}
if (this.isReact) {
this.renderReactTemplates();
}
}
afterContentRender(trgt, eventArgs, acrdnItem, acrdnHdr, acrdnCtn, acrdnCtnItem) {
const acrdActive = [];
this.trigger('clicked', eventArgs, (eventArgs) => {
if (eventArgs.cancel) {
return;
}
let cntclkCheck = (acrdnCtn && !isNullOrUndefined(select('.e-target', acrdnCtn)));
const inlineAcrdnSel = '.' + CLS_CONTENT + ' .' + CLS_ROOT$2;
const inlineEleAcrdn = acrdnCtn && !isNullOrUndefined(select('.' + CLS_ROOT$2, acrdnCtn)) && isNullOrUndefined(closest(trgt, inlineAcrdnSel));
const nestContCheck = acrdnCtn && isNullOrUndefined(select('.' + CLS_ROOT$2, acrdnCtn)) || !(closest(trgt, '.' + CLS_ROOT$2) === this.element);
cntclkCheck = cntclkCheck && (inlineEleAcrdn || nestContCheck);
trgt.classList.remove('e-target');
if (trgt.classList.contains(CLS_CONTENT) || trgt.classList.contains(CLS_CTENT) || cntclkCheck) {
return;
}
const acrdcontainer = this.element.querySelector('.' + CLS_CONTAINER);
const acrdnchild = (acrdcontainer) ? acrdcontainer.children : this.element.children;
[].slice.call(acrdnchild).forEach((el) => {
if (el.classList.contains(CLS_ACTIVE)) {
acrdActive.push(el);
}
});
const acrdAniEle = [].slice.call(this.element.querySelectorAll('.' + CLS_ITEM$1 + ' [' + CLS_ANIMATE + ']'));
if (acrdAniEle.length > 0) {
for (const el of acrdAniEle) {
acrdActive.push(el.parentElement);
}
}
const sameContentCheck = acrdActive.indexOf(acrdnCtnItem) !== -1 && acrdnCtn.getAttribute('e-animate') === 'true';
let sameHeader = false;
if (!isNullOrUndefined(acrdnItem) && !isNullOrUndefined(acrdnHdr)) {
const acrdnCtn = select('.' + CLS_CONTENT, acrdnItem);
const acrdnRoot = closest(acrdnItem, '.' + CLS_ACRDN_ROOT);
const expandState = acrdnRoot.querySelector('.' + CLS_EXPANDSTATE);
if (isNullOrUndefined(acrdnCtn)) {
return;
}
sameHeader = (expandState === acrdnItem);
if (isVisible(acrdnCtn) && (!sameContentCheck || acrdnCtnItem.classList.contains(CLS_SLCTED))) {
this.collapse(acrdnCtn);
}
else {
if ((acrdActive.length > 0) && this.expandMode === 'Single' && !sameContentCheck) {
acrdActive.forEach((el) => {
this.collapse(select('.' + CLS_CONTENT, el));
el.classList.remove(CLS_EXPANDSTATE);
});
}
this.expand(acrdnCtn);
}
if (!isNullOrUndefined(expandState) && !sameHeader) {
expandState.classList.remove(CLS_EXPANDSTATE);
}
}
});
}
eleMoveFocus(action, root, trgt) {
let clst;
let clstItem = closest(trgt, '.' + CLS_ITEM$1);
if (trgt === root) {
clst = ((action === 'moveUp' ? trgt.lastElementChild : trgt).querySelector('.' + CLS_HEADER));
}
else if (trgt.classList.contains(CLS_HEADER)) {
clstItem = (action === 'moveUp' ? clstItem.previousElementSibling : clstItem.nextElementSibling);
if (clstItem) {
clst = select('.' + CLS_HEADER, clstItem);
}
}
if (clst) {
clst.focus();
}
}
keyActionHandler(e) {
const trgt = e.target;
const header = closest(e.target, CLS_HEADER);
if (isNullOrUndefined(header) && !trgt.classList.contains(CLS_ROOT$2) && !trgt.classList.contains(CLS_HEADER)) {
return;
}
let clst;
const root = this.element;
let content;
switch (e.action) {
case 'moveUp':
this.eleMoveFocus(e.action, root, trgt);
break;
case 'moveDown':
this.eleMoveFocus(e.action, root, trgt);
break;
case 'space':
case 'enter':
content = trgt.nextElementSibling;
if (!isNullOrUndefined(content) && content.classList.contains(CLS_CONTENT)) {
if (content.getAttribute('e-animate') !== 'true') {
trgt.click();
}
}
else {
trgt.click();
}
e.preventDefault();
break;
case 'home':
case 'end':
clst = e.action === 'home' ? root.firstElementChild.children[0] : root.lastElementChild.children[0];
clst.focus();
e.preventDefault();
break;
}
}
headerEleGenerate() {
const header = this.createElement('div', { className: CLS_HEADER, id: getUniqueID('acrdn_header') });
const ariaAttr = {
'tabindex': '0', 'role': 'button', 'aria-disabled': 'false', 'aria-expanded': 'false'
};
attributes(header, ariaAttr);
return header;
}
renderInnerItem(item, index) {
const innerEle = this.createElement('div', {
className: CLS_ITEM$1, id: item.id || getUniqueID('acrdn_item')
});
if (this.headerTemplate) {
const ctnEle = this.headerEleGenerate();
const hdrEle = this.createElement('div', { className: CLS_HEADERCTN });
ctnEle.appendChild(hdrEle);
append(this.getHeaderTemplate()(item, this, 'headerTemplate', this.element.id + '_headerTemplate', false), hdrEle);
innerEle.appendChild(ctnEle);
ctnEle.appendChild(this.toggleIconGenerate());
this.add(innerEle, CLS_SLCT);
return innerEle;
}
if (item.header && this.angularnativeCondiCheck(item, 'header')) {
let header = item.header;
if (this.enableHtmlSanitizer && typeof (item.header) === 'string') {
header = SanitizeHtmlHelper.sanitize(item.header);
}
const ctnEle = this.headerEleGenerate();
const hdrEle = this.createElement('div', { className: CLS_HEADERCTN });
ctnEle.appendChild(hdrEle);
ctnEle.appendChild(this.fetchElement(hdrEle, header, index));
innerEle.appendChild(ctnEle);
}
let hdr = select('.' + CLS_HEADER, innerEle);
if (item.expanded && !isNullOrUndefined(index) && (!this.enablePersistence)) {
if (this.initExpand.indexOf(index) === -1) {
this.initExpand.push(index);
}
}
if (item.cssClass) {
addClass([innerEle], item.cssClass.split(' '));
}
if (item.disabled) {
addClass([innerEle], CLS_DISABLE$3);
}
if (item.visible === false) {
addClass([innerEle], CLS_ITEMHIDE);
}
if (item.iconCss) {
const hdrIcnEle = this.createElement('div', { className: CLS_HEADERICN });
const icon = this.createElement('span', { className: item.iconCss + ' e-icons' });
hdrIcnEle.appendChild(icon);
if (isNullOrUndefined(hdr)) {
hdr = this.headerEleGenerate();
hdr.appendChild(hdrIcnEle);
innerEle.appendChild(hdr);
}
else {
hdr.insertBefore(hdrIcnEle, hdr.childNodes[0]);
}
}
if (item.content && this.angularnativeCondiCheck(item, 'content')) {
const hdrIcon = this.toggleIconGenerate();
if (isNullOrUndefined(hdr)) {
hdr = this.headerEleGenerate();
innerEle.appendChild(hdr);
}
hdr.appendChild(hdrIcon);
this.add(innerEle, CLS_SLCT);
}
return innerEle;
}
angularnativeCondiCheck(item, prop) {
const property = prop === 'content' ? item.content : item.header;
const content = property;
if (this.isAngular && !isNullOrUndefined(content.elementRef)) {
const data = content.elementRef.nativeElement.data;
if (isNullOrUndefined(data) || data === '' || (data.indexOf('bindings=') === -1)) {
return true;
}
const parseddata = JSON.parse(content.elementRef.nativeElement.data.replace('bindings=', ''));
if (!isNullOrUndefined(parseddata) && parseddata['ng-reflect-ng-if'] === 'false') {
return false;
}
else {
return true;
}
}
else {
return true;
}
}
fetchElement(ele, value, index) {
let templateFn;
let temString;
try {
if (document.querySelectorAll(value).length && value !== 'Button') {
const eleVal = document.querySelector(value);
temString = eleVal.outerHTML.trim();
ele.appendChild(eleVal);
eleVal.style.display = '';
}
else {
templateFn = compile(value);
}
}
catch (e) {
if (typeof (value) === 'string') {
ele.innerHTML = this.enableHtmlSanitizer ? SanitizeHtmlHelper.sanitize(value) : value;
}
else if (value instanceof (HTMLElement)) {
ele.appendChild(value);
if (this.trgtEle) {
ele.firstElementChild.style.display = '';
}
}
else {
templateFn = compile(value);
}
}
let tempArray;
if (!isNullOrUndefined(templateFn)) {
if (this.isReact) {
this.renderReactTemplates();
}
let templateProps;
let templateName;
if (ele.classList.contains(CLS_HEADERCTN)) {
templateProps = this.element.id + index + '_header';
templateName = 'header';
}
else if (ele.classList.contains(CLS_CTENT)) {
templateProps = this.element.id + index + '_content';
templateName = 'content';
}
tempArray = templateFn({}, this, templateName, templateProps, this.isStringTemplate);
}
if (!isNullOrUndefined(tempArray) && tempArray.length > 0 && !(isNullOrUndefined(tempArray[0].tagName) && tempArray.length === 1)) {
[].slice.call(tempArray).forEach((el) => {
if (!isNullOrUndefined(el.tagName)) {
el.style.display = '';
}
ele.appendChild(el);
});
}
else if (ele.childElementCount === 0) {
ele.innerHTML = this.enableHtmlSanitizer ? SanitizeHtmlHelper.sanitize(value) : value;
}
if (!isNullOrUndefined(temString)) {
if (this.templateEle.indexOf(value) === -1) {
this.templateEle.push(value);
}
}
return ele;
}
ariaAttrUpdate(itemEle) {
const header = select('.' + CLS_HEADER, itemEle);
const content = select('.' + CLS_CONTENT, itemEle);
header.setAttribute('aria-controls', content.id);
content.setAttribute('aria-labelledby', header.id);
content.setAttribute('role', 'region');
}
contentRendering(index) {
const itemcnt = this.createElement('div', { className: CLS_CONTENT + ' ' + CLS_CTNHIDE, id: getUniqueID('acrdn_panel') });
attributes(itemcnt, { 'aria-hidden': 'true' });
const ctn = this.createElement('div', { className: CLS_CTENT });
if (!isNullOrUndefined(this.dataSource) && this.dataSource.length > 0) {
if (this.isReact) {
this.renderReactTemplates();
}
append(this.getItemTemplate()(this.dataSource[parseInt(index.toString(), 10)], this, 'itemTemplate', this.element.id + '_itemTemplate', false), ctn);
itemcnt.appendChild(ctn);
}
else {
let content = this.items[parseInt(index.toString(), 10)].content;
if (this.enableHtmlSanitizer && typeof (content) === 'string') {
content = SanitizeHtmlHelper.sanitize(content);
}
itemcnt.appendChild(this.fetchElement(ctn, content, index));
}
return itemcnt;
}
expand(trgt) {
const items = this.getItems();
const trgtItemEle = closest(trgt, '.' + CLS_ITEM$1);
if (isNullOrUndefined(trgt) || (isVisible(trgt) && trgt.getAttribute('e-animate') !== 'true') || trgtItemEle.classList.contains(CLS_DISABLE$3)) {
return;
}
const acrdnRoot = closest(trgtItemEle, '.' + CLS_ACRDN_ROOT);
const expandState = acrdnRoot.querySelector('.' + CLS_EXPANDSTATE);
const animation = {
name: this.animation.expand.effect,
duration: this.animation.expand.duration,
timingFunction: this.animation.expand.easing
};
const icon = select('.' + CLS_TOOGLEICN, trgtItemEle).firstElementChild;
const eventArgs = {
element: trgtItemEle,
item: items[this.getIndexByItem(trgtItemEle)],
index: this.getIndexByItem(trgtItemEle),
content: trgtItemEle.querySelector('.' + CLS_CONTENT),
isExpanded: true
};
this.trigger('expanding', eventArgs, (expandArgs) => {
if (!expandArgs.cancel) {
icon.classList.add(CLS_TOGANIMATE);
this.expandedItemsPush(trgtItemEle);
if (!isNullOrUndefined(expandState)) {
expandState.classList.remove(CLS_EXPANDSTATE);
}
trgtItemEle.classList.add(CLS_EXPANDSTATE);
if ((animation.name === 'None' && animationMode !== 'Enable') || (animationMode === 'Disable')) {
this.expandProgress('begin', icon, trgt, trgtItemEle, expandArgs);
this.expandProgress('end', icon, trgt, trgtItemEle, expandArgs);
}
else {
this.expandAnimation(animation.name, icon, trgt, trgtItemEle, animation, expandArgs);
}
}
});
}
expandAnimation(ef, icn, trgt, trgtItemEle, animate, args) {
if (ef === 'None' && animationMode === 'Enable') {
ef = 'SlideDown';
animate.name = 'SlideDown';
}
let height;
this.lastActiveItemId = trgtItemEle.id;
if (ef === 'SlideDown') {
animate.begin = () => {
this.expandProgress('begin', icn, trgt, trgtItemEle, args);
trgt.style.position = 'absolute';
height = trgtItemEle.offsetHeight;
trgt.style.maxHeight = (trgt.offsetHeight) + 'px';
trgtItemEle.style.maxHeight = '';
};
animate.progress = () => {
trgtItemEle.style.minHeight = (height + trgt.offsetHeight) + 'px';
};
animate.end = () => {
setStyleAttribute(trgt, { 'position': '', 'maxHeight': '' });
trgtItemEle.style.minHeight = '';
this.expandProgress('end', icn, trgt, trgtItemEle, args);
};
}
else {
animate.begin = () => {
this.expandProgress('begin', icn, trgt, trgtItemEle, args);
};
animate.end = () => {
this.expandProgress('end', icn, trgt, trgtItemEle, args);
};
}
new Animation(animate).animate(trgt);
}
expandProgress(progress, icon, trgt, trgtItemEle, eventArgs) {
this.remove(trgt, CLS_CTNHIDE);
this.add(trgtItemEle, CLS_SLCTED);
this.add(icon, CLS_EXPANDICN);
if (progress === 'end') {
this.add(trgtItemEle, CLS_ACTIVE);
trgt.setAttribute('aria-hidden', 'false');
attributes(trgt.previousElementSibling, { 'aria-expanded': 'true' });
icon.classList.remove(CLS_TOGANIMATE);
this.trigger('expanded', eventArgs);
}
}
expandedItemsPush(item) {
const index = this.getIndexByItem(item);
if (this.expandedIndices.indexOf(index) === -1) {
const temp = [].slice.call(this.expandedIndices);
temp.push(index);
this.setProperties({ expandedIndices: temp }, true);
}
}
getIndexByItem(item) {
const itemEle = this.getItemElements();
return [].slice.call(itemEle).indexOf(item);
}
getItemElements() {
const itemEle = [];
const itemCollection = this.element.children;
[].slice.call(itemCollection).forEach((el) => {
if (el.classList.contains(CLS_ITEM$1)) {
itemEle.push(el);
}
});
return itemEle;
}
expandedItemsPop(item) {
const index = this.getIndexByItem(item);
const temp = [].slice.call(this.expandedIndices);
temp.splice(temp.indexOf(index), 1);
this.setProperties({ expandedIndices: temp }, true);
}
collapse(trgt) {
if (isNullOrUndefined(trgt)) {
return;
}
const items = this.getItems();
const trgtItemEle = closest(trgt, '.' + CLS_ITEM$1);
if (!isVisible(trgt) || trgtItemEle.classList.contains(CLS_DISABLE$3)) {
return;
}
const animation = {
name: this.animation.collapse.effect,
duration: this.animation.collapse.duration,
timingFunction: this.animation.collapse.easing
};
const icon = select('.' + CLS_TOOGLEICN, trgtItemEle).firstElementChild;
const eventArgs = {
element: trgtItemEle,
item: items[this.getIndexByItem(trgtItemEle)],
index: this.getIndexByItem(trgtItemEle),
content: trgtItemEle.querySelector('.' + CLS_CONTENT),
isExpanded: false
};
this.trigger('expanding', eventArgs, (expandArgs) => {
if (!expandArgs.cancel) {
this.expandedItemsPop(trgtItemEle);
trgtItemEle.classList.remove(CLS_EXPANDSTATE);
icon.classList.add(CLS_TOGANIMATE);
if ((animation.name === 'None' && animationMode !== 'Enable') || (animationMode === 'Disable')) {
this.collapseProgress('begin', icon, trgt, trgtItemEle, expandArgs);
this.collapseProgress('end', icon, trgt, trgtItemEle, expandArgs);
}
else {
this.collapseAnimation(animation.name, trgt, trgtItemEle, icon, animation, expandArgs);
}
}
});
}
collapseAnimation(ef, trgt, trgtItEl, icn, animate, args) {
if (ef === 'None' && animationMode === 'Enable') {
ef = 'SlideUp';
animate.name = 'SlideUp';
}
let height;
let trgtHeight;
let itemHeight;
let remain;
this.lastActiveItemId = trgtItEl.id;
if (ef === 'SlideUp') {
animate.begin = () => {
itemHeight = trgtItEl.offsetHeight;
trgtItEl.style.minHeight = itemHeight + 'px';
trgt.style.position = 'absolute';
height = trgtItEl.offsetHeight;
trgtHeight = trgt.offsetHeight;
trgt.style.maxHeight = trgtHeight + 'px';
this.collapseProgress('begin', icn, trgt, trgtItEl, args);
};
animate.progress = () => {
remain = ((height - (trgtHeight - trgt.offsetHeight)));
if (remain < itemHeight) {
trgtItEl.style.minHeight = remain + 'px';
}
};
animate.end = () => {
trgt.style.display = 'none';
this.collapseProgress('end', icn, trgt, trgtItEl, args);
trgtItEl.style.minHeight = '';
setStyleAttribute(trgt, { 'position': '', 'maxHeight': '', 'display': '' });
};
}
else {
animate.begin = () => {
this.collapseProgress('begin', icn, trgt, trgtItEl, args);
};
animate.end = () => {
this.collapseProgress('end', icn, trgt, trgtItEl, args);
};
}
new Animation(animate).animate(trgt);
}
collapseProgress(progress, icon, trgt, trgtItemEle, eventArgs) {
this.remove(icon, CLS_EXPANDICN);
this.remove(trgtItemEle, CLS_SLCTED);
if (progress === 'end') {
this.add(trgt, CLS_CTNHIDE);
icon.classList.remove(CLS_TOGANIMATE);
this.remove(trgtItemEle, CLS_ACTIVE);
trgt.setAttribute('aria-hidden', 'true');
attributes(trgt.previousElementSibling, { 'aria-expanded': 'false' });
this.trigger('expanded', eventArgs);
}
}
/**
* Returns the current module name.
*
* @returns {string} - It returns the current module name.
* @private
*/
getModuleName() {
return 'accordion';
}
getItems() {
let items;
if (this.itemTemplate && this.headerTemplate) {
items = this.dataSource;
}
else {
items = this.items;
}
return items;
}
/**
* Adds new item to the Accordion with the specified index of the Accordion.
*
* @param {AccordionItemModel | AccordionItemModel[] | Object | Object[]} item - Item array that is to be added to the Accordion.
* @param {number} index - Number value that determines where the item should be added.
* By default, item is added at the last index if the index is not specified.
* @returns {void}
*/
addItem(item, index) {
const ele = this.element;
const itemEle = this.getItemElements();
const items = this.getItems();
if (isNullOrUndefined(index)) {
index = items.length;
}
if (ele.childElementCount >= index) {
const addItems = (item instanceof Array) ? item : [item];
addItems.forEach((addItem, i) => {
const itemIndex = index + i;
items.splice(itemIndex, 0, addItem);
const innerItemEle = this.renderInnerItem(addItem, itemIndex);
if (ele.childElementCount === itemIndex) {
ele.appendChild(innerItemEle);
}
else {
ele.insertBefore(innerItemEle, itemEle[parseInt(itemIndex.toString(), 10)]);
}
EventHandler.add(innerItemEle.querySelector('.' + CLS_HEADER), 'focus', this.focusIn, this);
EventHandler.add(innerItemEle.querySelector('.' + CLS_HEADER), 'blur', this.focusOut, this);
this.expandedIndices = [];
this.expandedItemRefresh();
if (addItem && addItem.expanded) {
this.expandItem(true, itemIndex);
}
});
}
if (this.isReact) {
this.renderReactTemplates();
}
}
expandedItemRefresh() {
const itemEle = this.getItemElements();
[].slice.call(itemEle).forEach((el) => {
if (el.classList.contains(CLS_SLCTED)) {
this.expandedItemsPush(el);
}
});
}
/**
* Dynamically removes item from Accordion.
*
* @param {number} index - Number value that determines which item should be removed.
* @returns {void}.
*/
removeItem(index) {
if (this.isReact || this.isAngular) {
const item = selectAll('.' + CLS_ITEM$1, this.element)[parseInt(index.toString(), 10)];
const header = select('.' + CLS_HEADERCTN, item);
const content = select('.' + CLS_CTENT, item);
this.clearAccordionTemplate(header, this.dataSource.length > 0 ? 'headerTemplate' : 'header', CLS_HEADERCTN);
this.clearAccordionTemplate(content, this.dataSource.length > 0 ? 'itemTemplate' : 'content', CLS_CTENT);
}
const itemEle = this.getItemElements();
const ele = itemEle[parseInt(index.toString(), 10)];
const items = this.getItems();
if (isNullOrUndefined(ele)) {
return;
}
this.restoreContent(index);
detach(ele);
items.splice(index, 1);
this.expandedIndices = [];
this.expandedItemRefresh();
}
/**
* Sets focus to the specified index item header in Accordion.
*
* @param {number} index - Number value that determines which item should be focused.
* @returns {void}.
*/
select(index) {
const itemEle = this.getItemElements();
const ele = itemEle[parseInt(index.toString(), 10)];
if (isNullOrUndefined(ele) || isNullOrUndefined(select('.' + CLS_HEADER, ele))) {
return;
}
ele.children[0].focus();
}
/**
* Shows or hides the specified item from Accordion.
*
* @param {number} index - Number value that determines which item should be hidden/shown.
* @param {boolean} isHidden - Boolean value that determines the action either hide (true) or show (false). Default value is false.
* If the `isHidden` value is false, the item is shown or else item it is hidden.
* @returns {void}.
*/
hideItem(index, isHidden) {
const itemEle = this.getItemElements();
const ele = itemEle[parseInt(index.toString(), 10)];
if (isNullOrUndefined(ele)) {
return;
}
if (isNullOrUndefined(isHidden)) {
isHidden = true;
}
if (isHidden) {
this.add(ele, CLS_ITEMHIDE);
}
else {
this.remove(ele, CLS_ITEMHIDE);
}
}
/**
* Enables/Disables the specified Accordion item.
*
* @param {number} index - Number value that determines which item should be enabled/disabled.
* @param {boolean} isEnable - Boolean value that determines the action as enable (true) or disable (false).
* If the `isEnable` value is true, the item is enabled or else it is disabled.
* @returns {void}.
*/
enableItem(index, isEnable) {
const itemEle = this.getItemElements();
const ele = itemEle[parseInt(index.toString(), 10)];
if (isNullOrUndefined(ele)) {
return;
}
const eleHeader = ele.firstElementChild;
if (isEnable) {
this.remove(ele, CLS_DISABLE$3);
attributes(eleHeader, { 'tabindex': '0', 'aria-disabled': 'false' });
eleHeader.focus();
}
else {
if (ele.classList.contains(CLS_ACTIVE)) {
this.expandItem(false, index);
this.eleMoveFocus('movedown', this.element, eleHeader);
}
this.add(ele, CLS_DISABLE$3);
eleHeader.setAttribute('aria-disabled', 'true');
eleHeader.removeAttribute('tabindex');
}
}
/**
* Expands/Collapses the specified Accordion item.
*
* @param {boolean} isExpand - Boolean value that determines the action as expand or collapse.
* @param {number} index - Number value that determines which item should be expanded/collapsed.`index` is optional parameter.
* Without Specifying index, based on the `isExpand` value all Accordion item can be expanded or collapsed.
* @returns {void}.
*/
expandItem(isExpand, index) {
const itemEle = this.getItemElements();
if (isNullOrUndefined(index)) {
if (this.expandMode === 'Single' && isExpand) {
const ele = itemEle[itemEle.length - 1];
this.itemExpand(isExpand, ele, this.getIndexByItem(ele));
}
else {
const item = select('#' + this.lastActiveItemId, this.element);
[].slice.call(itemEle).forEach((el) => {
this.itemExpand(isExpand, el, this.getIndexByItem(el));
el.classList.remove(CLS_EXPANDSTATE);
});
const expandedItem = select('.' + CLS_EXPANDSTATE, this.element);
if (expandedItem) {
expandedItem.classList.remove(CLS_EXPANDSTATE);
}
if (item) {
item.classList.add(CLS_EXPANDSTATE);
}
}
}
else {
const ele = itemEle[parseInt(index.toString(), 10)];
if (isNullOrUndefined(ele) || !ele.classList.contains(CLS_SLCT) || (ele.classList.contains(CLS_ACTIVE) && isExpand)) {
return;
}
else {
if (this.expandMode === 'Single') {
this.expandItem(false);
}
this.itemExpand(isExpand, ele, index);
}
}
}
itemExpand(isExpand, ele, index) {
let ctn = ele.children[1];
if (ele.classList.contains(CLS_DISABLE$3)) {
return;
}
if (isNullOrUndefined(ctn) && isExpand) {
ctn = this.contentRendering(index);
ele.appendChild(ctn);
this.ariaAttrUpdate(ele);
this.expand(ctn);
}
else if (!isNullOrUndefined(ctn)) {
if (isExpand) {
this.expand(ctn);
}
else {
this.collapse(ctn);
}
}
if (this.isReact) {
this.renderReactTemplates();
}
}
destroyItems() {
this.restoreContent(null);
if (this.isReact || this.isAngular || this.isVue) {
this.clearTemplate();
}
[].slice.call(this.element.querySelectorAll('.' + CLS_ITEM$1)).forEach((el) => {
detach(el);
});
}
restoreContent(index) {
let ctnElePos;
if (isNullOrUndefined(index)) {
ctnElePos = this.element;
}
else {
ctnElePos = this.element.querySelectorAll('.' + CLS_ITEM$1)[parseInt(index.toString(), 10)];
}
this.templateEle.forEach((eleStr) => {
if (!isNullOrUndefined(ctnElePos.querySelector(eleStr))) {
document.body.appendChild(ctnElePos.querySelector(eleStr)).style.display = 'none';
}
});
}
updateItem(item, index) {
if (!isNullOrUndefined(item)) {
const items = this.getItems();
const itemObj = items[parseInt(index.toString(), 10)];
items.splice(index, 1);
this.restoreContent(index);
const header = select('.' + CLS_HEADERCTN, item);
const content = select('.' + CLS_CTENT, item);
if (this.isReact || this.isAngular) {
this.clearAccordionTemplate(header, 'header', CLS_HEADERCTN);
this.clearAccordionTemplate(content, 'content', CLS_CTENT);
}
detach(item);
this.addItem(itemObj, index);
}
}
setTemplate(template, toElement, index) {
this.fetchElement(toElement, template, index);
if (this.isReact) {
this.renderReactTemplates();
}
}
clearAccordionTemplate(templateEle, templateName, className) {
if (this.registeredTemplate && this.registeredTemplate[`${templateName}`]) {
const registeredTemplates = this.registeredTemplate;
for (let index = 0; index < registeredTemplates[`${templateName}`].length; index++) {
const registeredItem = registeredTemplates[`${templateName}`][parseInt(index.toString(), 10)].rootNodes[0];
const closestItem = closest(registeredItem, '.' + className);
if (!isNullOrUndefined(closestItem) && closestItem === templateEle || isNullOrUndefined(registeredItem.parentNode)) {
this.clearTemplate([templateName], [registeredTemplates[`${templateName}`][parseInt(index.toString(), 10)]]);
break;
}
}
}
else if (this.portals && this.portals.length > 0) {
const portals = this.portals;
for (let index = 0; index < portals.length; index++) {
const portalItem = portals[parseInt(index.toString(), 10)];
const closestItem = closest(portalItem.containerInfo, '.' + className);
if (!isNullOrUndefined(closestItem) && closestItem === templateEle) {
this.clearTemplate([templateName], index);
break;
}
}
}
}
getPersistData() {
const keyEntity = ['expandedIndices'];
return this.addOnPersist(keyEntity);
}
/**
* Gets called when the model property changes.The data that describes the old and new values of the property that changed.
*
* @param {AccordionModel} newProp - It contains the new value of data.
* @param {AccordionModel} oldProp - It contains the old value of data.
* @returns {void}
* @private
*/
onPropertyChanged(newProp, oldProp) {
const acrdn = this.element;
let isRefresh = false;
for (const prop of Object.keys(newProp)) {
switch (prop) {
case 'items':
if (!(newProp.items instanceof Array && oldProp.items instanceof Array)) {
const changedProp = Object.keys(newProp.items);
for (let j = 0; j < changedProp.length; j++) {
const index = parseInt(Object.keys(newProp.items)[parseInt(j.toString(), 10)], 10);
const property = Object.keys(newProp.items[parseInt(index.toString(), 10)]);
for (let k = 0; k < property.length; k++) {
const item = selectAll('.' + CLS_ITEM$1, this.element)[parseInt(index.toString(), 10)];
const oldVal = Object(oldProp.items[parseInt(index.toString(), 10)])[`${property[parseInt(k.toString(), 10)]}`];
const newVal = Object(newProp.items[parseInt(index.toString(), 10)])[`${property[parseInt(k.toString(), 10)]}`];
const temp = property[parseInt(k.toString(), 10)];
const content = select('.' + CLS_CTENT, item);
if (temp === 'header' || temp === 'iconCss' || temp === 'expanded' || ((temp === 'content') && (oldVal === ''))) {
this.updateItem(item, index);
}
if (property[parseInt(k.toString(), 10)] === 'cssClass' && !isNullOrUndefined(item)) {
if (oldVal) {
removeClass([item], oldVal.split(' '));
}
if (newVal) {
addClass([item], newVal.split(' '));
}
}
if (property[parseInt(k.toString(), 10)] === 'visible' && !isNullOrUndefined(item)) {
if (Object(newProp.items[parseInt(index.toString(), 10)])[`${property[parseInt(k.toString(), 10)]}`] === false) {
item.classList.add(CLS_ITEMHIDE);
}
else {
item.classList.remove(CLS_ITEMHIDE);
}
}
if (property[parseInt(k.toString(), 10)] === 'disabled' && !isNullOrUndefined(item)) {
this.enableItem(index, !newVal);
}
if (property.indexOf('header') < 0 && property[parseInt(k.toString(), 10)] === 'content'
&& !isNullOrUndefined(item) && item.children.length === 2) {
if (typeof newVal === 'function') {
if (this.isAngular || this.isReact) {
this.clearAccordionTemplate(content, property[parseInt(k.toString(), 10)], CLS_CTENT);
}
const activeContent = item.querySelector('.' + CLS_CTENT);
activeContent.innerHTML = '';
this.setTemplate(newVal, activeContent, index);
}
else {
if (item.classList.contains(CLS_SLCTED)) {
this.expandItem(false, index);
}
detach(item.querySelector('.' + CLS_CONTENT));
}
}
}
}
}
else {
isRefresh = true;
}
break;
case 'dataSource':
case 'expandedIndices':
if (this.expandedIndices === null) {
this.expandedIndices = [];
}
isRefresh = true;
break;
case 'headerTemplate':
this.initializeHeaderTemplate();
isRefresh = true;
break;
case 'itemTemplate':
this.initializeItemTemplate();
isRefresh = true;
break;
case 'enableRtl':
if (newProp.enableRtl) {
this.add(acrdn, CLS_RTL$3);
}
else {
this.remove(acrdn, CLS_RTL$3);
}
break;
case 'height':
setStyleAttribute(this.element, { 'height': formatUnit(newProp.height) });
break;
case 'width':
setStyleAttribute(this.element, { 'width': formatUnit(newProp.width) });
break;
case 'expandMode':
if (newProp.expandMode === 'Single' && !isNullOrUndefined(this.expandedIndices) && this.expandedIndices.length > 1) {
this.expandItem(false);
}
break;
}
}
if (isRefresh) {
this.initExpand = [];
if (!isNullOrUndefined(this.expandedIndices) && this.expandedIndices.length > 0) {
this.initExpand = this.expandedIndices;
}
this.destroyItems();
this.renderItems();
this.initItemExpand();
}
}
};
__decorate$4([
Collection([], AccordionItem)
], Accordion.prototype, "items", void 0);
__decorate$4([
Property([])
], Accordion.prototype, "dataSource", void 0);
__decorate$4([
Property()
], Accordion.prototype, "itemTemplate", void 0);
__decorate$4([
Property()
], Accordion.prototype, "headerTemplate", void 0);
__decorate$4([
Property('100%')
], Accordion.prototype, "width", void 0);
__decorate$4([
Property('auto')
], Accordion.prototype, "height", void 0);
__decorate$4([
Property([])
], Accordion.prototype, "expandedIndices", void 0);
__decorate$4([
Property('Multiple')
], Accordion.prototype, "expandMode", void 0);
__decorate$4([
Property(true)
], Accordion.prototype, "enableHtmlSanitizer", void 0);
__decorate$4([
Complex({}, AccordionAnimationSettings)
], Accordion.prototype, "animation", void 0);
__decorate$4([
Event()
], Accordion.prototype, "clicked", void 0);
__decorate$4([
Event()
], Accordion.prototype, "expanding", void 0);
__decorate$4([
Event()
], Accordion.prototype, "expanded", void 0);
__decorate$4([
Event()
], Accordion.prototype, "created", void 0);
__decorate$4([
Event()
], Accordion.prototype, "destroyed", void 0);
Accordion = __decorate$4([
NotifyPropertyChanges
], Accordion);
var __decorate$5 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const CONTEXTMENUTEMPLATE = 'e-contextmenu-template';
/**
* The ContextMenu is a graphical user interface that appears on the user right click/touch hold operation.
* ```html
* <div id = 'target'></div>
* <ul id = 'contextmenu'></ul>
* ```
* ```typescript
* <script>
* var contextMenuObj = new ContextMenu({items: [{ text: 'Cut' }, { text: 'Copy' },{ text: 'Paste' }], target: '#target'});
* </script>
* ```
*/
let ContextMenu = class ContextMenu extends MenuBase {
/**
* Constructor for creating the widget.
*
* @private
* @param {ContextMenuModel} options - Specifies the context menu model
* @param {string} element - Specifies the element
*/
constructor(options, element) {
super(options, element);
}
/**
* For internal use only - prerender processing.
*
* @private
* @returns {void}
*/
preRender() {
this.isMenu = false;
this.element.id = this.element.id || getUniqueID('ej2-contextmenu');
super.preRender();
}
initialize() {
this.template = this.itemTemplate ? this.itemTemplate : null;
this.addTemplateClass();
super.initialize();
attributes(this.element, { 'role': 'menubar', 'tabindex': '0' });
this.element.style.zIndex = getZindexPartial(this.element).toString();
}
/**
* This method is used to open the ContextMenu in specified position.
*
* @param {number} top - To specify ContextMenu vertical positioning.
* @param {number} left - To specify ContextMenu horizontal positioning.
* @param {HTMLElement} target - To calculate z-index for ContextMenu based upon the specified target.
* @function open
* @returns {void}
*/
open(top, left, target) {
this.isOpenCalled = true;
super.openMenu(null, null, top, left, null, target);
this.isOpenCalled = false;
}
/**
* Closes the ContextMenu if it is opened.
*
* @function close
* @returns {void}
*/
close() {
super.closeMenu();
}
addTemplateClass() {
if (!isNullOrUndefined(this.itemTemplate) && typeof this.itemTemplate === 'function' ||
(typeof this.itemTemplate === 'string' && this.itemTemplate !== '')) {
addClass([this.element], CONTEXTMENUTEMPLATE);
}
}
/**
* Called internally if any of the property value changed.
*
* @private
* @param {ContextMenuModel} newProp - Specifies new properties
* @param {ContextMenuModel} oldProp - Specifies old properties
* @returns {void}
*/
onPropertyChanged(newProp, oldProp) {
super.onPropertyChanged(newProp, oldProp);
for (const prop of Object.keys(newProp)) {
switch (prop) {
case 'filter':
this.close();
this.filter = newProp.filter;
break;
case 'target':
this.unWireEvents(oldProp.target);
this.wireEvents();
break;
case 'itemTemplate':
this.itemTemplate = newProp.itemTemplate;
removeClass([this.element], CONTEXTMENUTEMPLATE);
this.addTemplateClass();
this.refresh();
}
}
}
/**
* Get module name.
*
* @returns {string} - Module Name
* @private
*/
getModuleName() {
return 'contextmenu';
}
};
__decorate$5([
Property('')
], ContextMenu.prototype, "target", void 0);
__decorate$5([
Property('')
], ContextMenu.prototype, "filter", void 0);
__decorate$5([
Collection([], MenuItem)
], ContextMenu.prototype, "items", void 0);
__decorate$5([
Property(null)
], ContextMenu.prototype, "itemTemplate", void 0);
__decorate$5([
Property(false)
], ContextMenu.prototype, "enableScrolling", void 0);
ContextMenu = __decorate$5([
NotifyPropertyChanges
], ContextMenu);
var __decorate$6 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const VMENU = 'e-vertical';
const SCROLLABLE = 'e-scrollable';
const HAMBURGER = 'e-hamburger';
/**
* The Menu is a graphical user interface that serve as navigation headers for your application or site.
* ```html
* <ul id = 'menu'></ul>
* ```
* ```typescript
* <script>
* var menuObj = new Menu({ items: [{ text: 'Home' }, { text: 'Contact Us' },{ text: 'Login' }]});
* menuObj.appendTo("#menu");
* </script>
* ```
*/
let Menu = class Menu extends MenuBase {
/**
* Constructor for creating the component.
*
* @private
* @param {MenuModel} options - Specifies the menu model
* @param {string} element - Specifies the element
*/
constructor(options, element) {
super(options, element);
this.tempItems = [];
}
/**
* Get module name.
*
* @private
* @returns {string} - Module Name
*/
getModuleName() {
return 'menu';
}
/**
* For internal use only - prerender processing.
*
* @private
* @returns {void}
*/
preRender() {
this.isMenu = true;
this.element.id = this.element.id || getUniqueID('ej2-menu');
if (this.template) {
try {
if (typeof this.template !== 'function' && document.querySelectorAll(this.template).length) {
this.template = document.querySelector(this.template).innerHTML.trim();
this.clearChanges();
}
}
catch (e) {
/* action on catch */
}
this.updateMenuItems(this.items);
}
else {
this.updateMenuItems(this.items);
}
super.preRender();
}
initialize() {
super.initialize();
attributes(this.element, { 'role': 'menubar', 'tabindex': '0' });
if (this.orientation === 'Vertical') {
this.element.classList.add(VMENU);
if (this.hamburgerMode && !this.target) {
this.element.previousElementSibling.classList.add(VMENU);
}
this.element.setAttribute('aria-orientation', 'vertical');
}
else {
if (Browser.isDevice && !this.enableScrolling) {
this.element.parentElement.classList.add(SCROLLABLE);
}
}
if (this.hamburgerMode) {
this.element.parentElement.classList.add(HAMBURGER);
if (this.orientation === 'Horizontal') {
this.element.classList.add('e-hide-menu');
}
}
}
updateMenuItems(items) {
this.tempItems = items;
this.items = [];
this.tempItems.map(this.createMenuItems, this);
this.setProperties({ items: this.items }, true);
this.tempItems = [];
}
/**
* Called internally if any of the property value changed.
*
* @private
* @param {MenuModel} newProp - Specifies the new properties.
* @param {MenuModel} oldProp - Specifies the old properties.
* @returns {void}
*/
onPropertyChanged(newProp, oldProp) {
for (const prop of Object.keys(newProp)) {
switch (prop) {
case 'orientation':
if (newProp.orientation === 'Vertical') {
this.element.classList.add(VMENU);
if (this.hamburgerMode) {
if (!this.target) {
this.element.previousElementSibling.classList.add(VMENU);
}
this.element.classList.remove('e-hide-menu');
}
this.element.setAttribute('aria-orientation', 'vertical');
}
else {
this.element.classList.remove(VMENU);
if (this.hamburgerMode) {
if (!this.target) {
this.element.previousElementSibling.classList.remove(VMENU);
}
this.element.classList.add('e-hide-menu');
}
this.element.removeAttribute('aria-orientation');
}
break;
case 'items':
if (!Object.keys(oldProp.items).length) {
this.updateMenuItems(newProp.items);
}
break;
case 'hamburgerMode':
if (!this.element.previousElementSibling) {
super.createHeaderContainer();
}
if (newProp.hamburgerMode) {
this.element.parentElement.classList.add(HAMBURGER);
[].slice.call(this.element.getElementsByClassName('e-blankicon')).forEach((li) => {
li.style[this.enableRtl ? 'paddingRight' : 'paddingLeft'] = '';
});
}
else {
this.element.parentElement.classList.remove(HAMBURGER);
if (this.orientation === 'Vertical') {
this.setBlankIconStyle(this.element);
}
}
if (this.orientation === 'Vertical') {
if (!this.target) {
this.element.previousElementSibling.classList.add(VMENU);
}
this.element.classList.remove('e-hide-menu');
}
else {
if (this.target) {
this.element.previousElementSibling.classList.add(VMENU);
}
else {
this.element.previousElementSibling.classList.remove(VMENU);
}
this.element.classList[newProp.hamburgerMode ? 'add' : 'remove']('e-hide-menu');
}
break;
case 'title':
if (this.hamburgerMode && this.element.previousElementSibling) {
newProp.title = (this.enableHtmlSanitizer) ? SanitizeHtmlHelper.sanitize(newProp.title) : newProp.title;
this.element.previousElementSibling.querySelector('.e-menu-title').innerHTML = newProp.title;
}
break;
case 'target':
if (this.hamburgerMode) {
this.unWireEvents(oldProp.target);
this.wireEvents();
if (this.orientation === 'Horizontal') {
if (!newProp.target) {
if (!this.element.previousElementSibling) {
super.createHeaderContainer();
}
this.element.previousElementSibling.classList.remove(VMENU);
}
else {
this.element.previousElementSibling.classList.add(VMENU);
}
this.element.classList.add('e-hide-menu');
}
}
break;
case 'template':
this.template = newProp.template;
this.refresh();
break;
}
}
super.onPropertyChanged(newProp, oldProp);
}
createMenuItems(item) {
let idx;
let i;
let items = this.items;
const pIdField = this.getField('parentId');
if (item[`${pIdField}`]) {
idx = this.getIndex(item[`${pIdField}`].toString(), true);
for (i = 0; i < idx.length; i++) {
if (!items[idx[i]].items) {
items[idx[i]].items = [];
}
items = items[idx[i]].items;
}
items.push(item);
}
else {
this.items.push(item);
}
}
/**
* This method is used to open the Menu in hamburger mode.
*
* @function open
* @returns {void}
*/
open() {
super.openHamburgerMenu();
}
/**
* Closes the Menu if it is opened in hamburger mode.
*
* @function close
* @returns {void}
*/
close() {
super.closeHamburgerMenu();
}
};
__decorate$6([
Property('Horizontal')
], Menu.prototype, "orientation", void 0);
__decorate$6([
Property('')
], Menu.prototype, "target", void 0);
__decorate$6([
Property(null)
], Menu.prototype, "template", void 0);
__decorate$6([
Property(false)
], Menu.prototype, "enableScrolling", void 0);
__decorate$6([
Property(false)
], Menu.prototype, "hamburgerMode", void 0);
__decorate$6([
Property('Menu')
], Menu.prototype, "title", void 0);
__decorate$6([
Property(true)
], Menu.prototype, "enableHtmlSanitizer", void 0);
__decorate$6([
Complex({ itemId: 'id', text: 'text', parentId: 'parentId', iconCss: 'iconCss', url: 'url', separator: 'separator', children: 'items' }, FieldSettings)
], Menu.prototype, "fields", void 0);
Menu = __decorate$6([
NotifyPropertyChanges
], Menu);
var __decorate$7 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const CLS_TAB = 'e-tab';
const CLS_HEADER$1 = 'e-tab-header';
const CLS_BLA_TEM = 'blazor-template';
const CLS_CONTENT$1 = 'e-content';
const CLS_NEST$1 = 'e-nested';
const CLS_ITEMS$1 = 'e-items';
const CLS_ITEM$2 = 'e-item';
const CLS_TEMPLATE$1 = 'e-template';
const CLS_RTL$4 = 'e-rtl';
const CLS_ACTIVE$1 = 'e-active';
const CLS_DISABLE$4 = 'e-disable';
const CLS_HIDDEN$1 = 'e-hidden';
const CLS_FOCUS = 'e-focused';
const CLS_ICONS = 'e-icons';
const CLS_ICON = 'e-icon';
const CLS_ICON_TAB = 'e-icon-tab';
const CLS_ICON_CLOSE = 'e-close-icon';
const CLS_CLOSE_SHOW = 'e-close-show';
const CLS_TEXT = 'e-tab-text';
const CLS_INDICATOR = 'e-indicator';
const CLS_WRAP = 'e-tab-wrap';
const CLS_TEXT_WRAP = 'e-text-wrap';
const CLS_TAB_ICON = 'e-tab-icon';
const CLS_TB_ITEMS = 'e-toolbar-items';
const CLS_TB_ITEM = 'e-toolbar-item';
const CLS_TB_POP = 'e-toolbar-pop';
const CLS_TB_POPUP = 'e-toolbar-popup';
const CLS_HOR_NAV = 'e-hor-nav';
const CLS_POPUP_OPEN = 'e-popup-open';
const CLS_POPUP_CLOSE = 'e-popup-close';
const CLS_PROGRESS = 'e-progress';
const CLS_IGNORE = 'e-ignore';
const CLS_OVERLAY$2 = 'e-overlay';
const CLS_HSCRCNT = 'e-hscroll-content';
const CLS_VSCRCNT = 'e-vscroll-content';
const CLS_VTAB = 'e-vertical-tab';
const CLS_VERTICAL$1 = 'e-vertical';
const CLS_VLEFT = 'e-vertical-left';
const CLS_VRIGHT = 'e-vertical-right';
const CLS_HBOTTOM = 'e-horizontal-bottom';
const CLS_FILL = 'e-fill-mode';
const TABITEMPREFIX = 'tabitem_';
const CLS_REORDER_ACTIVE_ITEM = 'e-reorder-active-item';
/**
* Objects used for configuring the Tab selecting item action properties.
*/
class TabActionSettings extends ChildProperty {
}
__decorate$7([
Property('SlideLeftIn')
], TabActionSettings.prototype, "effect", void 0);
__decorate$7([
Property(600)
], TabActionSettings.prototype, "duration", void 0);
__decorate$7([
Property('ease')
], TabActionSettings.prototype, "easing", void 0);
/**
* Objects used for configuring the Tab animation properties.
*/
class TabAnimationSettings extends ChildProperty {
}
__decorate$7([
Complex({ effect: 'SlideLeftIn', duration: 600, easing: 'ease' }, TabActionSettings)
], TabAnimationSettings.prototype, "previous", void 0);
__decorate$7([
Complex({ effect: 'SlideRightIn', duration: 600, easing: 'ease' }, TabActionSettings)
], TabAnimationSettings.prototype, "next", void 0);
/**
* Objects used for configuring the Tab item header properties.
*/
class Header extends ChildProperty {
}
__decorate$7([
Property('')
], Header.prototype, "text", void 0);
__decorate$7([
Property('')
], Header.prototype, "iconCss", void 0);
__decorate$7([
Property('left')
], Header.prototype, "iconPosition", void 0);
/**
* An array of object that is used to configure the Tab.
*/
class TabItem extends ChildProperty {
}
__decorate$7([
Complex({}, Header)
], TabItem.prototype, "header", void 0);
__decorate$7([
Property(null)
], TabItem.prototype, "headerTemplate", void 0);
__decorate$7([
Property('')
], TabItem.prototype, "content", void 0);
__decorate$7([
Property('')
], TabItem.prototype, "cssClass", void 0);
__decorate$7([
Property(false)
], TabItem.prototype, "disabled", void 0);
__decorate$7([
Property(true)
], TabItem.prototype, "visible", void 0);
__decorate$7([
Property()
], TabItem.prototype, "id", void 0);
__decorate$7([
Property(-1)
], TabItem.prototype, "tabIndex", void 0);
/**
* Tab is a content panel to show multiple contents in a single space, one at a time.
* Each Tab item has an associated content, that will be displayed based on the active Tab header item.
* ```html
* <div id="tab"></div>
* <script>
* var tabObj = new Tab();
* tab.appendTo("#tab");
* </script>
* ```
*/
let Tab = class Tab extends Component {
/**
* Initializes a new instance of the Tab class.
*
* @param {TabModel} options - Specifies Tab model properties as options.
* @param {string | HTMLElement} element - Specifies the element that is rendered as a Tab.
*/
constructor(options, element) {
super(options, element);
this.show = {};
this.hide = {};
this.maxHeight = 0;
this.title = 'Close';
this.isInteracted = false;
this.lastIndex = 0;
this.isAdd = false;
this.isIconAlone = false;
this.draggableItems = [];
this.resizeContext = this.refreshActiveTabBorder.bind(this);
/**
* Contains the keyboard configuration of the Tab.
*/
this.keyConfigs = {
tab: 'tab',
home: 'home',
end: 'end',
enter: 'enter',
space: 'space',
delete: 'delete',
moveLeft: 'leftarrow',
moveRight: 'rightarrow',
moveUp: 'uparrow',
moveDown: 'downarrow'
};
}
/**
* Removes the component from the DOM and detaches all its related event handlers, attributes and classes.
*
* @returns {void}
*/
destroy() {
if (this.isReact || this.isAngular) {
this.clearTemplate();
}
if (!isNullOrUndefined(this.tbObj)) {
this.tbObj.destroy();
this.tbObj = null;
}
this.unWireEvents();
this.element.removeAttribute('aria-disabled');
this.expTemplateContent();
if (!this.isTemplate) {
while (this.element.firstElementChild) {
remove(this.element.firstElementChild);
}
}
else {
const cntEle = select('.' + CLS_TAB + ' > .' + CLS_CONTENT$1, this.element);
this.element.classList.remove(CLS_TEMPLATE$1);
if (!isNullOrUndefined(cntEle)) {
cntEle.innerHTML = this.cnt;
}
}
if (this.btnCls) {
this.btnCls = null;
}
this.hdrEle = null;
this.cntEle = null;
this.tbItems = null;
this.tbItem = null;
this.tbPop = null;
this.prevItem = null;
this.popEle = null;
this.bdrLine = null;
this.content = null;
this.dragItem = null;
this.cloneElement = null;
this.draggingItems = [];
if (this.draggableItems && this.draggableItems.length > 0) {
for (let i = 0; i < this.draggableItems.length; i++) {
this.draggableItems[i].destroy();
this.draggableItems[i] = null;
}
this.draggableItems = [];
}
super.destroy();
this.trigger('destroyed');
}
/**
* Refresh the tab component
*
* @returns {void}
*/
refresh() {
if (this.isReact) {
this.clearTemplate();
}
super.refresh();
if (this.isReact) {
this.renderReactTemplates();
}
}
/**
* Reorganizes and adjusts the Tab headers to fit the available width without re-rendering the entire Tab component.
*
* This method is useful for optimizing the layout when:
* - A hidden tab item becomes visible.
* - The number of tab items changes dynamically.
*
* @returns {void} This method does not return a value.
*/
refreshOverflow() {
if (!isNullOrUndefined(this.tbObj)) {
this.tbObj.refreshOverflow();
}
}
/**
* Initialize component
*
* @private
* @returns {void}
*/
preRender() {
const nested = closest(this.element, '.' + CLS_CONTENT$1);
this.prevIndex = 0;
this.isNested = false;
this.isPopup = false;
this.initRender = true;
this.isSwiped = false;
this.itemIndexArray = [];
this.templateEle = [];
if (this.allowDragAndDrop) {
this.dragArea = !isNullOrUndefined(this.dragArea) ? this.dragArea : '#' + this.element.id + ' ' + ('.' + CLS_HEADER$1);
}
if (!isNullOrUndefined(nested)) {
nested.parentElement.classList.add(CLS_NEST$1);
this.isNested = true;
}
const name = Browser.info.name;
const css = (name === 'msie') ? 'e-ie' : (name === 'edge') ? 'e-edge' : (name === 'safari') ? 'e-safari' : '';
setStyleAttribute(this.element, { 'width': formatUnit(this.width), 'height': formatUnit(this.height) });
this.setCssClass(this.element, this.cssClass, true);
attributes(this.element, { 'aria-disabled': 'false' });
this.setCssClass(this.element, css, true);
this.updatePopAnimationConfig();
}
/**
* Initialize the component rendering
*
* @private
* @returns {void}
*/
render() {
this.btnCls = this.createElement('span', { className: CLS_ICONS + ' ' + CLS_ICON_CLOSE, attrs: { title: this.title } });
this.tabId = this.element.id.length > 0 ? ('-' + this.element.id) : getRandomId();
this.renderContainer();
this.wireEvents();
this.initRender = false;
if (this.isReact && this.portals && this.portals.length > 0) {
this.renderReactTemplates(() => {
this.refreshOverflow();
this.selectingContent(this.selectedItem, this.isInteracted);
this.refreshActiveBorder();
});
}
}
renderContainer() {
const ele = this.element;
this.items.forEach((item, index) => {
if (isNullOrUndefined(item.id) && !isNullOrUndefined(item.setProperties)) {
item.setProperties({ id: TABITEMPREFIX + index.toString() }, true);
}
});
if (this.items.length > 0 && ele.children.length === 0) {
ele.appendChild(this.createElement('div', { className: CLS_CONTENT$1 }));
this.setOrientation(this.headerPlacement, this.createElement('div', { className: CLS_HEADER$1 }));
this.isTemplate = false;
}
else if (this.element.children.length > 0) {
this.isTemplate = true;
ele.classList.add(CLS_TEMPLATE$1);
const header = ele.querySelector('.' + CLS_HEADER$1);
if (header && this.headerPlacement === 'Bottom') {
this.setOrientation(this.headerPlacement, header);
}
}
if (!isNullOrUndefined(select('.' + CLS_HEADER$1, this.element)) && !isNullOrUndefined(select('.' + CLS_CONTENT$1, this.element))) {
this.renderHeader();
this.tbItems = select('.' + CLS_HEADER$1 + ' .' + CLS_TB_ITEMS, this.element);
if (!isNullOrUndefined(this.tbItems)) {
rippleEffect(this.tbItems, { selector: '.e-tab-wrap' });
}
this.renderContent();
if (selectAll('.' + CLS_TB_ITEM, this.element).length > 0) {
this.tbItems = select('.' + CLS_HEADER$1 + ' .' + CLS_TB_ITEMS, this.element);
this.bdrLine = this.createElement('div', { className: CLS_INDICATOR + ' ' + CLS_HIDDEN$1 + ' ' + CLS_IGNORE });
const scrCnt = select('.' + this.scrCntClass, this.tbItems);
if (!isNullOrUndefined(scrCnt)) {
scrCnt.insertBefore(this.bdrLine, scrCnt.firstChild);
}
else {
this.tbItems.insertBefore(this.bdrLine, this.tbItems.firstChild);
}
this.setContentHeight(true);
this.select(this.selectedItem);
}
this.setRTL(this.enableRtl);
}
}
renderHeader() {
const hdrPlace = this.headerPlacement;
let tabItems = [];
this.hdrEle = this.getTabHeader();
this.addVerticalClass();
if (!this.isTemplate) {
tabItems = this.parseObject(this.items, 0);
}
else {
if (this.element.children.length > 1 && this.element.children[1].classList.contains(CLS_HEADER$1)) {
this.setProperties({ headerPlacement: 'Bottom' }, true);
}
const count = this.hdrEle.children.length;
const hdrItems = [];
for (let i = 0; i < count; i++) {
hdrItems.push(this.hdrEle.children.item(i));
}
if (count > 0) {
const tabItems = this.createElement('div', { className: CLS_ITEMS$1 });
this.hdrEle.appendChild(tabItems);
hdrItems.forEach((item, index) => {
this.lastIndex = index;
const attr = {
className: CLS_ITEM$2, id: CLS_ITEM$2 + this.tabId + '_' + index
};
const txt = this.createElement('span', {
className: CLS_TEXT, attrs: { 'role': 'presentation' }
}).outerHTML;
const cont = this.createElement('div', {
className: CLS_TEXT_WRAP, innerHTML: txt + this.btnCls.outerHTML
}).outerHTML;
const wrap = this.createElement('div', {
className: CLS_WRAP, innerHTML: cont,
attrs: { role: 'tab', tabIndex: '-1', 'aria-selected': 'false', 'aria-controls': CLS_CONTENT$1 + this.tabId + '_' + index, 'aria-disabled': 'false' }
});
wrap.querySelector('.' + CLS_TEXT).appendChild(item);
tabItems.appendChild(this.createElement('div', attr));
selectAll('.' + CLS_ITEM$2, tabItems)[index].appendChild(wrap);
});
}
}
this.tbObj = new Toolbar({
width: (hdrPlace === 'Left' || hdrPlace === 'Right') ? 'auto' : '100%',
height: (hdrPlace === 'Left' || hdrPlace === 'Right') ? '100%' : 'auto',
overflowMode: this.overflowMode,
items: (tabItems.length !== 0) ? tabItems : [],
clicked: this.clickHandler.bind(this),
scrollStep: this.scrollStep,
enableHtmlSanitizer: this.enableHtmlSanitizer,
cssClass: this.cssClass
});
this.tbObj.isStringTemplate = true;
this.tbObj.createElement = this.createElement;
this.tbObj.appendTo(this.hdrEle);
attributes(this.hdrEle, { role: 'tablist' });
if (!isNullOrUndefined(this.element.getAttribute('aria-label'))) {
this.hdrEle.setAttribute('aria-label', this.element.getAttribute('aria-label'));
this.element.removeAttribute('aria-label');
}
else if (!isNullOrUndefined(this.element.getAttribute('aria-labelledby'))) {
this.hdrEle.setAttribute('aria-labelledby', this.element.getAttribute('aria-labelledby'));
this.element.removeAttribute('aria-labelledby');
}
this.setCloseButton(this.showCloseButton);
const toolbarHeader = this.tbObj.element.querySelector('.' + CLS_TB_ITEMS);
if (!isNullOrUndefined(toolbarHeader)) {
if (isNullOrUndefined(toolbarHeader.id) || toolbarHeader.id === '') {
toolbarHeader.id = this.element.id + '_' + 'tab_header_items';
}
}
}
createContentElement(index) {
const contentElement = this.createElement('div', {
id: CLS_CONTENT$1 + this.tabId + '_' + index, className: CLS_ITEM$2,
attrs: { 'role': 'tabpanel', 'aria-labelledby': CLS_ITEM$2 + this.tabId + '_' + index }
});
if (['Dynamic', 'Demand'].indexOf(this.loadOn) !== -1 ||
(this.loadOn === 'Init' && index === this.selectedItem)) {
addClass([contentElement], CLS_ACTIVE$1);
}
return contentElement;
}
renderContent() {
this.cntEle = select('.' + CLS_CONTENT$1, this.element);
const hdrItem = selectAll('.' + CLS_TB_ITEM, this.element);
if (this.isTemplate) {
this.cnt = (this.cntEle.children.length > 0) ? this.cntEle.innerHTML : '';
const contents = this.cntEle.children;
for (let i = 0; i < hdrItem.length; i++) {
if (contents.length - 1 >= i) {
addClass([contents.item(i)], CLS_ITEM$2);
attributes(contents.item(i), { 'role': 'tabpanel', 'aria-labelledby': CLS_ITEM$2 + this.tabId + '_' + i });
contents.item(i).id = CLS_CONTENT$1 + this.tabId + '_' + i;
}
}
}
else {
if (selectAll('.' + CLS_TB_ITEM, this.element).length > 0) {
if (this.loadOn === 'Init') {
for (let i = 0; i < this.itemIndexArray.length; i++) {
if (this.itemIndexArray[i]) {
this.cntEle.appendChild(this.createContentElement(Number(this.extIndex(this.itemIndexArray[i]))));
}
}
}
else if (this.loadOn === 'Dynamic') {
this.cntEle.appendChild(this.createContentElement(this.selectedItem > 0 ?
this.selectedItem : Number(this.extIndex(this.itemIndexArray[0]))));
}
}
}
}
reRenderItems() {
this.renderContainer();
if (!isNullOrUndefined(this.cntEle)) {
this.bindSwipeEvents();
}
}
parseObject(items, index) {
const tbItems = Array.prototype.slice.call(selectAll('.e-tab-header .' + CLS_TB_ITEM, this.element));
let maxId = this.lastIndex;
if (!this.isReplace && tbItems.length > 0) {
maxId = this.getMaxIndicesFromItems(tbItems);
}
const tItems = [];
let txtWrapEle;
const spliceArray = [];
items.forEach((item, i) => {
const pos = (isNullOrUndefined(item.header) || isNullOrUndefined(item.header.iconPosition)) ? '' : item.header.iconPosition;
const css = (isNullOrUndefined(item.header) || isNullOrUndefined(item.header.iconCss)) ? '' : item.header.iconCss;
if ((isNullOrUndefined(item.headerTemplate)) && (isNullOrUndefined(item.header) || isNullOrUndefined(item.header.text) ||
((item.header.text.length === 0)) && (css === ''))) {
spliceArray.push(i);
return;
}
let txt = item.headerTemplate || item.header.text;
if (typeof txt === 'string' && this.enableHtmlSanitizer) {
txt = SanitizeHtmlHelper.sanitize(txt);
}
let itemIndex;
if (this.isReplace && !isNullOrUndefined(this.tbId) && this.tbId !== '') {
itemIndex = parseInt(this.tbId.substring(this.tbId.lastIndexOf('_') + 1), 10);
this.tbId = '';
}
else {
itemIndex = index + i;
}
this.lastIndex = ((tbItems.length === 0) ? i : ((this.isReplace) ? (itemIndex) : (maxId + 1 + i)));
const disabled = (item.disabled) ? ' ' + CLS_DISABLE$4 + ' ' + CLS_OVERLAY$2 : '';
const hidden = (item.visible === false) ? ' ' + CLS_HIDDEN$1 : '';
txtWrapEle = this.createElement('div', { className: CLS_TEXT, attrs: { 'role': 'presentation' } });
const tHtml = ((txt instanceof Object) ? txt.outerHTML : txt);
const txtEmpty = (!isNullOrUndefined(tHtml) && tHtml !== '');
if (!isNullOrUndefined(txt.tagName)) {
txtWrapEle.appendChild(txt);
}
else {
this.headerTextCompile(txtWrapEle, txt, i);
}
let tEle;
const icon = this.createElement('span', {
className: CLS_ICONS + ' ' + CLS_TAB_ICON + ' ' + CLS_ICON + '-' + pos + ' ' + css
});
const tCont = this.createElement('div', { className: CLS_TEXT_WRAP });
tCont.appendChild(txtWrapEle);
if ((txt !== '' && txt !== undefined) && css !== '') {
if ((pos === 'left' || pos === 'top')) {
tCont.insertBefore(icon, tCont.firstElementChild);
}
else {
tCont.appendChild(icon);
}
tEle = txtWrapEle;
this.isIconAlone = false;
}
else {
tEle = ((css === '') ? txtWrapEle : icon);
if (tEle === icon) {
detach(txtWrapEle);
tCont.appendChild(icon);
this.isIconAlone = true;
}
}
const tabIndex = isNullOrUndefined(item.tabIndex) ? '-1' : item.tabIndex.toString();
const wrapAttrs = (item.disabled) ? { role: 'tab', 'aria-disabled': 'true' } : { tabIndex: tabIndex, 'data-tabindex': tabIndex, role: 'tab', 'aria-selected': 'false', 'aria-disabled': 'false' };
tCont.appendChild(this.btnCls.cloneNode(true));
const wrap = this.createElement('div', { className: CLS_WRAP, attrs: wrapAttrs });
wrap.appendChild(tCont);
if (this.itemIndexArray instanceof Array) {
this.itemIndexArray.splice((index + i), 0, CLS_ITEM$2 + this.tabId + '_' + this.lastIndex);
}
const attrObj = {
id: CLS_ITEM$2 + this.tabId + '_' + this.lastIndex, 'data-id': item.id
};
const tItem = { htmlAttributes: attrObj, template: wrap };
tItem.cssClass = ((item.cssClass !== undefined) ? item.cssClass : ' ') + ' ' + disabled + ' ' + hidden + ' '
+ ((css !== '') ? 'e-i' + pos : '') + ' ' + ((!txtEmpty) ? CLS_ICON : '');
if (pos === 'top' || pos === 'bottom') {
this.element.classList.add('e-vertical-icon');
}
tItems.push(tItem);
i++;
});
if (!this.isAdd) {
spliceArray.forEach((spliceItemIndex) => {
this.items.splice(spliceItemIndex, 1);
});
}
if (this.isIconAlone) {
this.element.classList.add(CLS_ICON_TAB);
}
else {
this.element.classList.remove(CLS_ICON_TAB);
}
return tItems;
}
removeActiveClass() {
const tabHeader = this.getTabHeader();
if (tabHeader) {
const tabItems = selectAll('.' + CLS_TB_ITEM + '.' + CLS_ACTIVE$1, tabHeader);
[].slice.call(tabItems).forEach((node) => node.classList.remove(CLS_ACTIVE$1));
[].slice.call(tabItems).forEach((node) => node.firstElementChild.setAttribute('aria-selected', 'false'));
}
}
checkPopupOverflow(ele) {
this.tbPop = select('.' + CLS_TB_POP, this.element);
const popIcon = select('.e-hor-nav', this.element);
const tbrItems = select('.' + CLS_TB_ITEMS, this.element);
const lastChild = tbrItems.lastChild;
let isOverflow = false;
if (!this.isVertical() && ((this.enableRtl && ((popIcon.offsetLeft + popIcon.offsetWidth) > tbrItems.offsetLeft))
|| (!this.enableRtl && popIcon.offsetLeft < tbrItems.offsetWidth))) {
isOverflow = true;
}
else if (this.isVertical() && (popIcon.offsetTop < lastChild.offsetTop + lastChild.offsetHeight)) {
isOverflow = true;
}
if (isOverflow && !isNullOrUndefined(ele)) {
ele.classList.add(CLS_TB_POPUP);
this.tbPop.insertBefore(ele, selectAll('.' + CLS_TB_POPUP, this.tbPop)[0]);
}
return isOverflow;
}
popupHandler(target) {
const ripEle = target.querySelector('.e-ripple-element');
if (!isNullOrUndefined(ripEle)) {
ripEle.outerHTML = '';
target.querySelector('.' + CLS_WRAP).classList.remove('e-ripple');
}
this.tbItem = selectAll('.' + CLS_TB_ITEMS + ' .' + CLS_TB_ITEM, this.hdrEle);
const lastChild = this.tbItem[this.tbItem.length - 1];
if (this.tbItem.length >= 0) {
target.classList.remove(CLS_TB_POPUP);
target.removeAttribute('style');
this.tbItems.appendChild(target);
this.actEleId = target.id;
if (this.checkPopupOverflow(lastChild)) {
for (let i = 0; i < this.tbItems.children.length; i++) {
let prevEle = this.tbItems.lastChild.previousElementSibling;
prevEle = (prevEle && prevEle.classList.contains(CLS_INDICATOR) ? prevEle.previousElementSibling : prevEle);
if (!this.checkPopupOverflow(prevEle ? prevEle : target)) {
break;
}
}
}
this.isPopup = true;
}
const tabItemsLength = selectAll('.' + CLS_TB_ITEM, this.tbItems).length;
return tabItemsLength > 0 ? tabItemsLength - 1 : this.getEleIndex(target);
}
setCloseButton(val) {
const trg = select('.' + CLS_HEADER$1, this.element);
if (val === true) {
trg.classList.add(CLS_CLOSE_SHOW);
}
else {
trg.classList.remove(CLS_CLOSE_SHOW);
}
this.refreshOverflow();
this.refreshActiveTabBorder();
}
prevCtnAnimation(prev, current) {
let animation;
const checkRTL = this.enableRtl || this.element.classList.contains(CLS_RTL$4);
if (this.isPopup || prev <= current) {
if (this.animation.previous.effect === 'SlideLeftIn') {
animation = {
name: 'SlideLeftOut',
duration: this.animation.previous.duration, timingFunction: this.animation.previous.easing
};
}
else {
animation = null;
}
}
else {
if (this.animation.next.effect === 'SlideRightIn') {
animation = {
name: 'SlideRightOut',
duration: this.animation.next.duration, timingFunction: this.animation.next.easing
};
}
else {
animation = null;
}
}
return animation;
}
triggerPrevAnimation(oldCnt, prevIndex) {
const animateObj = this.prevCtnAnimation(prevIndex, this.selectedItem);
if (!isNullOrUndefined(animateObj)) {
animateObj.begin = () => {
setStyleAttribute(oldCnt, { 'position': 'absolute' });
oldCnt.classList.add(CLS_PROGRESS);
oldCnt.classList.add('e-view');
};
animateObj.end = () => {
oldCnt.style.display = 'none';
oldCnt.classList.remove(CLS_ACTIVE$1);
oldCnt.classList.remove(CLS_PROGRESS);
oldCnt.classList.remove('e-view');
setStyleAttribute(oldCnt, { 'display': '', 'position': '' });
if (oldCnt.childNodes.length === 0 && !this.isTemplate) {
detach(oldCnt);
}
};
new Animation(animateObj).animate(oldCnt);
}
else {
oldCnt.classList.remove(CLS_ACTIVE$1);
}
}
triggerAnimation(id, value) {
const prevIndex = this.prevIndex;
let oldCnt;
const itemCollection = [].slice.call(this.element.querySelector('.' + CLS_CONTENT$1).children);
itemCollection.forEach((item) => {
if (item.id === this.prevActiveEle) {
oldCnt = item;
}
});
const prevEle = this.tbItem[prevIndex];
const newCnt = this.getTrgContent(this.cntEle, this.extIndex(id));
if (isNullOrUndefined(oldCnt) && !isNullOrUndefined(prevEle)) {
const idNo = this.extIndex(prevEle.id);
oldCnt = this.getTrgContent(this.cntEle, idNo);
}
if (!isNullOrUndefined(newCnt)) {
this.prevActiveEle = newCnt.id;
}
const isPrevent = isNullOrUndefined(this.animation) || isNullOrUndefined(this.animation.next.effect) || isNullOrUndefined(this.animation.previous.effect)
|| this.animation.previous.effect === 'None' || this.animation.next.effect === 'None';
if (this.initRender || value === false || isPrevent) {
if (oldCnt && oldCnt !== newCnt) {
oldCnt.classList.remove(CLS_ACTIVE$1);
}
return;
}
const cnt = select('.' + CLS_CONTENT$1, this.element);
let animateObj;
if (this.prevIndex > this.selectedItem && !this.isPopup) {
const openEff = this.animation.previous.effect;
animateObj = {
name: ((openEff === 'None') ? '' : ((openEff !== 'SlideLeftIn') ? openEff : 'SlideLeftIn')),
duration: (this.animation.previous.duration === 0 && animationMode === 'Enable') ? 600 : this.animation.previous.duration,
timingFunction: this.animation.previous.easing
};
}
else if (this.isPopup || this.prevIndex < this.selectedItem || this.prevIndex === this.selectedItem) {
const clsEff = this.animation.next.effect;
animateObj = {
name: ((clsEff === 'None') ? '' : ((clsEff !== 'SlideRightIn') ? clsEff : 'SlideRightIn')),
duration: (this.animation.next.duration === 0 && animationMode === 'Enable') ? 600 : this.animation.next.duration,
timingFunction: this.animation.next.easing
};
}
animateObj.progress = () => {
cnt.classList.add(CLS_PROGRESS);
this.setActiveBorder();
};
animateObj.end = () => {
cnt.classList.remove(CLS_PROGRESS);
newCnt.classList.add(CLS_ACTIVE$1);
};
if (!this.initRender && !isNullOrUndefined(oldCnt)) {
this.triggerPrevAnimation(oldCnt, prevIndex);
}
this.isPopup = false;
if (animateObj.name === '') {
newCnt.classList.add(CLS_ACTIVE$1);
}
else {
new Animation(animateObj).animate(newCnt);
}
}
keyPressed(trg) {
const trgParent = closest(trg, '.' + CLS_HEADER$1 + ' .' + CLS_TB_ITEM);
const trgIndex = this.getEleIndex(trgParent);
if (!isNullOrUndefined(this.popEle) && trg.classList.contains('e-hor-nav')) {
(this.popEle.classList.contains(CLS_POPUP_OPEN)) ? this.popObj.hide(this.hide) : this.popObj.show(this.show);
}
else if (trg.classList.contains('e-scroll-nav')) {
trg.click();
}
else {
if (!isNullOrUndefined(trgParent) && trgParent.classList.contains(CLS_ACTIVE$1) === false) {
this.selectTab(trgIndex, null, true);
if (!isNullOrUndefined(this.popEle)) {
this.popObj.hide(this.hide);
}
}
}
}
getTabHeader() {
if (isNullOrUndefined(this.element)) {
return undefined;
}
const headers = [].slice.call(this.element.children).filter((e) => e.classList.contains(CLS_HEADER$1));
if (headers.length > 0) {
return headers[0];
}
else {
const wrap = [].slice.call(this.element.children).filter((e) => !e.classList.contains(CLS_BLA_TEM))[0];
if (!wrap) {
return undefined;
}
return [].slice.call(wrap.children).filter((e) => e.classList.contains(CLS_HEADER$1))[0];
}
}
getEleIndex(item) {
return Array.prototype.indexOf.call(selectAll('.' + CLS_TB_ITEM, this.getTabHeader()), item);
}
extIndex(id) {
return id.replace(CLS_ITEM$2 + this.tabId + '_', '');
}
getMaxIndicesFromItems(tbItems) {
const idList = [];
tbItems.forEach((item) => {
idList.push(this.getIndexFromEle(item.id));
});
return Math.max(...idList);
}
expTemplateContent() {
this.templateEle.forEach((eleStr) => {
if (!isNullOrUndefined(this.element.querySelector(eleStr))) {
document.body.appendChild(this.element.querySelector(eleStr)).style.display = 'none';
}
});
}
templateCompile(ele, cnt, index) {
const tempEle = this.createElement('div');
this.compileElement(tempEle, cnt, 'content', index);
if (tempEle.childNodes.length !== 0) {
ele.appendChild(tempEle);
}
if (this.isReact) {
this.renderReactTemplates();
}
}
compileElement(ele, val, prop, index) {
let templateFn;
if (typeof val === 'string') {
val = val.trim();
if (this.isVue) {
templateFn = compile(this.enableHtmlSanitizer ? SanitizeHtmlHelper.sanitize(val) : val);
}
else {
ele.innerHTML = this.enableHtmlSanitizer ? SanitizeHtmlHelper.sanitize(val) : val;
}
}
else {
templateFn = compile(val);
}
let templateFUN;
if (!isNullOrUndefined(templateFn)) {
templateFUN = templateFn({}, this, prop);
}
if (!isNullOrUndefined(templateFn) && templateFUN.length > 0) {
[].slice.call(templateFUN).forEach((el) => {
ele.appendChild(el);
});
}
}
headerTextCompile(element, text, index) {
this.compileElement(element, text, 'headerTemplate', index);
}
getContent(ele, cnt, callType, index) {
let eleStr;
cnt = isNullOrUndefined(cnt) ? '' : cnt;
if (typeof cnt === 'string' || isNullOrUndefined(cnt.innerHTML)) {
if (typeof cnt === 'string' && this.enableHtmlSanitizer) {
cnt = SanitizeHtmlHelper.sanitize(cnt);
}
if (cnt[0] === '.' || cnt[0] === '#') {
if (document.querySelectorAll(cnt).length) {
const eleVal = document.querySelector(cnt);
eleStr = eleVal.outerHTML.trim();
if (callType === 'clone') {
ele.appendChild(eleVal.cloneNode(true));
}
else {
ele.appendChild(eleVal);
eleVal.style.display = '';
}
}
else {
this.templateCompile(ele, cnt, index);
}
}
else {
this.templateCompile(ele, cnt, index);
}
}
else {
ele.appendChild(cnt);
}
if (!isNullOrUndefined(eleStr)) {
if (this.templateEle.indexOf(cnt.toString()) === -1) {
this.templateEle.push(cnt.toString());
}
}
}
getTrgContent(cntEle, no) {
let ele;
if (this.element.classList.contains(CLS_NEST$1)) {
ele = select('.' + CLS_NEST$1 + '> .' + CLS_CONTENT$1 + ' > #' + CLS_CONTENT$1 + this.tabId + '_' + no, this.element);
}
else {
ele = this.findEle(cntEle.children, CLS_CONTENT$1 + this.tabId + '_' + no);
}
return ele;
}
findEle(items, key) {
let ele;
for (let i = 0; i < items.length; i++) {
if (items[i].id === key) {
ele = items[i];
break;
}
}
return ele;
}
isVertical() {
const isVertical = (this.headerPlacement === 'Left' || this.headerPlacement === 'Right') ? true : false;
this.scrCntClass = (isVertical) ? CLS_VSCRCNT : CLS_HSCRCNT;
return isVertical;
}
addVerticalClass() {
if (this.isVertical()) {
const tbPos = (this.headerPlacement === 'Left') ? CLS_VLEFT : CLS_VRIGHT;
addClass([this.hdrEle], [CLS_VERTICAL$1, tbPos]);
if (!this.element.classList.contains(CLS_NEST$1)) {
addClass([this.element], [CLS_VTAB, tbPos]);
}
else {
addClass([this.hdrEle], [CLS_VTAB, tbPos]);
}
}
if (this.headerPlacement === 'Bottom') {
addClass([this.hdrEle], [CLS_HBOTTOM]);
}
}
updatePopAnimationConfig() {
this.show = { name: (this.isVertical() ? 'FadeIn' : 'SlideDown'), duration: 100 };
this.hide = { name: (this.isVertical() ? 'FadeOut' : 'SlideUp'), duration: 100 };
}
changeOrientation(place) {
this.setOrientation(place, this.hdrEle);
const activeTab = this.hdrEle.querySelector('.' + CLS_ACTIVE$1);
const isVertical = this.hdrEle.classList.contains(CLS_VERTICAL$1) ? true : false;
removeClass([this.element], [CLS_VTAB]);
removeClass([this.hdrEle], [CLS_VERTICAL$1, CLS_VLEFT, CLS_VRIGHT]);
if (isVertical !== this.isVertical()) {
this.changeToolbarOrientation();
if (!isNullOrUndefined(activeTab) && activeTab.classList.contains(CLS_TB_POPUP)) {
this.popupHandler(activeTab);
}
}
this.addVerticalClass();
this.setActiveBorder();
this.focusItem();
}
focusItem() {
const curActItem = select(' #' + CLS_ITEM$2 + this.tabId + '_' + this.selectedItem, this.hdrEle);
if (!isNullOrUndefined(curActItem)) {
curActItem.firstElementChild.focus();
}
}
changeToolbarOrientation() {
this.tbObj.setProperties({ height: (this.isVertical() ? '100%' : 'auto'), width: (this.isVertical() ? 'auto' : '100%') }, true);
this.tbObj.changeOrientation();
this.updatePopAnimationConfig();
}
setOrientation(place, ele) {
const headerPos = Array.prototype.indexOf.call(this.element.children, ele);
const contentPos = Array.prototype.indexOf.call(this.element.children, this.element.querySelector('.' + CLS_CONTENT$1));
if (place === 'Bottom' && (contentPos > headerPos)) {
this.element.appendChild(ele);
}
else {
removeClass([ele], [CLS_HBOTTOM]);
this.element.insertBefore(ele, select('.' + CLS_CONTENT$1, this.element));
}
}
setCssClass(ele, cls, val) {
if (cls === '' || isNullOrUndefined(cls)) {
return;
}
const list = cls.split(' ');
for (let i = 0; i < list.length; i++) {
if (val) {
ele.classList.add(list[i]);
}
else {
ele.classList.remove(list[i]);
}
}
}
loadContentInitMode(ele) {
if (!ele) {
return;
}
if (this.loadOn === 'Init') {
for (let i = 0; i < this.items.length; i++) {
if (this.cntEle.children.item(i)) {
this.getContent(this.cntEle.children.item(i), this.items[i].content, 'render', i);
}
}
}
}
loadContentElement() {
if (!this.isTemplate) {
const ele = this.cntEle.children.item(0);
this.loadContentInitMode(ele);
}
}
setContentHeight(val) {
if (this.element.classList.contains(CLS_FILL)) {
removeClass([this.element], [CLS_FILL]);
}
if (isNullOrUndefined(this.cntEle)) {
return;
}
const hdrEle = this.getTabHeader();
if (this.heightAdjustMode === 'None') {
this.loadContentElement();
if (this.height === 'auto') {
return;
}
else {
if (!this.isVertical()) {
setStyleAttribute(this.cntEle, { 'height': (this.element.clientHeight - hdrEle.offsetHeight) + 'px' });
}
}
}
else if (this.heightAdjustMode === 'Fill') {
addClass([this.element], [CLS_FILL]);
setStyleAttribute(this.element, { 'height': '100%' });
this.loadContentElement();
this.cntEle.style.height = 'calc(100% - ' + this.hdrEle.offsetHeight + 'px)';
}
else if (this.heightAdjustMode === 'Auto') {
if (this.isTemplate === true) {
const cnt = selectAll('.' + CLS_CONTENT$1 + ' > .' + CLS_ITEM$2, this.element);
for (let i = 0; i < cnt.length; i++) {
cnt[i].style.display = 'block';
cnt[i].style.visibility = 'visible';
this.maxHeight = Math.max(this.maxHeight, this.getHeight(cnt[i]));
cnt[i].style.removeProperty('display');
cnt[i].style.removeProperty('visibility');
}
}
else {
this.cntEle = select('.' + CLS_CONTENT$1, this.element);
if (val === true && this.loadOn === 'Demand') {
this.cntEle.appendChild(this.createContentElement(Number(this.extIndex(this.itemIndexArray[0]))));
}
const ele = this.cntEle.children.item(0);
for (let i = 0; i < this.items.length; i++) {
this.getContent(ele, this.items[i].content, 'clone', i);
this.maxHeight = Math.max(this.maxHeight, this.getHeight(ele));
while (ele.firstChild) {
ele.removeChild(ele.firstChild);
}
}
if (this.isReact || this.isAngular || this.isVue) {
this.clearTemplate(['content']);
}
this.templateEle = [];
if (this.loadOn === 'Demand') {
this.getContent(ele, this.items[0].content, 'render', 0);
}
this.loadContentInitMode(ele);
if (this.prevIndex !== this.selectedItem) {
ele.classList.remove(CLS_ACTIVE$1);
}
}
setStyleAttribute(this.cntEle, { 'height': this.maxHeight + 'px' });
}
else {
this.loadContentElement();
setStyleAttribute(this.cntEle, { 'height': 'auto' });
}
}
getHeight(ele) {
const cs = window.getComputedStyle(ele);
return ele.offsetHeight + parseFloat(cs.getPropertyValue('padding-top')) + parseFloat(cs.getPropertyValue('padding-bottom')) +
parseFloat(cs.getPropertyValue('margin-top')) + parseFloat(cs.getPropertyValue('margin-bottom'));
}
setActiveBorder() {
const trgHdrEle = this.getTabHeader();
const trg = select('.' + CLS_TB_ITEM + '.' + CLS_ACTIVE$1, trgHdrEle);
if (isNullOrUndefined(trg)) {
return;
}
if (!this.reorderActiveTab) {
if (trg.classList.contains(CLS_TB_POPUP) && !this.bdrLine.classList.contains(CLS_HIDDEN$1)) {
this.bdrLine.classList.add(CLS_HIDDEN$1);
}
if (trgHdrEle && !trgHdrEle.classList.contains(CLS_REORDER_ACTIVE_ITEM)) {
trgHdrEle.classList.add(CLS_REORDER_ACTIVE_ITEM);
}
}
else if (trgHdrEle) {
trgHdrEle.classList.remove(CLS_REORDER_ACTIVE_ITEM);
}
const root = closest(trg, '.' + CLS_TAB);
if (this.element !== root) {
return;
}
this.tbItems = select('.' + CLS_TB_ITEMS, trgHdrEle);
const bar = select('.' + CLS_INDICATOR, trgHdrEle);
const scrollCnt = select('.' + CLS_TB_ITEMS + ' .' + this.scrCntClass, trgHdrEle);
if (this.isVertical()) {
setStyleAttribute(bar, { 'left': '', 'right': '' });
const tbHeight = (isNullOrUndefined(scrollCnt)) ? this.tbItems.offsetHeight : scrollCnt.offsetHeight;
if (tbHeight !== 0) {
setStyleAttribute(bar, { 'top': trg.offsetTop + 'px', 'height': trg.offsetHeight + 'px' });
}
else {
setStyleAttribute(bar, { 'top': 0, 'height': 0 });
}
}
else {
if (this.overflowMode === 'MultiRow') {
const top = this.headerPlacement === 'Bottom' ? trg.offsetTop : trg.offsetHeight + trg.offsetTop;
setStyleAttribute(bar, { 'top': top + 'px', 'height': '' });
}
else {
setStyleAttribute(bar, { 'top': '', 'height': '' });
}
let tbWidth = (isNullOrUndefined(scrollCnt)) ? this.tbItems.offsetWidth : scrollCnt.offsetWidth;
if (tbWidth !== 0) {
setStyleAttribute(bar, { 'left': trg.offsetLeft + 'px', 'right': tbWidth - (trg.offsetLeft + trg.offsetWidth) + 'px' });
}
else {
setStyleAttribute(bar, { 'left': 'auto', 'right': 'auto' });
}
}
if (!isNullOrUndefined(this.bdrLine) && !trg.classList.contains(CLS_TB_POPUP)) {
this.bdrLine.classList.remove(CLS_HIDDEN$1);
}
}
setActive(value, skipDataBind = false, isInteracted = false) {
this.tbItem = selectAll('.' + CLS_TB_ITEM, this.getTabHeader());
const trg = this.tbItem[value];
if (value < 0 || isNaN(value) || this.tbItem.length === 0 || !isNullOrUndefined(trg) && trg.classList.contains(CLS_DISABLE$4)) {
return;
}
if (value >= 0 && !skipDataBind) {
this.allowServerDataBinding = false;
this.setProperties({ selectedItem: value }, true);
this.allowServerDataBinding = true;
if (!this.initRender) {
this.serverDataBind();
}
}
if (trg.classList.contains(CLS_ACTIVE$1)) {
this.setActiveBorder();
return;
}
if (!this.isTemplate) {
attributes(trg.firstElementChild, { 'aria-controls': CLS_CONTENT$1 + this.tabId + '_' + this.extIndex(trg.id) });
}
const id = trg.id;
this.removeActiveClass();
trg.classList.add(CLS_ACTIVE$1);
trg.firstElementChild.setAttribute('aria-selected', 'true');
const no = Number(this.extIndex(id));
if (isNullOrUndefined(this.prevActiveEle)) {
this.prevActiveEle = CLS_CONTENT$1 + this.tabId + '_' + no;
}
if (this.isTemplate) {
if (select('.' + CLS_CONTENT$1, this.element).children.length > 0) {
const trg = this.findEle(select('.' + CLS_CONTENT$1, this.element).children, CLS_CONTENT$1 + this.tabId + '_' + no);
if (!isNullOrUndefined(trg)) {
trg.classList.add(CLS_ACTIVE$1);
}
this.triggerAnimation(id, this.enableAnimation);
}
}
else {
this.cntEle = select('.' + CLS_TAB + ' > .' + CLS_CONTENT$1, this.element);
while (this.loadOn === 'Dynamic' && this.cntEle.firstElementChild) {
this.cntEle.removeChild(this.cntEle.firstElementChild);
}
const item = this.getTrgContent(this.cntEle, this.extIndex(id));
if (isNullOrUndefined(item)) {
this.cntEle.appendChild(this.createElement('div', {
id: CLS_CONTENT$1 + this.tabId + '_' + this.extIndex(id), className: CLS_ITEM$2 + ' ' + CLS_ACTIVE$1,
attrs: { role: 'tabpanel', 'aria-labelledby': CLS_ITEM$2 + this.tabId + '_' + this.extIndex(id) }
}));
const eleTrg = this.getTrgContent(this.cntEle, this.extIndex(id));
const itemIndex = Array.prototype.indexOf.call(this.itemIndexArray, id);
this.getContent(eleTrg, this.items[itemIndex].content, 'render', itemIndex);
}
else {
item.classList.add(CLS_ACTIVE$1);
}
this.triggerAnimation(id, this.enableAnimation);
}
this.setActiveBorder();
this.refreshItemVisibility(trg);
if (!this.initRender && !skipDataBind) {
const eventArg = {
previousItem: this.prevItem,
previousIndex: this.prevIndex,
selectedItem: trg,
selectedIndex: value,
selectedContent: select('#' + CLS_CONTENT$1 + this.tabId + '_' + this.selectingID, this.content),
isSwiped: this.isSwiped,
isInteracted: isInteracted,
preventFocus: false
};
this.trigger('selected', eventArg, (selectEventArgs) => {
if (!selectEventArgs.preventFocus) {
trg.firstElementChild.focus();
}
});
}
}
setItems(items) {
this.isReplace = true;
this.tbItems = select('.' + CLS_TB_ITEMS, this.getTabHeader());
this.tbObj.items = this.parseObject(items, 0);
this.tbObj.dataBind();
this.isReplace = false;
}
setRTL(value) {
this.tbObj.enableRtl = value;
this.tbObj.dataBind();
this.setCssClass(this.element, CLS_RTL$4, value);
this.refreshActiveBorder();
}
refreshActiveBorder() {
if (!isNullOrUndefined(this.bdrLine)) {
this.bdrLine.classList.add(CLS_HIDDEN$1);
}
this.setActiveBorder();
}
showPopup(config) {
const tbPop = select('.e-popup.e-toolbar-pop', this.hdrEle);
if (tbPop && tbPop.classList.contains('e-popup-close')) {
const tbPopObj = (tbPop && tbPop.ej2_instances[0]);
tbPopObj.position.X = (this.headerPlacement === 'Left' || this.element.classList.contains(CLS_RTL$4)) ? 'left' : 'right';
tbPopObj.dataBind();
tbPopObj.show(config);
}
}
bindDraggable() {
if (this.allowDragAndDrop) {
const tabHeader = this.element.querySelector('.' + CLS_HEADER$1);
if (tabHeader) {
const items = Array.prototype.slice.call(tabHeader.querySelectorAll('.' + CLS_TB_ITEM));
items.forEach((element) => {
this.initializeDrag(element);
});
}
}
}
bindSwipeEvents() {
if (this.swipeMode !== 'None') {
this.touchModule = new Touch(this.cntEle, { swipe: this.swipeHandler.bind(this) });
}
}
wireEvents() {
this.bindDraggable();
window.addEventListener('resize', this.resizeContext);
EventHandler.add(this.element, 'mouseover', this.hoverHandler, this);
EventHandler.add(this.element, 'keydown', this.spaceKeyDown, this);
if (!isNullOrUndefined(this.cntEle)) {
this.bindSwipeEvents();
}
this.keyModule = new KeyboardEvents(this.element, { keyAction: this.keyHandler.bind(this), keyConfigs: this.keyConfigs });
this.tabKeyModule = new KeyboardEvents(this.element, {
keyAction: this.keyHandler.bind(this),
keyConfigs: { openPopup: 'shift+f10', tab: 'tab', shiftTab: 'shift+tab' },
eventName: 'keydown'
});
}
unWireEvents() {
if (!isNullOrUndefined(this.keyModule)) {
this.keyModule.destroy();
}
if (!isNullOrUndefined(this.tabKeyModule)) {
this.tabKeyModule.destroy();
}
if (!isNullOrUndefined(this.cntEle) && !isNullOrUndefined(this.touchModule)) {
this.touchModule.destroy();
this.touchModule = null;
}
window.removeEventListener('resize', this.resizeContext);
EventHandler.remove(this.element, 'mouseover', this.hoverHandler);
EventHandler.remove(this.element, 'keydown', this.spaceKeyDown);
this.element.classList.remove(CLS_RTL$4);
this.element.classList.remove(CLS_FOCUS);
}
clickHandler(args) {
this.element.classList.remove(CLS_FOCUS);
const trg = args.originalEvent.target;
const trgParent = closest(trg, '.' + CLS_TB_ITEM);
const trgIndex = this.getEleIndex(trgParent);
if (trg.classList.contains(CLS_ICON_CLOSE)) {
this.removeTab(trgIndex);
}
else if (this.isVertical() && closest(trg, '.' + CLS_HOR_NAV)) {
this.showPopup(this.show);
}
else {
this.isPopup = false;
if (!isNullOrUndefined(trgParent) && (trgIndex !== this.selectedItem)) {
this.selectTab(trgIndex, args.originalEvent, true);
}
}
}
swipeHandler(e) {
if ((e.velocity < 3 && isNullOrUndefined(e.originalEvent.changedTouches)) ||
(this.swipeMode === 'Touch' && ((e.originalEvent.type === 'mouseup') || e.originalEvent.type === 'mouseleave')) ||
(this.swipeMode === 'Mouse' && e.originalEvent.type === 'touchend') || (this.swipeMode === 'None')) {
return;
}
if (this.isNested) {
this.element.setAttribute('data-swipe', 'true');
}
const nestedTab = this.element.querySelector('[data-swipe="true"]');
if (nestedTab) {
nestedTab.removeAttribute('data-swipe');
return;
}
this.isSwiped = true;
if (e.swipeDirection === 'Right' && this.selectedItem !== 0) {
for (let k = this.selectedItem - 1; k >= 0; k--) {
if (!this.tbItem[k].classList.contains(CLS_HIDDEN$1)) {
this.selectTab(k, null, true);
break;
}
}
}
else if (e.swipeDirection === 'Left' && (this.selectedItem !== selectAll('.' + CLS_TB_ITEM, this.element).length - 1)) {
for (let i = this.selectedItem + 1; i < this.tbItem.length; i++) {
if (!this.tbItem[i].classList.contains(CLS_HIDDEN$1)) {
this.selectTab(i, null, true);
break;
}
}
}
this.isSwiped = false;
}
spaceKeyDown(e) {
if ((e.keyCode === 32 && e.which === 32) || (e.keyCode === 35 && e.which === 35)) {
const clstHead = closest(e.target, '.' + CLS_HEADER$1);
if (!isNullOrUndefined(clstHead)) {
e.preventDefault();
}
}
}
keyHandler(e) {
if (this.element.classList.contains(CLS_DISABLE$4)) {
return;
}
this.element.classList.add(CLS_FOCUS);
const trg = e.target;
const tabHeader = this.getTabHeader();
const actEle = select('.' + CLS_ACTIVE$1, tabHeader);
this.popEle = select('.' + CLS_TB_POP, tabHeader);
if (!isNullOrUndefined(this.popEle)) {
this.popObj = this.popEle.ej2_instances[0];
}
const item = closest(document.activeElement, '.' + CLS_TB_ITEM);
const trgParent = closest(trg, '.' + CLS_TB_ITEM);
switch (e.action) {
case 'space':
case 'enter':
if (trg.parentElement.classList.contains(CLS_DISABLE$4)) {
return;
}
if (e.action === 'enter' && trg.classList.contains('e-hor-nav')) {
this.showPopup(this.show);
break;
}
this.keyPressed(trg);
break;
case 'tab':
case 'shiftTab':
if (trg.classList.contains(CLS_WRAP)
&& closest(trg, '.' + CLS_TB_ITEM).classList.contains(CLS_ACTIVE$1) === false) {
trg.setAttribute('tabindex', trg.getAttribute('data-tabindex'));
}
if (this.popObj && isVisible(this.popObj.element)) {
this.popObj.hide(this.hide);
}
if (!isNullOrUndefined(actEle) && actEle.children.item(0).getAttribute('tabindex') === '-1') {
actEle.children.item(0).setAttribute('tabindex', '0');
}
break;
case 'moveLeft':
case 'moveRight':
if (!isNullOrUndefined(item)) {
this.refreshItemVisibility(item);
}
break;
case 'openPopup':
if (!isNullOrUndefined(e.target) && (e.target.classList.contains(CLS_WRAP))) {
e.preventDefault();
}
if (!isNullOrUndefined(this.popEle) && this.popEle.classList.contains(CLS_POPUP_CLOSE)) {
this.popObj.show(this.show);
}
break;
case 'delete':
if (this.showCloseButton === true && !isNullOrUndefined(trgParent)) {
const nxtSib = trgParent.nextSibling;
if (!isNullOrUndefined(nxtSib) && nxtSib.classList.contains(CLS_TB_ITEM)) {
nxtSib.firstElementChild.focus();
}
this.removeTab(this.getEleIndex(trgParent));
}
this.setActiveBorder();
break;
}
}
refreshItemVisibility(target) {
const scrCnt = select('.' + this.scrCntClass, this.tbItems);
if (!this.isVertical() && !isNullOrUndefined(scrCnt)) {
const scrBar = select('.e-hscroll-bar', this.tbItems);
const scrStart = scrBar.scrollLeft;
const scrEnd = scrStart + scrBar.offsetWidth;
const eleStart = target.offsetLeft;
const eleWidth = target.offsetWidth;
const eleEnd = target.offsetLeft + target.offsetWidth;
if ((scrStart < eleStart) && (scrEnd < eleEnd)) {
const eleViewRange = scrEnd - eleStart;
scrBar.scrollLeft = scrStart + (eleWidth - eleViewRange);
}
else {
if ((scrStart > eleStart) && (scrEnd > eleEnd)) {
const eleViewRange = eleEnd - scrStart;
scrBar.scrollLeft = scrStart - (eleWidth - eleViewRange);
}
}
}
else {
return;
}
}
getIndexFromEle(id) {
return parseInt(id.substring(id.lastIndexOf('_') + 1), 10);
}
hoverHandler(e) {
const trg = e.target;
if (!isNullOrUndefined(trg.classList) && trg.classList.contains(CLS_ICON_CLOSE)) {
trg.setAttribute('title', new L10n('tab', { closeButtonTitle: this.title }, this.locale).getConstant('closeButtonTitle'));
}
}
evalOnPropertyChangeItems(newProp, oldProp) {
if (!(newProp.items instanceof Array && oldProp.items instanceof Array)) {
const changedProp = Object.keys(newProp.items);
for (let i = 0; i < changedProp.length; i++) {
const index = parseInt(Object.keys(newProp.items)[i], 10);
const properties = Object.keys(newProp.items[index]);
for (let j = 0; j < properties.length; j++) {
const oldVal = Object(oldProp.items[index])[properties[j]];
const newVal = Object(newProp.items[index])[properties[j]];
const hdr = this.element.querySelectorAll('.' + CLS_TB_ITEM)[index];
let itemIndex;
if (hdr && !isNullOrUndefined(hdr.id) && hdr.id !== '') {
itemIndex = this.getIndexFromEle(hdr.id);
}
else {
itemIndex = index;
}
const hdrItem = select('.' + CLS_TB_ITEMS + ' #' + CLS_ITEM$2 + this.tabId + '_' + itemIndex, this.element);
const cntItem = select('.' + CLS_CONTENT$1 + ' #' + CLS_CONTENT$1 + this.tabId + '_' + itemIndex, this.element);
if (properties[j] === 'header' || properties[j] === 'headerTemplate') {
const icon = (isNullOrUndefined(this.items[index].header) ||
isNullOrUndefined(this.items[index].header.iconCss)) ? '' : this.items[index].header.iconCss;
const textVal = this.items[index].headerTemplate || this.items[index].header.text;
if (properties[j] === 'headerTemplate') {
this.clearTabTemplate(hdrItem, properties[j], CLS_TB_ITEM);
}
if ((textVal === '') && (icon === '')) {
this.removeTab(index);
}
else {
this.tbId = hdr.id;
const arr = [];
arr.push(this.items[index]);
this.items.splice(index, 1);
this.itemIndexArray.splice(index, 1);
this.tbObj.items.splice(index, 1);
const isHiddenEle = hdrItem.classList.contains(CLS_HIDDEN$1);
detach(hdrItem);
this.isReplace = true;
this.addTab(arr, index);
if (isHiddenEle) {
this.hideTab(index);
}
this.isReplace = false;
}
}
if (properties[j] === 'content' && !isNullOrUndefined(cntItem)) {
const strVal = typeof newVal === 'string' || isNullOrUndefined(newVal.innerHTML);
if (strVal && (newVal[0] === '.' || newVal[0] === '#') && newVal.length) {
const eleVal = document.querySelector(newVal);
cntItem.appendChild(eleVal);
eleVal.style.display = '';
}
else if (newVal === '' && oldVal[0] === '#') {
document.body.appendChild(this.element.querySelector(oldVal)).style.display = 'none';
cntItem.innerHTML = newVal;
}
else if (this.isAngular || this.isReact) {
this.clearTabTemplate(cntItem, properties[j], CLS_ITEM$2);
cntItem.innerHTML = '';
this.templateCompile(cntItem, newVal, index);
}
else if (typeof newVal !== 'function') {
cntItem.innerHTML = newVal;
}
}
if (properties[j] === 'cssClass') {
if (!isNullOrUndefined(hdrItem)) {
hdrItem.classList.remove(oldVal);
hdrItem.classList.add(newVal);
}
if (!isNullOrUndefined(cntItem)) {
cntItem.classList.remove(oldVal);
cntItem.classList.add(newVal);
}
}
if (properties[j] === 'disabled') {
this.enableTab(index, ((newVal === true) ? false : true));
}
if (properties[j] === 'visible') {
this.hideTab(index, ((newVal === true) ? false : true));
}
}
}
if (this.isReact && this.portals && this.portals.length > 0) {
this.renderReactTemplates(() => {
this.refreshActiveTabBorder();
});
}
}
else {
this.lastIndex = 0;
if (isNullOrUndefined(this.tbObj)) {
this.reRenderItems();
}
else {
if (this.isReact || this.isAngular) {
this.clearTemplate();
}
this.setItems(newProp.items);
if (this.templateEle.length > 0) {
this.expTemplateContent();
}
this.templateEle = [];
const selectElement = select('.' + CLS_TAB + ' > .' + CLS_CONTENT$1, this.element);
while (selectElement.firstElementChild) {
detach(selectElement.firstElementChild);
}
this.select(this.selectedItem);
this.draggableItems = [];
this.bindDraggable();
}
}
}
clearTabTemplate(templateEle, templateName, className) {
if (!this.clearTemplates) {
return;
}
if (this.registeredTemplate && this.registeredTemplate[templateName]) {
const registeredTemplates = this.registeredTemplate;
for (let index = 0; index < registeredTemplates[templateName].length; index++) {
const registeredItem = registeredTemplates[templateName][index].rootNodes[0];
const closestItem = closest(registeredItem, '.' + className);
if (!isNullOrUndefined(closestItem) && closestItem === templateEle) {
this.clearTemplate([templateName], [registeredTemplates[templateName][index]]);
break;
}
}
}
else if (this.portals && this.portals.length > 0) {
const portals = this.portals;
for (let index = 0; index < portals.length; index++) {
const portalItem = portals[index];
const closestItem = closest(portalItem.containerInfo, '.' + className);
if (!isNullOrUndefined(closestItem) && closestItem === templateEle) {
this.clearTemplate([templateName], index);
break;
}
}
}
}
initializeDrag(target) {
let dragObj = new Draggable(target, {
dragArea: this.dragArea,
dragTarget: '.' + CLS_TB_ITEM,
clone: true,
helper: this.helper.bind(this),
dragStart: this.itemDragStart.bind(this),
drag: (e) => {
let dragIndex = this.getEleIndex(this.dragItem);
let dropIndex;
let dropItem;
let dragArgs = {
draggedItem: this.dragItem,
event: e.event,
target: e.target,
droppedItem: e.target.closest('.' + CLS_TB_ITEM),
clonedElement: this.cloneElement,
index: dragIndex
};
if (!isNullOrUndefined(e.target.closest('.' + CLS_TAB)) && !e.target.closest('.' + CLS_TAB).isEqualNode(this.element) &&
this.dragArea !== '.' + CLS_HEADER$1) {
this.trigger('dragging', dragArgs);
}
else {
if (!(e.target.closest(this.dragArea)) && this.overflowMode !== 'Popup') {
document.body.style.cursor = 'not-allowed';
addClass([this.cloneElement], CLS_HIDDEN$1);
if (this.dragItem.classList.contains(CLS_HIDDEN$1)) {
removeClass([this.dragItem], CLS_HIDDEN$1);
}
this.dragItem.querySelector('.' + CLS_WRAP).style.visibility = 'visible';
}
else {
document.body.style.cursor = '';
this.dragItem.querySelector('.' + CLS_WRAP).style.visibility = 'hidden';
if (this.cloneElement.classList.contains(CLS_HIDDEN$1)) {
removeClass([this.cloneElement], CLS_HIDDEN$1);
}
}
if (this.overflowMode === 'Scrollable' && !isNullOrUndefined(this.element.querySelector('.e-hscroll'))) {
let scrollRightNavEle = this.element.querySelector('.e-scroll-right-nav');
let scrollLeftNavEle = this.element.querySelector('.e-scroll-left-nav');
let hscrollBar = this.element.querySelector('.e-hscroll-bar');
if (!isNullOrUndefined(scrollRightNavEle) && Math.abs((scrollRightNavEle.offsetWidth / 2) +
scrollRightNavEle.offsetLeft) > this.cloneElement.offsetLeft + this.cloneElement.offsetWidth) {
hscrollBar.scrollLeft -= 10;
}
if (!isNullOrUndefined(scrollLeftNavEle) && Math.abs((scrollLeftNavEle.offsetLeft + scrollLeftNavEle.offsetWidth) -
this.cloneElement.offsetLeft) > (scrollLeftNavEle.offsetWidth / 2)) {
hscrollBar.scrollLeft += 10;
}
}
this.cloneElement.style.pointerEvents = 'none';
dropItem = closest(e.target, '.' + CLS_TB_ITEM + '.e-draggable');
let scrollContentWidth = 0;
if (this.overflowMode === 'Scrollable' && !isNullOrUndefined(this.element.querySelector('.e-hscroll'))) {
scrollContentWidth = this.element.querySelector('.e-hscroll-content').offsetWidth;
}
if (dropItem != null && !dropItem.isSameNode(this.dragItem) &&
dropItem.closest('.' + CLS_TAB).isSameNode(this.dragItem.closest('.' + CLS_TAB))) {
dropIndex = this.getEleIndex(dropItem);
if (dropIndex < dragIndex &&
(Math.abs((dropItem.offsetLeft + dropItem.offsetWidth) -
this.cloneElement.offsetLeft) > (dropItem.offsetWidth / 2))) {
this.dragAction(dropItem, dragIndex, dropIndex);
}
if (dropIndex > dragIndex &&
(Math.abs(dropItem.offsetWidth / 2) + dropItem.offsetLeft -
scrollContentWidth) < this.cloneElement.offsetLeft + this.cloneElement.offsetWidth) {
this.dragAction(dropItem, dragIndex, dropIndex);
}
}
this.droppedIndex = this.getEleIndex(this.dragItem);
this.trigger('dragging', dragArgs);
}
},
dragStop: this.itemDragStop.bind(this)
});
this.draggableItems.push(dragObj);
}
helper(e) {
this.cloneElement = this.createElement('div');
if (e.element) {
this.cloneElement = (e.element.cloneNode(true));
addClass([this.cloneElement], 'e-tab-clone-element');
if (this.element.querySelector('.' + CLS_HEADER$1).classList.contains(CLS_CLOSE_SHOW)) {
addClass([this.cloneElement], CLS_CLOSE_SHOW);
}
removeClass([this.cloneElement.querySelector('.' + CLS_WRAP)], 'e-ripple');
if (!isNullOrUndefined(this.cloneElement.querySelector('.e-ripple-element'))) {
remove(this.cloneElement.querySelector('.e-ripple-element'));
}
document.body.appendChild(this.cloneElement);
}
return this.cloneElement;
}
itemDragStart(e) {
this.draggingItems = this.items.map((x) => x);
this.dragItem = e.element;
let dragArgs = {
draggedItem: e.element,
event: e.event,
target: e.target,
droppedItem: null,
index: this.getEleIndex(this.dragItem),
clonedElement: this.cloneElement,
cancel: false
};
this.trigger('onDragStart', dragArgs, (tabItemDragArgs) => {
if (tabItemDragArgs.cancel) {
const dragObj = e.element.ej2_instances[0];
if (!isNullOrUndefined(dragObj)) {
dragObj.intDestroy(e.event);
}
detach(this.cloneElement);
}
else {
this.removeActiveClass();
addClass([this.tbItems.querySelector('.' + CLS_INDICATOR)], CLS_HIDDEN$1);
this.dragItem.querySelector('.' + CLS_WRAP).style.visibility = 'hidden';
}
});
}
dragAction(dropItem, dragsIndex, dropIndex) {
if (this.items.length > 0) {
let item = this.draggingItems[dragsIndex];
this.draggingItems.splice(dragsIndex, 1);
this.draggingItems.splice(dropIndex, 0, item);
}
if (this.overflowMode === 'MultiRow') {
dropItem.parentNode.insertBefore(this.dragItem, dropItem.nextElementSibling);
}
if (dragsIndex > dropIndex) {
if (!(this.dragItem.parentElement).isSameNode(dropItem.parentElement)) {
if (this.overflowMode === 'Extended') {
if (dropItem.isSameNode(dropItem.parentElement.lastChild)) {
let popupContainer = this.dragItem.parentNode;
dropItem.parentNode.insertBefore(this.dragItem, dropItem);
popupContainer.insertBefore(dropItem.parentElement.lastChild, popupContainer.childNodes[0]);
}
else {
this.dragItem.parentNode.insertBefore((dropItem.parentElement.lastChild), this.dragItem.parentElement.childNodes[0]);
dropItem.parentNode.insertBefore(this.dragItem, dropItem);
}
}
else {
let lastEle = (dropItem.parentElement).lastChild;
if (dropItem.isSameNode(lastEle)) {
let popupContainer = this.dragItem.parentNode;
dropItem.parentNode.insertBefore(this.dragItem, dropItem);
popupContainer.insertBefore(lastEle, popupContainer.childNodes[0]);
}
else {
this.dragItem.parentNode.insertBefore((dropItem.parentElement).lastChild, this.dragItem.parentElement.childNodes[0]);
dropItem.parentNode.insertBefore(this.dragItem, dropItem);
}
}
}
else {
this.dragItem.parentNode.insertBefore(this.dragItem, dropItem);
}
}
if (dragsIndex < dropIndex) {
if (!(this.dragItem.parentElement).isSameNode(dropItem.parentElement)) {
if (this.overflowMode === 'Extended') {
this.dragItem.parentElement.appendChild(dropItem.parentElement.firstElementChild);
dropItem.parentNode.insertBefore(this.dragItem, dropItem.nextSibling);
}
else {
this.dragItem.parentNode.insertBefore((dropItem.parentElement).lastChild, this.dragItem.parentElement.childNodes[0]);
dropItem.parentNode.insertBefore(this.dragItem, dropItem);
}
}
else {
this.dragItem.parentNode.insertBefore(this.dragItem, dropItem.nextElementSibling);
}
}
}
itemDragStop(e) {
detach(this.cloneElement);
this.cloneElement = null;
this.dragItem.querySelector('.' + CLS_WRAP).style.visibility = 'visible';
document.body.style.cursor = '';
let dragStopArgs = {
draggedItem: this.dragItem,
event: e.event,
target: e.target,
droppedItem: this.tbItem[this.droppedIndex],
clonedElement: null,
index: this.droppedIndex,
cancel: false
};
this.trigger('dragged', dragStopArgs, (tabItemDropArgs) => {
if (tabItemDropArgs.cancel) {
this.refresh();
}
else {
if (this.items.length > 0 && this.draggingItems.length > 0) {
this.items = this.draggingItems;
this.selectedItem = isNullOrUndefined(this.droppedIndex) ? this.getEleIndex(this.dragItem) : this.droppedIndex;
this.refresh();
}
else {
this.dragItem.querySelector('.' + CLS_WRAP).style.visibility = '';
removeClass([this.tbItems.querySelector('.' + CLS_INDICATOR)], CLS_HIDDEN$1);
this.droppedIndex = isNullOrUndefined(this.droppedIndex) ? this.getEleIndex(this.dragItem) : this.droppedIndex;
this.selectTab(this.droppedIndex, null, true);
}
}
});
this.dragItem = null;
this.droppedIndex = null;
}
/**
* Enables or disables the specified Tab item. On passing value as `false`, the item will be disabled.
*
* @param {number} index - Index value of target Tab item.
* @param {boolean} value - Boolean value that determines whether the command should be enabled or disabled.
* By default, isEnable is true.
* @returns {void}.
*/
enableTab(index, value) {
const tbItems = selectAll('.' + CLS_TB_ITEM, this.element)[index];
if (isNullOrUndefined(tbItems)) {
return;
}
if (value === true) {
tbItems.classList.remove(CLS_DISABLE$4, CLS_OVERLAY$2);
tbItems.firstElementChild.setAttribute('tabindex', tbItems.firstElementChild.getAttribute('data-tabindex'));
}
else {
tbItems.classList.add(CLS_DISABLE$4, CLS_OVERLAY$2);
tbItems.firstElementChild.removeAttribute('tabindex');
if (tbItems.classList.contains(CLS_ACTIVE$1)) {
this.select(index + 1);
}
}
if (!isNullOrUndefined(this.items[index])) {
this.items[index].disabled = !value;
this.dataBind();
}
tbItems.firstElementChild.setAttribute('aria-disabled', (value === true) ? 'false' : 'true');
}
/**
* Adds new items to the Tab that accepts an array as Tab items.
*
* @param {TabItemModel[]} items - An array of item that is added to the Tab.
* @param {number} index - Number value that determines where the items to be added. By default, index is 0.
* @returns {void}.
*/
addTab(items, index) {
const addArgs = { addedItems: items, cancel: false };
if (!this.isReplace) {
for (const item of items) {
item.disabled = item.disabled || false;
item.visible = item.visible || true;
}
if (items && items.length !== 0 && this.element && this.element.classList.contains(CLS_HIDDEN$1)) {
this.element.classList.remove(CLS_HIDDEN$1);
}
this.trigger('adding', addArgs, (tabAddingArgs) => {
if (!tabAddingArgs.cancel) {
this.addingTabContent(items, index);
}
});
}
else {
this.addingTabContent(items, index);
}
if (this.isReact) {
this.renderReactTemplates();
}
}
addingTabContent(items, index) {
let lastEleIndex = 0;
this.hdrEle = select('.' + CLS_HEADER$1, this.element);
if (isNullOrUndefined(this.hdrEle)) {
this.items = items;
this.reRenderItems();
this.bindDraggable();
}
else {
const tbItems = Array.from(selectAll('.e-tab-header .' + CLS_TB_ITEM, this.element));
const itemsCount = tbItems.length;
if (itemsCount !== 0) {
lastEleIndex = this.getMaxIndicesFromItems(tbItems) + 1;
}
if (isNullOrUndefined(index)) {
index = itemsCount - 1;
}
if (itemsCount < index || index < 0 || isNaN(index)) {
return;
}
if (itemsCount === 0 && !isNullOrUndefined(this.hdrEle)) {
this.hdrEle.style.display = '';
}
if (!isNullOrUndefined(this.bdrLine)) {
this.bdrLine.classList.add(CLS_HIDDEN$1);
}
this.tbItems = select('.' + CLS_TB_ITEMS, this.getTabHeader());
this.isAdd = true;
const tabItems = this.parseObject(items, index);
this.isAdd = false;
let i = 0;
let textValue;
items.forEach((item, place) => {
textValue = item.headerTemplate || item.header.text;
if (!(isNullOrUndefined(item.headerTemplate || item.header) || isNullOrUndefined(textValue) ||
(textValue.length === 0) && !isNullOrUndefined(item.header) && isNullOrUndefined(item.header.iconCss))) {
if (tabItems[place]) {
if (isNullOrUndefined(item.id)) {
item.id = CLS_ITEM$2 + this.tabId + '_' + TABITEMPREFIX + (lastEleIndex + place).toString();
}
tabItems[place].htmlAttributes['data-id'] = item.id;
}
this.items.splice((index + i), 0, item);
i++;
}
if (!isNullOrUndefined(item.header) && !isNullOrUndefined(item.header.text) && (this.isTemplate || this.loadOn === 'Init')) {
const no = lastEleIndex + place;
const ele = this.createElement('div', {
id: CLS_CONTENT$1 + this.tabId + '_' + no, className: CLS_ITEM$2,
attrs: { role: 'tabpanel', 'aria-labelledby': CLS_ITEM$2 + '_' + no }
});
this.cntEle.insertBefore(ele, this.cntEle.children[(index + place)]);
const eleTrg = this.getTrgContent(this.cntEle, no.toString());
this.getContent(eleTrg, item.content, 'render', index);
}
});
this.tbObj.addItems(tabItems, index);
if (!this.isReplace) {
this.trigger('added', { addedItems: items });
}
if (this.selectedItem === index) {
this.select(index);
}
else {
this.setActiveBorder();
this.tbItem = selectAll('.' + CLS_TB_ITEM, this.getTabHeader());
}
this.bindDraggable();
}
}
/**
* Removes the items in the Tab from the specified index.
*
* @param {number} index - Index of target item that is going to be removed.
* @returns {void}.
*/
removeTab(index) {
const trg = selectAll('.' + CLS_TB_ITEM, this.hdrEle)[index];
if (isNullOrUndefined(trg)) {
return;
}
const removeArgs = { removedItem: trg, removedIndex: index, cancel: false };
this.trigger('removing', removeArgs, (tabRemovingArgs) => {
if (!tabRemovingArgs.cancel) {
const header = select('#' + CLS_ITEM$2 + this.tabId + '_' + this.extIndex(trg.id), select('.' + CLS_TB_ITEMS, this.hdrEle));
if (!isNullOrUndefined(header)) {
this.clearTabTemplate(header, 'headerTemplate', CLS_TB_ITEM);
}
this.tbObj.removeItems(index);
if (this.allowDragAndDrop && (index !== Array.prototype.indexOf.call(this.itemIndexArray, trg.id))) {
index = Array.prototype.indexOf.call(this.itemIndexArray, trg.id);
}
const targetEleIndex = this.itemIndexArray.indexOf(trg.id);
this.items.splice(targetEleIndex, 1);
this.itemIndexArray.splice(targetEleIndex, 1);
this.refreshActiveBorder();
const cntTrg = select('#' + CLS_CONTENT$1 + this.tabId + '_' + this.extIndex(trg.id), select('.' + CLS_CONTENT$1, this.element));
if (!isNullOrUndefined(cntTrg)) {
this.clearTabTemplate(cntTrg, 'content', CLS_ITEM$2);
detach(cntTrg);
}
this.trigger('removed', tabRemovingArgs);
if (this.draggableItems && this.draggableItems.length > 0) {
this.draggableItems[index].destroy();
this.draggableItems[index] = null;
this.draggableItems.splice(index, 1);
}
if (trg.classList.contains(CLS_ACTIVE$1)) {
index = (index > selectAll('.' + CLS_TB_ITEM + ':not(.' + CLS_TB_POPUP + ')', this.element).length - 1) ? index - 1 : index;
this.enableAnimation = false;
this.tbItem = selectAll('.' + CLS_TB_ITEM, this.getTabHeader());
index = this.getSelectingTabIndex(index);
index = !isNaN(index) && index >= 0 && this.tbItem.length > index ? index : 0;
const tabItem = this.tbItem[index];
if (tabItem) {
if (tabItem.classList.contains(CLS_HIDDEN$1)) {
tabItem.classList.remove(CLS_HIDDEN$1);
}
const firstChild = tabItem.firstElementChild;
if (firstChild && firstChild.hasAttribute('aria-hidden')) {
firstChild.removeAttribute('aria-hidden');
}
}
this.selectedItem = index;
this.select(index);
}
else if (index !== this.selectedItem) {
if (index < this.selectedItem) {
index = this.itemIndexArray.indexOf(this.tbItem[this.selectedItem].id);
this.setProperties({ selectedItem: index > -1 ? index : this.selectedItem }, true);
this.prevIndex = this.selectedItem;
}
this.tbItem = selectAll('.' + CLS_TB_ITEM, this.getTabHeader());
}
if (selectAll('.' + CLS_TB_ITEM, this.element).length === 0) {
const cnt = select('.' + CLS_CONTENT$1, this.element);
detach(this.hdrEle);
detach(cnt);
}
this.enableAnimation = true;
}
});
}
/**
* Shows or hides the Tab that is in the specified index.
*
* @param {number} index - Index value of target item.
* @param {boolean} value - Based on this Boolean value, item will be hide (true) or show (false). By default, value is true.
* @returns {void}.
*/
hideTab(index, value) {
let items;
let tabId;
if (index >= 0 && index < this.tbItem.length) {
tabId = this.tbItem[index].getAttribute('id');
}
const item = this.element.querySelector(`[id="${tabId}"]`);
if (isNullOrUndefined(item)) {
return;
}
if (isNullOrUndefined(value)) {
value = true;
}
this.bdrLine.classList.add(CLS_HIDDEN$1);
if (value === true) {
item.classList.add(CLS_HIDDEN$1);
items = selectAll('.' + CLS_TB_ITEM + ':not(.' + CLS_HIDDEN$1 + ')', this.tbItems);
if (items.length !== 0 && item.classList.contains(CLS_ACTIVE$1)) {
if (index !== 0) {
for (let i = index - 1; i >= 0; i--) {
if (!this.tbItem[i].classList.contains(CLS_HIDDEN$1)) {
this.select(i);
break;
}
else if (i === 0) {
for (let k = index + 1; k < this.tbItem.length; k++) {
if (!this.tbItem[k].classList.contains(CLS_HIDDEN$1)) {
this.select(k);
break;
}
}
}
}
}
else {
for (let k = index + 1; k < this.tbItem.length; k++) {
if (!this.tbItem[k].classList.contains(CLS_HIDDEN$1)) {
this.select(k);
break;
}
}
}
}
else if (items.length === 0) {
this.element.classList.add(CLS_HIDDEN$1);
}
}
else {
this.element.classList.remove(CLS_HIDDEN$1);
items = selectAll('.' + CLS_TB_ITEM + ':not(.' + CLS_HIDDEN$1 + ')', this.tbItems);
item.classList.remove(CLS_HIDDEN$1);
if (items.length === 0) {
this.select(index);
}
}
this.setActiveBorder();
if (!isNullOrUndefined(this.items[index])) {
this.items[index].visible = !value;
this.dataBind();
}
if (!isNullOrUndefined(item.firstElementChild)) {
item.firstElementChild.setAttribute('aria-hidden', '' + value);
}
if (this.overflowMode === 'Popup') {
this.refreshOverflow();
}
}
selectTab(args, event = null, isInteracted = false) {
this.isInteracted = isInteracted;
this.select(args, event);
}
/**
* Specifies the index or HTMLElement to select an item from the Tab.
*
* @param {number | HTMLElement} args - Index or DOM element is used for selecting an item from the Tab.
* @param {Event} event - An event which takes place in DOM.
* @returns {void}
*/
select(args, event) {
const tabHeader = this.getTabHeader();
this.tbItems = select('.' + CLS_TB_ITEMS, tabHeader);
this.tbItem = selectAll('.' + CLS_TB_ITEM, tabHeader);
this.content = select('.' + CLS_CONTENT$1, this.element);
this.prevItem = this.tbItem[this.prevIndex];
if (isNullOrUndefined(this.selectedItem) || (this.selectedItem < 0) || (this.tbItem.length <= this.selectedItem) || isNaN(this.selectedItem)) {
this.selectedItem = 0;
}
else {
this.selectedID = this.extIndex(this.tbItem[this.selectedItem].id);
}
const trg = this.tbItem[args];
if (isNullOrUndefined(trg)) {
this.selectedID = '0';
}
else {
this.selectingID = this.extIndex(trg.id);
}
if (!isNullOrUndefined(this.prevItem) && !this.prevItem.classList.contains(CLS_DISABLE$4)) {
this.prevItem.children.item(0).setAttribute('tabindex', this.prevItem.firstElementChild.getAttribute('tabindex'));
}
const eventArg = {
event: event,
previousItem: this.prevItem,
previousIndex: this.prevIndex,
selectedItem: this.tbItem[this.selectedItem],
selectedIndex: this.selectedItem,
selectedContent: !isNullOrUndefined(this.content) ?
select('#' + CLS_CONTENT$1 + this.tabId + '_' + this.selectedID, this.content) : null,
selectingItem: trg,
selectingIndex: args,
selectingContent: !isNullOrUndefined(this.content) ?
select('#' + CLS_CONTENT$1 + this.tabId + '_' + this.selectingID, this.content) : null,
isSwiped: this.isSwiped,
isInteracted: this.isInteracted,
cancel: false
};
if (!this.initRender) {
this.trigger('selecting', eventArg, (selectArgs) => {
if (!selectArgs.cancel) {
this.selectingContent(args, this.isInteracted);
}
});
}
else {
this.selectingContent(args, this.isInteracted);
}
this.isInteracted = false;
}
getSelectingTabIndex(args) {
if (!isNullOrUndefined(this.tbItem[args]) && (this.tbItem[args].classList.contains(CLS_DISABLE$4) ||
this.tbItem[args].classList.contains(CLS_HIDDEN$1))) {
for (let i = args + 1; i < this.items.length; i++) {
if (this.items[i].disabled === false && this.items[i].visible === true) {
args = i;
break;
}
else {
args = 0;
}
}
}
return args;
}
selectingContent(args, isInteracted) {
if (typeof args === 'number') {
args = this.getSelectingTabIndex(args);
if (this.tbItem.length > args && args >= 0 && !isNaN(args)) {
this.prevIndex = this.selectedItem;
this.prevItem = this.tbItem[this.prevIndex];
if (this.tbItem[args].classList.contains(CLS_TB_POPUP) && this.reorderActiveTab) {
this.setActive(this.popupHandler(this.tbItem[args]), null, isInteracted);
if ((!isNullOrUndefined(this.items) && this.items.length > 0) && this.allowDragAndDrop) {
this.tbItem = selectAll('.' + CLS_TB_ITEMS + ' .' + CLS_TB_ITEM, this.hdrEle);
let item = this.items[args];
this.items.splice(args, 1);
this.items.splice(this.tbItem.length - 1, 0, item);
let itemId = this.itemIndexArray[args];
this.itemIndexArray.splice(args, 1);
this.itemIndexArray.splice(this.tbItem.length - 1, 0, itemId);
}
}
else {
this.setActive(args, null, isInteracted);
}
}
else {
this.setActive(0, null, isInteracted);
}
}
else if (args instanceof (HTMLElement)) {
this.setActive(this.getEleIndex(args), null, isInteracted);
}
}
/**
* Gets the item index from the Tab.
*
* @param {string} tabItemId - Item ID is used for getting index from the Tab.
* @returns {number} - It returns item index.
*/
getItemIndex(tabItemId) {
let tabIndex;
this.tbItem = selectAll('.' + CLS_TB_ITEM, this.getTabHeader());
for (let i = 0; i < this.tbItem.length; i++) {
const value = this.tbItem[i].getAttribute('data-id');
if (tabItemId === value) {
tabIndex = i;
break;
}
}
return tabIndex;
}
/**
* Specifies the value to disable/enable the Tab component.
* When set to `true`, the component will be disabled.
*
* @param {boolean} value - Based on this Boolean value, Tab will be enabled (false) or disabled (true).
* @returns {void}.
*/
disable(value) {
this.setCssClass(this.element, CLS_DISABLE$4, value);
this.element.setAttribute('aria-disabled', '' + value);
}
/**
* Get the properties to be maintained in the persisted state.
*
* @returns {string} - It returns the persisted state.
*/
getPersistData() {
return this.addOnPersist(['selectedItem', 'actEleId']);
}
/**
* Returns the current module name.
*
* @returns {string} - It returns the current module name.
* @private
*/
getModuleName() {
return 'tab';
}
/**
* Gets called when the model property changes.The data that describes the old and new values of the property that changed.
*
* @param {TabModel} newProp - It contains the new value of data.
* @param {TabModel} oldProp - It contains the old value of data.
* @returns {void}
* @private
*/
onPropertyChanged(newProp, oldProp) {
let sortedKeys = Object.keys(newProp).sort(function (a, b) {
if (a === 'items')
return -1;
if (b === 'items')
return 1;
return 0;
});
for (const prop of sortedKeys) {
switch (prop) {
case 'width':
setStyleAttribute(this.element, { width: formatUnit(newProp.width) });
break;
case 'height':
setStyleAttribute(this.element, { height: formatUnit(newProp.height) });
this.setContentHeight(false);
break;
case 'cssClass':
const headerEle = this.element.querySelector('.' + CLS_HEADER$1);
if (oldProp.cssClass !== '' && !isNullOrUndefined(oldProp.cssClass)) {
this.setCssClass(this.element, oldProp.cssClass, false);
this.setCssClass(this.element, newProp.cssClass, true);
if (!isNullOrUndefined(headerEle)) {
this.setCssClass(headerEle, oldProp.cssClass, false);
this.setCssClass(headerEle, newProp.cssClass, true);
}
}
else {
this.setCssClass(this.element, newProp.cssClass, true);
if (!isNullOrUndefined(headerEle)) {
this.setCssClass(headerEle, newProp.cssClass, true);
}
}
break;
case 'items':
this.evalOnPropertyChangeItems(newProp, oldProp);
break;
case 'showCloseButton':
this.setCloseButton(newProp.showCloseButton);
break;
case 'reorderActiveTab':
this.refreshActiveTabBorder();
break;
case 'selectedItem':
this.selectedItem = oldProp.selectedItem;
this.select(newProp.selectedItem);
break;
case 'headerPlacement':
this.changeOrientation(newProp.headerPlacement);
break;
case 'enableRtl':
this.setRTL(newProp.enableRtl);
break;
case 'overflowMode':
this.tbObj.overflowMode = newProp.overflowMode;
this.tbObj.dataBind();
this.refreshActiveTabBorder();
break;
case 'heightAdjustMode':
this.setContentHeight(false);
this.select(this.selectedItem);
break;
case 'scrollStep':
if (this.tbObj) {
this.tbObj.scrollStep = this.scrollStep;
}
break;
case 'allowDragAndDrop':
this.bindDraggable();
break;
case 'swipeMode':
if (this.touchModule) {
this.touchModule.destroy();
this.touchModule = null;
}
this.bindSwipeEvents();
break;
case 'dragArea':
if (this.allowDragAndDrop) {
this.draggableItems.forEach((item) => {
item.dragArea = this.dragArea;
});
this.refresh();
}
break;
}
}
}
/**
* To refresh the active tab contents.
*
* @returns {void}
*/
refreshActiveTab() {
if (this.isReact && this.isTemplate) {
this.clearTemplate();
}
if (!this.isTemplate) {
if (this.element.querySelector('.' + CLS_TB_ITEM + '.' + CLS_ACTIVE$1)) {
detach(this.element.querySelector('.' + CLS_TB_ITEM + '.' + CLS_ACTIVE$1).children[0]);
detach(this.element.querySelector('.' + CLS_CONTENT$1).querySelector('.' + CLS_ACTIVE$1).children[0]);
const item = this.items[this.selectedItem];
const pos = (isNullOrUndefined(item.header) || isNullOrUndefined(item.header.iconPosition)) ? '' : item.header.iconPosition;
const css = (isNullOrUndefined(item.header) || isNullOrUndefined(item.header.iconCss)) ? '' : item.header.iconCss;
const text = item.headerTemplate || item.header.text;
const txtWrap = this.createElement('div', { className: CLS_TEXT, attrs: { 'role': 'presentation' } });
if (!isNullOrUndefined(text.tagName)) {
txtWrap.appendChild(text);
}
else {
this.headerTextCompile(txtWrap, text, this.selectedItem);
}
let tEle;
const icon = this.createElement('span', {
className: CLS_ICONS + ' ' + CLS_TAB_ICON + ' ' + CLS_ICON + '-' + pos + ' ' + css
});
const tConts = this.createElement('div', { className: CLS_TEXT_WRAP });
tConts.appendChild(txtWrap);
if ((text !== '' && text !== undefined) && css !== '') {
if ((pos === 'left' || pos === 'top')) {
tConts.insertBefore(icon, tConts.firstElementChild);
}
else {
tConts.appendChild(icon);
}
tEle = txtWrap;
this.isIconAlone = false;
}
else {
tEle = ((css === '') ? txtWrap : icon);
if (tEle === icon) {
detach(txtWrap);
tConts.appendChild(icon);
this.isIconAlone = true;
}
}
const tabIndex = isNullOrUndefined(item.tabIndex) ? '-1' : item.tabIndex.toString();
const wrapAtt = (item.disabled) ? {} : { tabIndex: tabIndex, 'data-tabindex': tabIndex, role: 'tab', 'aria-selected': 'true', 'aria-disabled': 'false' };
tConts.appendChild(this.btnCls.cloneNode(true));
const wraper = this.createElement('div', { className: CLS_WRAP, attrs: wrapAtt });
wraper.appendChild(tConts);
if (pos === 'top' || pos === 'bottom') {
this.element.classList.add('e-vertical-icon');
}
this.element.querySelector('.' + CLS_TB_ITEM + '.' + CLS_ACTIVE$1).appendChild(wraper);
const crElem = this.createElement('div');
let cnt = item.content;
let eleStr;
if (typeof cnt === 'string' || isNullOrUndefined(cnt.innerHTML)) {
if (typeof cnt === 'string' && this.enableHtmlSanitizer) {
cnt = SanitizeHtmlHelper.sanitize(cnt);
}
if (cnt[0] === '.' || cnt[0] === '#') {
if (document.querySelectorAll(cnt).length) {
const eleVal = document.querySelector(cnt);
eleStr = eleVal.outerHTML.trim();
crElem.appendChild(eleVal);
eleVal.style.display = '';
}
else {
this.compileElement(crElem, cnt, 'content', this.selectedItem);
}
}
else {
this.compileElement(crElem, cnt, 'content', this.selectedItem);
}
}
else {
crElem.appendChild(cnt);
}
if (!isNullOrUndefined(eleStr)) {
if (this.templateEle.indexOf(cnt.toString()) === -1) {
this.templateEle.push(cnt.toString());
}
}
this.element.querySelector('.' + CLS_ITEM$2 + '.' + CLS_ACTIVE$1).appendChild(crElem);
}
}
else {
const tabItems = this.element.querySelector('.' + CLS_TB_ITEMS);
const element = this.element.querySelector('.' + CLS_TB_ITEM + '.' + CLS_ACTIVE$1);
const index = this.getIndexFromEle(element.id);
const header = element.innerText;
const detachContent = this.element.querySelector('.' + CLS_CONTENT$1).querySelector('.' + CLS_ACTIVE$1).children[0];
const mainContents = detachContent.innerHTML;
detach(element);
detach(detachContent);
const attr = {
className: CLS_TB_ITEM + ' ' + CLS_TEMPLATE$1 + ' ' + CLS_ACTIVE$1, id: CLS_ITEM$2 + this.tabId + '_' + index
};
const txtString = this.createElement('span', {
className: CLS_TEXT, innerHTML: header, attrs: { 'role': 'presentation' }
}).outerHTML;
const conte = this.createElement('div', {
className: CLS_TEXT_WRAP, innerHTML: txtString + this.btnCls.outerHTML
}).outerHTML;
const tabIndex = element.firstElementChild.getAttribute('data-tabindex');
const wrap = this.createElement('div', {
className: CLS_WRAP, innerHTML: conte,
attrs: { tabIndex: tabIndex, 'data-tabindex': tabIndex, role: 'tab', 'aria-controls': CLS_CONTENT$1 + this.tabId + '_' + index, 'aria-selected': 'true', 'aria-disabled': 'false' }
});
tabItems.insertBefore(this.createElement('div', attr), tabItems.children[index + 1]);
this.element.querySelector('.' + CLS_TB_ITEM + '.' + CLS_ACTIVE$1).appendChild(wrap);
const crElem = this.createElement('div', { innerHTML: mainContents });
this.element.querySelector('.' + CLS_CONTENT$1).querySelector('.' + CLS_ACTIVE$1).appendChild(crElem);
}
if (this.isReact) {
this.renderReactTemplates();
}
}
/**
* To refresh the active tab indicator.
*
* @returns {void}
*/
refreshActiveTabBorder() {
if (this.heightAdjustMode === 'None' && this.height !== 'auto' && this.cntEle && !this.isVertical()) {
const hdrEle = this.getTabHeader();
setStyleAttribute(this.cntEle, { 'height': (this.element.clientHeight - hdrEle.offsetHeight) + 'px' });
}
const activeEle = select('.' + CLS_TB_ITEM + '.' + CLS_TB_POPUP + '.' + CLS_ACTIVE$1, this.element);
if (!isNullOrUndefined(activeEle) && this.reorderActiveTab) {
this.select(this.getEleIndex(activeEle));
}
this.refreshActiveBorder();
}
};
__decorate$7([
Collection([], TabItem)
], Tab.prototype, "items", void 0);
__decorate$7([
Property('100%')
], Tab.prototype, "width", void 0);
__decorate$7([
Property('Both')
], Tab.prototype, "swipeMode", void 0);
__decorate$7([
Property('auto')
], Tab.prototype, "height", void 0);
__decorate$7([
Property('')
], Tab.prototype, "cssClass", void 0);
__decorate$7([
Property(0)
], Tab.prototype, "selectedItem", void 0);
__decorate$7([
Property('Top')
], Tab.prototype, "headerPlacement", void 0);
__decorate$7([
Property('Content')
], Tab.prototype, "heightAdjustMode", void 0);
__decorate$7([
Property('Scrollable')
], Tab.prototype, "overflowMode", void 0);
__decorate$7([
Property('Demand')
], Tab.prototype, "loadOn", void 0);
__decorate$7([
Property(false)
], Tab.prototype, "enablePersistence", void 0);
__decorate$7([
Property(true)
], Tab.prototype, "enableHtmlSanitizer", void 0);
__decorate$7([
Property(false)
], Tab.prototype, "showCloseButton", void 0);
__decorate$7([
Property(true)
], Tab.prototype, "reorderActiveTab", void 0);
__decorate$7([
Property()
], Tab.prototype, "scrollStep", void 0);
__decorate$7([
Property()
], Tab.prototype, "dragArea", void 0);
__decorate$7([
Property(false)
], Tab.prototype, "allowDragAndDrop", void 0);
__decorate$7([
Property(true)
], Tab.prototype, "clearTemplates", void 0);
__decorate$7([
Complex({}, TabAnimationSettings)
], Tab.prototype, "animation", void 0);
__decorate$7([
Event()
], Tab.prototype, "created", void 0);
__decorate$7([
Event()
], Tab.prototype, "adding", void 0);
__decorate$7([
Event()
], Tab.prototype, "added", void 0);
__decorate$7([
Event()
], Tab.prototype, "selecting", void 0);
__decorate$7([
Event()
], Tab.prototype, "selected", void 0);
__decorate$7([
Event()
], Tab.prototype, "removing", void 0);
__decorate$7([
Event()
], Tab.prototype, "removed", void 0);
__decorate$7([
Event()
], Tab.prototype, "onDragStart", void 0);
__decorate$7([
Event()
], Tab.prototype, "dragging", void 0);
__decorate$7([
Event()
], Tab.prototype, "dragged", void 0);
__decorate$7([
Event()
], Tab.prototype, "destroyed", void 0);
Tab = __decorate$7([
NotifyPropertyChanges
], Tab);
var __decorate$8 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var TreeView_1;
const ROOT = 'e-treeview';
const CONTROL = 'e-control';
const COLLAPSIBLE = 'e-icon-collapsible';
const EXPANDABLE = 'e-icon-expandable';
const LISTITEM = 'e-list-item';
const LISTTEXT = 'e-list-text';
const LISTWRAP = 'e-text-wrap';
const IELISTWRAP = 'e-ie-wrap';
const PARENTITEM = 'e-list-parent';
const HOVER = 'e-hover';
const ACTIVE = 'e-active';
const LOAD = 'e-icons-spinner';
const PROCESS = 'e-process';
const ICON = 'e-icons';
const TEXTWRAP = 'e-text-content';
const INPUT = 'e-input';
const INPUTGROUP = 'e-input-group';
const TREEINPUT = 'e-tree-input';
const EDITING = 'e-editing';
const RTL$1 = 'e-rtl';
const INTERACTION = 'e-interaction';
const DRAGITEM = 'e-drag-item';
const DROPPABLE = 'e-droppable';
const DRAGGING = 'e-dragging';
const SIBLING = 'e-sibling';
const DROPIN = 'e-drop-in';
const DROPNEXT = 'e-drop-next';
const DROPOUT = 'e-drop-out';
const NODROP = 'e-no-drop';
const FULLROWWRAP = 'e-fullrow-wrap';
const FULLROW = 'e-fullrow';
const SELECTED$1 = 'e-selected';
const EXPANDED = 'e-expanded';
const NODECOLLAPSED = 'e-node-collapsed';
const DISABLE = 'e-disable';
const DROPCOUNT = 'e-drop-count';
const CHECK = 'e-check';
const INDETERMINATE = 'e-stop';
const CHECKBOXWRAP = 'e-treeview-checkbox';
const CHECKBOXFRAME = 'e-frame';
const CHECKBOXRIPPLE = 'e-ripple-container';
const RIPPLE = 'e-ripple';
const RIPPLEELMENT = 'e-ripple-element';
const FOCUS = 'e-node-focus';
const IMAGE = 'e-list-img';
const BIGGER = 'e-bigger';
const SMALL = 'e-small';
const CHILD = 'e-has-child';
const ITEM_ANIMATION_ACTIVE = 'e-animation-active';
const DISABLED$1 = 'e-disabled';
const PREVENTSELECT = 'e-prevent';
const treeAriaAttr = {
treeRole: 'group',
itemRole: 'treeitem',
listRole: 'group',
itemText: '',
wrapperRole: ''
};
/**
* Configures the fields to bind to the properties of node in the TreeView component.
*/
class FieldsSettings extends ChildProperty {
}
__decorate$8([
Property('child')
], FieldsSettings.prototype, "child", void 0);
__decorate$8([
Property([])
], FieldsSettings.prototype, "dataSource", void 0);
__decorate$8([
Property('expanded')
], FieldsSettings.prototype, "expanded", void 0);
__decorate$8([
Property('hasChildren')
], FieldsSettings.prototype, "hasChildren", void 0);
__decorate$8([
Property('htmlAttributes')
], FieldsSettings.prototype, "htmlAttributes", void 0);
__decorate$8([
Property('iconCss')
], FieldsSettings.prototype, "iconCss", void 0);
__decorate$8([
Property('id')
], FieldsSettings.prototype, "id", void 0);
__decorate$8([
Property('imageUrl')
], FieldsSettings.prototype, "imageUrl", void 0);
__decorate$8([
Property('isChecked')
], FieldsSettings.prototype, "isChecked", void 0);
__decorate$8([
Property('parentID')
], FieldsSettings.prototype, "parentID", void 0);
__decorate$8([
Property(null)
], FieldsSettings.prototype, "query", void 0);
__decorate$8([
Property('selectable')
], FieldsSettings.prototype, "selectable", void 0);
__decorate$8([
Property('selected')
], FieldsSettings.prototype, "selected", void 0);
__decorate$8([
Property(null)
], FieldsSettings.prototype, "tableName", void 0);
__decorate$8([
Property('text')
], FieldsSettings.prototype, "text", void 0);
__decorate$8([
Property('tooltip')
], FieldsSettings.prototype, "tooltip", void 0);
__decorate$8([
Property('navigateUrl')
], FieldsSettings.prototype, "navigateUrl", void 0);
/**
* Configures animation settings for the TreeView component.
*/
class ActionSettings extends ChildProperty {
}
__decorate$8([
Property('SlideDown')
], ActionSettings.prototype, "effect", void 0);
__decorate$8([
Property(400)
], ActionSettings.prototype, "duration", void 0);
__decorate$8([
Property('linear')
], ActionSettings.prototype, "easing", void 0);
/**
* Configures the animation settings for expanding and collapsing nodes in TreeView.
*/
class NodeAnimationSettings extends ChildProperty {
}
__decorate$8([
Complex({ effect: 'SlideUp', duration: 400, easing: 'linear' }, ActionSettings)
], NodeAnimationSettings.prototype, "collapse", void 0);
__decorate$8([
Complex({ effect: 'SlideDown', duration: 400, easing: 'linear' }, ActionSettings)
], NodeAnimationSettings.prototype, "expand", void 0);
/**
* The TreeView component is used to represent hierarchical data in a tree like structure with advanced
* functions to perform edit, drag and drop, selection with check-box, and more.
* ```html
* <div id="tree"></div>
* ```
* ```typescript
* let treeObj: TreeView = new TreeView();
* treeObj.appendTo('#tree');
* ```
*/
let TreeView = TreeView_1 = class TreeView extends Component {
constructor(options, element) {
super(options, element);
this.isRefreshed = false;
this.preventExpand = false;
this.checkedElement = [];
this.disableNode = [];
this.validArr = [];
this.validNodes = [];
this.expandChildren = [];
this.isFieldChange = false;
this.changeDataSource = false;
this.hasTemplate = false;
this.isFirstRender = false;
this.batchParentNode = new Set();
// Specifies whether the node is dropped or not
this.isNodeDropped = false;
this.isInteracted = false;
this.isRightClick = false;
this.mouseDownStatus = false;
this.isDropIn = false;
this.OldCheckedData = [];
this.isHiddenItem = false;
}
/**
* Get component name.
*
* @returns {string} - returns module name.
* @private
*/
getModuleName() {
return 'treeview';
}
/**
* Initialize the event handler
*
* @returns {void}
*/
preRender() {
this.checkActionNodes = [];
this.parentNodeCheck = [];
this.dragStartAction = false;
this.isAnimate = false;
this.keyConfigs = {
escape: 'escape',
end: 'end',
enter: 'enter',
f2: 'f2',
home: 'home',
moveDown: 'downarrow',
moveLeft: 'leftarrow',
moveRight: 'rightarrow',
moveUp: 'uparrow',
ctrlDown: 'ctrl+downarrow',
ctrlUp: 'ctrl+uparrow',
ctrlEnter: 'ctrl+enter',
ctrlHome: 'ctrl+home',
ctrlEnd: 'ctrl+end',
ctrlA: 'ctrl+A',
shiftDown: 'shift+downarrow',
shiftUp: 'shift+uparrow',
shiftEnter: 'shift+enter',
shiftHome: 'shift+home',
shiftEnd: 'shift+end',
csDown: 'ctrl+shift+downarrow',
csUp: 'ctrl+shift+uparrow',
csEnter: 'ctrl+shift+enter',
csHome: 'ctrl+shift+home',
csEnd: 'ctrl+shift+end',
space: 'space',
shiftSpace: 'shift+space',
ctrlSpace: 'ctrl+space'
};
this.listBaseOption = {
expandCollapse: true,
showIcon: true,
expandIconClass: EXPANDABLE,
ariaAttributes: treeAriaAttr,
expandIconPosition: 'Left',
itemCreated: (e) => {
this.beforeNodeCreate(e);
},
enableHtmlSanitizer: this.enableHtmlSanitizer,
itemNavigable: this.fullRowNavigable
};
this.updateListProp(this.fields);
this.aniObj = new Animation({});
this.treeList = [];
this.isLoaded = false;
this.isInitalExpand = false;
this.expandChildren = [];
this.index = 0;
this.setTouchClass();
this.DDTTreeData = JSON.parse(JSON.stringify(this.fields.dataSource));
if (isNullOrUndefined(this.selectedNodes)) {
this.setProperties({ selectedNodes: [] }, true);
}
if (isNullOrUndefined(this.checkedNodes)) {
this.setProperties({ checkedNodes: [] }, true);
}
if (isNullOrUndefined(this.expandedNodes)) {
this.setProperties({ expandedNodes: [] }, true);
}
else {
this.isInitalExpand = true;
}
}
/**
* Get the properties to be maintained in the persisted state.
*
* @returns {string} - returns the persisted data
* @hidden
*/
getPersistData() {
const keyEntity = ['selectedNodes', 'checkedNodes', 'expandedNodes'];
return this.addOnPersist(keyEntity);
}
/**
* To Initialize the control rendering
*
* @private
* @returns {void}
*/
render() {
this.initialRender = true;
this.initialize();
this.setDataBinding(false);
this.setDisabledMode();
this.setExpandOnType();
if (!this.disabled) {
this.setRipple();
}
this.wireEditingEvents(this.allowEditing);
this.setDragAndDrop(this.allowDragAndDrop);
if (!this.disabled) {
this.wireEvents();
}
this.initialRender = false;
this.renderComplete();
}
initialize() {
this.element.setAttribute('role', 'tree');
if (!isNullOrUndefined(this.fields.dataSource) && Array.isArray(this.fields.dataSource) && this.fields.dataSource.length !== 0) {
this.element.setAttribute('aria-activedescendant', this.element.id + '_active');
}
this.setCssClass(null, this.cssClass);
this.setEnableRtl();
this.setFullRow(this.fullRowSelect);
this.setTextWrap();
this.nodeTemplateFn = this.templateComplier(this.nodeTemplate);
}
setDisabledMode() {
if (this.disabled) {
this.element.classList.add(DISABLED$1);
this.element.setAttribute('aria-disabled', 'true');
}
else {
this.element.classList.remove(DISABLED$1);
this.element.setAttribute('aria-disabled', 'false');
}
}
setEnableRtl() {
(this.enableRtl ? addClass : removeClass)([this.element], RTL$1);
}
setRipple() {
const tempStr = '.' + FULLROW + ',.' + TEXTWRAP;
const rippleModel = {
selector: tempStr,
ignore: '.' + TEXTWRAP + ' > .' + ICON + ',.' + INPUTGROUP + ',.' + INPUT + ', .' + CHECKBOXWRAP
};
this.rippleFn = rippleEffect(this.element, rippleModel);
const iconModel = {
selector: '.' + TEXTWRAP + ' > .' + ICON,
isCenterRipple: true
};
this.rippleIconFn = rippleEffect(this.element, iconModel);
}
setFullRow(isEnabled) {
(isEnabled ? addClass : removeClass)([this.element], FULLROWWRAP);
}
setMultiSelect(isEnabled) {
if (isEnabled) {
this.element.setAttribute('aria-multiselectable', 'true');
}
else {
this.element.setAttribute('aria-multiselectable', 'false');
}
}
templateComplier(template) {
if (template) {
this.hasTemplate = true;
this.element.classList.add(INTERACTION);
try {
if (typeof template !== 'function' && document.querySelectorAll(template).length) {
return compile(document.querySelector(template).innerHTML.trim());
}
else {
return compile(template);
}
}
catch (e) {
return compile(template);
}
}
this.element.classList.remove(INTERACTION);
return undefined;
}
setDataBinding(changeDataSource) {
this.treeList.push('false');
if (this.fields.dataSource instanceof DataManager) {
this.isOffline = this.fields.dataSource.dataSource.offline;
if (this.fields.dataSource.ready) {
this.fields.dataSource.ready.then((e) => {
this.isOffline = this.fields.dataSource.dataSource.offline;
if (this.fields.dataSource instanceof DataManager && this.isOffline) {
this.treeList.pop();
this.treeData = e.result;
this.isNumberTypeId = this.getType();
this.setRootData();
this.renderItems(true);
if (this.treeList.length === 0 && !this.isLoaded) {
this.finalize();
}
}
}).catch((e) => {
this.trigger('actionFailure', { error: e });
});
}
else {
this.fields.dataSource.executeQuery(this.getQuery(this.fields)).then((e) => {
this.treeList.pop();
this.treeData = e.result;
this.isNumberTypeId = this.getType();
this.setRootData();
if (changeDataSource) {
this.changeDataSource = true;
}
this.renderItems(true);
this.changeDataSource = false;
if (this.treeList.length === 0 && !this.isLoaded) {
this.finalize();
}
}).catch((e) => {
this.trigger('actionFailure', { error: e });
});
}
}
else {
this.treeList.pop();
if (isNullOrUndefined(this.fields.dataSource)) {
this.rootData = this.treeData = [];
}
else {
this.treeData = JSON.parse(JSON.stringify(this.fields.dataSource));
this.setRootData();
}
this.isNumberTypeId = this.getType();
this.renderItems(false);
}
if (this.treeList.length === 0 && !this.isLoaded) {
this.finalize();
}
}
getQuery(mapper, value = null) {
const columns = [];
let query;
if (!mapper.query) {
query = new Query();
const prop = this.getActualProperties(mapper);
for (const col of Object.keys(prop)) {
if (col !== 'dataSource' && col !== 'tableName' && col !== 'child' && !!mapper[`${col}`]
&& col !== 'url' && columns.indexOf(mapper[`${col}`]) === -1) {
columns.push(mapper[`${col}`]);
}
}
query.select(columns);
if (Object.prototype.hasOwnProperty.call(prop, 'tableName')) {
query.from(mapper.tableName);
}
}
else {
query = mapper.query.clone();
}
ListBase.addSorting(this.sortOrder, mapper.text, query);
if (!isNullOrUndefined(value) && !isNullOrUndefined(mapper.parentID)) {
query.where(mapper.parentID, 'equal', (this.isNumberTypeId ? parseFloat(value) : value));
}
return query;
}
getType() {
return this.treeData[0] ? ((typeof getValue(this.fields.id, this.treeData[0]) === 'number') ? true : false) : false;
}
setRootData() {
this.dataType = this.getDataType(this.treeData, this.fields);
if (this.dataType === 1) {
this.groupedData = this.getGroupedData(this.treeData, this.fields.parentID);
const rootItems = this.getChildNodes(this.treeData, undefined, true);
if (isNullOrUndefined(rootItems)) {
this.rootData = [];
}
else {
this.rootData = rootItems;
}
}
else {
this.rootData = this.treeData;
}
}
isChildObject() {
if (typeof this.fields.child === 'object') {
return true;
}
else {
return false;
}
}
renderItems(isSorted) {
this.listBaseOption.ariaAttributes.level = 1;
const sortedData = this.getSortedData(this.rootData);
this.ulElement = ListBase.createList(this.createElement, isSorted ? this.rootData : sortedData, this.listBaseOption);
this.element.appendChild(this.ulElement);
const rootNodes = this.ulElement.querySelectorAll('.e-list-item');
if (this.loadOnDemand === false) {
let i = 0;
while (i < rootNodes.length) {
this.renderChildNodes(rootNodes[parseInt(i.toString(), 10)], true, null, true);
i++;
}
}
const parentEle = selectAll('.' + PARENTITEM, this.element);
if ((parentEle.length === 1 && (rootNodes && rootNodes.length !== 0)) || this.loadOnDemand) {
this.finalizeNode(this.element);
}
this.parentNodeCheck = [];
this.parentCheckData = [];
this.updateCheckedStateFromDS();
if (this.autoCheck && this.showCheckBox && !this.isLoaded) {
this.updateParentCheckState();
}
}
/**
* Update the checkedNodes from datasource at initial rendering
*
* @returns {void}
*/
updateCheckedStateFromDS() {
this.validNodes = [];
if (this.treeData && this.showCheckBox) {
if (this.dataType === 1) {
const mapper = this.fields;
const resultData = new DataManager(this.treeData).executeLocal(new Query().where(mapper.isChecked, 'equal', true, false));
for (let i = 0; i < resultData.length; i++) {
const resultId = resultData[parseInt(i.toString(), 10)][this.fields.id]
? resultData[parseInt(i.toString(), 10)][this.fields.id].toString()
: null;
if (this.checkedNodes.indexOf(resultId) === -1 && !(this.isLoaded)) {
this.checkDisabledState(resultId, resultData[i]);
}
if (resultData[parseInt(i.toString(), 10)][this.fields.hasChildren]) {
const id = resultData[parseInt(i.toString(), 10)][this.fields.id];
const childData = new DataManager(this.treeData).
executeLocal(new Query().where(mapper.parentID, 'equal', id, false));
for (let child = 0; child < childData.length; child++) {
const childId = childData[parseInt(child.toString(), 10)][this.fields.id]
? childData[parseInt(child.toString(), 10)][this.fields.id].toString()
: null;
if (this.checkedNodes.indexOf(childId) === -1 && this.autoCheck) {
this.checkDisabledState(childId, childData[child]);
}
}
}
}
for (let i = 0; i < this.checkedNodes.length; i++) {
const mapper = this.fields;
const checkState = new DataManager(this.treeData).
executeLocal(new Query().where(mapper.id, 'equal', this.checkedNodes[parseInt(i.toString(), 10)], true));
if (checkState[0] && this.autoCheck) {
this.getCheckedNodeDetails(mapper, checkState);
this.checkIndeterminateState(checkState[0]);
}
if (checkState.length > 0) {
const checkedId = checkState[0][this.fields.id] ? checkState[0][this.fields.id].toString() : null;
if (this.checkedNodes.indexOf(checkedId) > -1 && this.validNodes.indexOf(checkedId) === -1) {
this.validNodes.push(checkedId);
}
}
const checkedData = new DataManager(this.treeData).
executeLocal(new Query().where(mapper.parentID, 'equal', this.checkedNodes[parseInt(i.toString(), 10)], true));
for (let index = 0; index < checkedData.length; index++) {
const checkedId = checkedData[parseInt(index.toString(), 10)][this.fields.id]
? checkedData[parseInt(index.toString(), 10)][this.fields.id].toString()
: null;
if (this.checkedNodes.indexOf(checkedId) === -1 && this.autoCheck) {
this.checkDisabledState(checkedId, checkedData[index]);
}
if (this.checkedNodes.indexOf(checkedId) > -1 && this.validNodes.indexOf(checkedId) === -1) {
this.validNodes.push(checkedId);
}
}
}
}
else if (this.dataType === 2 || (this.fields.dataSource instanceof DataManager &&
this.isOffline)) {
for (let index = 0; index < this.treeData.length; index++) {
const fieldId = this.treeData[parseInt(index.toString(), 10)][this.fields.id] ? this.treeData[parseInt(index.toString(), 10)][this.fields.id].toString() : '';
if (this.treeData[parseInt(index.toString(), 10)][this.fields.isChecked] &&
!(this.isLoaded) && this.checkedNodes.indexOf(fieldId) === -1) {
this.checkDisabledState(fieldId, this.treeData[index]);
}
if (this.checkedNodes.indexOf(fieldId) > -1 && this.validNodes.indexOf(fieldId) === -1) {
this.validNodes.push(fieldId);
}
const childItems = getValue(this.fields.child.toString(), this.treeData[parseInt(index.toString(), 10)]);
if (childItems) {
this.updateChildCheckState(childItems, this.treeData[parseInt(index.toString(), 10)]);
}
}
this.validNodes = (this.enablePersistence) ? this.checkedNodes : this.validNodes;
}
this.setProperties({ checkedNodes: this.validNodes }, true);
}
}
/**
* To check whether the list data has sub child and to change the parent check state accordingly
*
* @param {FieldsSettingsModel} mapper - The mapper object containing field settings.
* @param {Object[]} checkNodes - The array of checked nodes.
* @returns {void}
* @private
*/
getCheckedNodeDetails(mapper, checkNodes) {
const id = checkNodes[0][this.fields.parentID] ? checkNodes[0][this.fields.parentID].toString() : null;
let count = 0;
const element = this.element.querySelector('[data-uid="' + checkNodes[0][this.fields.id] + '"]');
const parentEle = this.element.querySelector('[data-uid="' + checkNodes[0][this.fields.parentID] + '"]');
if (!element && !parentEle) {
if (this.parentNodeCheck.indexOf(id) === -1) {
this.parentNodeCheck.push(id);
}
const childNodes = this.getChildNodes(this.treeData, id);
for (let i = 0; i < childNodes.length; i++) {
const childId = childNodes[parseInt(i.toString(), 10)][this.fields.id]
? childNodes[parseInt(i.toString(), 10)][this.fields.id].toString()
: null;
if (this.checkedNodes.indexOf(childId) !== -1) {
count++;
}
if (count === childNodes.length && this.checkedNodes.indexOf(id) === -1) {
this.checkDisabledState(id);
}
}
const preElement = new DataManager(this.treeData).
executeLocal(new Query().where(mapper.id, 'equal', id, true));
this.getCheckedNodeDetails(mapper, preElement);
}
else if (parentEle) {
const check = select('.' + CHECK, parentEle);
if (!check) {
this.changeState(parentEle, 'indeterminate', null, true, true);
}
}
}
/**
* Update the checkedNodes and parent state when all the child Nodes are in checkedstate at initial rendering
*
* @returns {void}
* @private
*/
updateParentCheckState() {
const indeterminate = selectAll('.' + INDETERMINATE, this.element);
let childCheckedElement;
let data = this.treeData;
if (this.element.classList.contains('e-filtering')) {
data = this.DDTTreeData;
}
for (let i = 0; i < indeterminate.length; i++) {
const node = closest(indeterminate[parseInt(i.toString(), 10)], '.' + LISTITEM);
const nodeId = node.getAttribute('data-uid').toString();
let OldCheckedNodes;
if (this.element.classList.contains('e-filtering')) {
OldCheckedNodes = new DataManager(this.OldCheckedData).executeLocal(new Query().where('parentID', 'equal', nodeId, true));
}
if (this.dataType === 1) {
childCheckedElement = new DataManager(data).
executeLocal(new Query().where(this.fields.parentID, 'equal', nodeId, true));
}
else {
childCheckedElement = this.getChildNodes(data, nodeId);
}
let count = 0;
if (childCheckedElement) {
for (let j = 0; j < childCheckedElement.length; j++) {
const childId = childCheckedElement[parseInt(j.toString(), 10)][this.fields.id].toString();
if (this.checkedNodes.indexOf(childId) !== -1) {
count++;
}
else if (this.element.classList.contains('e-filtering') && OldCheckedNodes.findIndex((e) => e['id'] === childId) !== -1) {
count++;
}
}
if (count === childCheckedElement.length) {
const nodeCheck = node.getAttribute('data-uid');
if (this.checkedNodes.indexOf(nodeCheck) === -1) {
this.checkDisabledState(nodeCheck);
}
this.changeState(node, 'check', null, true, true);
}
else if (count === 0 && this.checkedNodes.length === 0 && indeterminate.length === 0) {
this.changeState(node, 'uncheck', null, true, true);
}
}
}
}
/**
* Change the parent to indeterminate state whenever the child is in checked state which is not rendered in DOM
*
* @param {Object} data - The data object to check for indeterminate state.
* @returns {void}
* @private
*/
checkIndeterminateState(data) {
let element;
if (this.dataType === 1) {
element = this.element.querySelector('[data-uid="' + data[this.fields.parentID] + '"]');
}
else {
element = this.element.querySelector('[data-uid="' + data[this.fields.id] + '"]');
}
if (element) {
const ariaChecked = element.getAttribute('aria-checked');
if (ariaChecked !== 'true') {
this.changeState(element, 'indeterminate', null, true, true);
}
}
else if (this.dataType === 2) {
if (this.parentNodeCheck.indexOf(data[this.fields.id].toString()) === -1) {
this.parentNodeCheck.push(data[this.fields.id].toString());
}
}
}
/**
* Update the checkedNodes for child and subchild from datasource (hierarchical datasource) at initial rendering
*
* @param {Object[]} childItems - The array of child items to update the checked state.
* @param {Object} treeData - The tree data object containing field values.
* @returns {void}
* @private
*/
updateChildCheckState(childItems, treeData) {
let count = 0;
const checkedParent = treeData[this.fields.id] ? treeData[this.fields.id].toString() : '';
for (let index = 0; index < childItems.length; index++) {
const checkedChild = childItems[parseInt(index.toString(), 10)][this.fields.id] ? childItems[parseInt(index.toString(), 10)][this.fields.id].toString() : '';
if (childItems[parseInt(index.toString(), 10)][this.fields.isChecked] &&
!(this.isLoaded) && this.checkedNodes.indexOf(checkedChild) === -1) {
this.checkDisabledState(checkedChild, childItems[index]);
}
if (this.checkedNodes.indexOf(checkedParent) !== -1 && this.checkedNodes.indexOf(checkedChild) === -1 && this.autoCheck) {
this.checkDisabledState(checkedChild, childItems[index]);
}
if (this.checkedNodes.indexOf(checkedChild) !== -1 && this.autoCheck) {
count++;
}
if (this.checkedNodes.indexOf(checkedChild) > -1 && this.validNodes.indexOf(checkedChild) === -1) {
this.validNodes.push(checkedChild);
}
const subChildItems = getValue(this.fields.child.toString(), childItems[parseInt(index.toString(), 10)]);
if (subChildItems && subChildItems.length) {
if (this.parentCheckData.indexOf(treeData) === -1) {
this.parentCheckData.push(treeData);
}
this.updateChildCheckState(subChildItems, childItems[parseInt(index.toString(), 10)]);
}
if (count === childItems.length && this.autoCheck && this.checkedNodes.indexOf(checkedParent) === -1) {
this.checkDisabledState(checkedParent, treeData);
}
}
if (count !== 0 && this.autoCheck) {
this.checkIndeterminateState(treeData);
for (let len = 0; len < this.parentCheckData.length; len++) {
if ((treeData !== this.parentCheckData[parseInt(len.toString(), 10)]) &&
(this.parentCheckData[parseInt(len.toString(), 10)])) {
this.checkIndeterminateState(this.parentCheckData[parseInt(len.toString(), 10)]);
}
}
}
this.parentCheckData = [];
}
beforeNodeCreate(e) {
if (this.showCheckBox) {
const checkboxEle = createCheckBox(this.createElement, true, { cssClass: this.touchClass });
checkboxEle.classList.add(CHECKBOXWRAP);
const icon = select('div.' + EXPANDABLE + ', div.' + COLLAPSIBLE, e.item);
const id = e.item.getAttribute('data-uid');
e.item.childNodes[0].insertBefore(checkboxEle, e.item.childNodes[0].childNodes[isNullOrUndefined(icon) ? 0 : 1]);
const checkValue = getValue(e.fields.isChecked, e.curData);
if (this.checkedNodes.indexOf(id) > -1) {
select('.' + CHECKBOXFRAME, checkboxEle).classList.add(CHECK);
e.item.setAttribute('aria-checked', 'true');
this.addCheck(e.item);
}
else if (!isNullOrUndefined(checkValue) && checkValue.toString() === 'true') {
select('.' + CHECKBOXFRAME, checkboxEle).classList.add(CHECK);
e.item.setAttribute('aria-checked', 'true');
this.addCheck(e.item);
}
else {
e.item.setAttribute('aria-checked', 'false');
}
const frame = select('.' + CHECKBOXFRAME, checkboxEle);
EventHandler.add(frame, 'mousedown', this.frameMouseHandler, this);
EventHandler.add(frame, 'mouseup', this.frameMouseHandler, this);
EventHandler.add(frame, 'mouseleave', this.frameMouseHandler, this);
}
if (this.fullRowSelect) {
this.createFullRow(e.item);
}
if (this.allowMultiSelection && !e.item.classList.contains(SELECTED$1)) {
e.item.setAttribute('aria-selected', 'false');
}
const fields = e.fields;
this.addActionClass(e, fields.selected, SELECTED$1);
this.addActionClass(e, fields.expanded, EXPANDED);
e.item.setAttribute('tabindex', '-1');
EventHandler.add(e.item, 'focus', this.focusIn, this);
if (!isNullOrUndefined(this.nodeTemplateFn)) {
const textEle = e.item.querySelector('.' + LISTTEXT);
const dataId = e.item.getAttribute('data-uid');
textEle.innerHTML = '';
this.renderNodeTemplate(e.curData, textEle, dataId);
}
const eventArgs = {
node: e.item,
nodeData: e.curData,
text: e.text
};
if (!this.isRefreshed) {
this.trigger('drawNode', eventArgs);
if (e.curData[this.fields.selectable] === false && !this.showCheckBox) {
e.item.classList.add(PREVENTSELECT);
const firstChild = e.item.firstElementChild;
firstChild.style.cursor = 'not-allowed';
}
}
}
frameMouseHandler(e) {
const rippleSpan = select('.' + CHECKBOXRIPPLE, e.target.parentElement);
rippleMouseHandler(e, rippleSpan);
}
addActionClass(e, action, cssClass) {
const data = e.curData;
const actionValue = getValue(action, data);
if (!isNullOrUndefined(actionValue) && actionValue.toString() !== 'false') {
e.item.classList.add(cssClass);
}
}
getDataType(ds, mapper) {
if (this.fields.dataSource instanceof DataManager) {
for (let i = 0; i < ds.length; i++) {
if (this.isOffline) {
if ((typeof mapper.child === 'string') && isNullOrUndefined(getValue(mapper.child, ds[parseInt(i.toString(), 10)])) && !isNullOrUndefined(getValue(mapper.parentID, ds[parseInt(i.toString(), 10)]))) {
return 1;
}
}
else if ((typeof mapper.child === 'string') && isNullOrUndefined(getValue(mapper.child, ds[parseInt(i.toString(), 10)]))) {
return 1;
}
}
return 2;
}
for (let i = 0, len = ds.length; i < len; i++) {
if ((typeof mapper.child === 'string') && (!isNullOrUndefined(getValue(mapper.child, ds[parseInt(i.toString(), 10)])) || (Object.prototype.hasOwnProperty.call(ds[parseInt(i.toString(), 10)], mapper.child)))) {
return 2;
}
if (this.isChildObject()) {
return 2;
}
if (!isNullOrUndefined(getValue(mapper.parentID, ds[parseInt(i.toString(), 10)])) ||
!isNullOrUndefined(getValue(mapper.hasChildren, ds[parseInt(i.toString(), 10)]))) {
return 1;
}
}
return 1;
}
getGroupedData(dataSource, groupBy) {
const cusQuery = new Query().group(groupBy);
const ds = ListBase.getDataSource(dataSource, cusQuery);
const grpItem = [];
for (let j = 0; j < ds.length; j++) {
const itemObj = ds[parseInt(j.toString(), 10)].items;
grpItem.push(itemObj);
}
return grpItem;
}
getSortedData(list) {
if (list && this.sortOrder !== 'None') {
list = ListBase.getDataSource(list, ListBase.addSorting(this.sortOrder, this.fields.text));
}
return list;
}
finalizeNode(element, isFromExpandAll, expandChild) {
if (!isFromExpandAll) {
this.updateAttributes(element);
}
if (!expandChild) {
const eNodes = selectAll('.' + EXPANDED, element);
if (!this.loadOnDemand && this.fields.dataSource instanceof DataManager) {
this.isInitalExpand = this.treeData.filter((e) => e[this.fields.expanded] === true).length > 0
? true
: this.isInitalExpand;
}
if (!this.isInitalExpand) {
for (let i = 0; i < eNodes.length; i++) {
this.renderChildNodes(eNodes[parseInt(i.toString(), 10)]);
}
}
removeClass(eNodes, EXPANDED);
}
if (!isFromExpandAll) {
this.updateList();
}
if (this.isLoaded) {
this.updateCheckedProp();
}
}
updateAttributes(element) {
const iNodes = selectAll('.' + IMAGE, element);
for (let k = 0; k < iNodes.length; k++) {
iNodes[parseInt(k.toString(), 10)].setAttribute('alt', IMAGE);
}
if (this.isLoaded) {
const sNodes = selectAll('.' + SELECTED$1, element);
for (let i = 0; i < sNodes.length; i++) {
this.selectNode(sNodes[parseInt(i.toString(), 10)], null);
break;
}
removeClass(sNodes, SELECTED$1);
}
const cNodes = selectAll('.' + LISTITEM + ':not(.' + EXPANDED + ')', element);
for (let j = 0; j < cNodes.length; j++) {
const icon = select('div.' + ICON, cNodes[parseInt(j.toString(), 10)]);
if (icon && icon.classList.contains(EXPANDABLE)) {
this.disableExpandAttr(cNodes[parseInt(j.toString(), 10)]);
}
}
}
updateCheckedProp() {
if (this.showCheckBox) {
const nodes = [].concat([], this.checkedNodes);
this.setProperties({ checkedNodes: nodes }, true);
}
}
ensureIndeterminate() {
if (this.autoCheck) {
const liElement = selectAll('li', this.element);
let ulElement;
for (let i = 0; i < liElement.length; i++) {
if (liElement[parseInt(i.toString(), 10)].classList.contains(LISTITEM)) {
ulElement = select('.' + PARENTITEM, liElement[parseInt(i.toString(), 10)]);
if (ulElement) {
this.ensureParentCheckState(liElement[parseInt(i.toString(), 10)]);
}
else {
this.ensureChildCheckState(liElement[parseInt(i.toString(), 10)]);
}
}
}
}
else {
const indeterminate = selectAll('.' + INDETERMINATE, this.element);
for (let i = 0; i < indeterminate.length; i++) {
indeterminate[parseInt(i.toString(), 10)].classList.remove(INDETERMINATE);
}
}
}
ensureParentCheckState(element) {
if (!isNullOrUndefined(element)) {
if (element.classList.contains(ROOT)) {
return;
}
let ulElement = element;
if (element.classList.contains(LISTITEM)) {
ulElement = select('.' + PARENTITEM, element);
}
const checkedNodes = selectAll('.' + CHECKBOXWRAP + ' .' + CHECK, ulElement);
const indeterminateNodes = selectAll('.' + INDETERMINATE, ulElement);
const nodes = selectAll(this.checkDisabledChildren ? '.' + LISTITEM : '.' + LISTITEM + ':not(.' + DISABLE + ')', ulElement);
const checkBoxEle = element.getElementsByClassName(CHECKBOXWRAP)[0];
let count = nodes.length;
let checkedCount = checkedNodes.length;
let matchedChildNodes = [];
let oldChildCount = [];
const dataUid = element.getAttribute('data-uid');
let rootNodeChecked = true;
let childNodeChecked = false;
const ChildNodeData = this.getAllChildNodes(this.DDTTreeData, dataUid);
let selectedChildren = 0;
nodes.forEach((childNode) => {
if (childNode instanceof HTMLElement) {
const ariaChecked = childNode.getAttribute('aria-checked');
if (ariaChecked === 'true') {
childNodeChecked = true;
}
else {
rootNodeChecked = false;
}
}
});
let parentNodeChecked = false;
if (this.element.classList.contains('e-filtering')) {
const oldCheckedNodes = new DataManager(this.OldCheckedData).executeLocal(new Query().where('parentID', 'equal', dataUid, true));
checkedCount = oldCheckedNodes.length;
const parentNode = new DataManager(this.OldCheckedData).executeLocal(new Query().where('hasChildren', 'equal', true, true));
if (parentNode.length > 0 && childNodeChecked && ((this.OldCheckedData.some((oldNode) => oldNode.id === dataUid)) ||
this.parentNodeCheck.indexOf(dataUid) !== -1)) {
checkedCount = parentNode.length;
parentNodeChecked = true;
}
let childItems = [];
if (this.dataType === 1) {
childItems = new DataManager(this.DDTTreeData).executeLocal(new Query().where(this.fields.parentID, 'equal', dataUid, true));
}
else {
childItems = this.getChildNodes(this.DDTTreeData, dataUid);
}
count = childItems.length;
ChildNodeData.forEach((child) => {
const childKey = String(child[this.fields.id]);
if (this.checkedNodes.indexOf(childKey) !== -1 ||
this.OldCheckedData.some((oldNode) => oldNode['parentID'] === childKey)) {
selectedChildren++;
}
});
}
if (this.autoCheck && this.showCheckBox && !(this.fields.dataSource instanceof DataManager)) {
const selectedChildNodeDetails = this.getSelectedChildNodeDetails(dataUid);
matchedChildNodes = selectedChildNodeDetails;
oldChildCount = new DataManager(this.checkActionNodes)
.executeLocal(new Query().where('parentID', 'equal', dataUid, true));
}
if (count === 0 && checkedCount === 0) {
return;
}
else if (count === checkedCount || ((parentNodeChecked && count > 0) && ((oldChildCount.length === matchedChildNodes.length)
|| (oldChildCount.length !== matchedChildNodes.length))
&& (oldChildCount.length !== 0 && matchedChildNodes.length !== 0) && rootNodeChecked
&& (this.autoCheck && this.showCheckBox))) {
this.changeState(checkBoxEle, 'check', null, true, true);
}
else if ((checkedCount > 0 && !parentNodeChecked && (this.autoCheck && this.showCheckBox))) {
this.changeState(checkBoxEle, 'indeterminate', null, true, true);
}
else if (checkedCount > 0 || indeterminateNodes.length > 0 || selectedChildren > 0) {
this.changeState(checkBoxEle, 'indeterminate', null, true, true);
}
else if (checkedCount === 0) {
this.changeState(checkBoxEle, 'uncheck', null, true, true);
}
const parentUL = closest(element, '.' + PARENTITEM);
if (!isNullOrUndefined(parentUL)) {
const currentParent = closest(parentUL, '.' + LISTITEM);
this.ensureParentCheckState(currentParent);
}
}
}
getSelectedChildNodeDetails(dataUid) {
const childKey = typeof this.fields.child === 'string' ? this.fields.child : null;
const dataId = this.fields.id;
const parentKey = this.fields.parentID;
if (!this.nodeIndex) {
this.nodeIndex = new Map();
this.buildNodeIndex(this.treeData);
}
const matchesDataUid = (childNode) => {
if (!isNullOrUndefined(childKey) && childKey in childNode && Array.isArray(childNode[childKey])) {
const matchNode = childNode[dataId];
return !isNullOrUndefined(matchNode) &&
matchNode.toString() === dataUid;
}
else {
const childNodePid = childNode[parentKey];
return !isNullOrUndefined(childNodePid) && childNodePid.toString() === dataUid;
}
};
return this.checkedNodes
.map((id) => this.nodeIndex.get(id))
.filter((childNode) => {
if (childNode && typeof childNode === 'object' && (childKey in childNode)) {
return matchesDataUid(childNode);
}
else if (this.dataType !== 2 && typeof childNode === 'object' && (parentKey in childNode || childKey in childNode)) {
return matchesDataUid(childNode);
}
return false;
});
}
buildNodeIndex(nodes) {
const childKey = typeof this.fields.child === 'string' ? this.fields.child : null;
nodes.forEach((node) => {
const idVal = getValue(this.fields.id, node);
if (idVal != null) {
if (!this.nodeIndex) {
this.nodeIndex = new Map();
}
this.nodeIndex.set(idVal.toString(), node);
}
if (childKey) {
const children = getValue(childKey, node);
if (Array.isArray(children)) {
this.buildNodeIndex(children);
}
}
});
}
getAllChildNodes(data, parentId) {
if (isNullOrUndefined(data) || isNullOrUndefined(parentId)) {
return [];
}
if (this.dataType === 1) {
const pidField = this.fields.parentID;
const target = parentId.toString();
return data.filter((item) => {
const pidVal = getValue(pidField, item);
return !isNullOrUndefined(pidVal) && pidVal.toString() === target;
});
}
if (this.dataType === 2) {
const parentFieldId = this.fields.id;
const childField = this.fields.child.toString();
const target = parentId.toString();
const node = data.find((n) => {
const idVal = getValue(parentFieldId, n);
return !isNullOrUndefined(idVal) && idVal.toString() === target;
});
if (!node) {
return [];
}
const children = getValue(childField, node);
return Array.isArray(children) ? children : [];
}
return [];
}
ensureChildCheckState(element, e, isFromExpandAll) {
if (!isNullOrUndefined(element)) {
const childElement = select('.' + PARENTITEM, element);
let checkBoxes;
if (!isNullOrUndefined(childElement)) {
let childCheck = Array.from(childElement.querySelectorAll('li'));
checkBoxes = selectAll('.' + CHECKBOXWRAP, childElement);
if (this.isFilter) {
checkBoxes = Array.from(checkBoxes).filter((checkbox) => {
const dataUID = checkbox.closest('li').getAttribute('data-uid');
return dataUID !== null && this.checkedNodes.indexOf(dataUID) !== -1;
});
childCheck = Array.from(childCheck).filter((li) => {
const childIds = li.getAttribute('data-uid');
return childIds !== null && this.checkedNodes.indexOf(childIds) !== -1;
});
if (checkBoxes.length === 0) {
checkBoxes = selectAll('.' + CHECKBOXWRAP, childElement);
childCheck = Array.from(childElement.querySelectorAll('li'));
}
}
const isChecked = element.getElementsByClassName(CHECKBOXFRAME)[0].classList.contains(CHECK);
const parentCheck = element.getElementsByClassName(CHECKBOXFRAME)[0].classList.contains(INDETERMINATE);
let checkedState;
for (let index = 0; index < checkBoxes.length; index++) {
const childId = childCheck[parseInt(index.toString(), 10)].getAttribute('data-uid');
if (!isNullOrUndefined(this.currentLoadData) &&
!isNullOrUndefined(getValue(this.fields.isChecked, this.currentLoadData[parseInt(index.toString(), 10)]))) {
checkedState = getValue(this.fields.isChecked, this.currentLoadData[parseInt(index.toString(), 10)]) ? 'check' : 'uncheck';
if (this.ele !== -1) {
checkedState = isChecked ? 'check' : 'uncheck';
}
if ((checkedState === 'uncheck') && (!isUndefined(this.parentNodeCheck) && this.autoCheck
&& this.parentNodeCheck.indexOf(childId) !== -1)) {
this.parentNodeCheck.splice(this.parentNodeCheck.indexOf(childId), 1);
checkedState = 'indeterminate';
}
}
else {
const isNodeChecked = checkBoxes[parseInt(index.toString(), 10)]
.getElementsByClassName(CHECKBOXFRAME)[0]
.classList.contains(CHECK);
if (isChecked) {
checkedState = 'check';
}
else if (isNodeChecked && !this.isLoaded) {
checkedState = 'check';
}
else if (this.checkedNodes.indexOf(childId) !== -1 && this.isLoaded && (parentCheck || isChecked)) {
checkedState = 'check';
}
else if (childCheck[parseInt(index.toString(), 10)].classList.contains(CHILD) &&
(!isUndefined(this.parentNodeCheck) && this.autoCheck
&& (isChecked || parentCheck) && this.parentNodeCheck.indexOf(childId) !== -1)) {
checkedState = 'indeterminate';
this.parentNodeCheck.splice(this.parentNodeCheck.indexOf(childId), 1);
}
else if (this.dataType === 1 && (!isUndefined(this.parentNodeCheck) && this.autoCheck &&
(isChecked || parentCheck) && this.parentNodeCheck.indexOf(childId) !== -1)) {
checkedState = 'indeterminate';
this.parentNodeCheck.splice(this.parentNodeCheck.indexOf(childId), 1);
}
else {
checkedState = 'uncheck';
}
}
this.changeState(checkBoxes[parseInt(index.toString(), 10)], checkedState, e, true, true);
}
}
if (this.autoCheck && this.isLoaded && !isFromExpandAll) {
this.updateParentCheckState();
}
}
}
doCheckBoxAction(nodes, doCheck) {
if (!isNullOrUndefined(nodes)) {
if (nodes.length > 1 && this.autoCheck) {
this.isBatchMode = true;
this.batchParentNode = new Set();
}
nodes.reverse();
for (let len = nodes.length - 1; len >= 0; len--) {
const liEle = this.getElement(nodes[parseInt(len.toString(), 10)]);
if (isNullOrUndefined(liEle)) {
const node = nodes[len - nodes.length] ? nodes[len - nodes.length].toString()
: nodes[parseInt(len.toString(), 10)]
? nodes[parseInt(len.toString(), 10)].toString()
: null;
if (node !== '' && doCheck && node) {
this.setValidCheckedNode(node, nodes);
this.dynamicCheckState(node, doCheck);
}
else if (this.checkedNodes.indexOf(node) !== -1 && node !== '' && !doCheck) {
this.checkedNodes.splice(this.checkedNodes.indexOf(node), 1);
const childItems = this.getChildNodes(this.treeData, node);
if (childItems) {
for (let i = 0; i < childItems.length; i++) {
const id = childItems[parseInt(i.toString(), 10)][this.fields.id]
? childItems[parseInt(i.toString(), 10)][this.fields.id].toString()
: null;
if (this.checkedNodes.indexOf(id) !== -1) {
this.checkedNodes.splice(this.checkedNodes.indexOf(id), 1);
const ele = this.element.querySelector('[data-uid="' + id + '"]');
if (ele) {
this.changeState(ele, 'uncheck', null);
}
}
}
if (this.parentNodeCheck.indexOf(node) !== -1) {
this.parentNodeCheck.splice(this.parentNodeCheck.indexOf(node), 1);
}
}
if (node) {
this.dynamicCheckState(node, doCheck);
}
this.updateField(this.treeData, this.fields, node, 'isChecked', null);
}
continue;
}
const checkBox = select('.' + PARENTITEM + ' .' + CHECKBOXWRAP, liEle);
this.validateCheckNode(checkBox, !doCheck, liEle, null);
}
if (this.isBatchMode && this.autoCheck) {
this.isBatchMode = false;
Array.from(this.batchParentNode).forEach((parentId) => {
const parentLi = this.getElement(parentId);
if (parentLi) {
this.ensureParentCheckState(parentLi);
}
});
this.batchParentNode.clear();
}
}
else {
const checkBoxes = selectAll('.' + CHECKBOXWRAP, this.element);
if (this.loadOnDemand) {
for (let index = 0; index < checkBoxes.length; index++) {
const liEle = closest(checkBoxes[parseInt(index.toString(), 10)], '.' + LISTITEM);
this.updateFieldChecked(checkBoxes[parseInt(index.toString(), 10)], doCheck);
this.changeState(checkBoxes[parseInt(index.toString(), 10)], doCheck ? 'check' : 'uncheck', null, null, null, doCheck);
this.updateOldCheckedData([this.getNodeData(liEle)]);
}
}
else {
for (let index = 0; index < checkBoxes.length; index++) {
const liEle = closest(checkBoxes[parseInt(index.toString(), 10)], '.' + LISTITEM);
this.updateFieldChecked(checkBoxes[parseInt(index.toString(), 10)], doCheck);
this.changeState(checkBoxes[parseInt(index.toString(), 10)], doCheck ? 'check' : 'uncheck');
this.updateOldCheckedData([this.getNodeData(liEle)]);
}
}
}
if (nodes) {
for (let j = 0; j < nodes.length - 1; j++) {
const node = nodes[parseInt(j.toString(), 10)] ? nodes[parseInt(j.toString(), 10)].toString() : '';
if (!doCheck) {
this.updateField(this.treeData, this.fields, node, 'isChecked', null);
}
}
}
if (this.autoCheck) {
this.updateParentCheckState();
}
}
updateFieldChecked(checkbox, doCheck) {
const currLi = closest(checkbox, '.' + LISTITEM);
const id = currLi.getAttribute('data-uid');
const nodeDetails = this.getNodeData(currLi);
if (nodeDetails.isChecked === 'true' && !doCheck) {
this.updateField(this.treeData, this.fields, id, 'isChecked', null);
}
}
/**
* Changes the parent and child check state while changing the checkedNodes via setmodel
*
* @param {string} node - The unique identifier of the node.
* @param {boolean} doCheck - A boolean value indicating whether to check or uncheck the node.
* @returns {void}
* @private
*/
dynamicCheckState(node, doCheck) {
if (this.dataType === 1) {
let count = 0;
const resultId = new DataManager(this.treeData).executeLocal(new Query().where(this.fields.id, 'equal', node, true));
if (resultId[0]) {
const id = resultId[0][this.fields.id] ? resultId[0][this.fields.id].toString() : null;
const parent = resultId[0][this.fields.parentID] ? resultId[0][this.fields.parentID].toString() : null;
const parentElement = this.element.querySelector('[data-uid="' + parent + '"]');
const element = this.element.querySelector('[data-uid="' + id + '"]');
const childNodes = this.getChildNodes(this.treeData, parent);
if (childNodes) {
for (let i = 0; i < childNodes.length; i++) {
const childId = childNodes[parseInt(i.toString(), 10)][this.fields.id]
? childNodes[parseInt(i.toString(), 10)][this.fields.id].toString()
: null;
if (this.checkedNodes.indexOf(childId) !== -1) {
count++;
}
}
}
if (this.checkedNodes.indexOf(node) !== -1 && parentElement && (id === node) && this.autoCheck) {
this.changeState(parentElement, 'indeterminate', null);
}
else if (this.checkedNodes.indexOf(node) === -1 && element && (id === node) && !doCheck) {
this.changeState(element, 'uncheck', null);
}
else if (this.checkedNodes.indexOf(node) !== -1 && element && (id === node) && doCheck) {
this.changeState(element, 'check', null);
}
else if (this.checkedNodes.indexOf(node) === -1 && !element && parentElement && (id === node) && this.autoCheck
&& count !== 0) {
this.changeState(parentElement, 'indeterminate', null);
}
else if (this.checkedNodes.indexOf(node) === -1 && !element && parentElement && (id === node) && this.autoCheck
&& count === 0) {
this.changeState(parentElement, 'uncheck', null);
}
else if (!element && !parentElement && (id === node) && this.autoCheck) {
this.updateIndeterminate(node, doCheck);
}
}
}
else if (this.dataType === 2 || (this.fields.dataSource instanceof DataManager &&
this.isOffline)) {
let id;
let parentElement;
let check;
for (let i = 0; i < this.treeData.length; i++) {
id = this.treeData[parseInt(i.toString(), 10)][this.fields.id] ? this.treeData[parseInt(i.toString(), 10)][this.fields.id].toString() : '';
parentElement = this.element.querySelector('[data-uid="' + id + '"]');
check = parentElement ? select('.' + CHECK, parentElement) : null;
if (this.checkedNodes.indexOf(id) === -1 && parentElement && check && !doCheck) {
this.changeState(parentElement, 'uncheck', null);
}
const subChild = getValue(this.fields.child.toString(), this.treeData[parseInt(i.toString(), 10)]);
if (subChild) {
this.updateChildIndeterminate(subChild, id, node, doCheck, id);
}
}
}
}
/**
* updates the parent and child check state while changing the checkedNodes via setmodel for listData
*
* @param {string} node - The unique identifier of the node.
* @param {boolean} doCheck - A boolean value indicating whether to check or uncheck the node.
* @returns {void}
* @private
*/
updateIndeterminate(node, doCheck) {
const indeterminateData = this.getTreeData(node);
let count = 0;
let parent;
if (this.dataType === 1) {
parent = indeterminateData[0][this.fields.parentID] ? indeterminateData[0][this.fields.parentID].toString() : null;
}
const childNodes = this.getChildNodes(this.treeData, parent);
if (childNodes) {
for (let i = 0; i < childNodes.length; i++) {
const childId = childNodes[parseInt(i.toString(), 10)][this.fields.id]
? childNodes[parseInt(i.toString(), 10)][this.fields.id].toString()
: null;
if (this.checkedNodes.indexOf(childId) !== -1) {
count++;
}
}
}
const parentElement = this.element.querySelector('[data-uid="' + parent + '"]');
if (parentElement && doCheck) {
this.changeState(parentElement, 'indeterminate', null);
}
else if (!doCheck && parentElement && this.parentNodeCheck.indexOf(parent) === -1 && count !== 0) {
this.changeState(parentElement, 'indeterminate', null);
}
else if (!doCheck && parentElement && this.parentNodeCheck.indexOf(parent) === -1 && count === 0) {
this.changeState(parentElement, 'uncheck', null);
}
else if (!parentElement) {
if (!doCheck && this.checkedNodes.indexOf(parent) === -1 && this.parentNodeCheck.indexOf(parent) !== -1) {
this.parentNodeCheck.splice(this.parentNodeCheck.indexOf(parent), 1);
}
else if (doCheck && this.checkedNodes.indexOf(parent) === -1 && this.parentNodeCheck.indexOf(parent) === -1) {
this.parentNodeCheck.push(parent);
}
else if (!doCheck && this.checkedNodes.indexOf(parent) !== -1 && this.parentNodeCheck.indexOf(parent) === -1
&& count !== 0) {
this.parentNodeCheck.push(parent);
}
this.updateIndeterminate(parent, doCheck);
if (this.checkedNodes.indexOf(parent) !== -1 && !doCheck) {
this.checkedNodes.splice(this.checkedNodes.indexOf(parent), 1);
}
}
}
/**
* updates the parent and child check state while changing the checkedNodes via setmodel for hierarchical data
*
* @param {Object[]} subChild - Array of child nodes
* @param {string} parent - Parent identifier
* @param {string} node - Current node identifier
* @param {boolean} doCheck - Boolean indicating whether to perform a check
* @param {string} [child] - Optional child identifier
* @returns {void}
* @private
*/
updateChildIndeterminate(subChild, parent, node, doCheck, child) {
let count = 0;
for (let j = 0; j < subChild.length; j++) {
const subId = subChild[parseInt(j.toString(), 10)][this.fields.id] ? subChild[parseInt(j.toString(), 10)][this.fields.id].toString() : '';
if (this.checkedNodes.indexOf(subId) !== -1) {
count++;
}
const parentElement = this.element.querySelector('[data-uid="' + parent + '"]');
const indeterminate = parentElement ? select('.' + INDETERMINATE, parentElement) : null;
const check = parentElement ? select('.' + CHECK, parentElement) : null;
const element = this.element.querySelector('[data-uid="' + subId + '"]');
const childElementCheck = element ? select('.' + CHECK, element) : null;
if (this.checkedNodes.indexOf(node) !== -1 && parentElement && (subId === node) && this.autoCheck) {
this.changeState(parentElement, 'indeterminate', null);
}
else if (this.checkedNodes.indexOf(node) === -1 && parentElement && !element && (subId === node) && !doCheck) {
if (this.autoCheck) {
this.changeState(parentElement, 'uncheck', null);
}
else {
if (count !== 0) {
this.changeState(parentElement, 'indeterminate', null);
}
else {
this.changeState(parentElement, 'uncheck', null);
}
}
}
else if (this.checkedNodes.indexOf(node) === -1 && element && (subId === node) && !doCheck) {
this.changeState(element, 'uncheck', null);
}
else if (this.checkedNodes.indexOf(node) === -1 && indeterminate && (subId === node) && this.autoCheck && count === 0
&& !doCheck) {
indeterminate.classList.remove(INDETERMINATE);
}
else if (this.checkedNodes.indexOf(node) === -1 && !element && check && (subId === node) && count === 0) {
this.changeState(parentElement, 'uncheck', null);
}
else if (this.checkedNodes.indexOf(subId) === -1 && element && childElementCheck && count === 0) {
this.changeState(element, 'uncheck', null);
}
else if (!element && !parentElement && (subId === node) || (this.parentNodeCheck.indexOf(parent) !== -1) && this.autoCheck) {
const childElement = this.element.querySelector('[data-uid="' + child + '"]');
if (doCheck && count !== 0) {
this.changeState(childElement, 'indeterminate', null);
}
else if (doCheck && count === subChild.length && this.checkedNodes.indexOf(parent) === -1) {
this.checkDisabledState(parent);
}
else if (!doCheck && count === 0 && this.parentNodeCheck.indexOf(parent) !== -1) {
this.parentNodeCheck.splice(this.parentNodeCheck.indexOf(parent));
}
if (this.parentNodeCheck.indexOf(parent) === -1) {
this.parentNodeCheck.push(parent);
}
}
const innerChild = getValue(this.fields.child.toString(), subChild[parseInt(j.toString(), 10)]);
if (innerChild) {
this.updateChildIndeterminate(innerChild, subId, node, doCheck, child);
}
}
}
changeState(wrapper, state, e, isPrevent, isAdd, doCheck) {
let eventArgs;
const currLi = closest(wrapper, '.' + LISTITEM);
if (!this.checkDisabledChildren && currLi && (currLi.classList.contains(DISABLE)
|| (this.disableNode && this.disableNode.indexOf(currLi.getAttribute('data-uid')) !== -1))) {
return;
}
if (wrapper === currLi) {
wrapper = select('.' + CHECKBOXWRAP, currLi);
}
if (!isPrevent) {
this.checkActionNodes = [];
eventArgs = this.getCheckEvent(currLi, state, e);
this.trigger('nodeChecking', eventArgs, (observedArgs) => {
if (!observedArgs.cancel) {
this.nodeCheckAction(wrapper, state, currLi, observedArgs, e, isPrevent, isAdd, doCheck);
}
});
}
else {
this.nodeCheckAction(wrapper, state, currLi, eventArgs, e, isPrevent, isAdd, doCheck);
}
}
nodeCheckAction(wrapper, state, currLi, eventArgs, e, isPrevent, isAdd, doCheck) {
let ariaState;
const frameSpan = wrapper.getElementsByClassName(CHECKBOXFRAME)[0];
if (state === 'check' && !frameSpan.classList.contains(CHECK)) {
frameSpan.classList.remove(INDETERMINATE);
frameSpan.classList.add(CHECK);
this.addCheck(currLi);
ariaState = 'true';
}
else if (state === 'uncheck' && (frameSpan.classList.contains(CHECK) || frameSpan.classList.contains(INDETERMINATE))) {
removeClass([frameSpan], [CHECK, INDETERMINATE]);
this.removeCheck(currLi);
ariaState = 'false';
}
else if (state === 'indeterminate' && this.autoCheck) {
frameSpan.classList.remove(CHECK);
frameSpan.classList.add(INDETERMINATE);
this.removeCheck(currLi);
ariaState = 'mixed';
}
ariaState = state === 'check' ? 'true' : state === 'uncheck' ? 'false' : ariaState;
if (!isNullOrUndefined(ariaState)) {
currLi.setAttribute('aria-checked', ariaState);
}
if (isAdd) {
const data = [].concat([], this.checkActionNodes);
eventArgs = this.getCheckEvent(currLi, state, e);
if (isUndefined(isPrevent)) {
eventArgs.data = data;
}
}
if (doCheck !== undefined) {
this.ensureStateChange(currLi, doCheck);
}
if (!isPrevent) {
if (!isNullOrUndefined(ariaState)) {
currLi.setAttribute('aria-checked', ariaState);
eventArgs.data[0].checked = ariaState;
this.trigger('nodeChecked', eventArgs);
this.checkActionNodes = [];
}
}
}
addCheck(liEle) {
const id = liEle.getAttribute('data-uid');
if (!isNullOrUndefined(id) && this.checkedNodes.indexOf(id) === -1) {
this.checkDisabledState(id);
}
}
removeCheck(liEle) {
const index = this.checkedNodes.indexOf(liEle.getAttribute('data-uid'));
if (index > -1) {
this.checkedNodes.splice(index, 1);
}
}
getCheckEvent(currLi, action, e) {
this.checkActionNodes.push(this.getNodeData(currLi));
const nodeData = this.checkActionNodes;
return { action: action, cancel: false, isInteracted: isNullOrUndefined(e) ? false : true, node: currLi, data: nodeData };
}
finalize() {
const firstUl = select('.' + PARENTITEM, this.element);
if (!isNullOrUndefined(firstUl)) {
firstUl.setAttribute('role', treeAriaAttr.treeRole);
this.setMultiSelect(this.allowMultiSelection);
this.setNodeFocusable();
if (this.allowTextWrap) {
this.updateWrap();
}
this.renderReactTemplates();
this.hasPid = this.rootData[0] ? Object.prototype.hasOwnProperty.call(this.rootData[0], this.fields.parentID) : false;
this.doExpandAction();
}
}
setTextWrap() {
(this.allowTextWrap ? addClass : removeClass)([this.element], LISTWRAP);
if (Browser.isIE) {
(this.allowTextWrap ? addClass : removeClass)([this.element], IELISTWRAP);
}
}
updateWrap(ulEle) {
if (!this.fullRowSelect) {
return;
}
const liEle = ulEle ? selectAll('.' + LISTITEM, ulEle) : this.liList;
const length = liEle.length;
for (let i = 0; i < length; i++) {
this.calculateWrap(liEle[parseInt(i.toString(), 10)]);
}
}
calculateWrap(liEle) {
const element = select('.' + FULLROW, liEle);
if (element && element.nextElementSibling) {
element.style.height = this.allowTextWrap ? element.nextElementSibling.offsetHeight + 'px' : '';
}
}
doExpandAction() {
const eUids = this.expandedNodes;
if (!this.loadOnDemand && this.fields.dataSource instanceof DataManager) {
this.isInitalExpand = this.treeData.filter((e) => e[this.fields.expanded] === true).length > 0
? true
: this.isInitalExpand;
}
if (this.isInitalExpand && eUids.length > 0) {
this.setProperties({ expandedNodes: [] }, true);
if (this.fields.dataSource instanceof DataManager) {
this.expandGivenNodes(eUids);
}
else {
for (let i = 0; i < eUids.length; i++) {
const eNode = select('[data-uid="' + eUids[parseInt(i.toString(), 10)] + '"]', this.element);
if (!isNullOrUndefined(eNode)) {
const icon = select('.' + EXPANDABLE, select('.' + TEXTWRAP, eNode));
if (!isNullOrUndefined(icon)) {
this.expandAction(eNode, icon, null);
}
}
else {
if (eUids[parseInt(i.toString(), 10)] && this.expandChildren.indexOf(eUids[parseInt(i.toString(), 10)]) === -1) {
this.expandChildren.push(eUids[parseInt(i.toString(), 10)].toString());
}
continue;
}
}
this.afterFinalized();
}
}
else {
this.afterFinalized();
}
}
expandGivenNodes(arr) {
this.expandCallback(arr[this.index], () => {
this.index++;
if (this.index < arr.length) {
this.expandGivenNodes(arr);
}
else {
this.afterFinalized();
}
});
if (this.index > 0) {
this.index = 0;
}
}
expandCallback(eUid, callback) {
const eNode = select('[data-uid="' + eUid + '"]', this.element);
if (!isNullOrUndefined(eNode)) {
const icon = select('.' + EXPANDABLE, select('.' + TEXTWRAP, eNode));
if (!isNullOrUndefined(icon)) {
this.expandAction(eNode, icon, null, false, callback);
}
callback();
}
else {
callback();
}
}
afterFinalized() {
this.doSelectionAction();
this.updateCheckedProp();
this.isAnimate = true;
this.isInitalExpand = false;
if ((!this.isLoaded || this.isFieldChange) && !this.isNodeDropped) {
const eventArgs = { data: this.treeData };
this.trigger('dataBound', eventArgs);
}
this.isLoaded = true;
this.isNodeDropped = false;
}
doSelectionAction() {
const sNodes = selectAll('.' + SELECTED$1, this.element);
const sUids = this.selectedNodes;
if (sUids.length > 0) {
this.setProperties({ selectedNodes: [] }, true);
for (let i = 0; i < sUids.length; i++) {
const sNode = select('[data-uid="' + sUids[parseInt(i.toString(), 10)] + '"]', this.element);
if (sNode && !(sNode.classList.contains('e-active'))) {
this.selectNode(sNode, null, true);
}
else {
this.selectedNodes.push(sUids[parseInt(i.toString(), 10)]);
}
if (!this.allowMultiSelection) {
break;
}
}
}
else {
this.selectGivenNodes(sNodes);
}
removeClass(sNodes, SELECTED$1);
}
selectGivenNodes(sNodes) {
for (let i = 0; i < sNodes.length; i++) {
if (!sNodes[parseInt(i.toString(), 10)].classList.contains('e-disable')) {
this.selectNode(sNodes[parseInt(i.toString(), 10)], null, true);
}
if (!this.allowMultiSelection) {
break;
}
}
}
clickHandler(event) {
const target = Browser.isDevice && event.originalEvent.changedTouches && !Browser.isIos
? document.elementFromPoint(event.originalEvent.changedTouches[0].clientX, event.originalEvent.changedTouches[0].clientY)
: event.originalEvent.target;
EventHandler.remove(this.element, 'contextmenu', this.preventContextMenu);
if (!target || this.dragStartAction) {
return;
}
else {
const classList = target.classList;
const li = closest(target, '.' + LISTITEM);
if (!li || (li.classList.contains(PREVENTSELECT) && !(classList.contains(EXPANDABLE) || classList.contains(COLLAPSIBLE)))) {
return;
}
else if (event.originalEvent.which !== 3) {
const rippleElement = select('.' + RIPPLEELMENT, li);
const rippleIcons = select('.' + ICON, li);
this.removeHover();
this.setFocusElement(li);
const isExpandCollapseIcon = classList.contains(EXPANDABLE) || classList.contains(COLLAPSIBLE);
if (this.showCheckBox && !li.classList.contains('e-disable') && !isExpandCollapseIcon) {
const checkWrapper = this.checkOnClick ? select('.' + CHECKBOXWRAP, li) : closest(target, '.' + CHECKBOXWRAP);
if (!isNullOrUndefined(checkWrapper)) {
const checkElement = select('.' + CHECKBOXFRAME, checkWrapper);
this.validateCheckNode(checkWrapper, checkElement.classList.contains(CHECK), li, event.originalEvent);
this.triggerClickEvent(event.originalEvent, li);
return;
}
}
if (classList.contains(EXPANDABLE)) {
this.expandAction(li, target, event);
}
else if (classList.contains(COLLAPSIBLE)) {
this.collapseNode(li, target, event);
}
else if (rippleElement && rippleIcons) {
if (rippleIcons.classList.contains(RIPPLE) && rippleIcons.classList.contains(EXPANDABLE)) {
this.expandAction(li, rippleIcons, event);
}
else if (rippleIcons.classList.contains(RIPPLE) && rippleIcons.classList.contains(COLLAPSIBLE)) {
this.collapseNode(li, rippleIcons, event);
}
else if (!classList.contains(PARENTITEM) && !classList.contains(LISTITEM)) {
this.toggleSelect(li, event.originalEvent, false);
}
}
else {
if (!classList.contains(PARENTITEM) && !classList.contains(LISTITEM)) {
this.toggleSelect(li, event.originalEvent, false);
}
}
}
if (event.originalEvent.which === 3) {
this.isRightClick = true;
}
this.triggerClickEvent(event.originalEvent, li);
}
}
nodeCheckedEvent(wrapper, isCheck, e) {
const eventArgs = this.getCheckEvent(wrapper, isCheck ? 'uncheck' : 'check', e);
eventArgs.data = eventArgs.data.splice(0, eventArgs.data.length - 1);
this.trigger('nodeChecked', eventArgs);
}
updateOldCheckedData(data) {
const dataManager = new DataManager(data);
const childItems = dataManager.executeLocal(new Query().where('isChecked', 'equal', 'true', true));
const uncheckedItems = dataManager.executeLocal(new Query().where('isChecked', 'equal', 'false', true));
if (uncheckedItems.length > 0) {
const index = this.OldCheckedData.findIndex((e) => e['id'] === uncheckedItems[0]['id']);
if (index !== -1) {
this.OldCheckedData.splice(index, 1);
const childNodes = this.OldCheckedData.filter((e) => e['parentID'] === uncheckedItems[0]['id']);
if (childNodes.length > 0) {
childNodes.forEach((child) => {
const childIndex = this.OldCheckedData.findIndex((e) => e['id'] === child.id);
if (childIndex !== -1) {
this.OldCheckedData.splice(childIndex, 1);
}
});
}
return;
}
}
if (childItems.length > 0) {
const index = this.OldCheckedData.findIndex((e) => e['id'] === childItems[0]['id']);
if (index === -1) {
this.OldCheckedData.push(childItems[0]);
return;
}
}
}
triggerClickEvent(e, li) {
const eventArgs = {
event: e,
node: li
};
this.trigger('nodeClicked', eventArgs);
}
expandNode(currLi, icon, loaded) {
this.renderReactTemplates();
if (icon.classList.contains(LOAD)) {
this.hideSpinner(icon);
}
if (!this.initialRender) {
icon.classList.add('interaction');
}
if (loaded !== true || (loaded === true && currLi.classList.contains('e-expanded'))) {
if (this.preventExpand !== true) {
removeClass([icon], EXPANDABLE);
addClass([icon], COLLAPSIBLE);
let start = 0;
let end = 0;
const ul = select('.' + PARENTITEM, currLi);
const liEle = currLi;
if (this.isAnimate && !this.isRefreshed) {
this.setHeight(liEle, ul);
const activeElement = select('.' + LISTITEM + '.' + ACTIVE, currLi);
this.aniObj.animate(ul, {
name: this.animation.expand.effect,
duration: (this.animation.expand.duration === 0 && animationMode === 'Enable') ? 400 : this.animation.expand.duration,
timingFunction: this.animation.expand.easing,
begin: () => {
liEle.style.overflow = 'hidden';
if (!isNullOrUndefined(activeElement) && activeElement instanceof HTMLElement) {
activeElement.classList.add(ITEM_ANIMATION_ACTIVE);
}
start = liEle.offsetHeight;
const computedStyle = window.getComputedStyle(liEle);
const paddingTop = parseFloat(computedStyle.paddingTop);
const paddingBottom = parseFloat(computedStyle.paddingBottom);
end = select('.' + TEXTWRAP, currLi).offsetHeight + paddingBottom + paddingTop;
},
progress: (args) => {
args.element.style.display = 'block';
this.animateHeight(args, start, end);
},
end: (args) => {
args.element.style.display = 'block';
if (!isNullOrUndefined(activeElement) && activeElement instanceof HTMLElement) {
activeElement.classList.remove(ITEM_ANIMATION_ACTIVE);
}
this.expandedNode(liEle, ul, icon);
}
});
}
else {
this.expandedNode(liEle, ul, icon);
}
}
}
else {
const ul = select('.' + PARENTITEM, currLi);
ul.style.display = 'none';
if (this.fields.dataSource instanceof DataManager === true) {
this.preventExpand = false;
}
}
if (this.initialRender) {
icon.classList.add('interaction');
}
}
expandedNode(currLi, ul, icon) {
ul.style.display = 'block';
currLi.style.display = 'block';
currLi.style.overflow = '';
currLi.style.height = '';
removeClass([icon], PROCESS);
this.addExpand(currLi);
if (this.allowTextWrap && this.isLoaded && this.isFirstRender) {
this.updateWrap(currLi);
this.isFirstRender = false;
}
if (this.isLoaded && this.expandArgs && !this.isRefreshed) {
this.expandArgs = this.getExpandEvent(currLi, null);
this.expandArgs.isInteracted = this.isInteracted;
this.trigger('nodeExpanded', this.expandArgs);
}
if (this.isHiddenItem) {
this.collapseAll([this.getNodeData(currLi).id]);
}
}
addExpand(liEle) {
liEle.setAttribute('aria-expanded', 'true');
removeClass([liEle], NODECOLLAPSED);
const id = liEle.getAttribute('data-uid');
if (!isNullOrUndefined(id) && this.expandedNodes.indexOf(id) === -1) {
this.expandedNodes.push(id);
}
}
collapseNode(currLi, icon, e) {
if (icon.classList.contains(PROCESS)) {
return;
}
else {
addClass([icon], PROCESS);
}
let colArgs;
if (this.isLoaded) {
colArgs = this.getExpandEvent(currLi, e);
this.isInteracted = colArgs.isInteracted;
this.trigger('nodeCollapsing', colArgs, (observedArgs) => {
if (observedArgs.cancel) {
removeClass([icon], PROCESS);
}
else {
this.nodeCollapseAction(currLi, icon, observedArgs);
}
});
}
else {
this.nodeCollapseAction(currLi, icon, colArgs);
}
}
nodeCollapseAction(currLi, icon, colArgs) {
removeClass([icon], COLLAPSIBLE);
addClass([icon], EXPANDABLE);
let start = 0;
let end = 0;
const ul = select('.' + PARENTITEM, currLi);
const liEle = currLi;
const activeElement = select('.' + LISTITEM + '.' + ACTIVE, currLi);
if (this.isAnimate) {
this.aniObj.animate(ul, {
name: this.animation.collapse.effect,
duration: (this.animation.collapse.duration === 0 && animationMode === 'Enable') ? 400 : this.animation.collapse.duration,
timingFunction: this.animation.collapse.easing,
begin: () => {
liEle.style.overflow = 'hidden';
if (!isNullOrUndefined(activeElement) && activeElement instanceof HTMLElement) {
activeElement.classList.add(ITEM_ANIMATION_ACTIVE);
}
start = select('.' + TEXTWRAP, currLi).offsetHeight;
end = liEle.offsetHeight;
},
progress: (args) => {
this.animateHeight(args, start, end);
},
end: (args) => {
args.element.style.display = 'none';
if (!isNullOrUndefined(activeElement) && activeElement instanceof HTMLElement) {
activeElement.classList.remove(ITEM_ANIMATION_ACTIVE);
}
this.collapsedNode(liEle, ul, icon, colArgs);
}
});
}
else {
this.collapsedNode(liEle, ul, icon, colArgs);
}
}
collapsedNode(liEle, ul, icon, colArgs) {
ul.style.display = 'none';
liEle.style.overflow = '';
liEle.style.height = '';
removeClass([icon], PROCESS);
this.removeExpand(liEle);
if (this.isLoaded) {
colArgs = this.getExpandEvent(liEle, null);
colArgs.isInteracted = this.isInteracted;
this.trigger('nodeCollapsed', colArgs);
}
}
removeExpand(liEle, toRemove) {
if (toRemove) {
liEle.removeAttribute('aria-expanded');
}
else {
this.disableExpandAttr(liEle);
}
const index = this.expandedNodes.indexOf(liEle.getAttribute('data-uid'));
if (index > -1) {
this.expandedNodes.splice(index, 1);
}
}
disableExpandAttr(liEle) {
liEle.setAttribute('aria-expanded', 'false');
addClass([liEle], NODECOLLAPSED);
}
setHeight(currLi, ul) {
ul.style.display = 'block';
ul.style.visibility = 'hidden';
currLi.style.height = currLi.offsetHeight + 'px';
ul.style.display = 'none';
ul.style.visibility = '';
}
animateHeight(args, start, end) {
if (isNullOrUndefined(args.element.parentElement)) {
return;
}
const remaining = (args.duration - args.timeStamp) / args.duration;
const currentHeight = (end - start) * remaining + start;
args.element.parentElement.style.height = currentHeight + 'px';
}
renderChildNodes(parentLi, expandChild, callback, loaded, isFromExpandAll) {
const eicon = select('div.' + ICON, parentLi);
if (isNullOrUndefined(eicon)) {
return;
}
this.showSpinner(eicon);
let childItems;
if (this.fields.dataSource instanceof DataManager) {
const level = this.parents(parentLi, '.' + PARENTITEM).length;
const mapper = this.getChildFields(this.fields, level, 1);
if (isNullOrUndefined(mapper) || isNullOrUndefined(mapper.dataSource)) {
detach(eicon);
this.removeExpand(parentLi, true);
return;
}
this.treeList.push('false');
if (this.fields.dataSource instanceof DataManager && this.isOffline) {
this.treeList.pop();
childItems = this.getChildNodes(this.treeData, parentLi.getAttribute('data-uid'));
this.loadChild(childItems, mapper, eicon, parentLi, expandChild, callback, loaded);
}
else {
mapper.dataSource.executeQuery(this.getQuery(mapper, parentLi.getAttribute('data-uid'))).then((e) => {
this.treeList.pop();
childItems = e.result;
if (this.dataType === 1) {
this.dataType = 2;
}
this.loadChild(childItems, mapper, eicon, parentLi, expandChild, callback, loaded);
}).catch((e) => {
this.trigger('actionFailure', { error: e });
});
}
}
else {
childItems = this.getChildNodes(this.treeData, parentLi.getAttribute('data-uid'), false, parseFloat(parentLi.getAttribute('aria-level')) + 1);
this.currentLoadData = this.getSortedData(childItems);
if (isNullOrUndefined(childItems) || childItems.length === 0) {
detach(eicon);
if (eicon.classList.contains(LOAD)) {
this.hideSpinner(eicon);
}
this.removeExpand(parentLi, true);
return;
}
else {
this.listBaseOption.ariaAttributes.level = parseFloat(parentLi.getAttribute('aria-level')) + 1;
parentLi.appendChild(ListBase.createList(this.createElement, this.currentLoadData, this.listBaseOption));
this.expandNode(parentLi, eicon, loaded);
this.setSelectionForChildNodes(childItems);
this.ensureCheckNode(parentLi, isFromExpandAll);
this.finalizeNode(parentLi, isFromExpandAll, expandChild);
this.disableTreeNodes(childItems);
this.renderSubChild(parentLi, expandChild, loaded, isFromExpandAll);
}
}
}
loadChild(childItems, mapper, eicon, parentLi, expandChild, callback, loaded) {
this.currentLoadData = childItems;
if (isNullOrUndefined(childItems) || childItems.length === 0) {
detach(eicon);
this.removeExpand(parentLi, true);
}
else {
this.updateListProp(mapper);
if (this.fields.dataSource instanceof DataManager && !this.isOffline) {
const id = parentLi.getAttribute('data-uid');
const nodeData = this.getNodeObject(id);
setValue('child', childItems, nodeData);
}
this.listBaseOption.ariaAttributes.level = parseFloat(parentLi.getAttribute('aria-level')) + 1;
parentLi.appendChild(ListBase.createList(this.createElement, childItems, this.listBaseOption));
this.expandNode(parentLi, eicon, loaded);
this.setSelectionForChildNodes(childItems);
this.ensureCheckNode(parentLi);
this.finalizeNode(parentLi);
this.disableTreeNodes(childItems);
this.renderSubChild(parentLi, expandChild, loaded);
}
if (callback) {
callback();
}
if (expandChild) {
this.expandedNodes.push(parentLi.getAttribute('data-uid'));
}
if (this.treeList.length === 0 && !this.isLoaded) {
this.finalize();
}
}
disableTreeNodes(childItems) {
if (isNullOrUndefined(this.disableNode) || this.disableNode.length === 0) {
return;
}
let i = 0;
while (i < childItems.length) {
const id = childItems[parseInt(i.toString(), 10)][this.fields.id]
? childItems[parseInt(i.toString(), 10)][this.fields.id].toString()
: null;
if (this.disableNode !== undefined && this.disableNode.indexOf(id) !== -1) {
this.doDisableAction([id]);
}
i++;
}
}
/**
* Sets the child Item in selectedState while rendering the child node
*
* @param {Object[]} nodes - Array of nodes
* @returns {void}
*/
setSelectionForChildNodes(nodes) {
if (isNullOrUndefined(this.selectedNodes) || this.selectedNodes.length === 0) {
return;
}
let i;
for (i = 0; i < nodes.length; i++) {
const id = nodes[parseInt(i.toString(), 10)][this.fields.id]
? nodes[parseInt(i.toString(), 10)][this.fields.id].toString()
: null;
if (this.selectedNodes !== undefined && this.selectedNodes.indexOf(id) !== -1) {
this.doSelectionAction();
}
}
}
ensureCheckNode(element, isFromExpandAll) {
if (this.showCheckBox) {
this.ele = (this.checkedElement) ? this.checkedElement.indexOf(element.getAttribute('data-uid')) : null;
if (this.autoCheck) {
this.ensureChildCheckState(element, null, isFromExpandAll);
if (isFromExpandAll ? (select('.' + CHECK, this.element) || select('.' + INDETERMINATE, this.element)) : true) {
this.ensureParentCheckState(element);
}
}
}
this.currentLoadData = null;
}
getFields(mapper, nodeLevel, dataLevel) {
if (nodeLevel === dataLevel) {
return mapper;
}
else {
return this.getFields(this.getChildMapper(mapper), nodeLevel, dataLevel + 1);
}
}
getChildFields(mapper, nodeLevel, dataLevel) {
if (nodeLevel === dataLevel) {
return this.getChildMapper(mapper);
}
else {
return this.getChildFields(this.getChildMapper(mapper), nodeLevel, dataLevel + 1);
}
}
getChildMapper(mapper) {
return (typeof mapper.child === 'string' || isNullOrUndefined(mapper.child)) ? mapper : mapper.child;
}
getChildNodes(obj, parentId, isRoot = false, level) {
let childNodes;
if (isNullOrUndefined(obj)) {
return childNodes;
}
if (this.dataType === 1) {
return this.getChildGroup(this.groupedData, parentId, isRoot);
}
if (typeof this.fields.child === 'string') {
return this.findChildNodes(obj, this.fields.id, parentId) || this.findNestedChildNodes(obj, parentId, level) || [];
}
if (this.isChildObject()) {
let tempField = !isNullOrUndefined(level) ? this.fields : this.fields.child;
let i = 1;
while (i < level) {
if (!isNullOrUndefined(tempField.child)) {
tempField = tempField.child;
}
else {
break;
}
i++;
}
this.updateListProp(tempField);
const index = obj.findIndex((data) => getValue(this.fields.id, data) &&
getValue(this.fields.id, data).toString() === parentId);
if (index !== -1) {
return getValue('child', obj[parseInt(index.toString(), 10)]);
}
if (index === -1) {
for (let i = 0, objlen = obj.length; i < objlen; i++) {
const tempArray = getValue('child', obj[parseInt(i.toString(), 10)]);
const childIndex = !isNullOrUndefined(tempArray)
? tempArray.findIndex((data) => getValue(this.fields.child.id, data) &&
getValue(this.fields.child.id, data).toString() === parentId)
: -1;
if (childIndex !== -1) {
return getValue('child', tempArray[parseInt(childIndex.toString(), 10)]);
}
else if (!isNullOrUndefined(tempArray)) {
childNodes = this.getChildNodes(tempArray, parentId, false, level);
if (childNodes !== undefined) {
break;
}
}
}
}
}
return childNodes;
}
findChildNodes(items, idField, parentId) {
const index = items.findIndex((data) => {
const value = getValue(idField, data);
return value && value.toString() === parentId;
});
if (index !== -1) {
return getValue(this.fields.child, items[index]);
}
return null;
}
findNestedChildNodes(items, parentId, level) {
for (const item of items) {
const tempArray = getValue(this.fields.child, item);
if (!isNullOrUndefined(tempArray)) {
const childNodes = this.findChildNodes(tempArray, this.fields.id, parentId);
if (childNodes) {
return childNodes;
}
const nestedChildNodes = this.getChildNodes(tempArray, parentId, false, level);
if (nestedChildNodes && nestedChildNodes.length > 0) {
return nestedChildNodes;
}
}
}
return undefined;
}
getChildGroup(data, parentId, isRoot) {
const childNodes = [];
if (isNullOrUndefined(data)) {
return childNodes;
}
for (let i = 0, objlen = data.length; i < objlen; i++) {
if (!isNullOrUndefined(data[parseInt(i.toString(), 10)][0]) &&
!isNullOrUndefined(getValue(this.fields.parentID, data[parseInt(i.toString(), 10)][0]))) {
if (getValue(this.fields.parentID, data[parseInt(i.toString(), 10)][0]).toString() === parentId) {
return data[parseInt(i.toString(), 10)];
}
}
else if (isRoot) {
return data[parseInt(i.toString(), 10)];
}
}
return childNodes;
}
renderSubChild(element, expandChild, loaded, isFromExpandAll) {
if (expandChild) {
const cIcons = selectAll('.' + EXPANDABLE, element);
for (let i = 0, len = cIcons.length; i < len; i++) {
const icon = cIcons[parseInt(i.toString(), 10)];
if (element.querySelector('.e-icons') !== cIcons[parseInt(i.toString(), 10)]) {
const curLi = closest(icon, '.' + LISTITEM);
this.expandArgs = this.getExpandEvent(curLi, null);
if (loaded !== true) {
this.trigger('nodeExpanding', this.expandArgs);
}
this.renderChildNodes(curLi, expandChild, null, loaded, isFromExpandAll);
}
}
}
}
toggleSelect(li, e, multiSelect) {
if (!li.classList.contains('e-disable')) {
if (this.allowMultiSelection && ((e && e.ctrlKey) || multiSelect) && this.isActive(li)) {
this.unselectNode(li, e);
}
else {
this.selectNode(li, e, multiSelect);
}
}
}
isActive(li) {
return li.classList.contains(ACTIVE) ? true : false;
}
selectNode(li, e, multiSelect) {
if (isNullOrUndefined(li) || (!this.allowMultiSelection && this.isActive(li) && !isNullOrUndefined(e))) {
if (this.checkOnClick) {
const checkboxElement = select(' .' + CHECKBOXFRAME, li);
if (!isNullOrUndefined(checkboxElement) && checkboxElement.classList.contains(CHECK)) {
addClass([li], ACTIVE);
}
else {
removeClass([li], ACTIVE);
}
}
this.setFocusElement(li);
return;
}
let eventArgs;
if (this.isLoaded) {
eventArgs = this.getSelectEvent(li, 'select', e);
this.trigger('nodeSelecting', eventArgs, (observedArgs) => {
if ((!observedArgs.cancel) && !observedArgs.node.classList.contains(PREVENTSELECT)) {
this.nodeSelectAction(li, e, observedArgs, multiSelect);
}
});
}
else {
this.nodeSelectAction(li, e, eventArgs, multiSelect);
}
}
nodeSelectAction(li, e, eventArgs, multiSelect) {
if (!this.allowMultiSelection || (!multiSelect && (!e || (e && !(e.ctrlKey || e.metaKey))))) {
this.removeSelectAll();
}
if (this.allowMultiSelection && e && e.shiftKey) {
if (!this.startNode) {
this.startNode = li;
}
let startIndex = this.liList.indexOf(this.startNode);
let endIndex = this.liList.indexOf(li);
if (startIndex > endIndex) {
const temp = startIndex;
startIndex = endIndex;
endIndex = temp;
}
for (let i = startIndex; i <= endIndex; i++) {
const currNode = this.liList[parseInt(i.toString(), 10)];
if (isVisible(currNode) && !currNode.classList.contains('e-disable')) {
this.addSelect(currNode);
}
}
}
else {
this.startNode = li;
this.addSelect(li);
}
if (this.isLoaded) {
eventArgs.nodeData = this.getNodeData(li);
this.trigger('nodeSelected', eventArgs);
this.isRightClick = false;
}
this.isRightClick = false;
}
unselectNode(li, e) {
let eventArgs;
if (this.isLoaded) {
eventArgs = this.getSelectEvent(li, 'un-select', e);
this.trigger('nodeSelecting', eventArgs, (observedArgs) => {
if (!observedArgs.cancel) {
this.nodeUnselectAction(li, observedArgs);
}
});
}
else {
this.nodeUnselectAction(li, eventArgs);
}
}
nodeUnselectAction(li, eventArgs) {
this.removeSelect(li);
this.setFocusElement(li);
if (this.isLoaded) {
eventArgs.nodeData = this.getNodeData(li);
this.trigger('nodeSelected', eventArgs);
}
}
setFocusElement(li) {
if (!isNullOrUndefined(li)) {
const focusedNode = this.getFocusedNode();
if (focusedNode) {
removeClass([focusedNode], FOCUS);
focusedNode.setAttribute('tabindex', '-1');
}
addClass([li], FOCUS);
li.setAttribute('tabindex', '0');
EventHandler.add(li, 'blur', this.focusOut, this);
this.updateIdAttr(focusedNode, li);
}
}
addSelect(liEle) {
liEle.setAttribute('aria-selected', 'true');
addClass([liEle], ACTIVE);
const id = liEle.getAttribute('data-uid');
if (!isNullOrUndefined(id) && this.selectedNodes.indexOf(id) === -1) {
this.selectedNodes.push(id);
}
}
removeSelect(liEle) {
if (this.allowMultiSelection) {
liEle.setAttribute('aria-selected', 'false');
}
else {
liEle.removeAttribute('aria-selected');
}
removeClass([liEle], ACTIVE);
const index = this.selectedNodes.indexOf(liEle.getAttribute('data-uid'));
if (index > -1) {
this.selectedNodes.splice(index, 1);
}
}
removeSelectAll() {
const selectedLI = this.element.querySelectorAll('.' + ACTIVE);
for (const ele of selectedLI) {
if (this.allowMultiSelection) {
ele.setAttribute('aria-selected', 'false');
}
else {
ele.removeAttribute('aria-selected');
}
}
removeClass(selectedLI, ACTIVE);
this.setProperties({ selectedNodes: [] }, true);
}
getSelectEvent(currLi, action, e) {
const nodeData = this.getNodeData(currLi);
return { action: action, cancel: false, isInteracted: isNullOrUndefined(e) ? false : true, node: currLi, nodeData: nodeData };
}
setExpandOnType() {
this.expandOnType = (this.expandOn === 'Auto') ? (Browser.isDevice ? 'Click' : 'DblClick') : this.expandOn;
}
expandHandler(e) {
const target = Browser.isDevice && e.originalEvent.changedTouches && !Browser.isIos
? document.elementFromPoint(e.originalEvent.changedTouches[0].clientX, e.originalEvent.changedTouches[0].clientY)
: e.originalEvent.target;
if (!target || target.classList.contains(INPUT) || target.classList.contains(ROOT) ||
target.classList.contains(PARENTITEM) || target.classList.contains(LISTITEM) ||
target.classList.contains(ICON) || this.showCheckBox && closest(target, '.' + CHECKBOXWRAP)) {
return;
}
else {
this.expandCollapseAction(closest(target, '.' + LISTITEM), e);
}
}
expandCollapseAction(currLi, e) {
const icon = select('div.' + ICON, currLi);
if (!icon || icon.classList.contains(PROCESS)) {
return;
}
else {
const classList = icon.classList;
if (classList.contains(EXPANDABLE)) {
this.expandAction(currLi, icon, e);
}
else if (classList.contains(COLLAPSIBLE)) {
this.collapseNode(currLi, icon, e);
}
}
}
expandAction(currLi, icon, e, expandChild, callback, isFromExpandAll) {
if (icon.classList.contains(PROCESS)) {
return;
}
else {
addClass([icon], PROCESS);
}
if (this.isLoaded && !this.isRefreshed) {
this.expandArgs = this.getExpandEvent(currLi, e);
this.isInteracted = this.expandArgs.isInteracted;
this.trigger('nodeExpanding', this.expandArgs, (observedArgs) => {
if (observedArgs.cancel) {
removeClass([icon], PROCESS);
}
else {
this.nodeExpandAction(currLi, icon, expandChild, callback, isFromExpandAll);
}
});
}
else {
this.nodeExpandAction(currLi, icon, expandChild, callback, isFromExpandAll);
}
}
nodeExpandAction(currLi, icon, expandChild, callback, isFromExpandAll) {
const ul = select('.' + PARENTITEM, currLi);
if (ul && ul.nodeName === 'UL') {
this.expandNode(currLi, icon);
}
else {
this.isFirstRender = true;
this.renderChildNodes(currLi, expandChild, callback, null, isFromExpandAll);
if (isNullOrUndefined(this.expandChildren) || this.expandChildren.length === 0) {
return;
}
const liEles = selectAll('.' + LISTITEM, currLi);
for (let i = 0; i < liEles.length; i++) {
const id = this.getId(liEles[parseInt(i.toString(), 10)]);
if (this.expandChildren.indexOf(id) !== -1 && this.expandChildren !== undefined) {
const icon = select('.' + EXPANDABLE, select('.' + TEXTWRAP, liEles[parseInt(i.toString(), 10)]));
if (!isNullOrUndefined(icon)) {
this.expandAction(liEles[parseInt(i.toString(), 10)], icon, null);
}
this.expandChildren.splice(this.expandChildren.indexOf(id), 1);
}
}
}
}
keyActionHandler(e) {
const target = e.target;
const focusedNode = this.getFocusedNode();
if (target && target.classList.contains(INPUT)) {
const inpEle = target;
if (e.action === 'enter') {
inpEle.blur();
}
else if (e.action === 'escape') {
inpEle.value = this.oldText;
inpEle.blur();
}
return;
}
e.preventDefault();
const eventArgs = {
cancel: false,
event: e,
node: focusedNode
};
this.trigger('keyPress', eventArgs, (observedArgs) => {
if (!observedArgs.cancel) {
switch (e.action) {
case 'space':
if (this.showCheckBox) {
this.checkNode(e);
}
else {
this.toggleSelect(focusedNode, e);
}
break;
case 'moveRight':
this.openNode(this.enableRtl ? false : true, e);
break;
case 'moveLeft':
this.openNode(this.enableRtl ? true : false, e);
break;
case 'shiftDown':
this.shiftKeySelect(true, e);
break;
case 'moveDown':
case 'ctrlDown':
case 'csDown':
this.navigateNode(true);
break;
case 'shiftUp':
this.shiftKeySelect(false, e);
break;
case 'moveUp':
case 'ctrlUp':
case 'csUp':
this.navigateNode(false);
break;
case 'home':
case 'shiftHome':
case 'ctrlHome':
case 'csHome':
this.navigateRootNode(true);
break;
case 'end':
case 'shiftEnd':
case 'ctrlEnd':
case 'csEnd':
this.navigateRootNode(false);
break;
case 'enter':
case 'ctrlEnter':
case 'shiftEnter':
case 'csEnter':
case 'shiftSpace':
case 'ctrlSpace':
this.toggleSelect(focusedNode, e);
break;
case 'f2':
if (this.allowEditing && !focusedNode.classList.contains('e-disable')) {
this.createTextbox(focusedNode);
}
break;
case 'ctrlA':
if (this.allowMultiSelection) {
const sNodes = selectAll('.' + LISTITEM + ':not(.' + ACTIVE + ')', this.element);
this.selectGivenNodes(sNodes);
}
break;
}
}
});
}
navigateToFocus(isUp) {
const focusNode = this.getFocusedNode().querySelector('.' + TEXTWRAP);
const pos = focusNode.getBoundingClientRect();
const parent = this.getScrollParent(this.element);
if (!isNullOrUndefined(parent)) {
const parentPos = parent.getBoundingClientRect();
if (pos.bottom > parentPos.bottom) {
parent.scrollTop += pos.bottom - parentPos.bottom;
}
else if (pos.top < parentPos.top) {
parent.scrollTop -= parentPos.top - pos.top;
}
}
const isVisible = this.isVisibleInViewport(focusNode);
if (!isVisible) {
focusNode.scrollIntoView(isUp);
}
}
isVisibleInViewport(txtWrap) {
const pos = txtWrap.getBoundingClientRect();
return (pos.top >= 0 && pos.left >= 0 && pos.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
pos.right <= (window.innerWidth || document.documentElement.clientWidth));
}
getScrollParent(node) {
if (isNullOrUndefined(node)) {
return null;
}
return (node.scrollHeight > node.clientHeight) ? node : this.getScrollParent(node.parentElement);
}
shiftKeySelect(isTowards, e) {
if (this.allowMultiSelection) {
const focusedNode = this.getFocusedNode();
const nextNode = isTowards ? this.getNextNode(focusedNode) : this.getPrevNode(focusedNode);
this.removeHover();
this.setFocusElement(nextNode);
this.toggleSelect(nextNode, e, false);
this.navigateToFocus(!isTowards);
}
else {
this.navigateNode(isTowards);
}
}
checkNode(e) {
const focusedNode = this.getFocusedNode();
const checkWrap = select('.' + CHECKBOXWRAP, focusedNode);
const isChecked = select(' .' + CHECKBOXFRAME, checkWrap).classList.contains(CHECK);
if (!focusedNode.classList.contains('e-disable')) {
if (focusedNode.getElementsByClassName('e-checkbox-disabled').length === 0) {
this.validateCheckNode(checkWrap, isChecked, focusedNode, e);
}
}
}
validateCheckNode(checkWrap, isCheck, li, e) {
const currLi = closest(checkWrap, '.' + LISTITEM);
this.checkActionNodes = [];
const ariaState = !isCheck ? 'true' : 'false';
if (!isNullOrUndefined(ariaState)) {
currLi.setAttribute('aria-checked', ariaState);
}
const eventArgs = this.getCheckEvent(currLi, isCheck ? 'uncheck' : 'check', e);
this.trigger('nodeChecking', eventArgs, (observedArgs) => {
if (!observedArgs.cancel) {
this.nodeCheckingAction(checkWrap, isCheck, li, observedArgs, e);
}
});
}
nodeCheckingAction(checkWrap, isCheck, li, eventArgs, e) {
if (this.checkedElement.indexOf(li.getAttribute('data-uid')) === -1) {
this.checkedElement.push(li.getAttribute('data-uid'));
if (this.autoCheck) {
let child = this.getChildNodes(this.treeData, li.getAttribute('data-uid'));
if (child !== null) {
this.allCheckNode(child, this.checkedElement, null, null, false);
}
else {
child = null;
}
}
}
this.changeState(checkWrap, isCheck ? 'uncheck' : 'check', e, true);
this.updateActiveClass(li, isCheck);
if (this.autoCheck) {
this.ensureChildCheckState(li);
this.updateOldCheckedData([this.getNodeData(li)]);
const parentLi = closest(closest(li, '.' + PARENTITEM), '.' + LISTITEM);
if (this.isBatchMode) {
const parentId = !isNullOrUndefined(parentLi) ? parentLi.getAttribute('data-uid') : null;
if (parentId) {
this.batchParentNode.add(parentId);
}
}
else {
this.ensureParentCheckState(parentLi);
}
let doCheck;
if (eventArgs.action === 'check') {
doCheck = true;
}
else if (eventArgs.action === 'uncheck') {
doCheck = false;
}
this.ensureStateChange(li, doCheck);
}
this.nodeCheckedEvent(checkWrap, isCheck, e);
}
updateActiveClass(liElement, checkStatus) {
if (this.showCheckBox && this.checkOnClick) {
if (checkStatus === 'check' || checkStatus === false) {
this.removeSelectAll();
addClass([liElement], ACTIVE);
}
else if (checkStatus === 'uncheck' || checkStatus === 'indeterminate' || checkStatus === true) {
removeClass([liElement], ACTIVE);
}
}
}
/**
* Update checkedNodes when UI interaction happens before the child node renders in DOM
*
* @param {Element} li - The list item element
* @param {boolean} [doCheck] - Optional parameter to specify whether to perform a check
* @returns {void}
*/
ensureStateChange(li, doCheck) {
const childElement = select('.' + PARENTITEM, li);
const parentIndex = li.getAttribute('data-uid');
const mapper = this.fields;
if (this.dataType === 1 && this.autoCheck) {
let resultData = new DataManager(this.treeData).executeLocal(new Query().where(mapper.parentID, 'equal', parentIndex, true));
const childMatchesCheckedNodes = resultData.filter((item) => {
return this.checkedNodes.indexOf(item[mapper.id].toString()) !== -1;
}, this);
if (this.checkedNodes.indexOf(parentIndex) !== -1 && childMatchesCheckedNodes.length !== resultData.length && this.isFilter) {
if (childMatchesCheckedNodes.length > 0) {
resultData = childMatchesCheckedNodes;
}
}
for (let i = 0; i < resultData.length; i++) {
const resultId = resultData[parseInt(i.toString(), 10)][this.fields.id]
? resultData[parseInt(i.toString(), 10)][this.fields.id].toString()
: null;
const isCheck = resultData[parseInt(i.toString(), 10)][this.fields.isChecked]
? resultData[parseInt(i.toString(), 10)][this.fields.isChecked].toString()
: null;
if (this.checkedNodes.indexOf(parentIndex) !== -1 && this.checkedNodes.indexOf(resultId) === -1) {
this.checkDisabledState(resultId, resultData[i]);
const childItems = this.getChildNodes(this.treeData, resultId);
this.getChildItems(childItems, doCheck);
if (this.parentNodeCheck.indexOf(resultId) !== -1) {
this.parentNodeCheck.splice(this.parentNodeCheck.indexOf(resultId), 1);
}
}
else if (this.checkedNodes.indexOf(parentIndex) === -1 && childElement === null &&
this.checkedNodes.indexOf(resultId) !== -1) {
this.checkedNodes.splice(this.checkedNodes.indexOf(resultId), 1);
if (isCheck === 'true') {
this.updateField(this.treeData, this.fields, resultId, 'isChecked', null);
}
if (this.checkedNodes.indexOf(parentIndex) === -1 && childElement === null ||
this.parentNodeCheck.indexOf(resultId) !== -1) {
const childNodes = this.getChildNodes(this.treeData, resultId);
this.getChildItems(childNodes, doCheck);
if (this.parentNodeCheck.indexOf(resultId) !== -1) {
this.parentNodeCheck.splice(this.parentNodeCheck.indexOf(resultId), 1);
}
}
}
else {
const childItems = this.getChildNodes(this.treeData, resultId);
this.getChildItems(childItems, doCheck);
}
}
}
else if (this.dataType === 1 && !this.autoCheck) {
if (!doCheck) {
const checkedData = new DataManager(this.treeData).executeLocal(new Query().where(mapper.isChecked, 'equal', true, false));
for (let i = 0; i < checkedData.length; i++) {
const id = checkedData[parseInt(i.toString(), 10)][this.fields.id]
? checkedData[parseInt(i.toString(), 10)][this.fields.id].toString()
: null;
if (this.checkedNodes.indexOf(id) !== -1) {
this.checkedNodes.splice(this.checkedNodes.indexOf(id), 1);
}
this.updateField(this.treeData, this.fields, id, 'isChecked', null);
}
this.checkedNodes = [];
}
else {
for (let i = 0; i < this.treeData.length; i++) {
const checkedId = this.treeData[parseInt(i.toString(), 10)][this.fields.id]
? this.treeData[parseInt(i.toString(), 10)][this.fields.id].toString()
: null;
if (this.checkedNodes.indexOf(checkedId) === -1) {
this.checkDisabledState(checkedId, this.treeData[i]);
}
}
}
}
else {
let childItems = this.getChildNodes(this.treeData, parentIndex);
if (childItems) {
const filteredChildItems = childItems.filter((item) => {
const itemValue = String(item[Object.keys(item)[0]]);
return this.checkedNodes.indexOf(itemValue) !== -1;
});
if (filteredChildItems.length > 0 && childItems.length && this.isFilter) {
childItems = filteredChildItems;
}
this.childStateChange(childItems, parentIndex, childElement, doCheck);
}
}
}
checkDisabledState(resultId, currentItem) {
let requiresUpdate = this.checkDisabledChildren;
if (!requiresUpdate) {
let shouldPreventUpdate = true;
if (this.loadOnDemand && this.fields.htmlAttributes) {
currentItem = isNullOrUndefined(currentItem) ? currentItem : this.getNodeObject(resultId);
if (!isNullOrUndefined(currentItem)) {
const htmlAttributes = currentItem[this.fields.htmlAttributes];
if (htmlAttributes && !isNullOrUndefined(htmlAttributes.class) && htmlAttributes.class.indexOf(DISABLE) !== -1) {
shouldPreventUpdate = false;
}
}
}
const liElement = select(`[data-uid="${resultId}"]`, this.element);
requiresUpdate = liElement ? !liElement.classList.contains(DISABLE)
: (this.disableNode.indexOf(resultId) === -1 && shouldPreventUpdate);
}
if (requiresUpdate) {
this.checkedNodes.push(resultId);
}
}
getChildItems(childItems, doCheck) {
for (let i = 0; i < childItems.length; i++) {
const childId = childItems[parseInt(i.toString(), 10)][this.fields.id]
? childItems[parseInt(i.toString(), 10)][this.fields.id].toString()
: null;
const childIsCheck = childItems[parseInt(i.toString(), 10)][this.fields.isChecked]
? childItems[parseInt(i.toString(), 10)][this.fields.isChecked].toString()
: null;
if (this.checkedNodes.indexOf(childId) !== -1 && !doCheck) {
this.checkedNodes.splice(this.checkedNodes.indexOf(childId), 1);
}
if (this.checkedNodes.indexOf(childId) === -1 && doCheck) {
this.checkDisabledState(childId, childItems[i]);
}
if (childIsCheck === 'true' && !doCheck) {
this.updateField(this.treeData, this.fields, childId, 'isChecked', null);
}
const subChildItems = this.getChildNodes(this.treeData, childId);
if (subChildItems.length > 0) {
this.getChildItems(subChildItems, doCheck);
}
}
}
/**
* Update checkedNodes when UI interaction happens before the child node renders in DOM for hierarchical DS
*
* @param {Object[]} childItems - Array of child items
* @param {string} parent - Parent identifier
* @param {Element} childElement - Child DOM element
* @param {boolean} [doCheck] - Optional parameter to specify whether to perform a check
* @returns {void}
*/
childStateChange(childItems, parent, childElement, doCheck) {
for (let i = 0; i < childItems.length; i++) {
const checkedChild = childItems[parseInt(i.toString(), 10)][this.fields.id] ? childItems[parseInt(i.toString(), 10)][this.fields.id].toString() : '';
const isCheck = childItems[parseInt(i.toString(), 10)][this.fields.isChecked]
? childItems[parseInt(i.toString(), 10)][this.fields.isChecked].toString()
: null;
if (this.autoCheck) {
if (this.checkedNodes.indexOf(parent) !== -1 && this.checkedNodes.indexOf(checkedChild) === -1) {
this.checkDisabledState(checkedChild, childItems[i]);
if (this.parentNodeCheck.indexOf(checkedChild) !== -1) {
this.parentNodeCheck.splice(this.parentNodeCheck.indexOf(checkedChild), 1);
}
}
else if (this.checkedNodes.indexOf(parent) === -1 && this.checkedNodes.indexOf(checkedChild) !== -1 && !doCheck) {
this.checkedNodes.splice(this.checkedNodes.indexOf(checkedChild), 1);
if (isCheck === 'true') {
this.updateField(this.treeData, this.fields, checkedChild, 'isChecked', null);
}
}
}
else if (!this.autoCheck) {
if (!doCheck) {
if (this.checkedNodes.indexOf(checkedChild) !== -1) {
this.checkedNodes.splice(this.checkedNodes.indexOf(checkedChild), 1);
}
this.updateField(this.treeData, this.fields, checkedChild, 'isChecked', null);
this.checkedNodes = [];
}
else {
if (this.checkedNodes.indexOf(checkedChild) === -1) {
this.checkDisabledState(checkedChild, childItems[i]);
}
}
}
const subChild = this.getChildNodes([childItems[parseInt(i.toString(), 10)]], checkedChild);
if (subChild) {
this.childStateChange(subChild, parent, childElement, doCheck);
}
}
}
//This method can be used to get all child nodes of a parent by passing the children of a parent along with 'validateCheck' set to false
allCheckNode(child, newCheck, checked, childCheck, validateCheck) {
if (child) {
for (let length = 0; length < child.length; length++) {
const childId = getValue(this.fields.id, child[parseInt(length.toString(), 10)]);
const check = this.element.querySelector('[data-uid="' + childId + '"]');
//Validates isChecked case while no UI interaction has been performed on the node or it's parent
if (validateCheck !== false && this.checkedElement.indexOf(childId.toString()) === -1) {
if (((check === null && !isNullOrUndefined(child[parseInt(length.toString(), 10)][this.fields.isChecked]) &&
newCheck.indexOf(childId.toString()) === -1)
|| childCheck === 0 || checked === 2)) {
if (child[parseInt(length.toString(), 10)][this.fields.isChecked] !== false || checked === 2) {
newCheck.push(childId.toString());
}
else {
childCheck = null;
}
childCheck = (child[parseInt(length.toString(), 10)][this.fields.isChecked] !== false || checked === 2) ? 0 : null;
}
}
//Pushes child checked node done thro' UI interaction
if (newCheck.indexOf(childId.toString()) === -1 && isNullOrUndefined(checked)) {
newCheck.push(childId.toString());
}
const hierChildId = getValue(this.fields.child.toString(), child[parseInt(length.toString(), 10)]);
//Gets if any next level children are available for child nodes
if (getValue(this.fields.hasChildren, child[parseInt(length.toString(), 10)]) === true || hierChildId) {
const id = getValue(this.fields.id, child[parseInt(length.toString(), 10)]);
let childId;
if (this.dataType === 1) {
childId = this.getChildNodes(this.treeData, id.toString());
}
else {
childId = hierChildId;
}
if (childId) {
if (isNullOrUndefined(validateCheck)) {
this.allCheckNode(childId, newCheck, checked, childCheck);
}
else {
this.allCheckNode(childId, newCheck, checked, childCheck, validateCheck);
}
childCheck = null;
}
}
childCheck = null;
}
}
}
openNode(toBeOpened, e) {
const focusedNode = this.getFocusedNode();
const icon = select('div.' + ICON, focusedNode);
if (toBeOpened) {
if (!icon) {
return;
}
else if (icon.classList.contains(EXPANDABLE)) {
this.expandAction(focusedNode, icon, e);
}
else {
this.focusNextNode(focusedNode, true);
}
}
else {
if (icon && icon.classList.contains(COLLAPSIBLE)) {
this.collapseNode(focusedNode, icon, e);
}
else {
const parentLi = closest(closest(focusedNode, '.' + PARENTITEM), '.' + LISTITEM);
if (!parentLi) {
return;
}
else {
if (!parentLi.classList.contains('e-disable')) {
this.setFocus(focusedNode, parentLi);
this.navigateToFocus(true);
}
}
}
}
}
navigateNode(isTowards) {
const focusedNode = this.getFocusedNode();
this.focusNextNode(focusedNode, isTowards);
}
navigateRootNode(isBackwards) {
const focusedNode = this.getFocusedNode();
const rootNode = isBackwards ? this.getRootNode() : this.getEndNode();
if (!rootNode.classList.contains('e-disable')) {
this.setFocus(focusedNode, rootNode);
this.navigateToFocus(isBackwards);
}
}
getFocusedNode() {
let selectedItem;
const fNode = select('.' + LISTITEM + '[tabindex="0"]', this.element);
if (!isNullOrUndefined(fNode)) {
const ariaChecked = fNode.getAttribute('aria-checked');
if (ariaChecked === 'mixed' || ariaChecked === 'false') {
this.isFilter = false;
}
}
if (isNullOrUndefined(fNode)) {
selectedItem = select('.' + LISTITEM, this.element);
}
return isNullOrUndefined(fNode) ? (isNullOrUndefined(selectedItem) ? this.element.firstElementChild : selectedItem) : fNode;
}
focusNextNode(li, isTowards) {
const nextNode = isTowards ? this.getNextNode(li) : this.getPrevNode(li);
this.setFocus(li, nextNode);
this.navigateToFocus(!isTowards);
if (nextNode.classList.contains('e-disable')) {
const lastChild = nextNode.lastChild;
if (nextNode.previousSibling == null && nextNode.classList.contains('e-level-1')) {
this.focusNextNode(nextNode, true);
}
else if (nextNode.nextSibling == null && nextNode.classList.contains('e-node-collapsed')) {
this.focusNextNode(nextNode, false);
}
else if (nextNode.nextSibling == null && lastChild.classList.contains(TEXTWRAP)) {
this.focusNextNode(nextNode, false);
}
else {
this.focusNextNode(nextNode, isTowards);
}
}
}
getNextNode(li) {
let index = this.liList.indexOf(li);
let nextNode;
do {
index++;
nextNode = this.liList[parseInt(index.toString(), 10)];
if (isNullOrUndefined(nextNode)) {
return li;
}
} while (!isVisible(nextNode));
return nextNode;
}
getPrevNode(li) {
let index = this.liList.indexOf(li);
let prevNode;
do {
index--;
prevNode = this.liList[parseInt(index.toString(), 10)];
if (isNullOrUndefined(prevNode)) {
return li;
}
} while (!isVisible(prevNode));
return prevNode;
}
getRootNode() {
let index = 0;
let rootNode;
do {
rootNode = this.liList[parseInt(index.toString(), 10)];
index++;
} while (!isVisible(rootNode));
return rootNode;
}
getEndNode() {
let index = this.liList.length - 1;
let endNode;
do {
endNode = this.liList[parseInt(index.toString(), 10)];
index--;
} while (!isVisible(endNode));
return endNode;
}
setFocus(preNode, nextNode) {
removeClass([preNode], FOCUS);
preNode.setAttribute('tabindex', '-1');
if (!nextNode.classList.contains('e-disable')) {
addClass([nextNode], FOCUS);
nextNode.setAttribute('tabindex', '0');
nextNode.focus();
EventHandler.add(nextNode, 'blur', this.focusOut, this);
this.updateIdAttr(preNode, nextNode);
}
}
updateIdAttr(preNode, nextNode) {
this.element.removeAttribute('aria-activedescendant');
if (preNode) {
preNode.removeAttribute('id');
}
nextNode.setAttribute('id', this.element.id + '_active');
this.element.setAttribute('aria-activedescendant', this.element.id + '_active');
}
focusIn() {
if (!this.mouseDownStatus) {
const focusedElement = this.getFocusedNode();
if (focusedElement.classList.contains('e-disable')) {
focusedElement.setAttribute('tabindex', '-1');
this.navigateNode(true);
}
else {
focusedElement.setAttribute('tabindex', '0');
addClass([focusedElement], FOCUS);
EventHandler.add(focusedElement, 'blur', this.focusOut, this);
}
this.mouseDownStatus = false;
}
}
focusOut(event) {
const focusedElement = this.getFocusedNode();
if (event.target === focusedElement) {
removeClass([focusedElement], FOCUS);
EventHandler.remove(focusedElement, 'blur', this.focusOut);
}
}
onMouseOver(e) {
if (Browser.isDevice) {
return;
}
const target = e.target;
const classList = target.classList;
const currentLi = closest(target, '.' + LISTITEM);
if (!currentLi || classList.contains(PARENTITEM) || classList.contains(LISTITEM)) {
this.removeHover();
return;
}
else {
if (currentLi && !currentLi.classList.contains('e-disable')) {
this.setHover(currentLi);
}
}
}
setHover(li) {
if (!li.classList.contains(HOVER) && !li.classList.contains(PREVENTSELECT)) {
this.removeHover();
addClass([li], HOVER);
}
}
onMouseLeave() {
this.removeHover();
}
removeHover() {
const hoveredNode = selectAll('.' + HOVER, this.element);
if (hoveredNode && hoveredNode.length) {
removeClass(hoveredNode, HOVER);
}
}
getNodeData(currLi, fromDS, dragData) {
if (!isNullOrUndefined(currLi) && currLi.classList.contains(LISTITEM) &&
!isNullOrUndefined(closest(currLi, '.' + CONTROL)) && closest(currLi, '.' + CONTROL).classList.contains(ROOT)) {
const id = currLi.getAttribute('data-uid');
const text = this.getText(currLi, fromDS, dragData);
const pNode = closest(currLi.parentNode, '.' + LISTITEM);
const pid = pNode ? pNode.getAttribute('data-uid') : null;
const selected = currLi.classList.contains(ACTIVE);
const selectable = currLi.classList.contains(PREVENTSELECT) ? false : true;
const expanded = (currLi.getAttribute('aria-expanded') === 'true') ? true : false;
const hasChildren = currLi.getAttribute('aria-expanded') !== null ? true : (select('.' + EXPANDABLE, currLi) || select('.' + COLLAPSIBLE, currLi)) != null ? true : false;
let checked = null;
const checkboxElement = select('.' + CHECKBOXWRAP, currLi);
if (this.showCheckBox && checkboxElement) {
checked = currLi.getAttribute('aria-checked');
}
return {
id: id, text: text, parentID: pid, selected: selected, selectable: selectable, expanded: expanded,
isChecked: checked, hasChildren: hasChildren
};
}
return { id: '', text: '', parentID: '', selected: false, expanded: false, isChecked: '', hasChildren: false };
}
getText(currLi, fromDS, dragData) {
if (fromDS) {
const nodeData = !isNullOrUndefined(dragData) ? dragData : this.getNodeObject(currLi.getAttribute('data-uid'));
const level = parseFloat(currLi.getAttribute('aria-level'));
const nodeFields = this.getFields(this.fields, level, 1);
return !isNullOrUndefined(dragData) ? dragData.text : getValue(nodeFields.text, nodeData);
}
return select('.' + LISTTEXT, currLi).textContent;
}
getExpandEvent(currLi, e) {
const nodeData = this.getNodeData(currLi);
return { cancel: false, isInteracted: isNullOrUndefined(e) ? false : true, node: currLi, nodeData: nodeData, event: e };
}
renderNodeTemplate(data, textEle, dataId) {
let tempArr = this.nodeTemplateFn(data, this, 'nodeTemplate' + dataId, this.element.id + 'nodeTemplate', this.isStringTemplate, undefined, textEle, this.root);
if (tempArr) {
tempArr = Array.prototype.slice.call(tempArr);
append(tempArr, textEle);
}
}
destroyTemplate(liEle) {
this.clearTemplate(['nodeTemplate' + liEle.getAttribute('data-uid')]);
}
reRenderNodes() {
this.updateListProp(this.fields);
if (Browser.isIE) {
this.ulElement = this.element.querySelector('.e-list-parent.e-ul');
this.ulElement.parentElement.removeChild(this.ulElement);
}
else {
this.element.innerHTML = '';
}
if (!isNullOrUndefined(this.nodeTemplateFn)) {
this.clearTemplate();
}
this.setTouchClass();
this.setProperties({ selectedNodes: [], checkedNodes: [], expandedNodes: [] }, true);
this.checkedElement = [];
this.isLoaded = false;
this.setDataBinding(true);
}
setCssClass(oldClass, newClass) {
if (!isNullOrUndefined(oldClass) && oldClass !== '') {
removeClass([this.element], oldClass.split(' '));
}
if (!isNullOrUndefined(newClass) && newClass !== '') {
addClass([this.element], newClass.split(' '));
}
}
editingHandler(e) {
const target = e.target;
if (!target || target.classList.contains(ROOT) || target.classList.contains(PARENTITEM) ||
target.classList.contains(LISTITEM) || target.classList.contains(ICON) ||
target.classList.contains(INPUT) || target.classList.contains(INPUTGROUP)) {
return;
}
else {
const liEle = closest(target, '.' + LISTITEM);
this.createTextbox(liEle);
}
}
createTextbox(liEle) {
const oldInpEle = select('.' + TREEINPUT, this.element);
if (oldInpEle) {
oldInpEle.blur();
}
const textEle = select('.' + LISTTEXT, liEle);
this.updateOldText(liEle);
const innerEle = this.createElement('input', { className: TREEINPUT, attrs: { value: this.oldText } });
const eventArgs = this.getEditEvent(liEle, null, innerEle.outerHTML);
this.trigger('nodeEditing', eventArgs, (observedArgs) => {
if (!observedArgs.cancel) {
const inpWidth = textEle.offsetWidth + 5;
const widthSize = inpWidth + 'px';
addClass([liEle], EDITING);
if (!isNullOrUndefined(this.nodeTemplateFn)) {
this.destroyTemplate(liEle);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (this.isReact) {
setTimeout(() => {
this.renderTextBox(eventArgs, textEle, widthSize);
}, 5);
}
else {
this.renderTextBox(eventArgs, textEle, widthSize);
}
}
});
}
renderTextBox(eventArgs, textEle, widthSize) {
textEle.innerHTML = eventArgs.innerHtml;
const inpEle = select('.' + TREEINPUT, textEle);
this.inputObj = Input.createInput({
element: inpEle,
properties: {
enableRtl: this.enableRtl
}
}, this.createElement);
this.inputObj.container.style.width = widthSize;
inpEle.focus();
const inputEle = inpEle;
inputEle.setSelectionRange(0, inputEle.value.length);
this.wireInputEvents(inpEle);
}
updateOldText(liEle) {
const id = liEle.getAttribute('data-uid');
this.editData = this.getNodeObject(id);
const level = parseFloat(liEle.getAttribute('aria-level'));
this.editFields = this.getFields(this.fields, level, 1);
this.oldText = getValue(this.editFields.text, this.editData);
}
inputFocusOut(e) {
if (!select('.' + TREEINPUT, this.element)) {
return;
}
let target = e.target;
const newText = target.value;
const txtEle = closest(target, '.' + LISTTEXT);
const liEle = closest(target, '.' + LISTITEM);
detach(this.inputObj.container);
Input.destroy({ element: target, properties: this.properties });
if (this.fields.dataSource instanceof DataManager && !this.isOffline) {
this.crudOperation('update', null, liEle, newText, null, null, true);
}
else {
this.appendNewText(liEle, txtEle, newText, true);
}
EventHandler.remove(target, 'blur', this.inputFocusOut);
this.inputObj = null;
detach(target);
target = null;
}
appendNewText(liEle, txtEle, newText, isInput) {
const eventArgs = this.getEditEvent(liEle, newText, null);
this.trigger('nodeEdited', eventArgs, (observedArgs) => {
newText = observedArgs.cancel ? observedArgs.oldText : observedArgs.newText;
this.updateText(liEle, txtEle, newText, isInput);
if (observedArgs.oldText !== newText) {
this.triggerEvent('nodeEdited', [this.getNode(liEle)]);
}
});
}
updateText(liEle, txtEle, newText, isInput) {
const newData = setValue(this.editFields.text, newText, this.editData);
if (!isNullOrUndefined(this.nodeTemplateFn)) {
txtEle.innerText = '';
const dataId = liEle.getAttribute('data-uid');
this.renderNodeTemplate(newData, txtEle, dataId);
this.renderReactTemplates();
}
else {
if (this.enableHtmlSanitizer) {
txtEle.innerText = SanitizeHtmlHelper.sanitize(newText);
}
else {
txtEle.innerHTML = newText;
}
}
if (isInput) {
removeClass([liEle], EDITING);
liEle.focus();
EventHandler.add(liEle, 'blur', this.focusOut, this);
addClass([liEle], FOCUS);
}
if (this.allowTextWrap) {
this.calculateWrap(liEle);
}
}
getElement(ele) {
if (isNullOrUndefined(ele)) {
return null;
}
else if (typeof ele === 'string') {
return this.element.querySelector('[data-uid="' + ele + '"]');
}
else if (typeof ele === 'object') {
return getElement(ele);
}
else {
return null;
}
}
getId(ele) {
if (isNullOrUndefined(ele)) {
return null;
}
else if (typeof ele === 'string') {
return ele;
}
else if (typeof ele === 'object') {
return (getElement(ele)).getAttribute('data-uid');
}
else {
return null;
}
}
getEditEvent(liEle, newText, inpEle) {
const data = this.getNodeData(liEle);
return { cancel: false, newText: newText, node: liEle, nodeData: data, oldText: this.oldText, innerHtml: inpEle };
}
getNodeObject(id) {
let childNodes;
if (isNullOrUndefined(id)) {
return childNodes;
}
else if (this.dataType === 1) {
for (let i = 0, objlen = this.treeData.length; i < objlen; i++) {
const dataId = getValue(this.fields.id, this.treeData[parseInt(i.toString(), 10)]);
if (!isNullOrUndefined(this.treeData[parseInt(i.toString(), 10)]) && !isNullOrUndefined(dataId) && dataId.toString() === id) {
return this.treeData[parseInt(i.toString(), 10)];
}
}
}
else {
return this.getChildNodeObject(this.treeData, this.fields, id);
}
return childNodes;
}
getChildNodeObject(obj, mapper, id) {
let newList;
if (isNullOrUndefined(obj)) {
return newList;
}
for (let i = 0, objlen = obj.length; i < objlen; i++) {
const dataId = getValue(mapper.id, obj[parseInt(i.toString(), 10)]);
if (obj[parseInt(i.toString(), 10)] && dataId && dataId.toString() === id) {
return obj[parseInt(i.toString(), 10)];
}
else if (typeof mapper.child === 'string' && !isNullOrUndefined(getValue(mapper.child, obj[parseInt(i.toString(), 10)]))) {
const childData = getValue(mapper.child, obj[parseInt(i.toString(), 10)]);
newList = this.getChildNodeObject(childData, this.getChildMapper(mapper), id);
if (newList !== undefined) {
break;
}
}
else if (this.fields.dataSource instanceof DataManager && !isNullOrUndefined(getValue('child', obj[parseInt(i.toString(), 10)]))) {
const child = 'child';
newList = this.getChildNodeObject(getValue(child, obj[parseInt(i.toString(), 10)]), this.getChildMapper(mapper), id);
if (newList !== undefined) {
break;
}
}
else if (this.isChildObject()) {
const children = 'child';
const childData = getValue(children, obj[parseInt(i.toString(), 10)]);
newList = this.getChildNodeObject(childData, this.getChildMapper(mapper), id);
if (newList !== undefined) {
break;
}
}
}
return newList;
}
setDragAndDrop(toBind) {
if (toBind && !this.disabled) {
this.initializeDrag();
}
else {
this.destroyDrag();
}
}
initializeDrag() {
let virtualEle;
this.dragObj = new Draggable(this.element, {
enableTailMode: true, enableAutoScroll: true,
dragArea: this.dragArea,
dragTarget: '.' + TEXTWRAP,
enableTapHold: true,
tapHoldThreshold: 100,
helper: (e) => {
this.dragTarget = e.sender.target;
const dragRoot = closest(this.dragTarget, '.' + ROOT);
let dragWrap = closest(this.dragTarget, '.' + TEXTWRAP);
this.dragLi = closest(this.dragTarget, '.' + LISTITEM);
if (this.fullRowSelect && !dragWrap && this.dragTarget.classList.contains(FULLROW)) {
dragWrap = this.dragTarget.nextElementSibling;
}
if (!this.dragTarget || !e.element.isSameNode(dragRoot) || !dragWrap ||
this.dragTarget.classList.contains(ROOT) || this.dragTarget.classList.contains(PARENTITEM) ||
this.dragTarget.classList.contains(LISTITEM) || this.dragLi.classList.contains('e-disable')) {
return false;
}
const cloneEle = (dragWrap.cloneNode(true));
if (isNullOrUndefined(select('div.' + ICON, cloneEle))) {
const icon = this.createElement('div', { className: ICON + ' ' + EXPANDABLE });
cloneEle.insertBefore(icon, cloneEle.children[0]);
}
const cssClass = DRAGITEM + ' ' + ROOT + ' ' + this.cssClass + ' ' + (this.enableRtl ? RTL$1 : '');
virtualEle = this.createElement('div', { className: cssClass });
virtualEle.appendChild(cloneEle);
const nLen = this.selectedNodes.length;
if (nLen > 1 && this.allowMultiSelection && this.dragLi.classList.contains(ACTIVE)) {
const cNode = this.createElement('span', { className: DROPCOUNT, innerHTML: '' + nLen });
virtualEle.appendChild(cNode);
}
document.body.appendChild(virtualEle);
document.body.style.cursor = '';
this.dragData = this.getNodeData(this.dragLi);
return virtualEle;
},
dragStart: (e) => {
addClass([this.element], DRAGGING);
const listItem = closest(e.target, '.e-list-item');
let level;
if (listItem) {
level = parseInt(listItem.getAttribute('aria-level'), 10);
}
const eventArgs = this.getDragEvent(e.event, this, null, e.target, null, virtualEle, level);
if (eventArgs.draggedNode.classList.contains(EDITING)) {
this.dragObj.intDestroy(e.event);
this.dragCancelAction(virtualEle);
}
else {
this.trigger('nodeDragStart', eventArgs, (observedArgs) => {
if (observedArgs.cancel) {
this.dragObj.intDestroy(e.event);
this.dragCancelAction(virtualEle);
}
else {
this.dragStartAction = true;
}
});
}
},
drag: (e) => {
this.dragObj.setProperties({ cursorAt: { top: (!isNullOrUndefined(e.event.targetTouches) || Browser.isDevice) ? 60 : -20 } });
this.dragAction(e, virtualEle);
},
dragStop: (e) => {
if (!e.target) {
if (e.helper && e.helper.parentNode) {
detach(e.helper);
}
document.body.style.cursor = '';
removeClass([this.element], DRAGGING);
this.dragStartAction = false;
return;
}
removeClass([this.element], DRAGGING);
if (!e.target.classList.contains('e-sibling')) {
this.removeVirtualEle();
}
const dropTarget = e.target;
const preventTargetExpand = false;
const dropRoot = (closest(dropTarget, '.' + DROPPABLE));
if (!dropTarget || !dropRoot) {
detach(e.helper);
document.body.style.cursor = '';
}
const listItem = closest(dropTarget, '.e-list-item');
let level;
if (listItem) {
level = parseInt(listItem.getAttribute('aria-level'), 10);
}
const eventArgs = this.getDragEvent(e.event, this, dropTarget, dropTarget, null, e.helper, level);
eventArgs.preventTargetExpand = preventTargetExpand;
this.trigger('nodeDragStop', eventArgs, (observedArgs) => {
this.dragParent = observedArgs.draggedParentNode;
this.preventExpand = observedArgs.preventTargetExpand;
if (observedArgs.cancel) {
if (e.helper.parentNode) {
detach(e.helper);
}
document.body.style.cursor = '';
if (dropTarget.classList.contains('e-sibling')) {
this.removeVirtualEle();
}
}
this.dragStartAction = false;
});
}
});
this.dropObj = new Droppable(this.element, {
out: (e) => {
if (!e.target) {
return;
}
if (!isNullOrUndefined(e) && !e.target.classList.contains(SIBLING) &&
(this.dropObj.dragData.default && this.dropObj.dragData.default.helper.classList.contains(ROOT))) {
document.body.style.cursor = 'not-allowed';
}
},
over: () => {
document.body.style.cursor = '';
},
drop: (e) => {
this.dropAction(e);
this.removeVirtualEle();
}
});
}
dragCancelAction(virtualEle) {
detach(virtualEle);
removeClass([this.element], DRAGGING);
this.dragStartAction = false;
}
getOffsetX(event, target) {
const touchList = event.changedTouches;
if (touchList && touchList.length > 0) {
return touchList[0].clientX - target.getBoundingClientRect().left;
}
else {
return event.offsetX;
}
}
getOffsetY(event, target) {
const touchList = event.changedTouches;
if (touchList && touchList.length > 0) {
return touchList[0].clientY - target.getBoundingClientRect().top;
}
else {
return event.offsetY;
}
}
dragAction(e, virtualEle) {
if (!e.target) {
return;
}
const dropRoot = closest(e.target, '.' + DROPPABLE);
let dropWrap = closest(e.target, '.' + TEXTWRAP);
const icon = select('div.' + ICON, virtualEle);
removeClass([icon], [DROPIN, DROPNEXT, DROPOUT, NODROP]);
this.isDropIn = false;
this.removeVirtualEle();
document.body.style.cursor = '';
const classList = e.target.classList;
const event = e.event;
const offsetY = this.getOffsetY(event, e.target);
const offsetX = this.getOffsetX(event, e.target);
if (this.fullRowSelect && !dropWrap && !isNullOrUndefined(classList) && classList.contains(FULLROW)) {
dropWrap = e.target.nextElementSibling;
}
if (dropRoot) {
const dropLi = closest(e.target, '.' + LISTITEM);
const checkWrapper = closest(e.target, '.' + CHECKBOXWRAP);
const collapse = closest(e.target, '.' + COLLAPSIBLE);
const expand = closest(e.target, '.' + EXPANDABLE);
if (!dropRoot.classList.contains(ROOT) || (dropWrap &&
(!dropLi.isSameNode(this.dragLi) && !this.isDescendant(this.dragLi, dropLi)))) {
if (this.hasTemplate && dropLi) {
const templateTarget = select(this.fullRowSelect ? '.' + FULLROW : '.' + TEXTWRAP, dropLi);
if ((e && (!expand && !collapse) && offsetY < 7 && !checkWrapper) ||
(((expand && offsetY < 5) || (collapse && offsetX < 3)))) {
const index = this.fullRowSelect ? (1) : (0);
this.appendIndicator(dropLi, icon, index);
}
else if ((e && (!expand && !collapse) &&
!checkWrapper && templateTarget && offsetY > templateTarget.offsetHeight - 10) ||
((expand && offsetY > 19) || (collapse && offsetX > 19))) {
const index = this.fullRowSelect ? (2) : (1);
this.appendIndicator(dropLi, icon, index);
}
else {
addClass([icon], DROPIN);
this.isDropIn = true;
}
}
else {
if ((dropLi && e && (!expand && !collapse) && (offsetY < 7) && !checkWrapper) ||
(((expand && offsetY < 5) || (collapse && offsetX < 3)))) {
const index = this.fullRowSelect ? (1) : (0);
this.appendIndicator(dropLi, icon, index);
}
else if ((dropLi && e && (!expand && !collapse) &&
(e.target.offsetHeight > 0 && offsetY > (e.target.offsetHeight - 10)) && !checkWrapper) ||
(((expand && offsetY > 19) || (collapse && offsetX > 19)))) {
const index = this.fullRowSelect ? (2) : (1);
this.appendIndicator(dropLi, icon, index);
}
else {
addClass([icon], DROPIN);
this.isDropIn = true;
}
}
}
else if (e.target.nodeName === 'LI' && (!dropLi.isSameNode(this.dragLi) && !this.isDescendant(this.dragLi, dropLi))) {
addClass([icon], DROPNEXT);
this.renderVirtualEle(e);
}
else if (e.target.classList.contains(SIBLING)) {
addClass([icon], DROPNEXT);
}
else {
addClass([icon], DROPOUT);
}
}
else {
addClass([icon], NODROP);
document.body.style.cursor = 'not-allowed';
}
const listItem = closest(e.target, '.e-list-item');
let level;
if (listItem) {
level = parseInt(listItem.getAttribute('aria-level'), 10);
}
const eventArgs = this.getDragEvent(e.event, this, e.target, e.target, null, virtualEle, level);
if (eventArgs.dropIndicator) {
removeClass([icon], eventArgs.dropIndicator);
}
this.trigger('nodeDragging', eventArgs);
if (eventArgs.dropIndicator) {
addClass([icon], eventArgs.dropIndicator);
}
}
appendIndicator(dropLi, icon, index) {
addClass([icon], DROPNEXT);
const virEle = this.createElement('div', { className: SIBLING });
dropLi.insertBefore(virEle, dropLi.children[parseInt(index.toString(), 10)]);
}
dropAction(e) {
const event = e.event;
const offsetY = this.getOffsetY(event, e.target);
const dropTarget = e.target;
let dragObj;
let level;
let drop = false;
const nodeData = [];
let liArray = [];
const dragInstance = e.dragData.draggable;
for (let i = 0; i < dragInstance.ej2_instances.length; i++) {
if (dragInstance.ej2_instances[parseInt(i.toString(), 10)] instanceof TreeView_1) {
dragObj = dragInstance.ej2_instances[parseInt(i.toString(), 10)];
break;
}
}
if (dragObj && dragObj.dragTarget) {
const dragTarget = dragObj.dragTarget;
const dragLi = (closest(dragTarget, '.' + LISTITEM));
let dropLi = (closest(dropTarget, '.' + LISTITEM));
liArray.push(dragLi);
if (dropLi == null && dropTarget.classList.contains(ROOT)) {
dropLi = dropTarget.firstElementChild;
}
detach(e.droppedElement);
document.body.style.cursor = '';
if (!dropLi || dropLi.isSameNode(dragLi) || this.isDescendant(dragLi, dropLi)) {
if (this.fields.dataSource instanceof DataManager === false) {
this.preventExpand = false;
}
return;
}
if (dragObj.allowMultiSelection && dragLi.classList.contains(ACTIVE)) {
const sNodes = selectAll('.' + ACTIVE, dragObj.element);
liArray = sNodes;
if (e.target.offsetHeight <= 33 && offsetY > e.target.offsetHeight - 10 && offsetY > 6) {
for (let i = sNodes.length - 1; i >= 0; i--) {
if (dropLi.isSameNode(sNodes[parseInt(i.toString(), 10)]) ||
this.isDescendant(sNodes[parseInt(i.toString(), 10)], dropLi)) {
continue;
}
this.appendNode(dropTarget, sNodes[parseInt(i.toString(), 10)], dropLi, e, dragObj, offsetY);
}
}
else {
for (let i = 0; i < sNodes.length; i++) {
if (dropLi.isSameNode(sNodes[parseInt(i.toString(), 10)]) ||
this.isDescendant(sNodes[parseInt(i.toString(), 10)], dropLi)) {
continue;
}
this.appendNode(dropTarget, sNodes[parseInt(i.toString(), 10)], dropLi, e, dragObj, offsetY);
}
}
}
else {
this.appendNode(dropTarget, dragLi, dropLi, e, dragObj, offsetY);
}
level = parseInt(dragLi.getAttribute('aria-level'), 10);
drop = true;
}
if (this.fields.dataSource instanceof DataManager === false) {
this.preventExpand = false;
}
const dragData = isNullOrUndefined(dragObj) ? null : dragObj.dragData;
for (let i = 0; i < liArray.length; i++) {
nodeData.push(this.getNodeData(this.getElement(liArray[parseInt(i.toString(), 10)]), true, dragData));
}
this.trigger('nodeDropped', this.getDragEvent(e.event, dragObj, dropTarget, e.target, e.dragData.draggedElement, null, level, drop));
if (dragObj.element.id !== this.element.id) {
dragObj.triggerEvent('nodeDropped', nodeData);
this.isNodeDropped = true;
this.fields.dataSource = this.treeData;
}
this.triggerEvent('nodeDropped', nodeData);
}
appendNode(dropTarget, dragLi, dropLi, e, dragObj, offsetY) {
const checkWrapper = closest(dropTarget, '.' + CHECKBOXWRAP);
const collapse = closest(e.target, '.' + COLLAPSIBLE);
const expand = closest(e.target, '.' + EXPANDABLE);
if (!dragLi.classList.contains('e-disable') && !checkWrapper && ((expand && e.event.offsetY < 5) || (collapse && e.event.offsetX < 3) || (expand && e.event.offsetY > 19) || (collapse && e.event.offsetX > 19) || (!expand && !collapse))) {
if (dropTarget.nodeName === 'LI') {
this.dropAsSiblingNode(dragLi, dropLi, e, dragObj);
}
else if (dropTarget.firstElementChild && dropTarget.classList.contains(ROOT)) {
if (dropTarget.firstElementChild.nodeName === 'UL') {
this.dropAsSiblingNode(dragLi, dropLi, e, dragObj);
}
}
else if ((dropTarget.classList.contains('e-icon-collapsible')) || (dropTarget.classList.contains('e-icon-expandable'))) {
this.dropAsSiblingNode(dragLi, dropLi, e, dragObj);
}
else {
this.dropAsChildNode(dragLi, dropLi, dragObj, null, e, offsetY, null, dropTarget);
}
}
else {
this.dropAsChildNode(dragLi, dropLi, dragObj, null, e, offsetY, true, dropTarget);
}
if (this.showCheckBox) {
this.ensureIndeterminate();
}
}
dropAsSiblingNode(dragLi, dropLi, e, dragObj) {
const dropUl = closest(dropLi, '.' + PARENTITEM);
const dragParentUl = closest(dragLi, '.' + PARENTITEM);
const dragParentLi = closest(dragParentUl, '.' + LISTITEM);
let pre;
if (e.target.offsetHeight > 0 && e.event.offsetY > e.target.offsetHeight - 2) {
pre = false;
}
else if (e.event.offsetY < 2) {
pre = true;
}
else if (e.target.classList.contains('e-icon-expandable') || (e.target.classList.contains('e-icon-collapsible'))) {
if ((e.event.offsetY < 5) || (e.event.offsetX < 3)) {
pre = true;
}
else if ((e.event.offsetY > 15) || (e.event.offsetX > 17)) {
pre = false;
}
}
if ((e.target.classList.contains('e-icon-expandable')) || (e.target.classList.contains('e-icon-collapsible'))) {
const target = e.target.closest('li');
dropUl.insertBefore(dragLi, pre ? target : target.nextElementSibling);
}
else {
dropUl.insertBefore(dragLi, pre ? e.target : e.target.nextElementSibling);
}
this.moveData(dragLi, dropLi, dropUl, pre, dragObj);
this.updateElement(dragParentUl, dragParentLi);
this.updateAriaLevel(dragLi);
if (dragObj.element.id === this.element.id) {
this.updateList();
}
else {
dragObj.updateInstance();
this.updateInstance();
}
}
dropAsChildNode(dragLi, dropLi, dragObj, index, e, pos, isCheck, dropTarget) {
const dragParentUl = closest(dragLi, '.' + PARENTITEM);
const dragParentLi = closest(dragParentUl, '.' + LISTITEM);
const dropParentUl = closest(dropLi, '.' + PARENTITEM);
let templateTarget;
if (e && e.target) {
templateTarget = select(this.fullRowSelect ? '.' + FULLROW : '.' + TEXTWRAP, dropLi);
}
if (e && ((pos < 7 && !dropTarget.classList.contains('e-sibling')) || (dropTarget.classList.contains('e-sibling') && !dropLi.lastChild.classList.contains('e-sibling'))) && !isCheck) {
dropParentUl.insertBefore(dragLi, dropLi);
this.moveData(dragLi, dropLi, dropParentUl, true, dragObj);
}
else if (e && (e.target.offsetHeight > 0 && pos > (e.target.offsetHeight - 10)) && !isCheck && !this.hasTemplate) {
dropParentUl.insertBefore(dragLi, dropLi.nextElementSibling);
this.moveData(dragLi, dropLi, dropParentUl, false, dragObj);
}
else if (this.hasTemplate && templateTarget && pos > templateTarget.offsetHeight - 10 && !isCheck) {
dropParentUl.insertBefore(dragLi, dropLi.nextElementSibling);
this.moveData(dragLi, dropLi, dropParentUl, false, dragObj);
}
else {
const dropUl = this.expandParent(dropLi);
const childLi = !isNullOrUndefined(index) ? dropUl.childNodes[parseInt(index.toString(), 10)] : null;
dropUl.insertBefore(dragLi, childLi);
this.moveData(dragLi, childLi, dropUl, true, dragObj);
}
this.updateElement(dragParentUl, dragParentLi);
this.updateAriaLevel(dragLi);
if (dragObj.element.id === this.element.id) {
this.updateList();
}
else {
dragObj.updateInstance();
this.updateInstance();
}
}
moveData(dragLi, dropLi, dropUl, pre, dragObj) {
const dropParentLi = closest(dropUl, '.' + LISTITEM);
const id = this.getId(dragLi);
const removedData = dragObj.updateChildField(dragObj.treeData, dragObj.fields, id, null, null, true);
const refId = this.getId(dropLi);
const index = refId ? this.getDataPos(this.treeData, this.fields, refId) : null;
const parentId = this.getId(dropParentLi);
if (this.dataType === 1) {
this.updateField(this.treeData, this.fields, parentId, 'hasChildren', true);
let pos = isNullOrUndefined(index) ? this.treeData.length : (pre ? index : index + 1);
if (isNullOrUndefined(parentId) && !this.hasPid) {
delete removedData[0][this.fields.parentID];
}
else {
const currPid = this.isNumberTypeId ? parseFloat(parentId) : parentId;
setValue(this.fields.parentID, currPid, removedData[0]);
}
this.treeData.splice(pos, 0, removedData[0]);
if (dragObj.element.id !== this.element.id) {
const childData = dragObj.removeChildNodes(id);
pos++;
for (let i = 0, len = childData.length; i < len; i++) {
this.treeData.splice(pos, 0, childData[parseInt(i.toString(), 10)]);
pos++;
}
dragObj.groupedData = dragObj.getGroupedData(dragObj.treeData, dragObj.fields.parentID);
}
this.groupedData = this.getGroupedData(this.treeData, this.fields.parentID);
}
else {
this.addChildData(this.treeData, this.fields, parentId, removedData, pre ? index : index + 1);
}
}
expandParent(dropLi) {
const dropIcon = select('div.' + EXPANDABLE + ', div.' + COLLAPSIBLE, dropLi);
if (dropIcon && dropIcon.classList.contains(EXPANDABLE) && this.preventExpand !== true) {
this.expandAction(dropLi, dropIcon, null);
}
let dropUl = select('.' + PARENTITEM, dropLi);
if (this.preventExpand === true && !dropUl && dropIcon) {
this.renderChildNodes(dropLi);
}
dropUl = select('.' + PARENTITEM, dropLi);
if (!isNullOrUndefined(dropUl) && (this.preventExpand && !(dropLi.getAttribute('aria-expanded') === 'true'))) {
dropUl.style.display = 'none';
}
if (!isNullOrUndefined(dropUl) && this.preventExpand === false) {
dropUl.style.display = 'block';
}
if (isNullOrUndefined(dropUl) && this.preventExpand === true) {
if (isNullOrUndefined(dropIcon)) {
ListBase.generateIcon(this.createElement, dropLi, EXPANDABLE, this.listBaseOption);
}
const icon = select('div.' + EXPANDABLE + ', div.' + COLLAPSIBLE, dropLi);
if (icon) {
icon.classList.add('e-icon-expandable');
}
dropUl = ListBase.generateUL(this.createElement, [], null, this.listBaseOption);
dropLi.appendChild(dropUl);
if (icon) {
removeClass([icon], COLLAPSIBLE);
}
else {
ListBase.generateIcon(this.createElement, dropLi, EXPANDABLE, this.listBaseOption);
}
dropLi.setAttribute('aria-expanded', 'false');
dropUl.style.display = 'none';
}
if (isNullOrUndefined(dropUl)) {
const args = this.expandArgs;
if (isNullOrUndefined(args) || (args && args.name !== 'nodeExpanding')) {
this.trigger('nodeExpanding', this.getExpandEvent(dropLi, null));
}
if (isNullOrUndefined(dropIcon)) {
ListBase.generateIcon(this.createElement, dropLi, COLLAPSIBLE, this.listBaseOption);
}
let icon = select('div.' + EXPANDABLE + ', div.' + COLLAPSIBLE, dropLi);
if (icon) {
removeClass([icon], EXPANDABLE);
}
else {
ListBase.generateIcon(this.createElement, dropLi, COLLAPSIBLE, this.listBaseOption);
icon = select('div.' + ICON, dropLi);
removeClass([icon], EXPANDABLE);
}
dropUl = ListBase.generateUL(this.createElement, [], null, this.listBaseOption);
dropLi.appendChild(dropUl);
this.addExpand(dropLi);
this.trigger('nodeExpanded', this.getExpandEvent(dropLi, null));
}
const collapseIcon = select('div.' + COLLAPSIBLE, dropLi);
if (!isNullOrUndefined(dropUl) && collapseIcon && (this.preventExpand && !(dropLi.getAttribute('aria-expanded') === 'true'))) {
removeClass([collapseIcon], COLLAPSIBLE);
dropLi.setAttribute('aria-expanded', 'false');
addClass([collapseIcon], EXPANDABLE);
}
return dropUl;
}
updateElement(dragParentUl, dragParentLi) {
if (dragParentLi && dragParentUl.childElementCount === 0) {
const dragIcon = select('div.' + ICON, dragParentLi);
detach(dragParentUl);
detach(dragIcon);
const parentId = this.getId(dragParentLi);
this.updateField(this.treeData, this.fields, parentId, 'hasChildren', false);
this.removeExpand(dragParentLi, true);
}
}
updateAriaLevel(dragLi) {
const level = this.parents(dragLi, '.' + PARENTITEM).length;
dragLi.setAttribute('aria-level', '' + level);
this.updateChildAriaLevel(select('.' + PARENTITEM, dragLi), level + 1);
}
updateChildAriaLevel(element, level) {
if (!isNullOrUndefined(element)) {
const cNodes = element.childNodes;
for (let i = 0, len = cNodes.length; i < len; i++) {
const liEle = cNodes[parseInt(i.toString(), 10)];
liEle.setAttribute('aria-level', '' + level);
this.updateChildAriaLevel(select('.' + PARENTITEM, liEle), level + 1);
}
}
}
renderVirtualEle(e) {
let pre;
const event = e.event;
const offsetY = this.getOffsetY(event, e.target);
if (offsetY > e.target.offsetHeight - 2) {
pre = false;
}
else if (offsetY < 2) {
pre = true;
}
const virEle = this.createElement('div', { className: SIBLING });
const index = this.fullRowSelect ? (pre ? 1 : 2) : (pre ? 0 : 1);
e.target.insertBefore(virEle, e.target.children[parseInt(index.toString(), 10)]);
}
removeVirtualEle() {
const sibEle = select('.' + SIBLING);
if (sibEle) {
detach(sibEle);
}
}
destroyDrag() {
if (this.dragObj && this.dropObj) {
this.dragObj.destroy();
this.dropObj.destroy();
}
}
getDragEvent(event, obj, dropTarget, target, dragNode, cloneEle, level, drop) {
const dropLi = dropTarget ? closest(dropTarget, '.' + LISTITEM) : null;
const dropData = dropLi ? this.getNodeData(dropLi) : null;
const draggedNode = obj ? obj.dragLi : dragNode;
const draggedNodeData = obj ? obj.dragData : null;
const newParent = dropTarget ? this.parents(dropTarget, '.' + LISTITEM) : null;
const dragLiParent = obj.dragLi.parentElement;
let dragParent = obj.dragLi ? closest(dragLiParent, '.' + LISTITEM) : null;
let targetParent = null;
let indexValue = null;
const iconCss = [DROPNEXT, DROPIN, DROPOUT, NODROP];
let iconClass = null;
const node = (drop === true) ? draggedNode : dropLi;
const index = node ? closest(node, '.e-list-parent') : null;
let i = 0;
let position = null;
dragParent = (obj.dragLi && dragParent === null) ? closest(dragLiParent, '.' + ROOT) : dragParent;
dragParent = (drop === true) ? this.dragParent : dragParent;
if (cloneEle) {
while (i < 4) {
if (select('.' + ICON, cloneEle).classList.contains(iconCss[parseInt(i.toString(), 10)])) {
iconClass = iconCss[parseInt(i.toString(), 10)];
break;
}
i++;
}
}
if (index) {
let dropTar = 0;
for (i = 0; i < index.childElementCount; i++) {
dropTar = (drop !== true && index.children[parseInt(i.toString(), 10)] === draggedNode && dropLi !== draggedNode)
? ++dropTar
: dropTar;
if ((drop !== true && index.children[parseInt(i.toString(), 10)].classList.contains('e-hover'))) {
indexValue = (event.offsetY >= 23) ? i + 1 : i;
break;
}
else if (index.children[parseInt(i.toString(), 10)] === node) {
indexValue = (event.offsetY >= 23) ? i : i;
break;
}
}
indexValue = (dropTar !== 0) ? --indexValue : indexValue;
position = this.isDropIn ? 'Inside' : ((event.offsetY < 7) ? 'Before' : 'After');
}
if (dropTarget) {
if (newParent.length === 0) {
targetParent = null;
}
else if (dropTarget.classList.contains(LISTITEM)) {
targetParent = newParent[0];
}
else {
targetParent = newParent[1];
}
}
if (dropLi === draggedNode) {
targetParent = dropLi;
}
if (dropTarget && target.offsetHeight <= 33 && event.offsetY < target.offsetHeight - 10 && event.offsetY > 6) {
targetParent = dropLi;
if (drop !== true) {
level = ++level;
const parent = targetParent ? select('.e-list-parent', targetParent) : null;
indexValue = (parent) ? parent.children.length : 0;
if (!(this.fields.dataSource instanceof DataManager) && parent === null && targetParent) {
const parent = targetParent.hasAttribute('data-uid') ?
this.getChildNodes(this.fields.dataSource, targetParent.getAttribute('data-uid').toString()) : null;
indexValue = (parent) ? parent.length : 0;
}
}
}
return {
cancel: false,
clonedNode: cloneEle,
event: event,
draggedNode: draggedNode,
draggedNodeData: draggedNodeData,
droppedNode: dropLi,
droppedNodeData: dropData,
dropIndex: indexValue,
dropLevel: level,
draggedParentNode: dragParent,
dropTarget: targetParent,
dropIndicator: iconClass,
target: target,
position: position
};
}
addFullRow(toAdd) {
const len = this.liList.length;
if (toAdd) {
for (let i = 0; i < len; i++) {
this.createFullRow(this.liList[parseInt(i.toString(), 10)]);
}
}
else {
for (let i = 0; i < len; i++) {
const rowDiv = select('.' + FULLROW, this.liList[parseInt(i.toString(), 10)]);
detach(rowDiv);
}
}
}
createFullRow(item) {
const rowDiv = this.createElement('div', { className: FULLROW });
item.insertBefore(rowDiv, item.childNodes[0]);
}
addMultiSelect(toAdd) {
if (toAdd) {
const liEles = selectAll('.' + LISTITEM + ':not([aria-selected="true"])', this.element);
for (const ele of liEles) {
ele.setAttribute('aria-selected', 'false');
}
}
else {
const liEles = selectAll('.' + LISTITEM + '[aria-selected="false"]', this.element);
for (const ele of liEles) {
ele.removeAttribute('aria-selected');
}
}
}
collapseByLevel(element, level, excludeHiddenNodes, currentLevel) {
currentLevel = isNullOrUndefined(currentLevel) ? 1 : currentLevel;
if (level > 0 && !isNullOrUndefined(element)) {
const cNodes = this.getVisibleNodes(excludeHiddenNodes, element.childNodes);
for (let i = 0, len = cNodes.length; i < len; i++) {
const liEle = cNodes[parseInt(i.toString(), 10)];
const icon = select('.' + COLLAPSIBLE, select('.' + TEXTWRAP, liEle));
if (currentLevel >= level && !isNullOrUndefined(icon)) {
this.collapseNode(liEle, icon, null);
}
this.collapseByLevel(select('.' + PARENTITEM, liEle), level, excludeHiddenNodes, currentLevel + 1);
}
}
}
collapseAllNodes(excludeHiddenNodes) {
const cIcons = this.getVisibleNodes(excludeHiddenNodes, selectAll('.' + COLLAPSIBLE, this.element));
for (let i = 0, len = cIcons.length; i < len; i++) {
const icon = cIcons[parseInt(i.toString(), 10)];
const liEle = closest(icon, '.' + LISTITEM);
this.collapseNode(liEle, icon, null);
}
}
expandByLevel(element, level, excludeHiddenNodes) {
if (level > 0 && !isNullOrUndefined(element)) {
const eNodes = this.getVisibleNodes(excludeHiddenNodes, element.childNodes);
for (let i = 0, len = eNodes.length; i < len; i++) {
const liEle = eNodes[parseInt(i.toString(), 10)];
const icon = select('.' + EXPANDABLE, select('.' + TEXTWRAP, liEle));
if (!isNullOrUndefined(icon)) {
this.expandAction(liEle, icon, null);
}
this.expandByLevel(select('.' + PARENTITEM, liEle), level - 1, excludeHiddenNodes);
}
}
}
expandAllNodes(excludeHiddenNodes) {
const eIcons = this.getVisibleNodes(excludeHiddenNodes, selectAll('.' + EXPANDABLE, this.element));
for (const icon of eIcons) {
const liEle = closest(icon, '.' + LISTITEM);
this.expandAction(liEle, icon, null, true, null, true);
}
}
getVisibleNodes(excludeHiddenNodes, nodes) {
const vNodes = Array.prototype.slice.call(nodes);
if (excludeHiddenNodes) {
for (let i = 0; i < vNodes.length; i++) {
if (!isVisible(vNodes[parseInt(i.toString(), 10)])) {
vNodes.splice(i, 1);
i--;
}
}
}
return vNodes;
}
removeNode(node) {
const dragParentUl = closest(node, '.' + PARENTITEM);
const dragParentLi = closest(dragParentUl, '.' + LISTITEM);
if (!isNullOrUndefined(this.nodeTemplateFn)) {
this.destroyTemplate(node);
}
detach(node);
this.updateElement(dragParentUl, dragParentLi);
this.removeData(node);
}
updateInstance() {
this.updateList();
this.updateSelectedNodes();
this.updateExpandedNodes();
}
updateList() {
this.liList = Array.prototype.slice.call(selectAll('.' + LISTITEM, this.element));
}
updateSelectedNodes() {
this.setProperties({ selectedNodes: [] }, true);
const sNodes = selectAll('.' + ACTIVE, this.element);
this.selectGivenNodes(sNodes);
}
updateExpandedNodes() {
this.setProperties({ expandedNodes: [] }, true);
const eNodes = selectAll('[aria-expanded="true"]', this.element);
for (let i = 0, len = eNodes.length; i < len; i++) {
this.addExpand(eNodes[parseInt(i.toString(), 10)]);
}
}
removeData(node) {
if (this.dataType === 1) {
const dm = new DataManager(this.treeData);
const id = this.getId(node);
const data = {};
const newId = this.isNumberTypeId ? parseFloat(id) : id;
data[this.fields.id] = newId;
dm.remove(this.fields.id, data);
this.removeChildNodes(id);
}
else {
const id = this.getId(node);
this.updateChildField(this.treeData, this.fields, id, null, null, true);
}
}
removeChildNodes(parentId) {
const cNodes = this.getChildGroup(this.groupedData, parentId, false);
const childData = [];
for (let i = 0, len = cNodes.length; i < len; i++) {
const dm = new DataManager(this.treeData);
const id = getValue(this.fields.id, cNodes[parseInt(i.toString(), 10)]).toString();
const data = {};
const currId = this.isNumberTypeId ? parseFloat(id) : id;
data[this.fields.id] = currId;
const nodeData = dm.remove(this.fields.id, data);
childData.push(nodeData[0]);
this.removeChildNodes(id);
}
return childData;
}
doGivenAction(nodes, selector, toExpand) {
for (let i = 0, len = nodes.length; i < len; i++) {
const liEle = this.getElement(nodes[parseInt(i.toString(), 10)]);
if (isNullOrUndefined(liEle)) {
continue;
}
const icon = select('.' + selector, select('.' + TEXTWRAP, liEle));
if (!isNullOrUndefined(icon)) {
if (toExpand) {
this.expandAction(liEle, icon, null);
}
else {
this.collapseNode(liEle, icon, null);
}
}
}
}
addGivenNodes(nodes, dropLi, index, isRemote, dropEle) {
if (nodes.length === 0) {
return;
}
const sNodes = this.getSortedData(nodes);
const level = dropLi ? parseFloat(dropLi.getAttribute('aria-level')) + 1 : 1;
if (isRemote) {
this.updateMapper(level);
}
const li = ListBase.createListItemFromJson(this.createElement, sNodes, this.listBaseOption, level);
const id = this.getId(dropLi);
let dropIcon1;
if (!isNullOrUndefined(dropLi)) {
dropIcon1 = select('div.' + ICON, dropLi);
}
if (this.dataType === 1 && dropIcon1 && dropIcon1.classList.contains(EXPANDABLE) && this.preventExpand && !isNullOrUndefined(this.element.offsetParent) && !this.element.offsetParent.parentElement.classList.contains('e-filemanager')) {
this.preventExpand = true;
}
if (this.dataType !== 1) {
this.addChildData(this.treeData, this.fields, id, nodes, index);
this.isFirstRender = false;
}
let dropUl;
if (!dropEle) {
dropUl = dropLi ? this.expandParent(dropLi) : select('.' + PARENTITEM, this.element);
}
else {
dropUl = dropEle;
}
const refNode = !isNullOrUndefined(index) ? dropUl.childNodes[parseInt(index.toString(), 10)] : null;
if (!this.isFirstRender || this.dataType === 1) {
const args = this.expandArgs;
if (refNode || this.sortOrder === 'None') {
for (let i = 0; i < li.length; i++) {
dropUl.insertBefore(li[parseInt(i.toString(), 10)], refNode);
}
if (this.dataType === 1 && !isNullOrUndefined(dropLi) && !this.preventExpand && !isNullOrUndefined(this.element.offsetParent) && !this.element.offsetParent.parentElement.classList.contains('e-filemanager')) {
this.preventExpand = false;
const dropIcon = select('div.' + ICON, dropLi);
if (dropIcon && dropIcon.classList.contains(EXPANDABLE) && (isNullOrUndefined(args) || args.name !== 'nodeExpanding')) {
this.expandAction(dropLi, dropIcon, null);
}
}
}
if (!refNode && ((this.sortOrder === 'Ascending') || (this.sortOrder === 'Descending'))) {
if (dropUl.childNodes.length === 0) {
for (let i = 0; i < li.length; i++) {
dropUl.insertBefore(li[parseInt(i.toString(), 10)], refNode);
}
if (this.dataType === 1 && !isNullOrUndefined(dropLi) && !this.preventExpand && !isNullOrUndefined(this.element.offsetParent) && !this.element.offsetParent.parentElement.classList.contains('e-filemanager')) {
this.preventExpand = false;
const dropIcon = select('div.' + ICON, dropLi);
if (dropIcon && dropIcon.classList.contains(EXPANDABLE) && (isNullOrUndefined(args) || args.name !== 'nodeExpanding')) {
this.expandAction(dropLi, dropIcon, null);
}
}
}
else {
const cNodes = dropUl.childNodes;
for (let i = 0; i < li.length; i++) {
for (let j = 0; j < cNodes.length; j++) {
const returnValue = (this.sortOrder === 'Ascending') ? cNodes[parseInt(j.toString(), 10)].textContent.toUpperCase() > li[parseInt(i.toString(), 10)].innerText.toUpperCase() : cNodes[parseInt(j.toString(), 10)].textContent.toUpperCase() < li[parseInt(i.toString(), 10)].innerText.toUpperCase();
if (returnValue) {
dropUl.insertBefore(li[parseInt(i.toString(), 10)], cNodes[parseInt(j.toString(), 10)]);
break;
}
dropUl.insertBefore(li[parseInt(i.toString(), 10)], cNodes[cNodes.length]);
}
}
}
}
}
if (this.dataType === 1) {
this.updateField(this.treeData, this.fields, id, 'hasChildren', true);
const refId = this.getId(refNode);
let pos = isNullOrUndefined(refId) ? this.treeData.length : this.getDataPos(this.treeData, this.fields, refId);
for (let j = 0; j < nodes.length; j++) {
if (!isNullOrUndefined(id)) {
const currId = this.isNumberTypeId ? parseFloat(id) : id;
setValue(this.fields.parentID, currId, nodes[parseInt(j.toString(), 10)]);
}
this.treeData.splice(pos, 0, nodes[parseInt(j.toString(), 10)]);
pos++;
}
}
this.finalizeNode(dropUl);
}
updateMapper(level) {
const mapper = (level === 1) ? this.fields : this.getChildFields(this.fields, level - 1, 1);
this.updateListProp(mapper);
}
updateListProp(mapper) {
const prop = this.getActualProperties(mapper);
this.listBaseOption.fields = prop;
this.listBaseOption.fields.url = Object.prototype.hasOwnProperty.call(prop, 'navigateUrl') ? prop.navigateUrl : 'navigateUrl';
}
getDataPos(obj, mapper, id) {
let pos = null;
for (let i = 0, objlen = obj.length; i < objlen; i++) {
const nodeId = getValue(mapper.id, obj[parseInt(i.toString(), 10)]);
if (obj[parseInt(i.toString(), 10)] && nodeId && nodeId.toString() === id) {
return i;
}
else if (typeof mapper.child === 'string' && !isNullOrUndefined(getValue(mapper.child, obj[parseInt(i.toString(), 10)]))) {
const data = getValue(mapper.child, obj[parseInt(i.toString(), 10)]);
pos = this.getDataPos(data, this.getChildMapper(mapper), id);
if (pos !== null) {
break;
}
}
else if (this.fields.dataSource instanceof DataManager && !isNullOrUndefined(getValue('child', obj[parseInt(i.toString(), 10)]))) {
const items = getValue('child', obj[parseInt(i.toString(), 10)]);
pos = this.getDataPos(items, this.getChildMapper(mapper), id);
if (pos !== null) {
break;
}
}
}
return pos;
}
addChildData(obj, mapper, id, data, index) {
let updated;
if (isNullOrUndefined(id)) {
index = isNullOrUndefined(index) ? obj.length : index;
for (let k = 0, len = data.length; k < len; k++) {
obj.splice(index, 0, data[parseInt(k.toString(), 10)]);
index++;
}
return updated;
}
for (let i = 0, objlen = obj.length; i < objlen; i++) {
const nodeId = getValue(mapper.id, obj[parseInt(i.toString(), 10)]);
if (obj[parseInt(i.toString(), 10)] && nodeId && nodeId.toString() === id) {
if ((typeof mapper.child === 'string' && (Object.prototype.hasOwnProperty.call(obj[parseInt(i.toString(), 10)], mapper.child) && obj[parseInt(i.toString(), 10)][mapper.child] !== null)) ||
((this.fields.dataSource instanceof DataManager) && Object.prototype.hasOwnProperty.call(obj[parseInt(i.toString(), 10)], 'child'))) {
const key = (typeof mapper.child === 'string') ? mapper.child : 'child';
let childData = getValue(key, obj[parseInt(i.toString(), 10)]);
if (isNullOrUndefined(childData)) {
childData = [];
}
index = isNullOrUndefined(index) ? childData.length : index;
for (let k = 0, len = data.length; k < len; k++) {
childData.splice(index, 0, data[parseInt(k.toString(), 10)]);
index++;
}
}
else {
const key = (typeof mapper.child === 'string') ? mapper.child : 'child';
obj[parseInt(i.toString(), 10)][`${key}`] = data;
}
return true;
}
else if (typeof mapper.child === 'string' && !isNullOrUndefined(getValue(mapper.child, obj[parseInt(i.toString(), 10)]))) {
const childObj = getValue(mapper.child, obj[parseInt(i.toString(), 10)]);
updated = this.addChildData(childObj, this.getChildMapper(mapper), id, data, index);
if (updated !== undefined) {
break;
}
}
else if ((this.fields.dataSource instanceof DataManager) && !isNullOrUndefined(getValue('child', obj[parseInt(i.toString(), 10)]))) {
const childData = getValue('child', obj[parseInt(i.toString(), 10)]);
updated = this.addChildData(childData, this.getChildMapper(mapper), id, data, index);
if (updated !== undefined) {
break;
}
}
}
return updated;
}
doDisableAction(nodes) {
const validNodes = this.nodeType(nodes);
const validID = this.checkValidId(validNodes);
this.validArr = [];
for (let i = 0, len = validID.length; i < len; i++) {
const id = validID[parseInt(i.toString(), 10)][this.fields.id].toString();
if (id && this.disableNode.indexOf(id) === -1) {
this.disableNode.push(id);
}
const liEle = this.getElement(id);
if (liEle) {
liEle.setAttribute('aria-disabled', 'true');
addClass([liEle], DISABLE);
}
}
}
doEnableAction(nodes) {
const strNodes = this.nodeType(nodes);
for (let i = 0, len = strNodes.length; i < len; i++) {
const liEle = this.getElement(strNodes[parseInt(i.toString(), 10)]);
const id = strNodes[parseInt(i.toString(), 10)];
if (id && this.disableNode.indexOf(id) !== -1) {
this.disableNode.splice(this.disableNode.indexOf(id), 1);
}
if (liEle) {
liEle.removeAttribute('aria-disabled');
removeClass([liEle], DISABLE);
}
}
}
nodeType(nodes) {
const validID = [];
for (let i = 0, len = nodes.length; i < len; i++) {
let id;
if (typeof nodes[parseInt(i.toString(), 10)] == 'string') {
id = (nodes[parseInt(i.toString(), 10)]) ? nodes[parseInt(i.toString(), 10)].toString() : null;
}
else if (typeof nodes[parseInt(i.toString(), 10)] === 'object') {
id = nodes[parseInt(i.toString(), 10)] ? nodes[parseInt(i.toString(), 10)].getAttribute('data-uid').toString() : null;
}
if (validID.indexOf(id) === -1) {
validID.push(id);
}
}
return validID;
}
checkValidId(node) {
if (this.dataType === 1) {
this.validArr = this.treeData.filter((data) => {
return node.indexOf(data[this.fields.id] ? data[this.fields.id].toString() : null) !== -1;
});
}
else if (this.dataType === 2) {
for (let k = 0; k < this.treeData.length; k++) {
const id = this.treeData[parseInt(k.toString(), 10)][this.fields.id]
? this.treeData[parseInt(k.toString(), 10)][this.fields.id].toString()
: null;
if (node.indexOf(id) !== -1) {
this.validArr.push(this.treeData[parseInt(k.toString(), 10)]);
}
const childItems = getValue(this.fields.child.toString(), this.treeData[parseInt(k.toString(), 10)]);
if (childItems) {
this.filterNestedChild(childItems, node);
}
}
}
return this.validArr;
}
filterNestedChild(treeData, nodes) {
for (let k = 0; k < treeData.length; k++) {
const id = treeData[parseInt(k.toString(), 10)][this.fields.id]
? treeData[parseInt(k.toString(), 10)][this.fields.id].toString()
: null;
if (nodes.indexOf(id) !== -1) {
this.validArr.push(treeData[parseInt(k.toString(), 10)]);
}
const childItems = getValue(this.fields.child.toString(), treeData[parseInt(k.toString(), 10)]);
if (childItems) {
this.filterNestedChild(childItems, nodes);
}
}
}
setTouchClass() {
const ele = closest(this.element, '.' + BIGGER);
this.touchClass = isNullOrUndefined(ele) ? '' : SMALL;
}
updatePersistProp() {
this.removeField(this.treeData, this.fields, ['selected', 'expanded']);
const sleNodes = this.selectedNodes;
for (let l = 0, slelen = sleNodes.length; l < slelen; l++) {
this.updateField(this.treeData, this.fields, sleNodes[parseInt(l.toString(), 10)], 'selected', true);
}
const enodes = this.expandedNodes;
for (let k = 0, nodelen = enodes.length; k < nodelen; k++) {
this.updateField(this.treeData, this.fields, enodes[parseInt(k.toString(), 10)], 'expanded', true);
}
if (this.showCheckBox) {
this.removeField(this.treeData, this.fields, ['isChecked']);
const cnodes = this.checkedNodes;
for (let m = 0, nodelen = cnodes.length; m < nodelen; m++) {
this.updateField(this.treeData, this.fields, cnodes[parseInt(m.toString(), 10)], 'isChecked', true);
}
}
}
removeField(obj, mapper, names) {
if (isNullOrUndefined(obj) || isNullOrUndefined(mapper)) {
return;
}
for (let i = 0, objlen = obj.length; i < objlen; i++) {
for (let j = 0; j < names.length; j++) {
const field = this.getMapperProp(mapper, names[parseInt(j.toString(), 10)]);
if (!isNullOrUndefined(obj[parseInt(i.toString(), 10)][`${field}`])) {
delete obj[parseInt(i.toString(), 10)][`${field}`];
}
}
if (typeof mapper.child === 'string' && !isNullOrUndefined(getValue(mapper.child, obj[parseInt(i.toString(), 10)]))) {
this.removeField(getValue(mapper.child, obj[parseInt(i.toString(), 10)]), this.getChildMapper(mapper), names);
}
else if (this.fields.dataSource instanceof DataManager && !isNullOrUndefined(getValue('child', obj[parseInt(i.toString(), 10)]))) {
this.removeField(getValue('child', obj[parseInt(i.toString(), 10)]), this.getChildMapper(mapper), names);
}
}
}
getMapperProp(mapper, fieldName) {
switch (fieldName) {
case 'selected':
return !isNullOrUndefined(mapper.selected) ? mapper.selected : 'selected';
case 'expanded':
return !isNullOrUndefined(mapper.expanded) ? mapper.expanded : 'expanded';
case 'isChecked':
return !isNullOrUndefined(mapper.isChecked) ? mapper.isChecked : 'isChecked';
case 'hasChildren':
return !isNullOrUndefined(mapper.hasChildren) ? mapper.hasChildren : 'hasChildren';
default:
return fieldName;
}
}
updateField(obj, mapper, id, key, value) {
if (isNullOrUndefined(id)) {
return;
}
else if (this.dataType === 1) {
const newId = this.isNumberTypeId ? parseFloat(id) : id;
const resultData = new DataManager(this.treeData).executeLocal(new Query().where(mapper.id, 'equal', newId, false));
setValue(this.getMapperProp(mapper, key), value, resultData[0]);
}
else {
this.updateChildField(obj, mapper, id, key, value);
}
}
updateChildField(obj, mapper, id, key, value, remove) {
let removedData;
if (isNullOrUndefined(obj)) {
return removedData;
}
for (let i = 0, objlen = obj.length; i < objlen; i++) {
const nodeId = getValue(mapper.id, obj[parseInt(i.toString(), 10)]);
if (obj[parseInt(i.toString(), 10)] && !isNullOrUndefined(nodeId) && nodeId.toString() === id) {
if (remove) {
removedData = obj.splice(i, 1);
}
else {
setValue(this.getMapperProp(mapper, key), value, obj[parseInt(i.toString(), 10)]);
removedData = [];
}
return removedData;
}
else if (typeof mapper.child === 'string' && !isNullOrUndefined(getValue(mapper.child, obj[parseInt(i.toString(), 10)]))) {
const childData = getValue(mapper.child, obj[parseInt(i.toString(), 10)]);
removedData = this.updateChildField(childData, this.getChildMapper(mapper), id, key, value, remove);
if (removedData !== undefined) {
break;
}
}
else if (this.fields.dataSource instanceof DataManager && !isNullOrUndefined(getValue('child', obj[parseInt(i.toString(), 10)]))) {
const childItems = getValue('child', obj[parseInt(i.toString(), 10)]);
removedData = this.updateChildField(childItems, this.getChildMapper(mapper), id, key, value, remove);
if (removedData !== undefined) {
break;
}
}
}
return removedData;
}
triggerEvent(action, node) {
this.renderReactTemplates();
if (action === 'addNodes') {
const nodeData = [];
for (let i = 0; i < node.length; i++) {
nodeData.push(this.getNode(this.getElement(isNullOrUndefined(node[parseInt(i.toString(), 10)][this.fields.id])
? getValue(this.fields.id, node[parseInt(i.toString(), 10)]).toString()
: null)));
}
node = nodeData;
}
const eventArgs = { data: this.treeData, action: action, nodeData: node };
this.trigger('dataSourceChanged', eventArgs);
}
wireInputEvents(inpEle) {
EventHandler.add(inpEle, 'blur', this.inputFocusOut, this);
}
wireEditingEvents(toBind) {
if (toBind && !this.disabled) {
this.touchEditObj = new Touch(this.element, {
tap: (e) => {
if (this.isDoubleTapped(e) && e.tapCount === 2) {
e.originalEvent.preventDefault();
this.editingHandler(e.originalEvent);
}
}
});
}
else {
if (this.touchEditObj) {
this.touchEditObj.destroy();
}
}
}
wireClickEvent(toBind) {
if (toBind) {
this.touchClickObj = new Touch(this.element, {
tap: (e) => {
this.clickHandler(e);
}
});
}
else {
if (this.touchClickObj) {
this.touchClickObj.destroy();
}
}
}
wireExpandOnEvent(toBind) {
if (toBind) {
this.touchExpandObj = new Touch(this.element, {
tap: (e) => {
if ((this.expandOnType === 'Click' || (this.expandOnType === 'DblClick' && this.isDoubleTapped(e) && e.tapCount === 2))
&& e.originalEvent.which !== 3) {
this.expandHandler(e);
}
}
});
}
else {
if (this.touchExpandObj) {
this.touchExpandObj.destroy();
}
}
}
mouseDownHandler(e) {
this.mouseDownStatus = true;
if (e.shiftKey || e.ctrlKey) {
e.preventDefault();
}
if (e.ctrlKey && this.allowMultiSelection) {
EventHandler.add(this.element, 'contextmenu', this.preventContextMenu, this);
}
}
preventContextMenu(e) {
e.preventDefault();
}
wireEvents() {
EventHandler.add(this.element, 'mousedown', this.mouseDownHandler, this);
this.wireClickEvent(true);
if (this.expandOnType !== 'None') {
this.wireExpandOnEvent(true);
}
EventHandler.add(this.element, 'mouseover', this.onMouseOver, this);
EventHandler.add(this.element, 'mouseout', this.onMouseLeave, this);
this.keyboardModule = new KeyboardEvents(this.element, {
keyAction: this.keyActionHandler.bind(this),
keyConfigs: this.keyConfigs,
eventName: 'keydown'
});
}
unWireEvents() {
EventHandler.remove(this.element, 'mousedown', this.mouseDownHandler);
this.wireClickEvent(false);
this.wireExpandOnEvent(false);
EventHandler.remove(this.element, 'mouseover', this.onMouseOver);
EventHandler.remove(this.element, 'mouseout', this.onMouseLeave);
if (!this.disabled) {
this.keyboardModule.destroy();
}
}
parents(element, selector) {
const matched = [];
let el = element.parentNode;
while (!isNullOrUndefined(el)) {
if (matches(el, selector)) {
matched.push(el);
}
el = el.parentNode;
}
return matched;
}
isDoubleTapped(e) {
const target = e.originalEvent.target;
let secondTap;
if (target && e.tapCount) {
if (e.tapCount === 1) {
this.firstTap = closest(target, '.' + LISTITEM);
}
else if (e.tapCount === 2) {
secondTap = closest(target, '.' + LISTITEM);
}
}
return (this.firstTap === secondTap);
}
isDescendant(parent, child) {
let node = child.parentNode;
while (!isNullOrUndefined(node)) {
if (node === parent) {
return true;
}
node = node.parentNode;
}
return false;
}
showSpinner(element) {
addClass([element], LOAD);
createSpinner({
target: element,
width: Browser.isDevice ? 16 : 14
}, this.createElement);
showSpinner(element);
}
hideSpinner(element) {
hideSpinner(element);
element.innerHTML = '';
removeClass([element], LOAD);
}
setCheckedNodes(nodes) {
nodes = JSON.parse(JSON.stringify(nodes));
if (nodes.length > 1 && typeof this.nodeChecked === 'function' && this.nodeChecked.length > 0) {
this.isFilter = true;
}
this.uncheckAll(this.checkedNodes);
this.setIndeterminate(nodes);
if (nodes.length > 0) {
this.checkAll(nodes);
}
}
/**
* Checks whether the checkedNodes entered are valid and sets the valid checkedNodes while changing via setmodel
*
* @param {string} node - The unique identifier of the node.
* @param {string[]} [nodes=[]] - The list of node IDs to check.
* @returns {void}
* @private
*/
setValidCheckedNode(node, nodes = []) {
if (this.dataType === 1) {
const mapper = this.fields;
const resultData = new DataManager(this.treeData).executeLocal(new Query().where(mapper.id, 'equal', node, true));
if (resultData[0]) {
this.setChildCheckState(resultData, node, resultData[0], nodes);
if (this.autoCheck) {
const parent = resultData[0][this.fields.parentID] ? resultData[0][this.fields.parentID].toString() : null;
const childNodes = this.getChildNodes(this.treeData, parent);
let count = 0;
for (let len = 0; len < childNodes.length; len++) {
const childId = childNodes[parseInt(len.toString(), 10)][this.fields.id].toString();
if (this.checkedNodes.indexOf(childId) !== -1) {
count++;
}
}
if (count === childNodes.length && this.checkedNodes.indexOf(parent) === -1 && parent) {
this.checkDisabledState(parent);
}
}
}
}
else if (this.dataType === 2) {
for (let a = 0; a < this.treeData.length; a++) {
const index = this.treeData[parseInt(a.toString(), 10)][this.fields.id] ? this.treeData[parseInt(a.toString(), 10)][this.fields.id].toString() : '';
if (index === node && this.checkedNodes.indexOf(node) === -1) {
this.checkDisabledState(node);
break;
}
const childItems = getValue(this.fields.child.toString(), this.treeData[parseInt(a.toString(), 10)]);
if (childItems) {
this.setChildCheckState(childItems, node, this.treeData[parseInt(a.toString(), 10)], nodes);
}
}
}
}
/**
* Checks whether the checkedNodes entered are valid and sets the valid checkedNodes while changing via setmodel(for hierarchical DS)
*
* @param {Object[]} childItems - The child items to check.
* @param {string} node - The node to set the check state for.
* @param {Object} [treeData] - The optional tree data.
* @param {string[]} [nodes=[]] - The list of node IDs to check.
* @returns {void}
* @private
*/
setChildCheckState(childItems, node, treeData, nodes = []) {
let checkedParent;
let count = 0;
if (this.dataType === 1) {
if (treeData) {
checkedParent = treeData[this.fields.id] ? treeData[this.fields.id].toString() : null;
}
for (let index = 0; index < childItems.length; index++) {
const checkNode = childItems[parseInt(index.toString(), 10)][this.fields.id]
? childItems[parseInt(index.toString(), 10)][this.fields.id].toString()
: null;
if (treeData && checkedParent && this.autoCheck) {
if (this.checkedNodes.indexOf(checkedParent) !== -1 && this.checkedNodes.indexOf(checkNode) === -1) {
this.checkDisabledState(checkNode, childItems[index]);
}
}
if (checkNode === node && this.checkedNodes.indexOf(node) === -1) {
this.checkDisabledState(node);
}
const subChildItems = this.getChildNodes(this.treeData, checkNode);
const isParentNodeCheck = (nodes.length === 1 && nodes[0] === checkNode);
if (subChildItems.length === node.length || isParentNodeCheck) {
this.setChildCheckState(subChildItems, node, treeData);
}
}
}
else {
if (treeData) {
checkedParent = treeData[this.fields.id] ? treeData[this.fields.id].toString() : '';
}
for (let index = 0; index < childItems.length; index++) {
const checkedChild = childItems[parseInt(index.toString(), 10)][this.fields.id] ? childItems[parseInt(index.toString(), 10)][this.fields.id].toString() : '';
const isParentNodeCheck = ([node].length === 1 && nodes.length === 0);
if (treeData && checkedParent && this.autoCheck) {
if (this.checkedNodes.indexOf(checkedParent) !== -1 && this.checkedNodes.indexOf(checkedChild) === -1
&& (checkedChild === node || isParentNodeCheck)) {
this.checkDisabledState(checkedChild, childItems[index]);
}
}
if (checkedChild === node && this.checkedNodes.indexOf(node) === -1) {
this.checkDisabledState(node);
}
const subChildItems = getValue(this.fields.child.toString(), childItems[parseInt(index.toString(), 10)]);
if (subChildItems) {
this.setChildCheckState(subChildItems, node, childItems[parseInt(index.toString(), 10)]);
}
if (this.checkedNodes.indexOf(checkedChild) !== -1 && this.autoCheck) {
count++;
}
if (count === childItems.length && this.checkedNodes.indexOf(checkedParent) === -1 && this.autoCheck) {
this.checkDisabledState(checkedParent, treeData);
}
}
}
}
setIndeterminate(nodes) {
for (let i = 0; i < nodes.length; i++) {
this.setValidCheckedNode(nodes[parseInt(i.toString(), 10)], nodes);
}
}
updatePosition(id, newData, isRefreshChild, childValue) {
if (this.dataType === 1) {
let pos = this.getDataPos(this.treeData, this.fields, id);
this.treeData.splice(pos, 1, newData);
if (isRefreshChild) {
this.removeChildNodes(id);
for (let j = 0; j < childValue.length; j++) {
this.treeData.splice(pos, 0, childValue[parseInt(j.toString(), 10)]);
pos++;
}
}
this.groupedData = this.getGroupedData(this.treeData, this.fields.parentID);
}
else {
this.updateChildPosition(this.treeData, this.fields, id, [newData], undefined);
}
}
updateChildPosition(treeData, mapper, currID, newData, index) {
let found;
for (let i = 0, objlen = treeData.length; i < objlen; i++) {
const nodeId = getValue(mapper.id, treeData[parseInt(i.toString(), 10)]);
if (treeData[parseInt(i.toString(), 10)] && nodeId && nodeId.toString() === currID) {
treeData[parseInt(i.toString(), 10)] = newData[0];
return true;
}
else if (typeof mapper.child === 'string' && !isNullOrUndefined(getValue(mapper.child, treeData[parseInt(i.toString(), 10)]))) {
const childObj = getValue(mapper.child, treeData[parseInt(i.toString(), 10)]);
found = this.updateChildPosition(childObj, this.getChildMapper(mapper), currID, newData, index);
if (found !== undefined) {
break;
}
}
else if (this.fields.dataSource instanceof DataManager && !isNullOrUndefined(getValue('child', treeData[parseInt(i.toString(), 10)]))) {
const childData = getValue('child', treeData[parseInt(i.toString(), 10)]);
found = this.updateChildPosition(childData, this.getChildMapper(mapper), currID, newData, index);
if (found !== undefined) {
break;
}
}
}
return found;
}
dynamicState() {
this.setDragAndDrop(this.allowDragAndDrop);
this.wireEditingEvents(this.allowEditing);
if (!this.disabled) {
this.wireEvents();
this.setRipple();
}
else {
this.unWireEvents();
this.rippleFn();
this.rippleIconFn();
}
}
crudOperation(operation, nodes, target, newText, newNode, index, prevent) {
const data = this.fields.dataSource;
const matchedArr = [];
const query = this.getQuery(this.fields);
const key = this.fields.id;
let crud;
const changes = {
addedRecords: [],
deletedRecords: [],
changedRecords: []
};
let nodesID = [];
if (nodes) {
nodesID = this.nodeType(nodes);
}
else if (target) {
if (typeof target == 'string') {
nodesID[0] = target.toString();
}
else if (typeof target === 'object') {
nodesID[0] = target.getAttribute('data-uid').toString();
}
}
for (let i = 0, len = nodesID.length; i < len; i++) {
const liEle = this.getElement(nodesID[parseInt(i.toString(), 10)]);
if (isNullOrUndefined(liEle)) {
continue;
}
const removedData = this.getNodeObject(nodesID[parseInt(i.toString(), 10)]);
matchedArr.push(removedData);
}
switch (operation) {
case 'delete':
if (nodes.length === 1) {
crud = data.remove(key, matchedArr[0], query.fromTable, query);
}
else {
changes.deletedRecords = matchedArr;
crud = data.saveChanges(changes, key, query.fromTable, query);
}
crud.then(() => this.deleteSuccess(nodesID))
.catch((e) => this.dmFailure(e));
break;
case 'update':
matchedArr[0][this.fields.text] = newText;
crud = data.update(key, matchedArr[0], query.fromTable, query);
crud.then(() => this.editSucess(target, newText, prevent))
.catch((e) => this.dmFailure(e, target, prevent));
break;
case 'insert':
if (newNode.length === 1) {
crud = data.insert(newNode[0], query.fromTable, query);
}
else {
const arr = [];
for (let i = 0, len = newNode.length; i < len; i++) {
arr.push(newNode[parseInt(i.toString(), 10)]);
}
changes.addedRecords = arr;
crud = data.saveChanges(changes, key, query.fromTable, query);
}
crud.then(() => {
const dropLi = this.getElement(target);
this.addSuccess(newNode, dropLi, index);
this.preventExpand = false;
}).catch((e) => this.dmFailure(e));
break;
}
}
deleteSuccess(nodes) {
const nodeData = [];
for (let i = 0, len = nodes.length; i < len; i++) {
const liEle = this.getElement(nodes[parseInt(i.toString(), 10)]);
nodeData.push(this.getNode(liEle));
if (isNullOrUndefined(liEle)) {
continue;
}
this.removeNode(liEle);
}
this.updateInstance();
if (this.dataType === 1) {
this.groupedData = this.getGroupedData(this.treeData, this.fields.parentID);
}
this.triggerEvent('removeNode', nodeData);
}
editSucess(target, newText, prevent) {
const liEle = this.getElement(target);
const txtEle = select('.' + LISTTEXT, liEle);
this.appendNewText(liEle, txtEle, newText, prevent);
}
addSuccess(nodes, dropLi, index) {
let dropUl;
const icon = dropLi ? dropLi.querySelector('.' + ICON) : null;
if (dropLi && icon && icon.classList.contains(EXPANDABLE) &&
dropLi.querySelector('.' + PARENTITEM) === null) {
this.renderChildNodes(dropLi, null, () => {
dropUl = dropLi.querySelector('.' + PARENTITEM);
this.addGivenNodes(nodes, dropLi, index, true, dropUl);
this.triggerEvent('addNodes', nodes);
});
}
else {
this.addGivenNodes(nodes, dropLi, index, true);
this.triggerEvent('addNodes', nodes);
}
}
dmFailure(e, target, prevent) {
if (target) {
this.updatePreviousText(target, prevent);
}
this.trigger('actionFailure', { error: e });
}
updatePreviousText(target, prevent) {
const liEle = this.getElement(target);
const txtEle = select('.' + LISTTEXT, liEle);
this.updateText(liEle, txtEle, this.oldText, prevent);
}
getHierarchicalParentId(node, data, parentsID) {
let index = data.findIndex((data) => data[this.fields.id] && data[this.fields.id].toString() === node);
if (index === -1) {
for (let i = 0; i < data.length; i++) {
const childItems = getValue(this.fields.child.toString(), data[parseInt(i.toString(), 10)]);
if (!isNullOrUndefined(childItems)) {
index = childItems.findIndex((data) => data[this.fields.id] && data[this.fields.id].toString() === node);
if (index === -1) {
this.getHierarchicalParentId(node, childItems, parentsID);
}
else {
parentsID.push(data[parseInt(i.toString(), 10)][this.fields.id].toString());
this.getHierarchicalParentId(data[parseInt(i.toString(), 10)][this.fields.id].toString(), this.treeData, parentsID);
break;
}
}
}
}
return parentsID;
}
/**
* Called internally if any of the property value changed.
*
* @param {TreeViewModel} newProp - The new property value.
* @param {TreeViewModel} oldProp - The old property value.
* @returns {void}
* @private
*/
onPropertyChanged(newProp, oldProp) {
for (const prop of Object.keys(newProp)) {
switch (prop) {
case 'allowDragAndDrop':
this.setDragAndDrop(this.allowDragAndDrop);
break;
case 'dragArea':
if (this.allowDragAndDrop) {
this.dragObj.dragArea = this.dragArea;
}
break;
case 'allowEditing':
this.wireEditingEvents(this.allowEditing);
break;
case 'allowMultiSelection':
if (this.selectedNodes.length > 1) {
const sNode = this.getElement(this.selectedNodes[0]);
this.isLoaded = false;
this.removeSelectAll();
this.selectNode(sNode, null);
this.isLoaded = true;
}
this.setMultiSelect(this.allowMultiSelection);
this.addMultiSelect(this.allowMultiSelection);
break;
case 'allowTextWrap':
this.setTextWrap();
this.updateWrap();
break;
case 'checkedNodes':
if (JSON.stringify(oldProp.checkedNodes) !== JSON.stringify(newProp.checkedNodes)) {
if (this.showCheckBox) {
this.checkedNodes = oldProp.checkedNodes;
this.setCheckedNodes(newProp.checkedNodes);
}
}
break;
case 'autoCheck':
if (this.showCheckBox) {
this.autoCheck = newProp.autoCheck;
this.ensureIndeterminate();
}
break;
case 'cssClass':
this.setCssClass(oldProp.cssClass, newProp.cssClass);
break;
case 'enableRtl':
this.setEnableRtl();
break;
case 'expandedNodes':
this.isAnimate = false;
this.setProperties({ expandedNodes: [] }, true);
this.collapseAll();
this.isInitalExpand = true;
this.setProperties({ expandedNodes: isNullOrUndefined(newProp.expandedNodes) ? [] : newProp.expandedNodes }, true);
this.doExpandAction();
this.isInitalExpand = false;
this.isAnimate = true;
break;
case 'expandOn':
this.wireExpandOnEvent(false);
this.setExpandOnType();
if (this.expandOnType !== 'None' && !this.disabled) {
this.wireExpandOnEvent(true);
}
break;
case 'disabled':
this.setDisabledMode();
this.dynamicState();
break;
case 'fields':
this.isAnimate = false;
this.isFieldChange = true;
this.initialRender = true;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (!this.isReact || this.isReact && !(this.fields.dataSource instanceof DataManager)) {
if (!this.element.classList.contains('e-filtering')) {
this.DDTTreeData = JSON.parse(JSON.stringify(this.fields.dataSource));
}
this.reRenderNodes();
}
this.initialRender = false;
this.isAnimate = true;
this.isFieldChange = false;
break;
case 'fullRowSelect':
this.setFullRow(this.fullRowSelect);
this.addFullRow(this.fullRowSelect);
if (this.allowTextWrap) {
this.setTextWrap();
this.updateWrap();
}
break;
case 'loadOnDemand':
if (this.loadOnDemand === false && !this.onLoaded) {
const nodes = this.element.querySelectorAll('li');
let i = 0;
while (i < nodes.length) {
if (nodes[parseInt(i.toString(), 10)].getAttribute('aria-expanded') !== 'true') {
this.renderChildNodes(nodes[parseInt(i.toString(), 10)], true, null, true);
}
i++;
}
this.onLoaded = true;
}
break;
case 'nodeTemplate':
this.hasTemplate = false;
this.nodeTemplateFn = this.templateComplier(this.nodeTemplate);
this.reRenderNodes();
break;
case 'selectedNodes':
this.removeSelectAll();
this.setProperties({ selectedNodes: newProp.selectedNodes }, true);
this.doSelectionAction();
break;
case 'showCheckBox':
case 'checkDisabledChildren':
this.reRenderNodes();
break;
case 'sortOrder':
this.reRenderNodes();
break;
case 'fullRowNavigable':
this.setProperties({ fullRowNavigable: newProp.fullRowNavigable }, true);
this.listBaseOption.itemNavigable = newProp.fullRowNavigable;
this.reRenderNodes();
break;
}
}
}
/**
* Removes the component from the DOM and detaches all its related event handlers. It also removes the attributes and classes.
*
* @returns {void}
*/
destroy() {
this.clearTemplate();
this.element.removeAttribute('aria-activedescendant');
this.unWireEvents();
this.wireEditingEvents(false);
if (!this.disabled) {
this.rippleFn();
this.rippleIconFn();
}
this.setCssClass(this.cssClass, null);
this.setDragAndDrop(false);
this.setFullRow(false);
if (this.ulElement && this.ulElement.parentElement) {
this.ulElement.parentElement.removeChild(this.ulElement);
}
this.ulElement = null;
this.liList = null;
this.startNode = null;
this.firstTap = null;
this.expandArgs = null;
this.dragLi = null;
this.dragTarget = null;
this.dragParent = null;
this.dragObj = null;
this.dropObj = null;
this.inputObj = null;
this.touchEditObj = null;
this.touchExpandObj = null;
this.touchClickObj = null;
super.destroy();
}
/**
* Adds the collection of TreeView nodes based on target and index position. If target node is not specified,
* then the nodes are added as children of the given parentID or in the root level of TreeView.
*
* @param { object } nodes - Specifies the array of JSON data that has to be added.
* @param { string | Element } target - Specifies ID of TreeView node/TreeView node as target element.
* @param { number } index - Specifies the index to place the newly added nodes in the target element.
* @param { boolean } preventTargetExpand - If set to true, the target parent node will be prevented from auto expanding.
* @returns {void}
*/
addNodes(nodes, target, index, preventTargetExpand) {
if (isNullOrUndefined(nodes)) {
return;
}
nodes = JSON.parse(JSON.stringify(nodes));
let dropLi = this.getElement(target);
this.preventExpand = preventTargetExpand;
if (this.fields.dataSource instanceof DataManager) {
if (!this.isOffline) {
this.crudOperation('insert', null, target, null, nodes, index, this.preventExpand);
}
else {
this.addSuccess(nodes, dropLi, index);
}
}
else if (this.dataType === 2) {
this.addGivenNodes(nodes, dropLi, index);
}
else {
if (dropLi) {
this.addGivenNodes(nodes, dropLi, index);
}
else {
nodes = this.getSortedData(nodes);
for (let i = 0; i < nodes.length; i++) {
const pid = getValue(this.fields.parentID, nodes[parseInt(i.toString(), 10)]);
dropLi = pid ? this.getElement(pid.toString()) : pid;
if (!isNullOrUndefined(pid) && isNullOrUndefined(dropLi)) {
this.isHiddenItem = true;
this.preventExpand = false;
this.ensureVisible(pid);
this.preventExpand = preventTargetExpand;
this.isHiddenItem = false;
dropLi = this.getElement(pid.toString());
}
this.addGivenNodes([nodes[parseInt(i.toString(), 10)]], dropLi, index);
}
}
this.groupedData = this.getGroupedData(this.treeData, this.fields.parentID);
}
const fNode = select('.' + LISTITEM + '[tabindex="0"]', this.element);
if (isNullOrUndefined(fNode)) {
this.setNodeFocusable();
}
this.updateCheckedStateFromDS();
if (this.showCheckBox && dropLi && this.autoCheck) {
this.ensureParentCheckState(dropLi);
}
if ((this.fields.dataSource instanceof DataManager === false)) {
this.preventExpand = false;
this.triggerEvent('addNodes', nodes);
}
}
/**
* Editing can also be enabled by using the `beginEdit` property, instead of clicking on the
* TreeView node. On passing the node ID or element through this property, the edit textBox
* will be created for the particular node thus allowing us to edit it.
*
* @param {string | Element} node - Specifies ID of TreeView node/TreeView node.
* @returns {void}
*/
beginEdit(node) {
const ele = this.getElement(node);
if (isNullOrUndefined(ele) || this.disabled) {
return;
}
this.createTextbox(ele);
}
/**
* Checks all the unchecked nodes. You can also check specific nodes by passing array of unchecked nodes
* as argument to this method.
*
* @param {string[] | Element[]} nodes - Specifies the array of TreeView nodes ID/array of TreeView node.
* @returns {void}
*/
checkAll(nodes) {
if (this.showCheckBox) {
this.doCheckBoxAction(nodes, true);
}
}
/**
* Collapses all the expanded TreeView nodes. You can collapse specific nodes by passing array of nodes as argument to this method.
* You can also collapse all the nodes excluding the hidden nodes by setting **excludeHiddenNodes** to true. If you want to collapse
* a specific level of nodes, set **level** as argument to collapseAll method.
*
* @param {string[] | Element[]} nodes - Specifies the array of TreeView nodes ID/ array of TreeView node.
* @param {number} level - TreeView nodes will collapse up to the given level.
* @param {boolean} excludeHiddenNodes - Whether or not to exclude hidden nodes of TreeView when collapsing all nodes.
* @returns {void}
*/
collapseAll(nodes, level, excludeHiddenNodes) {
if (!isNullOrUndefined(nodes)) {
this.doGivenAction(nodes, COLLAPSIBLE, false);
}
else {
if (level > 0) {
this.collapseByLevel(select('.' + PARENTITEM, this.element), level, excludeHiddenNodes);
}
else {
this.collapseAllNodes(excludeHiddenNodes);
}
}
}
/**
* Disables the collection of nodes by passing the ID of nodes or node elements in the array.
*
* @param {string[] | Element[]} nodes - Specifies the array of TreeView nodes ID/array of TreeView nodes.
* @returns {void}
*/
disableNodes(nodes) {
if (!isNullOrUndefined(nodes)) {
this.doDisableAction(nodes);
}
}
/**
* Enables the collection of disabled nodes by passing the ID of nodes or node elements in the array.
*
* @param {string[] | Element[]} nodes - Specifies the array of TreeView nodes ID/array of TreeView nodes.
* @returns {void}
*/
enableNodes(nodes) {
if (!isNullOrUndefined(nodes)) {
this.doEnableAction(nodes);
}
}
/**
* Ensures visibility of the TreeView node by using node ID or node element.
* When many TreeView nodes are present and we need to find a particular node, `ensureVisible` property
* helps bring the node to visibility by expanding the TreeView and scrolling to the specific node.
*
* @param {string | Element} node - Specifies ID of TreeView node/TreeView nodes.
* @returns {void}
*/
ensureVisible(node) {
let parentsId = [];
if (this.dataType === 1) {
let nodeData = this.getTreeData(node);
while (nodeData.length !== 0 && !isNullOrUndefined(nodeData[0][this.fields.parentID])) {
parentsId.push(nodeData[0][this.fields.parentID].toString());
nodeData = this.getTreeData(nodeData[0][this.fields.parentID].toString());
}
}
else if (this.dataType === 2) {
parentsId = this.getHierarchicalParentId(node, this.treeData, parentsId);
}
this.expandAll(parentsId.reverse(), null, null, this.isHiddenItem);
const liEle = this.getElement(node);
if (!isNullOrUndefined(liEle)) {
if (typeof node == 'object') {
const parents = this.parents(liEle, '.' + LISTITEM);
this.expandAll(parents);
}
setTimeout(() => { liEle.scrollIntoView({ behavior: 'smooth' }); }, 450);
}
}
/**
* Expands all the collapsed TreeView nodes. You can expand the specific nodes by passing the array of collapsed nodes
* as argument to this method. You can also expand all the collapsed nodes by excluding the hidden nodes by setting
* **excludeHiddenNodes** to true to this method. To expand a specific level of nodes, set **level** as argument to expandAll method.
*
* @param {string[] | Element[]} nodes - Specifies the array of TreeView nodes ID/array of TreeView nodes.
* @param {number} level - TreeView nodes will expand up to the given level.
* @param {boolean} excludeHiddenNodes - Whether or not to exclude hidden nodes when expanding all nodes.
* @param {boolean} preventAnimation - Prevent the expand animation when expanding all nodes.
* @returns {void}
*/
expandAll(nodes, level, excludeHiddenNodes, preventAnimation) {
this.isAnimate = !preventAnimation;
if (!isNullOrUndefined(nodes)) {
this.doGivenAction(nodes, EXPANDABLE, true);
}
else {
if (level > 0) {
this.expandByLevel(select('.' + PARENTITEM, this.element), level, excludeHiddenNodes);
}
else {
this.expandAllNodes(excludeHiddenNodes);
if (!this.loadOnDemand || this.element.classList.contains('e-filtering')) {
this.updateAttributes(this.element);
this.updateList();
}
}
}
this.isAnimate = true;
}
/**
* Gets all the checked nodes including child, whether it is loaded or not.
*
* @returns {string[]} - An array of strings representing the unique identifiers of checked nodes.
*/
getAllCheckedNodes() {
const checkNodes = this.checkedNodes;
return checkNodes;
}
/**
* Gets all the disabled nodes including child, whether it is loaded or not.
*
* @returns {string[]} An array of strings representing the unique identifiers of disabled nodes.
*/
getDisabledNodes() {
const disabledNodes = this.disableNode;
return disabledNodes;
}
/**
* Gets the node's data such as id, text, parentID, selected, isChecked, and expanded by passing the node element or it's ID.
*
* @param {string | Element} node - Specifies ID of TreeView node/TreeView node.
* @returns {Object} - The data associated with the specified node.
*/
getNode(node) {
const ele = this.getElement(node);
return this.getNodeData(ele, true);
}
/**
* To get the updated data source of TreeView after performing some operation like drag and drop, node editing,
* node selecting/unSelecting, node expanding/collapsing, node checking/unChecking, adding and removing node.
* * If you pass the ID of TreeView node as arguments for this method then it will return the updated data source
* of the corresponding node otherwise it will return the entire updated data source of TreeView.
* * The updated data source also contains custom attributes if you specified in data source.
*
* @param {string | Element} node - Specifies ID of TreeView node/TreeView node.
* @isGenericType true
* @returns {Object} - The tree data associated with the specified node or element.
*/
getTreeData(node) {
const id = this.getId(node);
this.updatePersistProp();
if (isNullOrUndefined(id)) {
return this.treeData;
}
else {
const data = this.getNodeObject(id);
return isNullOrUndefined(data) ? [] : [data];
}
}
/**
* Moves the collection of nodes within the same TreeView based on target or its index position.
*
* @param {string[] | Element[]} sourceNodes - Specifies the array of TreeView nodes ID/array of TreeView node.
* @param {string | Element} target - Specifies ID of TreeView node/TreeView node as target element.
* @param {number} index - Specifies the index to place the moved nodes in the target element.
* @param { boolean } preventTargetExpand - If set to true, the target parent node will be prevented from auto expanding.
* @returns {void}
*/
moveNodes(sourceNodes, target, index, preventTargetExpand) {
if (isNullOrUndefined(sourceNodes) || sourceNodes.length === 0) {
return;
}
let dropLi = this.getElement(target);
const nodeData = [];
if (isNullOrUndefined(dropLi)) {
this.isHiddenItem = true;
this.ensureVisible(target);
this.isHiddenItem = false;
dropLi = this.getElement(target);
}
for (let i = 0; i < sourceNodes.length; i++) {
const dragLi = this.getElement(sourceNodes[parseInt(i.toString(), 10)]);
nodeData.push(this.getNode(dragLi));
if (isNullOrUndefined(dragLi) || dropLi.isSameNode(dragLi) || this.isDescendant(dragLi, dropLi)) {
continue;
}
this.preventExpand = preventTargetExpand;
this.dropAsChildNode(dragLi, dropLi, this, index, null, null, null, dropLi);
}
if (this.fields.dataSource instanceof DataManager === false) {
this.preventExpand = false;
}
this.triggerEvent('moveNodes', nodeData);
}
/**
* Refreshes a particular node of the TreeView.
*
* @param {string | Element} target - Specifies the ID of TreeView node or TreeView node as target element.
* @param {Object[]} newData - Specifies the new data of TreeView node.
* @returns {void}
* ```typescript
* var treeObj = document.getElementById("treeview").ej2_instances[0];
* var data = treeObj.getTreeData("01");
* var newData = {
* id: data[0].id,
* name: "new Text",
* };
* treeObj.refreshNode("01", [newData]);
* ```
*/
refreshNode(target, newData) {
if (isNullOrUndefined(target) || isNullOrUndefined(newData)) {
return;
}
let isRefreshChild = false;
if (this.dataType === 1 && newData.length > 1) {
isRefreshChild = true;
}
else if (this.dataType === 2 && newData.length === 1) {
const updatedChildValue = getValue(this.fields.child.toString(), newData[0]);
if (!isNullOrUndefined(updatedChildValue)) {
isRefreshChild = true;
}
}
let liEle = this.getElement(target);
const id = liEle ? liEle.getAttribute('data-uid') : ((target) ? target.toString() : null);
this.refreshData = this.getNodeObject(id);
newData = JSON.parse(JSON.stringify(newData));
let newNodeData;
let parentData;
if (this.dataType === 1 && isRefreshChild) {
for (let k = 0; k < newData.length; k++) {
if (isNullOrUndefined(newData[parseInt(k.toString(), 10)][this.fields.parentID])) {
parentData = newData[parseInt(k.toString(), 10)];
newData.splice(k, 1);
break;
}
}
newNodeData = extend({}, this.refreshData, parentData);
}
else {
newNodeData = extend({}, this.refreshData, newData[0]);
}
if (isNullOrUndefined(liEle)) {
this.updatePosition(id, newNodeData, isRefreshChild, newData);
return;
}
this.isRefreshed = true;
const level = parseFloat(liEle.getAttribute('aria-level'));
const newliEle = ListBase.createListItemFromJson(this.createElement, [newNodeData], this.listBaseOption, level);
const ul = select('.' + PARENTITEM, liEle);
const childItems = getValue(this.fields.child.toString(), newNodeData);
if ((isRefreshChild && ul) || (isRefreshChild && !isNullOrUndefined(childItems))) {
const parentEle = liEle.parentElement;
const index = Array.prototype.indexOf.call(parentEle.childNodes, liEle);
remove(liEle);
parentEle.insertBefore(newliEle[0], parentEle.childNodes[parseInt(index.toString(), 10)]);
this.updatePosition(id, newNodeData, isRefreshChild, newData);
if (isRefreshChild && ul) {
this.expandAll([id]);
}
}
else {
const txtEle = select('.' + TEXTWRAP, liEle);
const newTextEle = select('.' + TEXTWRAP, newliEle[0]);
const icon = select('div.' + ICON, txtEle);
const newIcon = select('div.' + ICON, newTextEle);
if (icon && newIcon) {
if (newIcon.classList.contains(EXPANDABLE) && icon.classList.contains(COLLAPSIBLE)) {
removeClass([newIcon], EXPANDABLE);
addClass([newIcon], COLLAPSIBLE);
}
else if (newIcon.classList.contains(COLLAPSIBLE) && icon.classList.contains(EXPANDABLE)) {
removeClass([newIcon], COLLAPSIBLE);
addClass([newIcon], EXPANDABLE);
}
else if (icon.classList.contains('interaction')) {
addClass([newIcon], 'interaction');
}
}
remove(txtEle);
const fullEle = select('.' + FULLROW, liEle);
fullEle.parentNode.insertBefore(newTextEle, fullEle.nextSibling);
this.updatePosition(id, newNodeData, isRefreshChild, newData);
}
liEle = this.getElement(target);
if (newNodeData[this.fields.tooltip]) {
liEle.setAttribute('title', newNodeData[this.fields.tooltip]);
}
if (Object.prototype.hasOwnProperty.call(newNodeData, this.fields.htmlAttributes) && newNodeData[this.fields.htmlAttributes]) {
const attr = {};
merge(attr, newNodeData[this.fields.htmlAttributes]);
if (attr.class) {
addClass([liEle], attr.class.split(' '));
delete attr.class;
}
else {
attributes(liEle, attr);
}
}
if (this.selectedNodes.indexOf(id) !== -1) {
liEle.setAttribute('aria-selected', 'true');
addClass([liEle], ACTIVE);
}
this.isRefreshed = false;
this.triggerEvent('refreshNode', [this.getNode(liEle)]);
}
/**
* Removes the collection of TreeView nodes by passing the array of node details as argument to this method.
*
* @param {string[] | Element[]} nodes - Specifies the array of TreeView nodes ID/array of TreeView node.
* @returns {void}
*/
removeNodes(nodes) {
if (!isNullOrUndefined(nodes)) {
if (this.fields.dataSource instanceof DataManager && !this.isOffline) {
this.crudOperation('delete', nodes);
}
else {
this.deleteSuccess(nodes);
}
}
}
/**
* Replaces the text of the TreeView node with the given text only when the `allowEditing` property is enabled.
*
* @param {string | Element} target - Specifies ID of TreeView node/TreeView node as target element.
* @param {string} newText - Specifies the new text of TreeView node.
* @returns {void}
*/
updateNode(target, newText) {
if (isNullOrUndefined(target) || isNullOrUndefined(newText) || !this.allowEditing) {
return;
}
const liEle = this.getElement(target);
if (isNullOrUndefined(liEle)) {
return;
}
const txtEle = select('.' + LISTTEXT, liEle);
this.updateOldText(liEle);
const eventArgs = this.getEditEvent(liEle, null, null);
this.trigger('nodeEditing', eventArgs, (observedArgs) => {
if (!observedArgs.cancel) {
if (this.fields.dataSource instanceof DataManager && !this.isOffline) {
this.crudOperation('update', null, target, newText, null, null, false);
}
else {
this.appendNewText(liEle, txtEle, newText, false);
}
}
});
}
/**
* Unchecks all the checked nodes. You can also uncheck the specific nodes by passing array of checked nodes
* as argument to this method.
*
* @param {string[] | Element[]} nodes - Specifies the array of TreeView nodes ID/array of TreeView node.
* @returns {void}
*/
uncheckAll(nodes) {
if (this.showCheckBox && this.checkedNodes.length > 0) {
this.doCheckBoxAction(nodes, false);
}
}
setNodeFocusable() {
const firstNode = select('.' + LISTITEM, this.element);
if (firstNode) {
firstNode.setAttribute('tabindex', '0');
this.updateIdAttr(null, firstNode);
}
}
};
__decorate$8([
Property(false)
], TreeView.prototype, "allowDragAndDrop", void 0);
__decorate$8([
Property(false)
], TreeView.prototype, "allowEditing", void 0);
__decorate$8([
Property(false)
], TreeView.prototype, "allowMultiSelection", void 0);
__decorate$8([
Property(false)
], TreeView.prototype, "allowTextWrap", void 0);
__decorate$8([
Complex({}, NodeAnimationSettings)
], TreeView.prototype, "animation", void 0);
__decorate$8([
Property()
], TreeView.prototype, "checkedNodes", void 0);
__decorate$8([
Property(true)
], TreeView.prototype, "checkDisabledChildren", void 0);
__decorate$8([
Property('')
], TreeView.prototype, "cssClass", void 0);
__decorate$8([
Property(false)
], TreeView.prototype, "disabled", void 0);
__decorate$8([
Property(null)
], TreeView.prototype, "dragArea", void 0);
__decorate$8([
Property(true)
], TreeView.prototype, "enableHtmlSanitizer", void 0);
__decorate$8([
Property(false)
], TreeView.prototype, "enablePersistence", void 0);
__decorate$8([
Property()
], TreeView.prototype, "expandedNodes", void 0);
__decorate$8([
Property('Auto')
], TreeView.prototype, "expandOn", void 0);
__decorate$8([
Complex({}, FieldsSettings)
], TreeView.prototype, "fields", void 0);
__decorate$8([
Property(true)
], TreeView.prototype, "fullRowSelect", void 0);
__decorate$8([
Property(true)
], TreeView.prototype, "loadOnDemand", void 0);
__decorate$8([
Property()
], TreeView.prototype, "locale", void 0);
__decorate$8([
Property()
], TreeView.prototype, "nodeTemplate", void 0);
__decorate$8([
Property()
], TreeView.prototype, "selectedNodes", void 0);
__decorate$8([
Property('None')
], TreeView.prototype, "sortOrder", void 0);
__decorate$8([
Property(false)
], TreeView.prototype, "showCheckBox", void 0);
__decorate$8([
Property(false)
], TreeView.prototype, "checkOnClick", void 0);
__decorate$8([
Property(true)
], TreeView.prototype, "autoCheck", void 0);
__decorate$8([
Property(false)
], TreeView.prototype, "fullRowNavigable", void 0);
__decorate$8([
Event()
], TreeView.prototype, "actionFailure", void 0);
__decorate$8([
Event()
], TreeView.prototype, "created", void 0);
__decorate$8([
Event()
], TreeView.prototype, "dataBound", void 0);
__decorate$8([
Event()
], TreeView.prototype, "dataSourceChanged", void 0);
__decorate$8([
Event()
], TreeView.prototype, "drawNode", void 0);
__decorate$8([
Event()
], TreeView.prototype, "destroyed", void 0);
__decorate$8([
Event()
], TreeView.prototype, "keyPress", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeChecked", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeChecking", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeClicked", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeCollapsed", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeCollapsing", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeDragging", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeDragStart", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeDragStop", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeDropped", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeEdited", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeEditing", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeExpanded", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeExpanding", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeSelected", void 0);
__decorate$8([
Event()
], TreeView.prototype, "nodeSelecting", void 0);
TreeView = TreeView_1 = __decorate$8([
NotifyPropertyChanges
], TreeView);
var __decorate$9 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const CONTROL$1 = 'e-control';
const ROOT$1 = 'e-sidebar';
const DOCKER = 'e-dock';
const CLOSE = 'e-close';
const OPEN = 'e-open';
const TRASITION = 'e-transition';
const DEFAULTBACKDROP = 'e-sidebar-overlay';
const RTL$2 = 'e-rtl';
const RIGHT = 'e-right';
const LEFT = 'e-left';
const OVER = 'e-over';
const PUSH = 'e-push';
const SLIDE = 'e-slide';
const VISIBILITY = 'e-visibility';
const DISPLAY = 'e-sidebar-display';
const MAINCONTENTANIMATION = 'e-content-animation';
const DISABLEANIMATION = 'e-disable-animation';
const CONTEXT = 'e-sidebar-context';
const SIDEBARABSOLUTE = 'e-sidebar-absolute';
/**
* Sidebar is an expandable or collapsible
* component that typically act as a side container to place the primary or secondary content alongside of the main content.
* ```html
* <aside id="sidebar">
* </aside>
* ```
* ```typescript
* <script>
* let sidebarObject: Sidebar = new Sidebar();
* sidebarObject.appendTo("#sidebar");
* </script>
* ```
*/
let Sidebar = class Sidebar extends Component {
constructor(options, element) {
super(options, element);
this.documentClickContext = this.documentclickHandler.bind(this);
}
preRender() {
this.setWidth();
}
render() {
this.initialize();
this.wireEvents();
this.renderComplete();
}
initialize() {
this.setTarget();
this.addClass();
this.setZindex();
if (this.enableDock) {
this.setDock();
}
if (this.isOpen) {
this.show();
this.firstRender = true;
}
else {
this.setMediaQuery();
}
this.checkType(true);
this.setType(this.type);
this.setCloseOnDocumentClick();
this.setEnableRTL();
if (Browser.isDevice) {
this.windowWidth = window.innerWidth;
}
}
setEnableRTL() {
(this.enableRtl ? addClass : removeClass)([this.element], RTL$2);
}
setTarget() {
this.targetEle = this.element.nextElementSibling;
this.sidebarEleCopy = this.element.cloneNode(true);
if (typeof (this.target) === 'string') {
this.setProperties({ target: document.querySelector(this.target) }, true);
}
if (this.target) {
this.target.insertBefore(this.element, this.target.children[0]);
addClass([this.element], SIDEBARABSOLUTE);
addClass([this.target], CONTEXT);
this.targetEle = this.getTargetElement();
}
}
getTargetElement() {
let siblingElement = this.element.nextElementSibling;
while (!isNullOrUndefined(siblingElement)) {
if (!siblingElement.classList.contains(ROOT$1)) {
break;
}
siblingElement = siblingElement.nextElementSibling;
}
return siblingElement;
}
setCloseOnDocumentClick() {
if (this.closeOnDocumentClick) {
document.addEventListener('mousedown', this.documentClickContext);
document.addEventListener('touchstart', this.documentClickContext);
}
else {
document.removeEventListener('mousedown', this.documentClickContext);
document.removeEventListener('touchstart', this.documentClickContext);
}
}
setWidth() {
if (this.enableDock && this.position === 'Left') {
setStyleAttribute(this.element, { 'width': this.setDimension(this.dockSize) });
}
else if (this.enableDock && this.position === 'Right') {
setStyleAttribute(this.element, { 'width': this.setDimension(this.dockSize) });
}
else if (!this.enableDock) {
setStyleAttribute(this.element, { 'width': this.setDimension(this.width) });
}
}
setDimension(width) {
if (typeof width === 'number') {
width = formatUnit(width);
}
else if (typeof width === 'string') {
width = (width.match(/px|%|em/)) ? width : formatUnit(width);
}
else {
width = '100%';
}
return width;
}
setZindex() {
setStyleAttribute(this.element, { 'z-index': '' + this.zIndex });
}
addClass() {
if (this.element.tagName === 'EJS-SIDEBAR') {
addClass([this.element], DISPLAY);
}
const classELement = document.querySelector('.e-main-content');
if (!isNullOrUndefined(classELement || this.targetEle)) {
addClass([classELement || this.targetEle], [MAINCONTENTANIMATION]);
}
this.tabIndex = this.element.hasAttribute('tabindex') ? this.element.getAttribute('tabindex') : null;
if (!this.enableDock && this.type !== 'Auto') {
addClass([this.element], [VISIBILITY]);
}
removeClass([this.element], [OPEN, CLOSE, RIGHT, LEFT, SLIDE, PUSH, OVER]);
this.element.classList.add(ROOT$1);
addClass([this.element], (this.position === 'Right') ? RIGHT : LEFT);
if (this.enableDock) {
addClass([this.element], DOCKER);
}
if (!isNullOrUndefined(this.tabIndex)) {
this.element.setAttribute('tabindex', this.tabIndex);
}
if (this.type === 'Auto' && !Browser.isDevice && this.checkMediaQuery()) {
this.show();
}
else if (!this.isOpen) {
addClass([this.element], [CLOSE, DISABLEANIMATION]);
}
}
checkType(val) {
if (!(this.type === 'Push' || this.type === 'Over' || this.type === 'Slide')) {
this.type = 'Auto';
}
else {
if (!this.element.classList.contains(CLOSE) && !val) {
this.hide();
}
}
}
transitionEnd(e) {
this.setDock();
if (!isNullOrUndefined(e) && !this.firstRender) {
this.triggerChange();
}
this.firstRender = false;
EventHandler.remove(this.element, 'transitionend', this.transitionEnd);
}
destroyBackDrop() {
const sibling = document.querySelector('.e-main-content') || this.targetEle;
if (this.target && this.showBackdrop && sibling && !isNullOrUndefined(this.defaultBackdropDiv)) {
removeClass([this.defaultBackdropDiv], DEFAULTBACKDROP);
this.defaultBackdropDiv.remove();
this.defaultBackdropDiv = null;
}
else if (this.showBackdrop && this.modal) {
this.modal.style.display = 'none';
this.modal.outerHTML = '';
this.modal = null;
}
}
/**
* Hide the Sidebar component, if it is in an open state.
*
* @param {Event} e - The event triggering the hide action.
* @returns {void}
*
*/
hide(e) {
const closeArguments = {
model: this,
element: this.element,
cancel: false,
isInteracted: !isNullOrUndefined(e),
event: (e || null)
};
this.trigger('close', closeArguments, (observedcloseArgs) => {
if (!observedcloseArgs.cancel) {
if (this.element.classList.contains(CLOSE)) {
return;
}
if (this.element.classList.contains(OPEN) && !this.animate) {
this.triggerChange();
}
addClass([this.element], CLOSE);
removeClass([this.element], OPEN);
setStyleAttribute(this.element, { 'width': formatUnit(this.enableDock ? this.dockSize : this.width) });
this.setType(this.type);
const sibling = document.querySelector('.e-main-content') || this.targetEle;
if (!this.enableDock && sibling) {
sibling.style.transform = 'translateX(' + 0 + 'px)';
sibling.style[this.position === 'Left' ? 'marginLeft' : 'marginRight'] = '0px';
}
this.destroyBackDrop();
this.setAnimation();
if (this.type === 'Slide') {
document.body.classList.remove('e-sidebar-overflow');
}
this.setProperties({ isOpen: false }, true);
if (this.enableDock) {
setTimeout(() => this.setTimeOut(), 50);
}
EventHandler.add(this.element, 'transitionend', this.transitionEnd, this);
}
});
}
setTimeOut() {
const sibling = document.querySelector('.e-main-content') || this.targetEle;
const elementWidth = this.element.getBoundingClientRect().width;
if (this.element.classList.contains(OPEN) && sibling && !(this.type === 'Over' && this.enableDock)) {
if (this.position === 'Left') {
sibling.style.marginLeft = this.setDimension(this.width === 'auto' ? elementWidth : this.width);
}
else {
sibling.style.marginRight = this.setDimension(this.width === 'auto' ? elementWidth : this.width);
}
}
else if (this.element.classList.contains(CLOSE) && sibling) {
if (this.position === 'Left') {
sibling.style.marginLeft = this.setDimension(this.dockSize === 'auto' ? elementWidth : this.dockSize);
}
else {
sibling.style.marginRight = this.setDimension(this.dockSize === 'auto' ? elementWidth : this.dockSize);
}
}
}
/**
* Shows the Sidebar component, if it is in closed state.
*
* @param {Event} e - The optional event triggering the show action.
* @returns {void}
*/
show(e) {
const openArguments = {
model: this,
element: this.element,
cancel: false,
isInteracted: !isNullOrUndefined(e),
event: (e || null)
};
this.trigger('open', openArguments, (observedopenArgs) => {
if (!observedopenArgs.cancel) {
removeClass([this.element], [VISIBILITY, DISABLEANIMATION]);
if (this.element.classList.contains(OPEN)) {
return;
}
if (this.element.classList.contains(CLOSE) && !this.animate) {
this.triggerChange();
}
addClass([this.element], [OPEN, TRASITION]);
setStyleAttribute(this.element, { 'transform': '' });
removeClass([this.element], CLOSE);
setStyleAttribute(this.element, { 'width': formatUnit(this.width) });
this.setType(this.type);
if (this.targetEle && !this.targetEle.querySelector('.e-sidebar-overlay')) {
this.createBackDrop();
}
this.setAnimation();
if (this.type === 'Slide') {
document.body.classList.add('e-sidebar-overflow');
}
this.setProperties({ isOpen: true }, true);
EventHandler.add(this.element, 'transitionend', this.transitionEnd, this);
}
});
}
setAnimation() {
if (this.animate) {
removeClass([this.element], DISABLEANIMATION);
}
else {
addClass([this.element], DISABLEANIMATION);
}
}
triggerChange() {
const changeArguments = { name: 'change', element: this.element };
this.trigger('change', changeArguments);
}
setDock() {
if (this.enableDock && this.position === 'Left' && !this.getState()) {
setStyleAttribute(this.element, { 'transform': 'translateX(' + -100 + '%) translateX(' + this.setDimension(this.dockSize) + ')' });
}
else if (this.enableDock && this.position === 'Right' && !this.getState()) {
setStyleAttribute(this.element, { 'transform': 'translateX(' + 100 + '%) translateX(' + '-' + this.setDimension(this.dockSize) + ')' });
}
if (this.element.classList.contains(CLOSE) && this.enableDock) {
setStyleAttribute(this.element, { 'width': this.setDimension(this.dockSize) });
}
}
createBackDrop() {
if (this.target && this.showBackdrop && this.getState()) {
const targetString = this.target;
const sibling = document.querySelector('.e-main-content') || this.targetEle;
this.defaultBackdropDiv = this.createElement('div');
addClass([this.defaultBackdropDiv], DEFAULTBACKDROP);
setStyleAttribute(this.defaultBackdropDiv, { height: targetString.style.height });
sibling.appendChild(this.defaultBackdropDiv);
}
else if (this.showBackdrop && !this.modal && this.getState()) {
this.modal = this.createElement('div');
this.modal.className = DEFAULTBACKDROP;
this.modal.style.display = 'block';
document.body.appendChild(this.modal);
}
}
getPersistData() {
return this.addOnPersist(['type', 'position', 'isOpen']);
}
/**
* Returns the current module name.
*
* @returns {string} - returns module name.
* @private
*
*/
getModuleName() {
return 'sidebar';
}
/**
* Shows or hides the Sidebar based on the current state.
*
* @returns {void}
*/
toggle() {
if (this.element.classList.contains(OPEN)) {
this.hide();
}
else {
this.show();
}
}
getState() {
return this.element.classList.contains(OPEN) ? true : false;
}
setMediaQuery() {
if (this.mediaQuery) {
let media = false;
if (typeof (this.mediaQuery) === 'string') {
media = window.matchMedia(this.mediaQuery).matches;
}
else {
media = (this.mediaQuery).matches;
}
if (media && this.windowWidth !== window.innerWidth) {
this.show();
}
else if (this.getState() && this.windowWidth !== window.innerWidth) {
this.hide();
}
}
}
checkMediaQuery() {
if (isNullOrUndefined(this.mediaQuery)) {
return true;
}
return (typeof (this.mediaQuery) === 'string') ?
window.matchMedia(this.mediaQuery).matches : (this.mediaQuery).matches;
}
resize() {
if (!isNullOrUndefined(this.width) && this.width !== 'auto' && typeof this.width === 'string' && !this.width.includes('px')) {
this.setType(this.type);
}
if (this.type === 'Auto') {
if (Browser.isDevice) {
addClass([this.element], OVER);
}
else {
addClass([this.element], PUSH);
}
}
this.setMediaQuery();
if (Browser.isDevice) {
this.windowWidth = window.innerWidth;
}
}
documentclickHandler(e) {
if (closest(e.target, '.' + CONTROL$1 + '' + '.' + ROOT$1)) {
return;
}
this.hide(e);
}
enableGestureHandler(args) {
if (!this.isOpen && this.position === 'Left' && args.swipeDirection === 'Right' &&
(args.startX <= 20 && args.distanceX >= 50 && args.velocity >= 0.5)) {
this.show();
}
else if (this.isOpen && this.position === 'Left' && args.swipeDirection === 'Left') {
this.hide(args.originalEvent);
}
else if (this.isOpen && this.position === 'Right' && args.swipeDirection === 'Right') {
this.hide(args.originalEvent);
}
else if (!this.isOpen && this.position === 'Right' && args.swipeDirection === 'Left'
&& (window.innerWidth - args.startX <= 20 && args.distanceX >= 50 && args.velocity >= 0.5)) {
this.show();
}
}
setEnableGestures() {
if (this.enableGestures) {
this.mainContentEle = new Touch(document.body, { swipe: this.enableGestureHandler.bind(this) });
this.sidebarEle = new Touch(this.element, { swipe: this.enableGestureHandler.bind(this) });
}
else {
if (this.mainContentEle && this.sidebarEle) {
this.mainContentEle.destroy();
this.sidebarEle.destroy();
}
}
}
wireEvents() {
this.setEnableGestures();
EventHandler.add(window, 'resize', this.resize, this);
}
unWireEvents() {
EventHandler.remove(window, 'resize', this.resize);
EventHandler.remove(document, 'mousedown touchstart', this.documentclickHandler);
if (this.mainContentEle) {
this.mainContentEle.destroy();
}
if (this.sidebarEle) {
this.sidebarEle.destroy();
}
}
/**
* Called internally if any of the property value changed.
*
* @param {SidebarModel} newProp - specifies newProp value.
* @param {SidebarModel} oldProp - specifies oldProp value.
* @returns {void}
* @private
*
*/
onPropertyChanged(newProp, oldProp) {
const sibling = document.querySelector('.e-main-content') || this.targetEle;
const isRendered = this.isServerRendered;
for (const prop of Object.keys(newProp)) {
switch (prop) {
case 'isOpen':
if (this.isOpen) {
this.show();
}
else {
this.hide();
}
break;
case 'width':
this.setWidth();
if (!this.getState()) {
this.setDock();
}
break;
case 'animate':
this.setAnimation();
break;
case 'type':
this.checkType(false);
removeClass([this.element], [VISIBILITY]);
this.addClass();
addClass([this.element], this.type === 'Auto' ? (Browser.isDevice ? ['e-over'] :
['e-push']) : ['e-' + this.type.toLowerCase()]);
break;
case 'position':
this.element.style.transform = '';
this.setDock();
if (sibling) {
sibling.style[this.position === 'Left' ? 'marginRight' : 'marginLeft'] = '0px';
}
if (this.position === 'Right') {
removeClass([this.element], LEFT);
addClass([this.element], RIGHT);
}
else {
removeClass([this.element], RIGHT);
addClass([this.element], LEFT);
}
this.setType(this.type);
break;
case 'showBackdrop':
if (this.showBackdrop) {
this.createBackDrop();
}
else {
if (this.modal) {
this.modal.style.display = 'none';
this.modal.outerHTML = '';
this.modal = null;
}
}
break;
case 'target':
if (typeof (this.target) === 'string') {
this.setProperties({ target: document.querySelector(this.target) }, true);
}
if (isNullOrUndefined(this.target)) {
removeClass([this.element], SIDEBARABSOLUTE);
removeClass([oldProp.target], CONTEXT);
setStyleAttribute(sibling, { 'margin-left': 0, 'margin-right': 0 });
document.body.insertAdjacentElement('afterbegin', this.element);
}
this.isServerRendered = false;
super.refresh();
this.isServerRendered = isRendered;
break;
case 'closeOnDocumentClick':
this.setCloseOnDocumentClick();
break;
case 'enableDock':
if (!this.getState()) {
this.setDock();
}
break;
case 'zIndex':
this.setZindex();
break;
case 'mediaQuery':
this.setMediaQuery();
break;
case 'enableGestures':
this.setEnableGestures();
break;
case 'enableRtl':
this.setEnableRTL();
break;
}
}
}
setType(type) {
const elementWidth = this.element.getBoundingClientRect().width;
this.setZindex();
const sibling = document.querySelector('.e-main-content') || this.targetEle;
if (sibling) {
sibling.style.transform = 'translateX(' + 0 + 'px)';
if (!Browser.isDevice && this.type !== 'Auto' && !(this.type === 'Over' && this.enableDock)) {
sibling.style[this.position === 'Left' ? 'marginLeft' : 'marginRight'] = '0px';
}
}
const margin = this.position === 'Left' ? elementWidth + 'px' : elementWidth + 'px';
const eleWidth = this.position === 'Left' ? elementWidth : -(elementWidth);
removeClass([this.element], [PUSH, OVER, SLIDE]);
switch (type) {
case 'Push':
addClass([this.element], [PUSH]);
if (sibling && (this.enableDock || this.element.classList.contains(OPEN))) {
sibling.style[this.position === 'Left' ? 'marginLeft' : 'marginRight'] = margin;
}
break;
case 'Slide':
addClass([this.element], [SLIDE]);
if (sibling && (this.enableDock || this.element.classList.contains(OPEN))) {
sibling.style.transform = 'translateX(' + eleWidth + 'px)';
}
break;
case 'Over':
addClass([this.element], [OVER]);
if (this.enableDock && (this.element.classList.contains(CLOSE) || this.isOpen)) {
if (sibling) {
sibling.style[this.position === 'Left' ? 'marginLeft' : 'marginRight'] = this.setDimension(this.dockSize);
}
}
break;
case 'Auto':
addClass([this.element], [TRASITION]);
if (Browser.isDevice) {
if (sibling && (this.enableDock) && !this.getState()) {
sibling.style[this.position === 'Left' ? 'marginLeft' : 'marginRight'] = margin;
addClass([this.element], PUSH);
}
else {
addClass([this.element], OVER);
}
}
else {
addClass([this.element], PUSH);
if (sibling && (this.enableDock || this.element.classList.contains(OPEN))) {
sibling.style[this.position === 'Left' ? 'marginLeft' : 'marginRight'] = margin;
}
}
this.createBackDrop();
}
}
/**
* Removes the control from the DOM and detaches all its related event handlers. Also it removes the attributes and classes.
*
* @returns {void}
*
*/
destroy() {
super.destroy();
if (this.target) {
removeClass([this.target], CONTEXT);
}
this.destroyBackDrop();
if (this.element) {
removeClass([this.element], [OPEN, CLOSE, PUSH, SLIDE, OVER, LEFT, RIGHT, TRASITION, DISABLEANIMATION]);
removeClass([this.element], SIDEBARABSOLUTE);
this.element.style.width = '';
this.element.style.zIndex = '';
this.element.style.transform = '';
if (!isNullOrUndefined(this.sidebarEleCopy.getAttribute('tabindex'))) {
this.element.setAttribute('tabindex', this.tabIndex);
}
else {
this.element.removeAttribute('tabindex');
}
}
this.windowWidth = null;
const sibling = document.querySelector('.e-main-content') || this.targetEle;
if (!isNullOrUndefined(sibling)) {
sibling.style.margin = '';
sibling.style.transform = '';
}
this.unWireEvents();
}
};
__decorate$9([
Property('auto')
], Sidebar.prototype, "dockSize", void 0);
__decorate$9([
Property(null)
], Sidebar.prototype, "mediaQuery", void 0);
__decorate$9([
Property(false)
], Sidebar.prototype, "enableDock", void 0);
__decorate$9([
Property('en-US')
], Sidebar.prototype, "locale", void 0);
__decorate$9([
Property(false)
], Sidebar.prototype, "enablePersistence", void 0);
__decorate$9([
Property(true)
], Sidebar.prototype, "enableGestures", void 0);
__decorate$9([
Property(false)
], Sidebar.prototype, "isOpen", void 0);
__decorate$9([
Property(false)
], Sidebar.prototype, "enableRtl", void 0);
__decorate$9([
Property(true)
], Sidebar.prototype, "animate", void 0);
__decorate$9([
Property('auto')
], Sidebar.prototype, "height", void 0);
__decorate$9([
Property(false)
], Sidebar.prototype, "closeOnDocumentClick", void 0);
__decorate$9([
Property('Left')
], Sidebar.prototype, "position", void 0);
__decorate$9([
Property(null)
], Sidebar.prototype, "target", void 0);
__decorate$9([
Property(false)
], Sidebar.prototype, "showBackdrop", void 0);
__decorate$9([
Property('Auto')
], Sidebar.prototype, "type", void 0);
__decorate$9([
Property('auto')
], Sidebar.prototype, "width", void 0);
__decorate$9([
Property(1000)
], Sidebar.prototype, "zIndex", void 0);
__decorate$9([
Event()
], Sidebar.prototype, "created", void 0);
__decorate$9([
Event()
], Sidebar.prototype, "close", void 0);
__decorate$9([
Event()
], Sidebar.prototype, "open", void 0);
__decorate$9([
Event()
], Sidebar.prototype, "change", void 0);
__decorate$9([
Event()
], Sidebar.prototype, "destroyed", void 0);
Sidebar = __decorate$9([
NotifyPropertyChanges
], Sidebar);
var __decorate$a = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const ICONRIGHT = 'e-icon-right';
const ITEMTEXTCLASS = 'e-breadcrumb-text';
const ICONCLASS = 'e-breadcrumb-icon';
const MENUCLASS = 'e-breadcrumb-menu';
const ITEMCLASS = 'e-breadcrumb-item';
const POPUPCLASS = 'e-breadcrumb-popup';
const WRAPMODECLASS = 'e-breadcrumb-wrap-mode';
const SCROLLMODECLASS = 'e-breadcrumb-scroll-mode';
const TABINDEX = 'tabindex';
const DISABLEDCLASS = 'e-disabled';
const ARIADISABLED = 'aria-disabled';
const DOT = '.';
/**
* Defines the Breadcrumb overflow modes.
*/
var BreadcrumbOverflowMode;
(function (BreadcrumbOverflowMode) {
/**
* Hidden mode shows the maximum number of items possible in the container space and hides the remaining items.
* Clicking on a previous item will make the hidden item visible.
*/
BreadcrumbOverflowMode["Hidden"] = "Hidden";
/**
* Collapsed mode shows the first and last Breadcrumb items and hides the remaining items with a collapsed icon.
* When the collapsed icon is clicked, all items become visible and navigable.
*/
BreadcrumbOverflowMode["Collapsed"] = "Collapsed";
/**
* Menu mode shows the number of Breadcrumb items that can be accommodated within the container space and creates a submenu with the remaining items.
*/
BreadcrumbOverflowMode["Menu"] = "Menu";
/**
* Wrap mode wraps the items to multiple lines when the Breadcrumb’s width exceeds the container space.
*/
BreadcrumbOverflowMode["Wrap"] = "Wrap";
/**
* Scroll mode shows an HTML scroll bar when the Breadcrumb’s width exceeds the container space.
*/
BreadcrumbOverflowMode["Scroll"] = "Scroll";
/**
* None mode shows all the items in a single line.
*/
BreadcrumbOverflowMode["None"] = "None";
})(BreadcrumbOverflowMode || (BreadcrumbOverflowMode = {}));
class BreadcrumbItem extends ChildProperty {
}
__decorate$a([
Property('')
], BreadcrumbItem.prototype, "text", void 0);
__decorate$a([
Property('')
], BreadcrumbItem.prototype, "id", void 0);
__decorate$a([
Property('')
], BreadcrumbItem.prototype, "url", void 0);
__decorate$a([
Property(null)
], BreadcrumbItem.prototype, "iconCss", void 0);
__decorate$a([
Property(false)
], BreadcrumbItem.prototype, "disabled", void 0);
/**
* Breadcrumb is a graphical user interface that helps to identify or highlight the current location within a hierarchical structure of websites.
* The aim is to make the user aware of their current position in a hierarchy of website links.
* ```html
* <nav id='breadcrumb'></nav>
* ```
* ```typescript
* <script>
* var breadcrumbObj = new Breadcrumb({ items: [{ text: 'Home', url: '/' }, { text: 'Index', url: './index.html }]});
* breadcrumbObj.appendTo("#breadcrumb");
* </script>
* ```
*/
let Breadcrumb = class Breadcrumb extends Component {
/**
* Constructor for creating the widget.
*
* @private
* @param {BreadcrumbModel} options - Specifies the Breadcrumb model.
* @param {string | HTMLElement} element - Specifies the element.
*/
constructor(options, element) {
super(options, element);
this.isPopupCreated = false;
}
/**
* @private
* @returns {void}
*/
preRender() {
// pre render code
}
/**
* Initialize the control rendering.
*
* @private
* @returns {void}
*/
render() {
this.initialize();
this.renderItems(this.items);
this.wireEvents();
}
initialize() {
this._maxItems = this.maxItems;
if (isNullOrUndefined(this.element.getAttribute('aria-label'))) {
this.element.setAttribute('aria-label', 'breadcrumb');
}
if (this.cssClass) {
addClass([this.element], this.cssClass.replace(/\s+/g, ' ').trim().split(' '));
}
if (this.enableRtl) {
this.element.classList.add('e-rtl');
}
if (this.disabled) {
this.element.classList.add(DISABLEDCLASS);
this.element.setAttribute(ARIADISABLED, 'true');
}
if (this.overflowMode === 'Wrap') {
this.element.classList.add(WRAPMODECLASS);
}
else if (this.overflowMode === 'Scroll') {
this.element.classList.add(SCROLLMODECLASS);
}
this.initItems();
this.initPvtProps();
}
initPvtProps() {
if (this.overflowMode === 'Hidden' && this._maxItems > 0) {
this.endIndex = this.getEndIndex();
this.startIndex = this.endIndex + 1 - (this._maxItems - 1);
}
if (this.overflowMode === 'Menu') {
if (this._maxItems >= 0) {
this.startIndex = this._maxItems > 1 ? 1 : 0;
this.endIndex = this.getEndIndex();
this.popupUl = this.createElement('ul', { attrs: { TABINDEX: '0', 'role': 'menu' } });
}
else {
this.startIndex = this.endIndex = null;
}
}
}
getEndIndex() {
let endIndex;
if (this.activeItem) {
this.items.forEach((item, idx) => {
if (item.url === this.activeItem || item.text === this.activeItem) {
endIndex = idx;
}
});
}
else {
endIndex = this.items.length - 1;
}
return endIndex;
}
initItems() {
if (!this.items.length) {
let baseUri;
let uri;
const items = [];
if (this.url) {
const url = new URL(this.url, window.location.origin);
baseUri = url.origin + '/';
uri = url.href.split(baseUri)[1].split('/');
}
else {
baseUri = window.location.origin + '/';
uri = window.location.href.split(baseUri)[1].split('/');
}
items.push({ iconCss: 'e-icons e-home', url: baseUri });
for (let i = 0; i < uri.length; i++) {
if (uri[i]) {
items.push({ text: uri[i], url: baseUri + uri[i] });
baseUri += uri[i] + '/';
}
}
this.setProperties({ items: items }, true);
}
}
renderItems(items) {
let item;
let isSingleLevel;
const isIconRight = this.element.classList.contains(ICONRIGHT);
const itemsLength = items.length;
if (itemsLength) {
let isActiveItem;
let isLastItem;
let isLastItemInPopup;
let j = 0;
let wrapDiv;
const len = (itemsLength * 2) - 1;
let isItemCancelled = false;
const ol = this.createElement('ol', { className: this.overflowMode === 'Wrap' ? 'e-breadcrumb-wrapped-ol' : '' });
const firstOl = this.createElement('ol', { className: this.overflowMode === 'Wrap' ? 'e-breadcrumb-first-ol' : '' });
const showIcon = this.hasField(items, 'iconCss');
const isCollasped = (this.overflowMode === 'Collapsed' && this._maxItems > 0 && itemsLength > this._maxItems && !this.isExpanded);
const isDefaultOverflowMode = (this.overflowMode === 'Hidden' && this._maxItems > 0);
if (this.overflowMode === 'Menu' && this.popupUl) {
this.popupUl.innerHTML = '';
}
const listBaseOptions = {
moduleName: this.getModuleName(),
showIcon: showIcon,
itemNavigable: true,
itemCreated: (args) => {
const isLastItem = args.curData.isLastItem;
if (isLastItem && args.item.children.length && !this.itemTemplate) {
delete args.curData.isLastItem;
if (!isLastItemInPopup && !this.enableActiveItemNavigation) {
args.item.innerHTML = this.createElement('span', { className: ITEMTEXTCLASS, innerHTML: args.item.children[0].innerHTML }).outerHTML;
}
}
if (args.curData.iconCss && !args.curData.text && !this.itemTemplate) {
args.item.classList.add('e-icon-item');
}
if (isDefaultOverflowMode) {
args.item.setAttribute('item-index', j.toString());
}
const eventArgs = {
item: extend({}, args.curData.properties ?
args.curData.properties : args.curData), element: args.item, cancel: false
};
this.trigger('beforeItemRender', eventArgs);
isItemCancelled = eventArgs.cancel;
const containsRightIcon = (isIconRight || eventArgs.element.classList.contains(ICONRIGHT));
if (containsRightIcon && args.curData.iconCss && !this.itemTemplate) {
args.item.querySelector('.e-anchor-wrap').appendChild(args.item.querySelector(DOT + ICONCLASS));
}
if (eventArgs.item.disabled) {
args.item.setAttribute(ARIADISABLED, 'true');
args.item.classList.add(DISABLEDCLASS);
}
if (eventArgs.item.id) {
args.item.setAttribute('id', eventArgs.item.id);
}
if ((eventArgs.item.disabled || this.disabled) && args.item.children.length && !this.itemTemplate) {
args.item.children[0].setAttribute(TABINDEX, '-1');
}
if (args.curData.isEmptyUrl) {
args.item.children[0].removeAttribute('href');
if ((!isLastItem || (isLastItem && this.enableActiveItemNavigation)) && !(eventArgs.item.disabled
|| this.disabled)) {
args.item.children[0].setAttribute(TABINDEX, '0');
EventHandler.add(args.item.children[0], 'keydown', this.keyDownHandler, this);
}
}
args.item.removeAttribute('role');
if (isLastItem) {
args.item.setAttribute('data-active-item', '');
args.item.setAttribute('aria-current', 'page');
}
else {
args.item.removeAttribute('aria-current');
}
if (!this.itemTemplate) {
this.beforeItemRenderChanges(args.curData, eventArgs.item, args.item, containsRightIcon);
}
}
};
for (let i = 0; i < len; (i % 2 && j++), i++) {
isActiveItem = (this.activeItem && (this.activeItem === items[j].url ||
this.activeItem === items[j].text));
if (isCollasped && i > 1 && i < len - 2) {
continue;
}
else if (isDefaultOverflowMode && ((j < this.startIndex || j > this.endIndex)
&& (i % 2 ? j !== this.startIndex - 1 : true)) && j !== 0) {
continue;
}
if (i % 2) {
// separator item
wrapDiv = this.createElement('div', { className: 'e-breadcrumb-item-wrapper' });
if ((this.separatorTemplate && this.separatorTemplate === '/') || isNullOrUndefined(this.separatorTemplate)) {
listBaseOptions.template = initializeCSPTemplate(function () {
return '/';
});
}
else {
listBaseOptions.template = this.separatorTemplate;
}
listBaseOptions.itemClass = 'e-breadcrumb-separator';
isSingleLevel = false;
item = [{ previousItem: items[j], nextItem: items[j + 1] }];
}
else {
// list item
listBaseOptions.itemClass = '';
if (this.itemTemplate) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
listBaseOptions.template = this.itemTemplate;
isSingleLevel = false;
}
else {
isSingleLevel = true;
}
item = [extend({}, items[j].properties ?
items[j].properties
: items[j])];
if (!item[0].url && !this.itemTemplate) {
item = [extend({}, item[0], { isEmptyUrl: true, url: '#' })];
}
isLastItem = (isDefaultOverflowMode || this.overflowMode === 'Menu') && (j === this.endIndex);
if (((i === len - 1 || isLastItem) && !this.itemTemplate) || isActiveItem) {
item[0].isLastItem = true;
}
}
let parent = ol;
const lastPopupItemIdx = this.startIndex + this.endIndex - this._maxItems;
if (this.overflowMode === 'Menu' && ((j >= this.startIndex && (j <= lastPopupItemIdx && (i % 2 ? !(j === lastPopupItemIdx) : true)) && this.endIndex >= this._maxItems && this._maxItems > 0) || this._maxItems === 0)) {
if (i % 2) {
continue;
}
else {
parent = this.popupUl;
if (isLastItem) {
isLastItemInPopup = true;
}
}
}
else if (this.overflowMode === 'Wrap') {
if (i === 0) {
parent = firstOl;
}
else {
parent = wrapDiv;
}
}
const li = ListBase.createList(this.createElement, item, listBaseOptions, isSingleLevel, this).childNodes;
if (!isItemCancelled) {
append(li, parent);
}
else if (isDefaultOverflowMode || isCollasped || this.overflowMode === 'Menu' || this.overflowMode === 'Wrap') {
items.splice(j, 1);
this.initPvtProps();
return this.reRenderItems();
}
else if ((i === len - 1 || isLastItem)) {
remove(parent.lastElementChild);
}
if (this.overflowMode === 'Wrap' && i !== 0 && i % 2 === 0) {
ol.appendChild(wrapDiv);
}
if (isCollasped && i === 1) {
const li = this.createElement('li', { className: 'e-icons e-breadcrumb-collapsed', attrs: { TABINDEX: '0' } });
EventHandler.add(li, 'keyup', this.expandHandler, this);
ol.appendChild(li);
}
if (this.overflowMode === 'Menu' && this.startIndex === i && this.endIndex >= this._maxItems && this._maxItems >= 0) {
const menu = this.getMenuElement();
EventHandler.add(menu, 'keyup', this.keyDownHandler, this);
ol.appendChild(menu);
}
if (isActiveItem || isLastItem) {
break;
}
if (isItemCancelled) {
i++;
}
}
if (this.isReact) {
this.renderReactTemplates();
setTimeout(() => {
this.calculateMaxItems();
}, 5);
}
if (this.overflowMode === 'Wrap') {
this.element.appendChild(firstOl);
}
this.element.appendChild(ol);
if (!this.isReact) {
this.calculateMaxItems();
}
}
}
calculateMaxItems() {
if (this.overflowMode === 'Hidden' || this.overflowMode === 'Collapsed' || this.overflowMode === 'Menu') {
let maxItems;
const width = this.element.offsetWidth;
const liElems = [].slice.call(this.element.children[0].children).reverse();
let liWidth = this.overflowMode === 'Menu' ? 0 : liElems[liElems.length - 1].offsetWidth + (liElems[liElems.length - 2] ? liElems[liElems.length - 2].offsetWidth : 0);
if (this.overflowMode === 'Menu') {
const menuEle = this.getMenuElement();
this.element.appendChild(menuEle);
liWidth += menuEle.offsetWidth;
remove(menuEle);
}
for (let i = 0; i < liElems.length - 2; i++) {
if (liWidth > width) {
maxItems = Math.ceil((i - 1) / 2) + ((this.overflowMode === 'Menu' && i <= 2) ? 0 : 1);
if (((this.maxItems > maxItems && !(this.maxItems > -1 && maxItems === -1)) ||
this.maxItems === -1) && this._maxItems !== maxItems) {
this._maxItems = maxItems;
this.initPvtProps();
return this.reRenderItems();
}
else {
break;
}
}
else {
if (this.overflowMode === 'Menu' && i === 2) {
liWidth += liElems[liElems.length - 1].offsetWidth + liElems[liElems.length - 2].offsetWidth;
if (liWidth > width) {
this._maxItems = 1;
this.initPvtProps();
return this.reRenderItems();
}
}
if (!(this.overflowMode === 'Menu' && liElems[i].classList.contains(MENUCLASS))) {
liWidth += liElems[i].offsetWidth;
}
}
}
}
else if ((this.overflowMode === 'Wrap' || this.overflowMode === 'Scroll') && this._maxItems > 0) {
let width = 0;
const liElems = this.element.querySelectorAll(DOT + ITEMCLASS);
if (liElems.length > this._maxItems + this._maxItems - 1) {
for (let i = this.overflowMode === 'Wrap' ? 1 : 0; i < this._maxItems + this._maxItems - 1; i++) {
width += liElems[i].offsetWidth;
}
width = width + 5 + (parseInt(getComputedStyle(this.element.children[0]).paddingLeft, 10) * 2);
if (this.overflowMode === 'Wrap') {
this.element.querySelector('.e-breadcrumb-wrapped-ol').style.width = width + 'px';
}
else {
this.element.style.width = width + 'px';
}
}
}
}
hasField(items, field) {
for (let i = 0, len = items.length; i < len; i++) {
if (items[i][`${field}`]) {
return true;
}
}
return false;
}
getMenuElement() {
return this.createElement('li', { className: 'e-icons e-breadcrumb-menu', attrs: { TABINDEX: '0' } });
}
beforeItemRenderChanges(prevItem, currItem, elem, isRightIcon) {
const wrapElem = elem.querySelector('.e-anchor-wrap');
if (currItem.text !== prevItem.text && wrapElem) {
wrapElem.childNodes.forEach((child) => {
if (child.nodeType === Node.TEXT_NODE) {
child.textContent = currItem.text;
}
});
}
if (currItem.iconCss !== prevItem.iconCss && wrapElem) { // wrapElem - for checking it is item not a separator
const iconElem = elem.querySelector(DOT + ICONCLASS);
if (iconElem) {
if (currItem.iconCss) {
removeClass([iconElem], prevItem.iconCss.split(' '));
addClass([iconElem], currItem.iconCss.split(' '));
}
else {
remove(iconElem);
}
}
else if (currItem.iconCss) {
const iconElem = this.createElement('span', { className: ICONCLASS + ' ' + currItem.iconCss });
if (isRightIcon) {
append([iconElem], wrapElem);
}
else {
wrapElem.insertBefore(iconElem, wrapElem.childNodes[0]);
}
}
}
if (currItem.url !== prevItem.url && this.enableNavigation) {
const anchor = elem.querySelector('a.' + ITEMTEXTCLASS);
if (anchor) {
if (currItem.url) {
anchor.setAttribute('href', currItem.url);
}
else {
anchor.removeAttribute('href');
}
}
}
}
reRenderItems() {
if (this.overflowMode === 'Menu' && this.popupObj && this.popupObj.element.classList.contains('e-popup-open') && this.popupObj.element.querySelector('.e-edit-template')) {
this.popupObj.hide();
this.popupObj.destroy();
this.isPopupCreated = false;
detach(this.popupObj.element);
}
this.element.innerHTML = '';
this.renderItems(this.items);
}
clickHandler(e) {
const li = closest(e.target, DOT + ITEMCLASS + ':not(.e-breadcrumb-separator)');
if (!this.enableNavigation) {
e.preventDefault();
}
if (li && (closest(e.target, DOT + ITEMTEXTCLASS) || this.itemTemplate)) {
let idx;
if (this.overflowMode === 'Wrap') {
idx = [].slice.call(this.element.querySelectorAll(DOT + ITEMCLASS)).indexOf(li);
}
else {
idx = [].slice.call(li.parentElement.children).indexOf(li);
}
if (this.overflowMode === 'Menu') {
if (closest(e.target, DOT + POPUPCLASS)) {
idx += this.startIndex;
this.endIndex = idx;
if (e.type === 'keydown') {
this.documentClickHandler(e);
}
}
else if (this.element.querySelector(DOT + MENUCLASS)) {
if (idx > [].slice.call(this.element.children[0].children).indexOf(this.element.querySelector(DOT + MENUCLASS))) {
idx += (this.popupUl.childElementCount * 2) - 2;
idx = Math.floor(idx / 2);
this.endIndex = idx;
}
else {
this.startIndex = this.endIndex = idx;
}
}
else {
idx = Math.floor(idx / 2);
this.startIndex = this.endIndex = idx;
}
}
else {
idx = Math.floor(idx / 2);
}
if (this.overflowMode === 'Hidden' && this._maxItems > 0 && this.endIndex !== 0) {
idx = parseInt(li.getAttribute('item-index'), 10);
if (this.startIndex > 1) {
this.startIndex -= (this.endIndex - idx);
}
this.endIndex = idx;
}
const itemClickArgs = { element: li,
item: this.items[idx], event: e, cancel: false };
this.trigger('itemClick', itemClickArgs);
if (itemClickArgs.cancel) {
return;
}
if (this.items[idx]) {
this.activeItem = this.items[idx].url || this.items[idx].text;
}
this.dataBind();
}
if (e.target.classList.contains('e-breadcrumb-collapsed')) {
this.isExpanded = true;
this.reRenderItems();
}
if (e.target.classList.contains(MENUCLASS) && !this.isPopupCreated) {
this.renderPopup();
}
}
renderPopup() {
const wrapper = this.createElement('div', { className: POPUPCLASS + ' ' + this.cssClass + (this.enableRtl ? ' e-rtl' : '') });
document.body.appendChild(wrapper);
this.isPopupCreated = true;
this.popupObj = new Popup(wrapper, {
content: this.popupUl,
relateTo: this.element.querySelector(DOT + MENUCLASS),
enableRtl: this.enableRtl,
position: { X: 'left', Y: 'bottom' },
collision: { X: 'fit', Y: 'flip' },
open: () => {
if (this.popupUl) {
this.popupUl.focus();
}
}
});
this.popupWireEvents();
this.popupObj.show();
}
documentClickHandler(e) {
if (this.overflowMode === 'Menu' && this.popupObj && this.popupObj.element.classList.contains('e-popup-open') && !closest(e.target, DOT + MENUCLASS) && !closest(e.target, DOT + 'e-edit-template')) {
this.popupObj.hide();
this.popupObj.destroy();
this.isPopupCreated = false;
detach(this.popupObj.element);
}
}
resize() {
this._maxItems = this.maxItems;
this.initPvtProps();
this.reRenderItems();
}
expandHandler(e) {
if (e.key === 'Enter') {
this.isExpanded = true;
this.reRenderItems();
}
}
keyDownHandler(e) {
if (e.key === 'Enter') {
this.clickHandler(e);
}
}
popupKeyDownHandler(e) {
if (e.key === 'Escape') {
this.documentClickHandler(e);
}
}
/**
* Called internally if any of the property value changed.
*
* @private
* @param {BreadcrumbModel} newProp - Specifies the new properties.
* @param {BreadcrumbModel} oldProp - Specifies the old properties.
* @returns {void}
*/
onPropertyChanged(newProp, oldProp) {
for (const prop of Object.keys(newProp)) {
switch (prop) {
case 'enableActiveItemNavigation':
this.reRenderItems();
break;
case 'items':
case 'activeItem':
this._maxItems = this.maxItems;
this.initPvtProps();
this.reRenderItems();
break;
case 'overflowMode':
case 'maxItems':
this._maxItems = this.maxItems;
this.initPvtProps();
this.reRenderItems();
if (oldProp.overflowMode === 'Wrap') {
this.element.classList.remove(WRAPMODECLASS);
}
else if (newProp.overflowMode === 'Wrap') {
this.element.classList.add(WRAPMODECLASS);
}
if (oldProp.overflowMode === 'Scroll') {
this.element.classList.remove(SCROLLMODECLASS);
}
else if (newProp.overflowMode === 'Scroll') {
this.element.classList.add(SCROLLMODECLASS);
}
break;
case 'url':
this.initItems();
this.reRenderItems();
break;
case 'cssClass':
if (oldProp.cssClass) {
removeClass([this.element], oldProp.cssClass.split(' '));
}
if (newProp.cssClass) {
addClass([this.element], newProp.cssClass.replace(/\s+/g, ' ').trim().split(' '));
}
if ((oldProp.cssClass && oldProp.cssClass.indexOf(ICONRIGHT) > -1) && !(newProp.cssClass &&
newProp.cssClass.indexOf(ICONRIGHT) > -1) || !(oldProp.cssClass && oldProp.cssClass.indexOf(ICONRIGHT) > -1) &&
(newProp.cssClass && newProp.cssClass.indexOf(ICONRIGHT) > -1)) {
this.reRenderItems();
}
break;
case 'enableRtl':
this.element.classList.toggle('e-rtl');
break;
case 'disabled':
this.element.classList.toggle(DISABLEDCLASS);
this.element.setAttribute(ARIADISABLED, newProp.disabled + '');
break;
}
}
}
wireEvents() {
this.delegateClickHanlder = this.documentClickHandler.bind(this);
EventHandler.add(document, 'click', this.delegateClickHanlder, this);
EventHandler.add(this.element, 'click', this.clickHandler, this);
window.addEventListener('resize', this.resize.bind(this));
}
popupWireEvents() {
EventHandler.add(this.popupObj.element, 'click', this.clickHandler, this);
EventHandler.add(this.popupObj.element, 'keydown', this.popupKeyDownHandler, this);
}
unWireEvents() {
EventHandler.remove(document, 'click', this.delegateClickHanlder);
EventHandler.remove(this.element, 'click', this.clickHandler);
window.removeEventListener('resize', this.resize.bind(this));
if (this.popupObj) {
EventHandler.remove(this.popupObj.element, 'click', this.clickHandler);
EventHandler.remove(this.popupObj.element, 'keydown', this.popupKeyDownHandler);
}
}
/**
* Get the properties to be maintained in the persisted state.
*
* @returns {string} - Persist data
*/
getPersistData() {
return this.addOnPersist(['activeItem']);
}
/**
* Get module name.
*
* @private
* @returns {string} - Module Name
*/
getModuleName() {
return 'breadcrumb';
}
/**
* Destroys the widget.
*
* @returns {void}
*/
destroy() {
if (this.popupObj && this.popupObj.element.classList.contains('e-popup-open')) {
this.popupObj.destroy();
this.isPopupCreated = false;
detach(this.popupObj.element);
}
const classes = [];
const attributes = ['aria-label'];
if (this.cssClass) {
classes.concat(this.cssClass.split(' '));
}
if (this.enableRtl) {
classes.push('e-rtl');
}
if (this.disabled) {
classes.push(DISABLEDCLASS);
attributes.push(ARIADISABLED);
}
if (this.overflowMode === 'Wrap') {
classes.push(WRAPMODECLASS);
}
else if (this.overflowMode === 'Scroll') {
classes.push(SCROLLMODECLASS);
}
this.unWireEvents();
this.element.innerHTML = '';
removeClass([this.element], classes);
attributes.forEach((attribute) => {
this.element.removeAttribute(attribute);
});
super.destroy();
}
};
__decorate$a([
Property('')
], Breadcrumb.prototype, "url", void 0);
__decorate$a([
Collection([], BreadcrumbItem)
], Breadcrumb.prototype, "items", void 0);
__decorate$a([
Property('')
], Breadcrumb.prototype, "activeItem", void 0);
__decorate$a([
Property(-1)
], Breadcrumb.prototype, "maxItems", void 0);
__decorate$a([
Property('Menu')
], Breadcrumb.prototype, "overflowMode", void 0);
__decorate$a([
Property('')
], Breadcrumb.prototype, "cssClass", void 0);
__decorate$a([
Property(null)
], Breadcrumb.prototype, "itemTemplate", void 0);
__decorate$a([
Property('/')
], Breadcrumb.prototype, "separatorTemplate", void 0);
__decorate$a([
Property(true)
], Breadcrumb.prototype, "enableNavigation", void 0);
__decorate$a([
Property(false)
], Breadcrumb.prototype, "enableActiveItemNavigation", void 0);
__decorate$a([
Property(false)
], Breadcrumb.prototype, "disabled", void 0);
__decorate$a([
Property('')
], Breadcrumb.prototype, "locale", void 0);
__decorate$a([
Event()
], Breadcrumb.prototype, "beforeItemRender", void 0);
__decorate$a([
Event()
], Breadcrumb.prototype, "itemClick", void 0);
__decorate$a([
Event()
], Breadcrumb.prototype, "created", void 0);
Breadcrumb = __decorate$a([
NotifyPropertyChanges
], Breadcrumb);
var __decorate$b = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
// Constant variables
const CLS_CAROUSEL = 'e-carousel';
const CLS_ACTIVE$2 = 'e-active';
const CLS_RTL$5 = 'e-rtl';
const CLS_PARTIAL = 'e-partial';
const CLS_SWIPE = 'e-swipe';
const CLS_SLIDE_CONTAINER = 'e-carousel-slide-container';
const CLS_ITEMS$2 = 'e-carousel-items';
const CLS_CLONED = 'e-cloned';
const CLS_ITEM$3 = 'e-carousel-item';
const CLS_PREVIOUS = 'e-previous';
const CLS_NEXT = 'e-next';
const CLS_PREV_ICON = 'e-previous-icon';
const CLS_NEXT_ICON = 'e-next-icon';
const CLS_NAVIGATORS = 'e-carousel-navigators';
const CLS_INDICATORS = 'e-carousel-indicators';
const CLS_INDICATOR_BARS = 'e-indicator-bars';
const CLS_INDICATOR_BAR = 'e-indicator-bar';
const CLS_INDICATOR$1 = 'e-indicator';
const CLS_ICON$1 = 'e-icons';
const CLS_PLAY_PAUSE = 'e-play-pause';
const CLS_PLAY_ICON = 'e-play-icon';
const CLS_PAUSE_ICON = 'e-pause-icon';
const CLS_PREV_BUTTON = 'e-previous-button';
const CLS_NEXT_BUTTON = 'e-next-button';
const CLS_PLAY_BUTTON = 'e-play-button';
const CLS_FLAT = 'e-flat';
const CLS_ROUND = 'e-round';
const CLS_HOVER_ARROWS = 'e-hover-arrows';
const CLS_HOVER = 'e-carousel-hover';
const CLS_TEMPLATE$2 = 'e-template';
const CLS_SLIDE_ANIMATION = 'e-carousel-slide-animation';
const CLS_FADE_ANIMATION = 'e-carousel-fade-animation';
const CLS_CUSTOM_ANIMATION = 'e-carousel-custom-animation';
const CLS_ANIMATION_NONE = 'e-carousel-animation-none';
const CLS_PREV_SLIDE = 'e-prev';
const CLS_NEXT_SLIDE = 'e-next';
const CLS_TRANSITION_START = 'e-transition-start';
const CLS_TRANSITION_END = 'e-transition-end';
/**
* Specifies the action (touch & mouse) which enables the slide swiping action in carousel.
* * Touch - Enables or disables the swiping action in touch interaction.
* * Mouse - Enables or disables the swiping action in mouse interaction.
*
* @aspNumberEnum
*/
var CarouselSwipeMode;
(function (CarouselSwipeMode) {
/** Enables or disables the swiping action in touch interaction. */
CarouselSwipeMode[CarouselSwipeMode["Touch"] = 1] = "Touch";
/** Enables or disables the swiping action in mouse interaction. */
CarouselSwipeMode[CarouselSwipeMode["Mouse"] = 2] = "Mouse";
})(CarouselSwipeMode || (CarouselSwipeMode = {}));
/** Specifies the carousel individual item. */
class CarouselItem extends ChildProperty {
}
__decorate$b([
Property()
], CarouselItem.prototype, "cssClass", void 0);
__decorate$b([
Property()
], CarouselItem.prototype, "interval", void 0);
__decorate$b([
Property()
], CarouselItem.prototype, "template", void 0);
__decorate$b([
Property()
], CarouselItem.prototype, "htmlAttributes", void 0);
let Carousel = class Carousel extends Component {
/**
* Constructor for creating the Carousel widget
*
* @param {CarouselModel} options Accepts the carousel model properties to initiate the rendering
* @param {string | HTMLElement} element Accepts the DOM element reference
*/
constructor(options, element) {
super(options, element);
this.isSwipe = false;
}
getModuleName() {
return CLS_CAROUSEL.replace('e-', '');
}
getPersistData() {
return this.addOnPersist(['selectedIndex']);
}
preRender() {
this.keyConfigs = {
home: 'home',
end: 'end',
space: 'space',
moveLeft: 'leftarrow',
moveRight: 'rightarrow',
moveUp: 'uparrow',
moveDown: 'downarrow'
};
const defaultLocale = {
nextSlide: 'Next slide',
of: 'of',
pauseSlideTransition: 'Pause slide transition',
playSlideTransition: 'Play slide transition',
previousSlide: 'Previous slide',
slide: 'Slide',
slideShow: 'Slide show'
};
this.localeObj = new L10n(this.getModuleName(), defaultLocale, this.locale);
}
render() {
this.initialize();
this.renderSlides();
this.renderNavigators();
this.renderPlayButton();
this.renderIndicators();
this.applyAnimation();
this.wireEvents();
}
onPropertyChanged(newProp, oldProp) {
let target;
let rtlElement;
for (const prop of Object.keys(newProp)) {
switch (prop) {
case 'animationEffect':
this.applyAnimation();
break;
case 'cssClass':
classList(this.element, [newProp.cssClass], [oldProp.cssClass]);
break;
case 'selectedIndex':
this.setActiveSlide(this.selectedIndex, oldProp.selectedIndex > this.selectedIndex ? 'Previous' : 'Next');
this.autoSlide();
break;
case 'htmlAttributes':
if (!isNullOrUndefined(this.htmlAttributes)) {
this.setHtmlAttributes(this.htmlAttributes, this.element);
}
break;
case 'enableTouchSwipe':
if (this.element.querySelector(`.${CLS_ITEMS$2}`)) {
this.renderTouchActions();
}
break;
case 'loop':
if (this.loop && isNullOrUndefined(this.autoSlideInterval)) {
this.applySlideInterval();
}
this.handleNavigatorsActions(this.selectedIndex);
if (this.partialVisible || !(this.swipeMode === (~CarouselSwipeMode.Touch & ~CarouselSwipeMode.Mouse))) {
this.reRenderSlides();
}
break;
case 'allowKeyboardInteraction':
if (this.keyModule) {
this.keyModule.destroy();
this.keyModule = null;
}
if (newProp.allowKeyboardInteraction) {
this.renderKeyboardActions();
}
break;
case 'enableRtl':
rtlElement = [].slice.call(this.element.querySelectorAll(`.${CLS_PREV_BUTTON},
.${CLS_NEXT_BUTTON}, .${CLS_PLAY_BUTTON}`));
rtlElement.push(this.element);
if (this.enableRtl) {
addClass(rtlElement, CLS_RTL$5);
}
else {
removeClass(rtlElement, CLS_RTL$5);
}
if (this.partialVisible || !(this.swipeMode === (~CarouselSwipeMode.Touch & ~CarouselSwipeMode.Mouse))) {
const cloneCount = this.loop ? this.getNumOfItems() : 0;
const slideWidth = this.itemsContainer.firstElementChild.clientWidth;
this.itemsContainer.style.transform = this.getTranslateX(slideWidth, this.selectedIndex + cloneCount);
}
break;
case 'buttonsVisibility':
target = this.element.querySelector(`.${CLS_NAVIGATORS}`);
if (target) {
switch (this.buttonsVisibility) {
case 'Hidden':
this.resetTemplates(['previousButtonTemplate', 'nextButtonTemplate']);
remove(target);
break;
case 'VisibleOnHover':
addClass([].slice.call(target.childNodes), CLS_HOVER_ARROWS);
break;
case 'Visible':
removeClass([].slice.call(target.childNodes), CLS_HOVER_ARROWS);
break;
}
}
else {
this.renderNavigators();
this.renderPlayButton();
}
break;
case 'width':
setStyleAttribute(this.element, { 'width': formatUnit(this.width) });
break;
case 'height':
setStyleAttribute(this.element, { 'height': formatUnit(this.height) });
break;
case 'autoPlay':
if (this.showPlayButton && isNullOrUndefined(this.playButtonTemplate)) {
this.playButtonClickHandler(null, true);
}
this.autoSlide();
break;
case 'interval':
this.autoSlide();
break;
case 'showIndicators':
case 'indicatorsType':
target = this.element.querySelector(`.${CLS_INDICATORS}`);
if (target) {
this.resetTemplates(['indicatorsTemplate']);
remove(target);
}
this.renderIndicators();
break;
case 'showPlayButton':
target = this.element.querySelector(`.${CLS_PLAY_PAUSE}`);
if (!this.showPlayButton && target) {
remove(target);
this.resetTemplates(['playButtonTemplate']);
}
this.renderPlayButton();
break;
case 'items':
case 'dataSource': {
const selectedData = prop === 'dataSource' ? this.dataSource : this.items;
if (!isNullOrUndefined(selectedData) && selectedData.length > 0 && this.selectedIndex >= selectedData.length) {
this.setActiveSlide(selectedData.length - 1, 'Previous');
this.autoSlide();
}
this.reRenderSlides();
this.reRenderIndicators();
break;
}
case 'partialVisible':
if (this.partialVisible) {
addClass([this.element], CLS_PARTIAL);
}
else {
removeClass([this.element], CLS_PARTIAL);
}
this.reRenderSlides();
break;
case 'swipeMode':
EventHandler.remove(this.element, 'mousedown touchstart', this.swipeStart);
EventHandler.remove(this.element, 'mousemove touchmove', this.swiping);
EventHandler.remove(this.element, 'mouseup touchend', this.swipStop);
this.swipeModehandlers();
this.reRenderSlides();
break;
}
}
}
reRenderSlides() {
const target = this.element.querySelector(`.${CLS_ITEMS$2}`);
if (target) {
this.resetTemplates(['itemTemplate']);
remove(target);
}
this.renderSlides();
}
reRenderIndicators() {
const target = this.element.querySelector(`.${CLS_INDICATORS}`);
if (target) {
this.resetTemplates(['indicatorsTemplate']);
remove(target);
}
this.renderIndicators();
}
initialize() {
const carouselClasses = [];
carouselClasses.push(CLS_CAROUSEL);
if (this.cssClass) {
carouselClasses.push(this.cssClass);
}
if (this.enableRtl) {
carouselClasses.push(CLS_RTL$5);
}
if (this.partialVisible) {
carouselClasses.push(CLS_PARTIAL);
}
if (!(this.swipeMode === (~CarouselSwipeMode.Touch & ~CarouselSwipeMode.Mouse))) {
carouselClasses.push(CLS_SWIPE);
}
addClass([this.element], carouselClasses);
setStyleAttribute(this.element, { 'width': formatUnit(this.width), 'height': formatUnit(this.height) });
attributes(this.element, { 'role': 'group', 'aria-roledescription': 'carousel', 'aria-label': this.localeObj.getConstant('slideShow') });
if (!isNullOrUndefined(this.htmlAttributes)) {
this.setHtmlAttributes(this.htmlAttributes, this.element);
}
}
renderSlides() {
let slideContainer = this.element.querySelector('.' + CLS_SLIDE_CONTAINER);
if (!slideContainer) {
slideContainer = this.createElement('div', { className: CLS_SLIDE_CONTAINER, attrs: { 'tabindex': '0', 'role': 'tabpanel' } });
this.element.appendChild(slideContainer);
}
this.itemsContainer = this.createElement('div', { className: CLS_ITEMS$2, attrs: { 'aria-live': this.autoPlay ? 'off' : 'polite' } });
slideContainer.appendChild(this.itemsContainer);
const numOfItems = this.getNumOfItems();
if (numOfItems > 0 && this.loop) {
if (this.items.length > 0) {
this.items.slice(-numOfItems).forEach((item, index) => {
this.renderSlide(item, item.template, index, this.itemsContainer, true);
});
}
else if (!isNullOrUndefined(this.dataSource) && this.dataSource.length > 0) {
this.dataSource.slice(-numOfItems).forEach((item, index) => {
this.renderSlide(item, this.itemTemplate, index, this.itemsContainer, true);
});
}
}
if (this.items.length > 0) {
this.slideItems = this.items;
this.items.forEach((item, index) => {
this.renderSlide(item, item.template, index, this.itemsContainer);
});
}
else if (!isNullOrUndefined(this.dataSource) && this.dataSource.length > 0) {
this.slideItems = this.dataSource;
this.dataSource.forEach((item, index) => {
this.renderSlide(item, this.itemTemplate, index, this.itemsContainer);
});
}
if (numOfItems > 0 && this.loop) {
if (this.items.length > 0) {
this.items.slice(0, numOfItems).forEach((item, index) => {
this.renderSlide(item, item.template, index, this.itemsContainer, true);
});
}
else if (!isNullOrUndefined(this.dataSource) && this.dataSource.length > 0) {
this.dataSource.slice(0, numOfItems).forEach((item, index) => {
this.renderSlide(item, this.itemTemplate, index, this.itemsContainer, true);
});
}
}
this.renderTemplates();
this.itemsContainer.style.setProperty('--carousel-items-count', `${this.itemsContainer.children.length}`);
const slideWidth = isNullOrUndefined(this.itemsContainer.firstElementChild) ? 0 :
this.itemsContainer.firstElementChild.clientWidth;
this.itemsContainer.style.transitionProperty = 'none';
const cloneCount = this.loop ? numOfItems : 0;
this.itemsContainer.style.transform = this.getTranslateX(slideWidth, this.selectedIndex + cloneCount);
this.autoSlide();
this.renderTouchActions();
this.renderKeyboardActions();
}
getTranslateX(slideWidth, count = 1) {
return this.enableRtl ? `translateX(${(slideWidth) * (count)}px)` :
`translateX(${-(slideWidth) * (count)}px)`;
}
renderSlide(item, itemTemplate, index, container, isClone = false) {
const itemEle = this.createElement('div', {
id: getUniqueID('carousel_item'),
className: `${CLS_ITEM$3} ${item.cssClass ? item.cssClass : ''} ${this.selectedIndex === index && !isClone ? CLS_ACTIVE$2 : ''}`,
attrs: {
'aria-hidden': this.selectedIndex === index && !isClone ? 'false' : 'true', 'data-index': index.toString(),
'role': 'group', 'aria-roledescription': 'slide'
}
});
if (isClone) {
itemEle.classList.add(CLS_CLONED);
}
if (!(this.selectedIndex === index && !isClone)) {
itemEle.setAttribute('inert', 'true');
}
if (!isNullOrUndefined(item.htmlAttributes)) {
this.setHtmlAttributes(item.htmlAttributes, itemEle);
}
const templateId = this.element.id + '_template';
const template = this.templateParser(itemTemplate)(item, this, 'itemTemplate', templateId, false);
append(template, itemEle);
container.appendChild(itemEle);
}
renderNavigators() {
if (this.buttonsVisibility === 'Hidden') {
return;
}
const navigators = this.createElement('div', { className: CLS_NAVIGATORS });
const itemsContainer = this.element.querySelector(`.${CLS_SLIDE_CONTAINER}`);
itemsContainer.insertAdjacentElement('afterend', navigators);
if (!isNullOrUndefined(this.slideItems) && this.slideItems.length > 1) {
this.renderNavigatorButton('Previous');
this.renderNavigatorButton('Next');
}
this.renderTemplates();
}
renderNavigatorButton(direction) {
const buttonContainer = this.createElement('div', {
className: (direction === 'Previous' ? CLS_PREVIOUS : CLS_NEXT) + ' ' + (this.buttonsVisibility === 'VisibleOnHover' ? CLS_HOVER_ARROWS : '')
});
if (direction === 'Previous' && this.previousButtonTemplate) {
addClass([buttonContainer], CLS_TEMPLATE$2);
const templateId = this.element.id + '_previousButtonTemplate';
const template = this.templateParser(this.previousButtonTemplate)({ type: 'Previous' }, this, 'previousButtonTemplate', templateId, false);
append(template, buttonContainer);
}
else if (direction === 'Next' && this.nextButtonTemplate) {
addClass([buttonContainer], CLS_TEMPLATE$2);
const templateId = this.element.id + '_nextButtonTemplate';
const template = this.templateParser(this.nextButtonTemplate)({ type: 'Next' }, this, 'nextButtonTemplate', templateId, false);
append(template, buttonContainer);
}
else {
const button = this.createElement('button', {
attrs: { 'aria-label': this.localeObj.getConstant(direction === 'Previous' ? 'previousSlide' : 'nextSlide'), 'type': 'button' }
});
const buttonObj = new Button({
cssClass: CLS_FLAT + ' ' + CLS_ROUND + ' ' + (direction === 'Previous' ? CLS_PREV_BUTTON : CLS_NEXT_BUTTON),
iconCss: CLS_ICON$1 + ' ' + (direction === 'Previous' ? CLS_PREV_ICON : CLS_NEXT_ICON),
enableRtl: this.enableRtl,
disabled: !this.loop && this.selectedIndex === (direction === 'Previous' ? 0 : this.slideItems.length - 1)
});
buttonObj.appendTo(button);
buttonContainer.appendChild(button);
}
this.element.querySelector('.' + CLS_NAVIGATORS).appendChild(buttonContainer);
EventHandler.add(buttonContainer, 'click', this.navigatorClickHandler, this);
}
renderPlayButton() {
if (isNullOrUndefined(this.slideItems) || this.buttonsVisibility === 'Hidden' || !this.showPlayButton || this.slideItems.length <= 1) {
return;
}
const playPauseWrap = this.createElement('div', {
className: CLS_PLAY_PAUSE + ' ' + (this.buttonsVisibility === 'VisibleOnHover' ? CLS_HOVER_ARROWS : '')
});
if (this.playButtonTemplate) {
addClass([playPauseWrap], CLS_TEMPLATE$2);
const templateId = this.element.id + '_playButtonTemplate';
const template = this.templateParser(this.playButtonTemplate)({}, this, 'playButtonTemplate', templateId, false);
append(template, playPauseWrap);
}
else {
const playButton = this.createElement('button', {
attrs: { 'aria-label': this.localeObj.getConstant(this.autoPlay ? 'pauseSlideTransition' : 'playSlideTransition'), 'type': 'button' }
});
const isLastSlide = this.selectedIndex === this.slideItems.length - 1 && !this.loop;
const buttonObj = new Button({
cssClass: CLS_FLAT + ' ' + CLS_ROUND + ' ' + CLS_PLAY_BUTTON,
iconCss: CLS_ICON$1 + ' ' + (this.autoPlay && !isLastSlide ? CLS_PAUSE_ICON : CLS_PLAY_ICON),
isToggle: true,
enableRtl: this.enableRtl
});
if (isLastSlide) {
this.setProperties({ autoPlay: false }, true);
playButton.setAttribute('aria-label', this.localeObj.getConstant('playSlideTransition'));
this.itemsContainer.setAttribute('aria-live', 'polite');
}
buttonObj.appendTo(playButton);
playPauseWrap.appendChild(playButton);
}
const navigators = this.element.querySelector(`.${CLS_NAVIGATORS}`);
navigators.insertBefore(playPauseWrap, navigators.lastElementChild);
this.renderTemplates();
EventHandler.add(playPauseWrap, 'click', this.playButtonClickHandler, this);
}
renderIndicators() {
if (!this.showIndicators || isNullOrUndefined(this.indicatorsType)) {
return;
}
let indicatorClass = 'e-default';
if (!this.indicatorsTemplate) {
indicatorClass = `e-${this.indicatorsType.toLowerCase()}`;
}
const indicatorWrap = this.createElement('div', { className: `${CLS_INDICATORS} ${indicatorClass}` });
const indicatorBars = this.createElement('div', { className: CLS_INDICATOR_BARS });
indicatorWrap.appendChild(indicatorBars);
let progress;
if (this.slideItems) {
switch (this.indicatorsType) {
case 'Fraction':
if (this.indicatorsTemplate) {
this.renderIndicatorTemplate(indicatorBars, this.selectedIndex + 1);
}
else {
indicatorBars.innerText = `${this.selectedIndex + 1} / ${this.slideItems.length}`;
}
break;
case 'Progress':
if (this.indicatorsTemplate) {
this.renderIndicatorTemplate(indicatorBars, this.selectedIndex + 1);
}
else {
progress = this.createElement('div', { className: CLS_INDICATOR_BAR });
progress.style.setProperty('--carousel-items-current', `${this.selectedIndex + 1}`);
progress.style.setProperty('--carousel-items-count', `${this.slideItems.length}`);
indicatorBars.appendChild(progress);
}
break;
case 'Default':
case 'Dynamic':
this.slideItems.forEach((item, index) => {
const indicatorBar = this.createElement('div', {
className: CLS_INDICATOR_BAR + ' ' + (this.selectedIndex === index ? CLS_ACTIVE$2 : this.selectedIndex - 1 === index ? CLS_PREV_SLIDE : this.selectedIndex + 1 === index ? CLS_NEXT_SLIDE : ''),
attrs: { 'data-index': index.toString(), 'aria-current': this.selectedIndex === index ? 'true' : 'false' }
});
indicatorBar.style.setProperty('--carousel-items-current', `${this.selectedIndex}`);
if (this.indicatorsTemplate) {
this.renderIndicatorTemplate(indicatorBar, index);
}
else if (this.indicatorsType === 'Default') {
const indicator = this.createElement('button', { className: CLS_INDICATOR$1, attrs: { 'type': 'button', 'aria-label': this.localeObj.getConstant('slide') + ' ' + (index + 1) + ' ' + this.localeObj.getConstant('of') + ' ' + this.slideItems.length } });
indicatorBar.appendChild(indicator);
indicator.appendChild(this.createElement('div', {}));
const buttonObj = new Button({ cssClass: 'e-flat e-small' });
buttonObj.appendTo(indicator);
}
indicatorBars.appendChild(indicatorBar);
if (this.indicatorsType === 'Default') {
EventHandler.add(indicatorBar, 'click', this.indicatorClickHandler, this);
}
});
break;
}
}
this.element.appendChild(indicatorWrap);
}
renderIndicatorTemplate(indicatorBar, index = 0) {
addClass([indicatorBar], CLS_TEMPLATE$2);
const templateId = this.element.id + '_indicatorsTemplate';
const template = this.templateParser(this.indicatorsTemplate)({ index: index, selectedIndex: this.selectedIndex }, this, 'indicatorsTemplate', templateId, false);
append(template, indicatorBar);
}
renderKeyboardActions() {
if (!this.allowKeyboardInteraction) {
return;
}
this.keyModule = new KeyboardEvents(this.element, { keyAction: this.keyHandler.bind(this), keyConfigs: this.keyConfigs });
}
renderTouchActions() {
this.touchModule = new Touch(this.element, { swipe: this.swipeHandler.bind(this) });
}
applyAnimation() {
removeClass([this.element], [CLS_CUSTOM_ANIMATION, CLS_FADE_ANIMATION, CLS_SLIDE_ANIMATION, CLS_ANIMATION_NONE]);
switch (this.animationEffect) {
case 'Slide':
addClass([this.element], CLS_SLIDE_ANIMATION);
break;
case 'Fade':
addClass([this.element], CLS_FADE_ANIMATION);
break;
case 'None':
addClass([this.element], CLS_ANIMATION_NONE);
break;
case 'Custom':
addClass([this.element], CLS_CUSTOM_ANIMATION);
break;
}
}
autoSlide() {
if (isNullOrUndefined(this.slideItems) || this.slideItems.length <= 1) {
return;
}
this.resetSlideInterval();
this.applySlideInterval();
}
autoSlideChange() {
const activeSlide = this.element.querySelector(`.${CLS_ITEM$3}.${CLS_ACTIVE$2}`)
|| this.element.querySelector(`.${CLS_INDICATORS} .${CLS_ACTIVE$2}`);
if (isNullOrUndefined(activeSlide)) {
return;
}
const activeIndex = parseInt(activeSlide.dataset.index, 10);
if (!this.loop && activeIndex === this.slideItems.length - 1) {
this.resetSlideInterval();
}
else {
const index = (activeIndex + 1) % this.slideItems.length;
if (!this.element.classList.contains(CLS_HOVER)) {
this.setActiveSlide(index, 'Next');
}
this.autoSlide();
}
}
applySlideInterval() {
if (!this.autoPlay || this.element.classList.contains(CLS_HOVER)) {
return;
}
let itemInterval = this.interval;
if (this.items.length > 0 && !isNullOrUndefined(this.items[this.selectedIndex || 0].interval)) {
itemInterval = this.items[this.selectedIndex || 0].interval;
}
this.autoSlideInterval = setInterval(() => this.autoSlideChange(), itemInterval);
}
resetSlideInterval() {
clearInterval(this.autoSlideInterval);
this.autoSlideInterval = null;
}
getSlideIndex(direction) {
let currentIndex = this.selectedIndex || 0;
if (direction === 'Previous') {
currentIndex--;
if (currentIndex < 0) {
currentIndex = this.slideItems.length - 1;
}
}
else {
currentIndex++;
if (currentIndex === this.slideItems.length) {
currentIndex = 0;
}
}
return currentIndex;
}
setActiveSlide(currentIndex, direction, isSwiped = false) {
if (this.element.querySelectorAll(`.${CLS_ITEM$3}.${CLS_PREV_SLIDE},.${CLS_ITEM$3}.${CLS_NEXT_SLIDE}`).length > 0) {
return;
}
currentIndex = isNullOrUndefined(currentIndex) ? 0 : currentIndex;
const allSlides = [].slice.call(this.element.querySelectorAll(`.${CLS_ITEM$3}:not(.e-cloned)`));
const activeSlide = this.element.querySelector(`.${CLS_ITEM$3}.${CLS_ACTIVE$2}`);
if (isNullOrUndefined(activeSlide) && this.showIndicators) {
const activeIndicator = this.element.querySelector(`.${CLS_INDICATOR_BAR}.${CLS_ACTIVE$2}`);
const activeIndex = parseInt(activeIndicator.dataset.index, 10);
addClass([allSlides[parseInt(activeIndex.toString(), 10)]], CLS_ACTIVE$2);
return;
}
else if (isNullOrUndefined(activeSlide)) {
addClass([allSlides[parseInt(currentIndex.toString(), 10)]], CLS_ACTIVE$2);
return;
}
const activeIndex = parseInt(activeSlide.dataset.index, 10);
const currentSlide = allSlides[parseInt(currentIndex.toString(), 10)];
const eventArgs = {
currentIndex: activeIndex,
nextIndex: currentIndex,
currentSlide: activeSlide,
nextSlide: currentSlide,
slideDirection: direction,
isSwiped: isSwiped,
cancel: false
};
this.trigger('slideChanging', eventArgs, (args) => {
if (args.cancel) {
return;
}
this.setProperties({ selectedIndex: currentIndex }, true);
attributes(args.currentSlide, { 'aria-hidden': 'true' });
args.currentSlide.setAttribute('inert', 'true');
attributes(args.nextSlide, { 'aria-hidden': 'false' });
args.nextSlide.removeAttribute('inert');
this.refreshIndicators(activeIndex, currentIndex);
this.slideChangedEventArgs = {
currentIndex: args.nextIndex,
previousIndex: args.currentIndex,
currentSlide: args.nextSlide,
previousSlide: args.currentSlide,
slideDirection: direction,
isSwiped: isSwiped
};
const slideWidth = allSlides[parseInt(currentIndex.toString(), 10)].clientWidth;
const numOfItems = this.getNumOfItems();
if (!this.isSwipe) {
this.itemsContainer.style.transitionDuration = '0.6s';
}
this.isSwipe = false;
if ((this.animationEffect === 'Fade')) {
this.itemsContainer.classList.add('e-fade-in-out');
}
else {
this.itemsContainer.style.transitionProperty = 'transform';
}
if (this.loop) {
if (this.slideChangedEventArgs.currentIndex === 0 && this.slideChangedEventArgs.slideDirection === 'Next') {
this.itemsContainer.style.transform = this.getTranslateX(slideWidth, allSlides.length + numOfItems);
}
else if (this.slideChangedEventArgs.currentIndex === this.slideItems.length - 1 && this.slideChangedEventArgs.slideDirection === 'Previous') {
this.itemsContainer.style.transform = this.partialVisible ? this.getTranslateX(slideWidth) : 'translateX(0px)';
}
else {
this.itemsContainer.style.transform = this.getTranslateX(slideWidth, currentIndex + numOfItems);
}
}
else {
this.itemsContainer.style.transform = this.getTranslateX(slideWidth, currentIndex);
}
if (this.animationEffect === 'Slide') {
if (direction === 'Previous') {
addClass([args.nextSlide], CLS_PREV_SLIDE);
args.nextSlide.setAttribute('data-slide-height', args.nextSlide.offsetHeight.toString());
addClass([args.currentSlide, args.nextSlide], CLS_TRANSITION_END);
}
else {
addClass([args.nextSlide], CLS_NEXT_SLIDE);
args.nextSlide.setAttribute('data-slide-height', args.nextSlide.offsetHeight.toString());
addClass([args.currentSlide, args.nextSlide], CLS_TRANSITION_START);
}
}
else if (this.animationEffect === 'Fade') {
removeClass([args.currentSlide], CLS_ACTIVE$2);
addClass([args.nextSlide], CLS_ACTIVE$2);
}
else if (this.animationEffect === 'Custom') {
if (direction === 'Previous') {
addClass([args.nextSlide], CLS_NEXT_SLIDE);
addClass([args.currentSlide], CLS_PREV_SLIDE);
}
else {
addClass([args.currentSlide], CLS_PREV_SLIDE);
addClass([args.nextSlide], CLS_NEXT_SLIDE);
}
}
else {
this.onTransitionEnd();
}
this.handleNavigatorsActions(currentIndex);
});
}
onTransitionEnd() {
removeClass(this.element.querySelectorAll(`.${CLS_ITEMS$2}`), 'e-fade-in-out');
const numOfItems = this.getNumOfItems();
if (this.slideChangedEventArgs) {
this.itemsContainer.style.transitionProperty = 'none';
if (this.loop && (this.slideChangedEventArgs.currentIndex === 0 && this.slideChangedEventArgs.slideDirection === 'Next' ||
this.slideChangedEventArgs.currentIndex === this.slideItems.length - 1 && this.slideChangedEventArgs.slideDirection === 'Previous')) {
const slideWidth = this.slideChangedEventArgs.currentSlide.clientWidth;
this.itemsContainer.style.transform = this.getTranslateX(slideWidth, this.slideChangedEventArgs.currentIndex + numOfItems);
}
addClass([this.slideChangedEventArgs.currentSlide], CLS_ACTIVE$2);
removeClass([this.slideChangedEventArgs.previousSlide], CLS_ACTIVE$2);
this.trigger('slideChanged', this.slideChangedEventArgs, () => {
removeClass(this.element.querySelectorAll(`.${CLS_ITEM$3}`), [CLS_PREV_SLIDE, CLS_NEXT_SLIDE, CLS_TRANSITION_START, CLS_TRANSITION_END]);
this.slideChangedEventArgs = null;
});
}
}
refreshIndicators(activeIndex, currentIndex) {
const slideIndicator = this.element.querySelector(`.${CLS_INDICATOR_BARS}`);
if (isNullOrUndefined(slideIndicator)) {
return;
}
const indicators = [].slice.call(slideIndicator.childNodes);
switch (this.indicatorsType) {
case 'Default':
case 'Dynamic':
attributes(indicators[parseInt(activeIndex.toString(), 10)], { 'aria-current': 'false' });
attributes(indicators[parseInt(currentIndex.toString(), 10)], { 'aria-current': 'true' });
removeClass(indicators, [CLS_ACTIVE$2, CLS_PREV_SLIDE, CLS_NEXT_SLIDE]);
addClass([indicators[parseInt(currentIndex.toString(), 10)]], CLS_ACTIVE$2);
if (indicators[currentIndex - 1]) {
addClass([indicators[currentIndex - 1]], CLS_PREV_SLIDE);
}
if (indicators[currentIndex + 1]) {
addClass([indicators[currentIndex + 1]], CLS_NEXT_SLIDE);
}
indicators.forEach((item) => item.style.setProperty('--carousel-items-current', `${this.selectedIndex}`));
break;
case 'Fraction':
if (this.indicatorsTemplate) {
if (slideIndicator.children.length > 0) {
slideIndicator.removeChild(slideIndicator.firstElementChild);
}
this.renderIndicatorTemplate(slideIndicator, currentIndex + 1);
}
else {
slideIndicator.innerText = `${this.selectedIndex + 1} / ${this.slideItems.length}`;
}
break;
case 'Progress':
if (this.indicatorsTemplate) {
if (slideIndicator.children.length > 0) {
slideIndicator.removeChild(slideIndicator.firstElementChild);
}
this.renderIndicatorTemplate(slideIndicator, currentIndex + 1);
}
else {
slideIndicator.firstElementChild.style.setProperty('--carousel-items-current', `${this.selectedIndex + 1}`);
}
break;
}
}
setHtmlAttributes(attribute, element) {
const keys = Object.keys(attribute);
for (const key of keys) {
if (key === 'class') {
addClass([element], attribute[`${key}`]);
}
else {
element.setAttribute(key, attribute[`${key}`]);
}
}
}
templateParser(template) {
if (template) {
try {
if (typeof template !== 'function' && document.querySelectorAll(template).length) {
return compile(document.querySelector(template).innerHTML.trim());
}
else {
return compile(template);
}
}
catch (error) {
return compile(template);
}
}
return undefined;
}
getNavigatorState(target, isPrevious) {
const button = target.querySelector(`.${isPrevious ? CLS_PREV_BUTTON : CLS_NEXT_BUTTON}`);
if (button) {
const buttonObj = getInstance(button, Button);
return buttonObj.disabled;
}
return false;
}
navigatorClickHandler(e) {
const target = e.currentTarget;
const isDisabled = this.getNavigatorState(target, target.classList.contains(CLS_PREVIOUS));
if (isDisabled) {
return;
}
const direction = target.classList.contains(CLS_PREVIOUS) ? 'Previous' : 'Next';
this.setActiveSlide(this.getSlideIndex(direction), direction);
this.autoSlide();
}
indicatorClickHandler(e) {
const target = closest(e.target, `.${CLS_INDICATOR_BAR}`);
const index = parseInt(target.dataset.index, 10);
if (this.selectedIndex !== index) {
this.setActiveSlide(index, this.selectedIndex > index ? 'Previous' : 'Next');
this.autoSlide();
}
}
playButtonClickHandler(e, isPropertyChange = false) {
const playButton = this.element.querySelector(`.${CLS_PLAY_BUTTON}`);
if (playButton) {
const buttonObj = getInstance(playButton, Button);
if (!isPropertyChange) {
this.setProperties({ autoPlay: !this.autoPlay }, true);
}
playButton.setAttribute('aria-label', this.localeObj.getConstant(this.autoPlay ? 'pauseSlideTransition' : 'playSlideTransition'));
buttonObj.iconCss = CLS_ICON$1 + ' ' + (this.autoPlay ? CLS_PAUSE_ICON : CLS_PLAY_ICON);
buttonObj.dataBind();
this.itemsContainer.setAttribute('aria-live', this.autoPlay ? 'off' : 'polite');
if (this.autoPlay && !this.loop && this.selectedIndex === this.slideItems.length - 1) {
this.setActiveSlide(0, 'Next');
}
this.autoSlide();
}
}
keyHandler(e) {
if (!this.allowKeyboardInteraction) {
return;
}
let direction;
let slideIndex;
let isSlideTransition = false;
const target = e.target;
e.preventDefault();
switch (e.action) {
case 'space':
if (this.showIndicators && target.classList.contains(CLS_INDICATOR$1)) {
target.click();
}
else if (target.classList.contains(CLS_CAROUSEL) || target.classList.contains(CLS_PLAY_BUTTON)) {
this.playButtonClickHandler(e);
}
else if (target.classList.contains(CLS_NEXT_BUTTON)) {
this.next();
}
else if (target.classList.contains(CLS_PREV_BUTTON)) {
this.prev();
}
break;
case 'end':
slideIndex = this.slideItems.length - 1;
direction = 'Next';
isSlideTransition = true;
break;
case 'home':
slideIndex = 0;
direction = 'Previous';
isSlideTransition = true;
break;
case 'moveUp':
case 'moveLeft':
case 'moveDown':
case 'moveRight':
if (this.showIndicators && isNullOrUndefined(this.indicatorsTemplate)) {
this.element.focus();
}
direction = (e.action === 'moveUp' || e.action === 'moveLeft') ? 'Previous' : 'Next';
slideIndex = this.getSlideIndex(direction);
isSlideTransition = !this.isSuspendSlideTransition(slideIndex, direction);
break;
}
if (isSlideTransition) {
this.setActiveSlide(slideIndex, direction);
this.autoSlide();
isSlideTransition = false;
}
}
swipeHandler(e) {
if (this.element.classList.contains(CLS_HOVER) || isNullOrUndefined(this.slideItems) || this.slideItems.length <= 1) {
return;
}
if (this.swipeMode === (~CarouselSwipeMode.Touch & ~CarouselSwipeMode.Mouse)) {
return;
}
const eventType = e.startEvents ? e.startEvents.toString() : null;
if (eventType && ((this.swipeMode === CarouselSwipeMode.Mouse && eventType.includes('Touch')) ||
(this.swipeMode === CarouselSwipeMode.Touch && eventType.includes('Mouse')))) {
return;
}
const direction = (e.swipeDirection === 'Right') ? 'Previous' : 'Next';
const slideIndex = this.getSlideIndex(direction);
if (!this.isSuspendSlideTransition(slideIndex, direction)) {
this.setActiveSlide(slideIndex, direction, true);
this.autoSlide();
}
}
isSuspendSlideTransition(index, direction) {
return !this.loop && (direction === 'Next' && index === 0 || direction === 'Previous' && index === this.slideItems.length - 1);
}
handleNavigatorsActions(index) {
if (this.buttonsVisibility === 'Hidden') {
return;
}
if (this.showPlayButton) {
const playButton = this.element.querySelector(`.${CLS_PLAY_BUTTON}`);
const isLastSlide = this.selectedIndex === this.slideItems.length - 1 && !this.loop;
let isButtonUpdate = isNullOrUndefined(this.playButtonTemplate) && playButton && isLastSlide;
if (isNullOrUndefined(this.playButtonTemplate) && playButton && !isLastSlide) {
isButtonUpdate = !playButton.classList.contains(CLS_ACTIVE$2);
}
if (isButtonUpdate) {
this.setProperties({ autoPlay: !isLastSlide }, true);
playButton.setAttribute('aria-label', this.localeObj.getConstant(this.autoPlay ? 'pauseSlideTransition' : 'playSlideTransition'));
this.itemsContainer.setAttribute('aria-live', this.autoPlay ? 'off' : 'polite');
const buttonObj = getInstance(playButton, Button);
buttonObj.iconCss = CLS_ICON$1 + ' ' + (this.autoPlay ? CLS_PAUSE_ICON : CLS_PLAY_ICON);
buttonObj.dataBind();
}
}
const prevButton = this.element.querySelector(`.${CLS_PREV_BUTTON}`);
if (prevButton && isNullOrUndefined(this.previousButtonTemplate)) {
const buttonObj = getInstance(prevButton, Button);
buttonObj.disabled = !this.loop && index === 0;
buttonObj.dataBind();
}
const nextButton = this.element.querySelector(`.${CLS_NEXT_BUTTON}`);
if (nextButton && isNullOrUndefined(this.nextButtonTemplate)) {
const buttonObj = getInstance(nextButton, Button);
buttonObj.disabled = !this.loop && index === this.slideItems.length - 1;
buttonObj.dataBind();
}
}
onHoverActions(e) {
const navigator = this.element.querySelector(`.${CLS_NAVIGATORS}`);
switch (e.type) {
case 'mouseenter':
if (this.buttonsVisibility === 'VisibleOnHover' && navigator) {
removeClass([].slice.call(navigator.childNodes), CLS_HOVER_ARROWS);
}
if (this.pauseOnHover) {
addClass([this.element], CLS_HOVER);
}
break;
case 'mouseleave':
if (this.buttonsVisibility === 'VisibleOnHover' && navigator) {
addClass([].slice.call(navigator.childNodes), CLS_HOVER_ARROWS);
}
removeClass([this.element], CLS_HOVER);
if (this.isSwipe) {
this.swipStop();
}
break;
}
this.autoSlide();
}
onFocusActions(e) {
switch (e.type) {
case 'focusin':
addClass([this.element], CLS_HOVER);
break;
case 'focusout':
removeClass([this.element], CLS_HOVER);
break;
}
this.autoSlide();
}
destroyButtons() {
const buttonCollections = [].slice.call(this.element.querySelectorAll('.e-control.e-btn'));
for (const button of buttonCollections) {
const instance = getInstance(button, Button);
if (instance) {
instance.destroy();
}
}
}
getNumOfItems() {
return this.partialVisible ? 2 : 1;
}
getTranslateValue(element) {
const style = getComputedStyle(element);
return window.WebKitCSSMatrix ?
new WebKitCSSMatrix(style.webkitTransform).m41 : 0;
}
swipeStart(e) {
if (!this.timeStampStart) {
this.timeStampStart = Date.now();
}
e.preventDefault();
this.isSwipe = false;
this.itemsContainer.classList.add('e-swipe-start');
this.prevPageX = e.touches ? e.touches[0].pageX : e.pageX;
this.initialTranslate = this.getTranslateValue(this.itemsContainer);
}
swiping(e) {
if (!this.itemsContainer.classList.contains('e-swipe-start')) {
return;
}
this.isSwipe = true;
e.preventDefault();
const pageX = e.touches ? e.touches[0].pageX : e.pageX;
const positionDiff = this.prevPageX - (pageX);
if (!this.loop && ((this.enableRtl && ((this.selectedIndex === 0 && positionDiff > 0) ||
(this.selectedIndex === this.itemsContainer.childElementCount - 1 && positionDiff < 0))) ||
(!this.enableRtl && ((this.selectedIndex === 0 && positionDiff < 0) ||
(this.selectedIndex === this.itemsContainer.childElementCount - 1 && positionDiff > 0))))) {
return;
}
this.itemsContainer.style.transform = `translateX(${this.initialTranslate + (this.enableRtl ? positionDiff : -positionDiff)}px)`;
}
swipStop() {
const time = Date.now() - this.timeStampStart;
let distanceX = this.getTranslateValue(this.itemsContainer) - this.initialTranslate;
distanceX = distanceX < 0 ? distanceX * -1 : distanceX;
if (this.isSwipe) {
const offsetDist = distanceX * (Browser.isDevice ? 6 : 1.66);
this.itemsContainer.style.transitionDuration = (((Browser.isDevice ? distanceX : offsetDist) / time) / 10) + 's';
}
const slideWidth = this.itemsContainer.firstElementChild.clientWidth;
const threshold = slideWidth / 2;
this.itemsContainer.classList.remove('e-swipe-start');
const value = this.getTranslateValue(this.itemsContainer);
if (value - this.initialTranslate < -threshold) {
this.swipeNavigation(!this.enableRtl);
}
else if (value - this.initialTranslate > threshold) {
this.swipeNavigation(this.enableRtl);
}
else {
this.itemsContainer.style.transform = `translateX(${this.initialTranslate}px)`;
if (this.animationEffect === 'Fade') {
this.itemsContainer.classList.add('e-fade-in-out');
}
}
}
swipeNavigation(isRtl) {
if (isRtl) {
this.next();
}
else {
this.prev();
}
}
swipeModehandlers() {
if ((this.swipeMode & CarouselSwipeMode.Touch) === CarouselSwipeMode.Touch) {
EventHandler.add(this.itemsContainer, 'touchstart', this.swipeStart, this);
EventHandler.add(this.itemsContainer, 'touchmove', this.swiping, this);
EventHandler.add(this.itemsContainer, 'touchend', this.swipStop, this);
}
if ((this.swipeMode & CarouselSwipeMode.Mouse) === CarouselSwipeMode.Mouse) {
EventHandler.add(this.itemsContainer, 'mousedown', this.swipeStart, this);
EventHandler.add(this.itemsContainer, 'mousemove', this.swiping, this);
EventHandler.add(this.itemsContainer, 'mouseup', this.swipStop, this);
}
if ((this.swipeMode === 0) && (this.swipeMode & CarouselSwipeMode.Mouse & CarouselSwipeMode.Touch) ===
(CarouselSwipeMode.Mouse & CarouselSwipeMode.Touch)) {
EventHandler.add(this.itemsContainer, 'mousedown touchstart', this.swipeStart, this);
EventHandler.add(this.itemsContainer, 'mousemove touchmove', this.swiping, this);
EventHandler.add(this.itemsContainer, 'mouseup touchend', this.swipStop, this);
}
}
resizeHandler() {
if (this.itemsContainer && this.itemsContainer.firstElementChild) {
const numOfItems = this.getNumOfItems();
const slideWidth = this.itemsContainer.firstElementChild.clientWidth;
if (this.loop) {
this.itemsContainer.style.transform = this.getTranslateX(slideWidth, this.selectedIndex + numOfItems);
}
else {
this.itemsContainer.style.transform = this.getTranslateX(slideWidth, this.selectedIndex);
}
}
}
wireEvents() {
if (this.animationEffect !== 'Custom') {
this.swipeModehandlers();
}
EventHandler.add(this.element, 'focusin focusout', this.onFocusActions, this);
EventHandler.add(this.element, 'mouseenter mouseleave', this.onHoverActions, this);
EventHandler.add(this.element.firstElementChild, 'animationend', this.onTransitionEnd, this);
EventHandler.add(this.element.firstElementChild, 'transitionend', this.onTransitionEnd, this);
EventHandler.add(window, 'resize', this.resizeHandler, this);
}
unWireEvents() {
const indicators = [].slice.call(this.element.querySelectorAll(`.${CLS_INDICATOR_BAR}`));
indicators.forEach((indicator) => {
EventHandler.remove(indicator, 'click', this.indicatorClickHandler);
});
const navigators = [].slice.call(this.element.querySelectorAll(`.${CLS_PREVIOUS},.${CLS_NEXT}`));
navigators.forEach((navigator) => {
EventHandler.remove(navigator, 'click', this.navigatorClickHandler);
});
const playIcon = this.element.querySelector(`.${CLS_PLAY_PAUSE}`);
if (playIcon) {
EventHandler.remove(playIcon, 'click', this.playButtonClickHandler);
}
EventHandler.remove(this.element.firstElementChild, 'animationend', this.onTransitionEnd);
EventHandler.remove(this.element.firstElementChild, 'transitionend', this.onTransitionEnd);
EventHandler.clearEvents(this.element);
EventHandler.clearEvents(this.itemsContainer);
EventHandler.remove(window, 'resize', this.resizeHandler);
}
/**
* Method to transit from the current slide to the previous slide.
*
* @returns {void}
*/
prev() {
if (!this.loop && this.selectedIndex === 0) {
return;
}
const index = (this.selectedIndex === 0) ? this.slideItems.length - 1 : this.selectedIndex - 1;
this.setActiveSlide(index, 'Previous');
this.autoSlide();
}
/**
* Method to transit from the current slide to the next slide.
*
* @returns {void}
*/
next() {
if (!this.loop && this.selectedIndex === this.slideItems.length - 1) {
return;
}
const index = (this.selectedIndex === this.slideItems.length - 1) ? 0 : this.selectedIndex + 1;
this.setActiveSlide(index, 'Next');
this.autoSlide();
}
/**
* Method to play the slides programmatically.
*
* @returns {void}
*/
play() {
const playIcon = this.element.querySelector(`.${CLS_PLAY_ICON}`);
if (this.showPlayButton && playIcon) {
classList(playIcon, [CLS_PAUSE_ICON], [CLS_PLAY_ICON]);
const playButton = this.element.querySelector(`.${CLS_PLAY_BUTTON}`);
playButton.setAttribute('aria-label', this.localeObj.getConstant('pauseSlideTransition'));
}
this.setProperties({ autoPlay: true }, true);
this.itemsContainer.setAttribute('aria-live', 'off');
this.applySlideInterval();
}
/**
* Method to pause the slides programmatically.
*
* @returns {void}
*/
pause() {
const pauseIcon = this.element.querySelector(`.${CLS_PAUSE_ICON}`);
if (this.showPlayButton && pauseIcon) {
const playButton = this.element.querySelector(`.${CLS_PLAY_BUTTON}`);
playButton.setAttribute('aria-label', this.localeObj.getConstant('playSlideTransition'));
classList(pauseIcon, [CLS_PLAY_ICON], [CLS_PAUSE_ICON]);
}
this.setProperties({ autoPlay: false }, true);
this.itemsContainer.setAttribute('aria-live', 'off');
this.resetSlideInterval();
}
/**
* Method to render react and angular templates
*
* @returns {void}
* @private
*/
renderTemplates() {
if (this.isAngular || this.isReact) {
this.renderReactTemplates();
}
}
/**
* Method to reset react and angular templates
*
* @param {string[]} templates Accepts the template ID
* @returns {void}
* @private
*/
resetTemplates(templates) {
if (this.isAngular || this.isReact) {
this.clearTemplate(templates);
}
}
/**
* Method for destroy the carousel component.
*
* @returns {void}
*/
destroy() {
this.resetTemplates();
if (this.touchModule) {
this.touchModule.destroy();
this.touchModule = null;
}
if (this.keyModule) {
this.keyModule.destroy();
this.keyModule = null;
}
this.resetSlideInterval();
this.destroyButtons();
this.unWireEvents();
[].slice.call(this.element.children).forEach((ele) => { this.element.removeChild(ele); });
removeClass([this.element], [CLS_CAROUSEL, this.cssClass, CLS_RTL$5, CLS_SWIPE]);
['role', 'style'].forEach((attr) => { this.element.removeAttribute(attr); });
this.itemsContainer = null;
super.destroy();
}
};
__decorate$b([
Collection([], CarouselItem)
], Carousel.prototype, "items", void 0);
__decorate$b([
Property('Slide')
], Carousel.prototype, "animationEffect", void 0);
__decorate$b([
Property()
], Carousel.prototype, "previousButtonTemplate", void 0);
__decorate$b([
Property()
], Carousel.prototype, "nextButtonTemplate", void 0);
__decorate$b([
Property()
], Carousel.prototype, "indicatorsTemplate", void 0);
__decorate$b([
Property()
], Carousel.prototype, "playButtonTemplate", void 0);
__decorate$b([
Property()
], Carousel.prototype, "cssClass", void 0);
__decorate$b([
Property([])
], Carousel.prototype, "dataSource", void 0);
__decorate$b([
Property()
], Carousel.prototype, "itemTemplate", void 0);
__decorate$b([
Property(0)
], Carousel.prototype, "selectedIndex", void 0);
__decorate$b([
Property('100%')
], Carousel.prototype, "width", void 0);
__decorate$b([
Property('100%')
], Carousel.prototype, "height", void 0);
__decorate$b([
Property(5000)
], Carousel.prototype, "interval", void 0);
__decorate$b([
Property(true)
], Carousel.prototype, "autoPlay", void 0);
__decorate$b([
Property(true)
], Carousel.prototype, "pauseOnHover", void 0);
__decorate$b([
Property(true)
], Carousel.prototype, "loop", void 0);
__decorate$b([
Property(false)
], Carousel.prototype, "showPlayButton", void 0);
__decorate$b([
Property(true)
], Carousel.prototype, "enableTouchSwipe", void 0);
__decorate$b([
Property(true)
], Carousel.prototype, "allowKeyboardInteraction", void 0);
__decorate$b([
Property(true)
], Carousel.prototype, "showIndicators", void 0);
__decorate$b([
Property('Default')
], Carousel.prototype, "indicatorsType", void 0);
__decorate$b([
Property('Visible')
], Carousel.prototype, "buttonsVisibility", void 0);
__decorate$b([
Property(false)
], Carousel.prototype, "partialVisible", void 0);
__decorate$b([
Property(CarouselSwipeMode.Touch)
], Carousel.prototype, "swipeMode", void 0);
__decorate$b([
Property()
], Carousel.prototype, "htmlAttributes", void 0);
__decorate$b([
Event()
], Carousel.prototype, "slideChanging", void 0);
__decorate$b([
Event()
], Carousel.prototype, "slideChanged", void 0);
Carousel = __decorate$b([
NotifyPropertyChanges
], Carousel);
var __decorate$c = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
// Constant variables
const CLS_APPBAR = 'e-appbar';
const CLS_HORIZONTAL_BOTTOM = 'e-horizontal-bottom';
const CLS_STICKY = 'e-sticky';
const CLS_PROMINENT = 'e-prominent';
const CLS_DENSE = 'e-dense';
const CLS_RTL$6 = 'e-rtl';
const CLS_LIGHT = 'e-light';
const CLS_DARK = 'e-dark';
const CLS_PRIMARY = 'e-primary';
const CLS_INHERIT = 'e-inherit';
/**
* The AppBar displays the information and actions related to the current application screen. It is used to show branding, screen titles, navigation, and actions.
* Support to inherit colors from AppBar provided to <c>Button</c>, <c>DropDownButton</c>, <c>Menu</c> and <c>TextBox</c>.
* Set <c>CssClass</c> property with <code>e-inherit</code> CSS class to inherit the background and color from AppBar.
*/
let AppBar = class AppBar extends Component {
/**
* Constructor for creating the AppBar widget
*
* @param {AppBarModel} options Accepts the AppBar model properties to initiate the rendering
* @param {string | HTMLElement} element Accepts the DOM element reference
*/
constructor(options, element) {
super(options, element);
}
/**
* Removes the control from the DOM and also removes all its related events.
*
* @returns {void}
*/
destroy() {
super.destroy();
this.element.classList.remove(CLS_APPBAR);
this.element.removeAttribute('style');
this.element.removeAttribute('role');
}
getModuleName() {
return 'appbar';
}
getPersistData() {
return this.addOnPersist([]);
}
preRender() {
// pre render code
}
render() {
this.element.classList.add(CLS_APPBAR);
if (this.element.tagName !== 'HEADER') {
this.element.setAttribute('role', 'banner');
}
if (this.cssClass) {
addClass([this.element], this.cssClass.split(' '));
}
if (this.position === 'Bottom') {
this.element.classList.add(CLS_HORIZONTAL_BOTTOM);
}
if (this.isSticky) {
this.element.classList.add(CLS_STICKY);
}
if (this.enableRtl) {
this.element.classList.add(CLS_RTL$6);
}
this.setHeightMode();
this.setColorMode();
if (!isNullOrUndefined(this.htmlAttributes)) {
this.setHtmlAttributes(this.htmlAttributes, this.element);
}
}
onPropertyChanged(newProp, oldProp) {
for (const prop of Object.keys(newProp)) {
switch (prop) {
case 'mode':
removeClass([this.element], [CLS_DENSE, CLS_PROMINENT]);
this.setHeightMode();
break;
case 'position':
if (this.position === 'Bottom') {
addClass([this.element], CLS_HORIZONTAL_BOTTOM);
}
else {
removeClass([this.element], CLS_HORIZONTAL_BOTTOM);
}
break;
case 'cssClass':
if (oldProp.cssClass) {
removeClass([this.element], oldProp.cssClass.split(' '));
}
if (newProp.cssClass) {
addClass([this.element], newProp.cssClass.split(' '));
}
break;
case 'isSticky':
if (this.isSticky) {
addClass([this.element], CLS_STICKY);
}
else {
removeClass([this.element], CLS_STICKY);
}
break;
case 'htmlAttributes':
if (!isNullOrUndefined(this.htmlAttributes)) {
if (!isNullOrUndefined(oldProp.htmlAttributes)) {
const keys = Object.keys(oldProp.htmlAttributes);
for (const key of keys) {
if (key === 'class') {
removeClass([this.element], oldProp.htmlAttributes[`${key}`]);
}
else {
this.element.removeAttribute(key);
}
}
}
this.setHtmlAttributes(newProp.htmlAttributes, this.element);
}
break;
case 'colorMode':
removeClass([this.element], [CLS_DARK, CLS_PRIMARY, CLS_INHERIT, CLS_LIGHT]);
this.setColorMode();
break;
case 'enableRtl':
if (this.enableRtl) {
addClass([this.element], CLS_RTL$6);
}
else {
removeClass([this.element], CLS_RTL$6);
}
break;
}
}
}
setHtmlAttributes(attribute, element) {
const keys = Object.keys(attribute);
for (const key of keys) {
if (key === 'class') {
addClass([element], attribute[`${key}`]);
}
else {
element.setAttribute(key, attribute[`${key}`]);
}
}
}
setHeightMode() {
if (this.mode === 'Prominent') {
this.element.classList.add(CLS_PROMINENT);
}
else if (this.mode === 'Dense') {
this.element.classList.add(CLS_DENSE);
}
}
setColorMode() {
switch (this.colorMode) {
case 'Light':
this.element.classList.add(CLS_LIGHT);
break;
case 'Dark':
this.element.classList.add(CLS_DARK);
break;
case 'Primary':
this.element.classList.add(CLS_PRIMARY);
break;
case 'Inherit':
this.element.classList.add(CLS_INHERIT);
break;
}
}
};
__decorate$c([
Property('Regular')
], AppBar.prototype, "mode", void 0);
__decorate$c([
Property('Top')
], AppBar.prototype, "position", void 0);
__decorate$c([
Property()
], AppBar.prototype, "cssClass", void 0);
__decorate$c([
Property(false)
], AppBar.prototype, "isSticky", void 0);
__decorate$c([
Property()
], AppBar.prototype, "htmlAttributes", void 0);
__decorate$c([
Property('Light')
], AppBar.prototype, "colorMode", void 0);
__decorate$c([
Event()
], AppBar.prototype, "created", void 0);
__decorate$c([
Event()
], AppBar.prototype, "destroyed", void 0);
AppBar = __decorate$c([
NotifyPropertyChanges
], AppBar);
var __decorate$d = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const PROGRESSVALUE = '--progress-value';
const PROGRESSPOS = '--progress-position';
const VERTICALSTEP = 'e-vertical';
const HORIZSTEP = 'e-horizontal';
const ITEMLIST = 'e-stepper-steps';
/**
* Defines the status of the step.
*/
var StepStatus;
(function (StepStatus) {
/**
* Shows the status of the step is not started.
*/
StepStatus["NotStarted"] = "NotStarted";
/**
* Shows the step is in progress.
*/
StepStatus["InProgress"] = "InProgress";
/**
* Shows the status of the step is completed.
*/
StepStatus["Completed"] = "Completed";
})(StepStatus || (StepStatus = {}));
/**
* Specifies the steps of the Stepper.
*/
class Step extends ChildProperty {
}
__decorate$d([
Property('')
], Step.prototype, "cssClass", void 0);
__decorate$d([
Property(false)
], Step.prototype, "disabled", void 0);
__decorate$d([
Property('')
], Step.prototype, "iconCss", void 0);
__decorate$d([
Property(null)
], Step.prototype, "isValid", void 0);
__decorate$d([
Property('')
], Step.prototype, "label", void 0);
__decorate$d([
Property(false)
], Step.prototype, "optional", void 0);
__decorate$d([
Property(StepStatus.NotStarted)
], Step.prototype, "status", void 0);
__decorate$d([
Property('')
], Step.prototype, "text", void 0);
/**
* Defines the orientation type of the Stepper.
*/
var StepperOrientation;
(function (StepperOrientation) {
/**
* Steps are displayed horizontally.
*/
StepperOrientation["Horizontal"] = "Horizontal";
/**
* Steps are displayed vertically.
*/
StepperOrientation["Vertical"] = "Vertical";
})(StepperOrientation || (StepperOrientation = {}));
/**
* StepperBase component act as base class to the stepper component.
*/
let StepperBase = class StepperBase extends Component {
/**
* * Constructor for Base class
*
* @param {StepperBaseModel} options - Specifies the Base model.
* @param {string | HTMLElement} element - Specifies the element to render as component.
* @private
*/
constructor(options, element) {
super(options, element);
}
/**
* This method is abstract member of the Component<HTMLElement>.
*
* @private
* @returns {void}
*/
// eslint-disable-next-line @typescript-eslint/no-empty-function
preRender() {
}
/**
* This method is abstract member of the Component<HTMLElement>.
*
* @private
* @returns {string} - It returns the current module name.
*/
getModuleName() {
return 'stepperBase';
}
/**
* This method is abstract member of the Component<HTMLElement>.
*
* @private
* @returns {string} - It returns the persisted data.
*/
getPersistData() {
return this.addOnPersist([]);
}
/**
* This method is abstract member of the Component<HTMLElement>.
*
* @private
* @returns {void}
*/
// eslint-disable-next-line @typescript-eslint/no-empty-function
render() {
}
updateOrientaion(wrapper) {
if (wrapper.classList.contains(HORIZSTEP) || wrapper.classList.contains(VERTICALSTEP)) {
wrapper.classList.remove(HORIZSTEP, VERTICALSTEP);
}
if (!(isNullOrUndefined(this.orientation))) {
wrapper.classList.add('e-' + this.orientation.toLocaleLowerCase());
}
}
renderProgressBar(wrapper) {
this.progressStep = this.createElement('div', { className: 'e-stepper-progressbar' });
this.progressbar = this.createElement('div', { className: 'e-progressbar-value' });
const beforeLabel = (wrapper.querySelector('li').querySelector('.e-step-label-container'));
this.progressStep.appendChild(this.progressbar);
wrapper.prepend(this.progressStep);
this.progressbar.style.setProperty(PROGRESSVALUE, (0) + '%');
if (wrapper.classList.contains(VERTICALSTEP)) {
if (wrapper.classList.contains('e-label-bottom') || wrapper.classList.contains('e-label-top')) {
const stepsContainer = (wrapper.querySelector('.' + ITEMLIST));
this.progressStep.style.setProperty(PROGRESSPOS, (stepsContainer.offsetWidth / 2) + 'px');
}
else {
this.progressStep.style.setProperty(PROGRESSPOS, ((this.progressBarPosition / 2) - 1) + 'px');
}
}
if (beforeLabel && (beforeLabel.classList.contains('e-label-before'))) {
this.progressStep.style.setProperty(PROGRESSPOS, (((this.progressBarPosition) - 1)) + 5 + 'px');
}
if (wrapper.classList.contains(HORIZSTEP)) {
this.setProgressPosition(wrapper);
}
}
setProgressPosition(wrapper, isResize) {
const stepItemContainer = (wrapper.querySelector('.e-step-container'));
const stepItemEle = stepItemContainer.firstElementChild;
if (isResize !== true) {
let topPos = 0;
if (wrapper.classList.contains('e-label-before')) {
topPos = (stepItemContainer.offsetParent.offsetHeight - (stepItemEle.offsetHeight / 2) - 1);
}
else {
topPos = (stepItemEle.offsetHeight / 2);
}
this.progressStep.style.setProperty('--progress-top-position', topPos + 'px');
}
const lastEle = wrapper.querySelector('.' + ITEMLIST).lastChild.firstChild;
if (wrapper.classList.contains('e-rtl')) {
const leftPost = ((stepItemEle.offsetLeft + stepItemEle.offsetWidth) - wrapper.querySelector('.' + ITEMLIST).offsetWidth);
this.progressStep.style.setProperty('--progress-left-position', Math.abs(leftPost) + 'px');
this.progressStep.style.setProperty('--progress-bar-width', Math.abs(lastEle.offsetLeft - stepItemEle.offsetLeft) + 'px');
}
else {
this.progressStep.style.setProperty('--progress-left-position', (stepItemEle.offsetLeft + 1) + 'px');
this.progressStep.style.setProperty('--progress-bar-width', ((lastEle.offsetWidth + lastEle.offsetLeft - 2) - (stepItemEle.offsetLeft + 2)) + 'px');
}
}
/**
* This method is abstract member of the Component<HTMLElement>.
*
* @param {StepperBaseModel} newProp - Specifies new properties
* @param {StepperBaseModel} oldProp - Specifies old properties
* @private
* @returns {void}
*/
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
onPropertyChanged(newProp, oldProp) {
}
};
__decorate$d([
Collection([], Step)
], StepperBase.prototype, "steps", void 0);
__decorate$d([
Property('')
], StepperBase.prototype, "cssClass", void 0);
__decorate$d([
Property(false)
], StepperBase.prototype, "readOnly", void 0);
__decorate$d([
Property(StepperOrientation.Horizontal)
], StepperBase.prototype, "orientation", void 0);
__decorate$d([
Event()
], StepperBase.prototype, "created", void 0);
StepperBase = __decorate$d([
NotifyPropertyChanges
], StepperBase);
var __decorate$e = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const ITEMCONTAINER = 'e-step-container';
const ITEMLIST$1 = 'e-stepper-steps';
const ICONCSS = 'e-indicator';
const TEXTCSS = 'e-step-text-container';
const STEPLABEL = 'e-step-label-container';
const OPTIONAL = 'e-step-label-optional';
const SELECTED$2 = 'e-step-selected';
const INPROGRESS = 'e-step-inprogress';
const NOTSTARTED = 'e-step-notstarted';
const FOCUS$1 = 'e-step-focus';
const COMPLETED = 'e-step-completed';
const DISABLED$2 = 'e-step-disabled';
const READONLY = 'e-stepper-readonly';
const PROGRESSVALUE$1 = '--progress-value';
const RTL$3 = 'e-rtl';
const TEMPLATE = 'e-step-template';
const LABELAFTER = 'e-label-after';
const LABELBEFORE = 'e-label-before';
const VERTICALSTEP$1 = 'e-vertical';
const HORIZSTEP$1 = 'e-horizontal';
const STEPICON = 'e-step-item';
const STEPTEXT = 'e-step-text';
const TEXT = 'e-text';
const STEPSLABEL = 'e-step-label';
const LABEL = 'e-label';
const STEPINDICATOR = 'e-step-type-indicator';
const LABELINDICATOR = 'e-step-type-label';
const INDICATORICON = 'e-step-indicator';
const STEPPERTOOLTIP = 'e-stepper-tooltip';
const STEPPERIPROGRESSTIP = 'e-step-inprogress-tip';
const LINEARSTEP = 'e-linear';
const PREVSTEP = 'e-previous';
const NEXTSTEP = 'e-next';
/**
* Defines the step progress animation of the Stepper.
*/
class StepperAnimationSettings extends ChildProperty {
}
__decorate$e([
Property(true)
], StepperAnimationSettings.prototype, "enable", void 0);
__decorate$e([
Property(2000)
], StepperAnimationSettings.prototype, "duration", void 0);
__decorate$e([
Property(0)
], StepperAnimationSettings.prototype, "delay", void 0);
/**
* Defines the label position in the Stepper.
*/
var StepLabelPosition;
(function (StepLabelPosition) {
/**
* Displays the label on top position regardless of the Stepper's orientation.
*/
StepLabelPosition["Top"] = "Top";
/**
* Displays the label on bottom position regardless of the Stepper's orientation.
*/
StepLabelPosition["Bottom"] = "Bottom";
/**
* Displays the label on left side regardless of the Stepper's orientation.
*/
StepLabelPosition["Start"] = "Start";
/**
* Displays the label on right side regardless of the Stepper's orientation.
*/
StepLabelPosition["End"] = "End";
})(StepLabelPosition || (StepLabelPosition = {}));
/**
* Defines whether steps are display with only indicator, only labels or combination of both.
*/
var StepType;
(function (StepType) {
/**
* Steps are shown indicator with label defined.
*/
StepType["Default"] = "Default";
/**
* Steps are shown with only label.
*/
StepType["Label"] = "Label";
/**
* Steps are shown with only indicator.
*/
StepType["Indicator"] = "Indicator";
})(StepType || (StepType = {}));
/**
* The Stepper component visualizes several steps and indicates the current progress by highlighting already completed steps.
*
* ```html
* <nav id="stepper"></nav>
* ```
* ```typescript
* <script>
* let stepperObj: Stepper = new Stepper({steps : [{}, {}, {}, {}, {}]});
* stepperObj.appendTo('#stepper');
* </script>
* ```
*/
let Stepper = class Stepper extends StepperBase {
/**
* * Constructor for creating the Stepper component.
*
* @param {StepperModel} options - Specifies the Stepper model.
* @param {string | HTMLElement} element - Specifies the element to render as component.
* @private
*/
constructor(options, element) {
super(options, element);
this.stepperItemElements = [];
}
preRender() {
if (!this.element.id) {
this.element.id = getUniqueID('e-' + this.getModuleName());
}
const localeText = { optional: 'Optional' };
this.l10n = new L10n('stepper', localeText, this.locale);
this.keyConfigs = {
downarrow: 'downarrow',
leftarrow: 'leftarrow',
rightarrow: 'rightarrow',
uparrow: 'uparrow',
space: 'space',
enter: 'enter',
home: 'home',
end: 'end',
tab: 'tab',
shiftTab: 'shift+tab',
escape: 'escape'
};
this.tooltipOpen = false;
}
/**
* To get component name.
*
* @returns {string} - It returns the current module name.
* @private
*/
getModuleName() {
return 'stepper';
}
render() {
this.initialize();
this.navigationHandler(this.activeStep, null, false);
this.updateStepperStatus(true);
}
initialize() {
this.element.setAttribute('aria-label', this.element.id);
this.updatePosition();
this.stepperItemList = this.createElement('ol', { className: ITEMLIST$1 });
this.updateOrientaion(this.element);
this.updateStepType();
this.element.appendChild(this.stepperItemList);
if (this.cssClass) {
addClass([this.element], this.cssClass.trim().split(' '));
}
if (this.readOnly) {
this.element.classList.add(READONLY);
}
if (this.enableRtl) {
this.element.classList.add(RTL$3);
}
this.wireEvents();
this.updateTemplateFunction();
this.renderItems();
if (this.steps.length > 0) {
this.initiateProgressBar();
this.checkValidStep();
this.updateAnimation();
this.updateTooltip();
this.wireKeyboardEvent();
}
}
initiateProgressBar() {
if (this.steps.length > 1) {
if (this.isAngular && this.template) {
setTimeout(() => { this.renderProgressBar(this.element); });
}
else {
this.renderProgressBar(this.element);
}
}
}
updatePosition() {
this.progressBarPosition = this.beforeLabelWidth = this.textEleWidth = 0;
}
renderDefault(index) {
const step = this.steps[parseInt(index.toString(), 10)];
return !step.iconCss && !step.text && !step.label;
}
updateAnimation() {
const progressEle = this.element.querySelector('.e-progressbar-value');
if (this.animation.enable) {
if (this.animation.delay >= 0) {
if (progressEle) {
progressEle.style.setProperty('--delay', ((this.animation.delay) + 'ms'));
}
}
}
else {
if (progressEle) {
progressEle.style.setProperty('--delay', (0 + 'ms'));
progressEle.style.setProperty('--duration', (0 + 'ms'));
}
}
}
updateStepType() {
if (!isNullOrUndefined(this.stepType)) {
const stepTypeLower = this.stepType.toLowerCase();
const validStepTypes = ['indicator', 'label', 'default'];
if (validStepTypes.indexOf(stepTypeLower) !== -1) {
if (stepTypeLower !== 'default') {
this.element.classList.add('e-step-type-' + stepTypeLower);
}
if ((stepTypeLower === 'indicator' || stepTypeLower === 'label') && this.labelContainer) {
this.clearLabelPosition();
}
}
}
}
wireEvents() {
EventHandler.add(window, 'resize', this.updateResize, this);
EventHandler.add(window, 'click', this.updateStepFocus, this);
}
unWireEvents() {
EventHandler.remove(window, 'resize', this.updateResize);
EventHandler.remove(window, 'click', this.updateStepFocus);
}
updateResize() {
if (this.stepperItemList && this.progressbar && this.element.classList.contains(HORIZSTEP$1)) {
this.setProgressPosition(this.element, true);
}
this.navigateToStep(this.activeStep, null, null, false, false);
}
updateStepFocus() {
if (this.isKeyNavFocus) {
this.isKeyNavFocus = false;
const isFocus = this.element.querySelector('.' + FOCUS$1);
if (isFocus) {
isFocus.classList.remove(FOCUS$1);
this.element.classList.remove('e-steps-focus');
}
}
}
updateStepperStatus(isInitial) {
for (let index = 0; index < this.steps.length; index++) {
const item = this.steps[parseInt(index.toString(), 10)];
const status = item.status.toLowerCase();
if (isInitial && this.activeStep === 0 && index === 0) {
const prevOnChange = this.isProtectedOnChange;
this.isProtectedOnChange = true;
item.status = StepStatus.InProgress;
this.isProtectedOnChange = prevOnChange;
}
if (item && status !== 'notstarted' && index === this.activeStep) {
for (let i = 0; i < this.steps.length; i++) {
const itemElement = this.stepperItemElements[parseInt(i.toString(), 10)];
itemElement.classList.remove(SELECTED$2, INPROGRESS, COMPLETED, NOTSTARTED);
const prevOnChange = this.isProtectedOnChange;
this.isProtectedOnChange = true;
if (status === 'completed') {
this.updateStatusClass(i, index, itemElement);
}
else {
this.updateStatusClass(i, index, itemElement, true);
}
this.isProtectedOnChange = prevOnChange;
}
}
else if (item && status !== 'notstarted' && index !== this.activeStep) {
this.navigationHandler(this.activeStep, null, true);
}
}
}
updateStatusClass(currentStep, index, ele, isInprogress) {
const stepItem = this.steps[parseInt(currentStep.toString(), 10)];
if (currentStep < index) {
ele.classList.add(COMPLETED);
stepItem.status = StepStatus.Completed;
}
else if (currentStep === index) {
ele.classList.add(isInprogress ? INPROGRESS : COMPLETED, SELECTED$2);
}
else {
ele.classList.add(NOTSTARTED);
}
}
renderItems() {
const isHorizontal = this.element.classList.contains(HORIZSTEP$1);
const isVertical = this.element.classList.contains(VERTICALSTEP$1);
const labelPositionLower = !isNullOrUndefined(this.labelPosition) ? this.labelPosition.toLowerCase() : '';
for (let index = 0; index < this.steps.length; index++) {
this.stepperItemContainer = this.createElement('li', { className: ITEMCONTAINER });
const stepSpan = this.createElement('span', { className: 'e-step' });
const item = this.steps[parseInt(index.toString(), 10)];
let isItemLabel = item.label ? true : false;
let isItemText = item.text ? true : false;
const isIndicator = this.element.classList.contains(STEPINDICATOR);
this.stepperItemContainer.classList[(index === 0) ? 'add' : 'remove'](SELECTED$2, INPROGRESS);
this.stepperItemContainer.classList[(index !== 0) ? 'add' : 'remove'](NOTSTARTED);
if (isHorizontal) {
this.stepperItemContainer.style.setProperty('--max-width', 100 / this.steps.length + '%');
}
if (this.renderDefault(index) && (isNullOrUndefined(this.template) || this.template === '')) {
const isIndicator = !this.element.classList.contains('e-step-type-default') && this.stepType.toLowerCase() === 'indicator';
if (isIndicator) {
stepSpan.classList.add('e-icons', INDICATORICON);
}
if (!isIndicator && item.isValid == null) {
stepSpan.classList.add('e-step-content');
stepSpan.innerHTML = (index + 1).toString();
}
this.stepperItemContainer.appendChild(stepSpan);
}
else if (isNullOrUndefined(this.template) || this.template === '') {
let isRender = true;
if ((item.iconCss || (!item.iconCss && isItemText && isItemLabel)) && (((!isItemText && !isItemLabel) ||
!this.element.classList.contains(LABELINDICATOR)))) {
if (item.iconCss) {
const itemIcon = item.iconCss.trim().split(' ');
stepSpan.classList.add(ICONCSS, ...itemIcon);
this.stepperItemContainer.classList.add(STEPICON);
}
else if (!item.iconCss && isItemText && isItemLabel) {
stepSpan.classList.add(ICONCSS);
stepSpan.innerHTML = item.text;
this.stepperItemContainer.classList.add(STEPICON);
}
this.stepperItemContainer.appendChild(stepSpan);
if (((isHorizontal && (labelPositionLower === 'start' || labelPositionLower === 'end') && isItemLabel) ||
(isVertical && (labelPositionLower === 'top' || labelPositionLower === 'bottom') && isItemLabel)) && !isIndicator) {
this.element.classList.add('e-label-' + labelPositionLower);
this.createTextLabelElement(item.label);
isRender = false;
}
}
if (isItemText && (!item.iconCss || !isIndicator) && isRender &&
!(item.iconCss && isItemLabel)) {
if ((!item.iconCss && isIndicator) ||
((!item.iconCss || this.element.classList.contains(LABELINDICATOR)) && !isItemLabel)) {
if (!item.iconCss && !isItemLabel) {
this.element.classList.add('e-step-type-indicator');
}
this.checkValidState(item, stepSpan);
isItemLabel = false;
}
else {
if (!isItemLabel) {
this.createTextLabelElement(item.text);
}
if (isItemLabel && this.element.classList.contains(LABELINDICATOR)) {
const textSpan = this.createElement('span', { className: TEXT });
textSpan.innerText = item.label;
}
isItemText = isItemLabel ? false : true;
}
}
if (isItemLabel && isItemLabel && (!item.iconCss || !isIndicator) && isRender) {
if (!item.iconCss && !isItemText && isIndicator) {
this.checkValidState(item, stepSpan, true);
}
else if ((!((this.element.classList.contains(LABELINDICATOR)) && isItemText)) ||
(this.element.classList.contains(LABELINDICATOR) && isItemLabel)) {
this.createTextLabelElement(item.label, true);
this.updateLabelPosition();
if ((!item.iconCss && !isItemText && !this.stepperItemContainer.classList.contains(STEPICON)) ||
this.element.classList.contains(LABELINDICATOR)) {
this.stepperItemContainer.classList.add('e-step-label-only');
if (item.isValid !== null) {
const iconSpan = this.createElement('span', { className: 'e-step-validation-icon e-icons' });
this.labelContainer.appendChild(iconSpan);
}
}
}
}
}
if (item.optional) {
const optionalSpan = this.createElement('span', { className: OPTIONAL });
this.l10n.setLocale(this.locale);
const optionalContent = this.l10n.getConstant('optional');
optionalSpan.innerText = optionalContent;
if (isItemLabel && (this.labelContainer && ((this.element.classList.contains(LABELAFTER) && !this.stepperItemContainer.classList.contains('e-step-label-only'))
|| (isHorizontal && this.element.classList.contains(LABELBEFORE) && !this.stepperItemContainer.classList.contains('e-step-label-only'))))
|| (isVertical && this.element.classList.contains(LABELBEFORE))) {
this.labelContainer.appendChild(optionalSpan);
}
else {
this.stepperItemContainer.appendChild(optionalSpan);
}
if (item.isValid !== null) {
this.stepperItemContainer.classList.add(item.isValid ? 'e-step-valid' : 'e-step-error');
}
}
if (item.cssClass) {
addClass([this.stepperItemContainer], item.cssClass.trim().split(' '));
}
if (item.disabled) {
this.stepperItemContainer.classList[item.disabled ? 'add' : 'remove'](DISABLED$2);
attributes(this.stepperItemContainer, { 'tabindex': '-1', 'aria-disabled': 'true' });
}
if (item.isValid !== null) {
if (item.isValid) {
this.stepperItemContainer.classList.add('e-step-valid');
}
else {
this.stepperItemContainer.classList.add('e-step-error');
}
}
this.renderItemContent(index, false);
if (this.stepperItemContainer.classList.contains(INPROGRESS)) {
attributes(this.stepperItemContainer, { 'tabindex': '0', 'aria-current': 'true' });
}
else {
attributes(this.stepperItemContainer, { 'tabindex': '-1' });
}
this.wireItemsEvents(this.stepperItemContainer, index);
this.stepperItemElements.push(this.stepperItemContainer);
const eventArgs = { element: this.stepperItemContainer, index: index };
this.trigger('beforeStepRender', eventArgs, (args) => {
this.stepperItemList.appendChild(args.element);
});
if (isVertical) {
if (this.isAngular && this.template) {
setTimeout(() => { this.calculateProgressBarPosition(); });
}
else {
this.calculateProgressBarPosition();
}
}
}
if (isVertical) {
if (this.element.classList.contains(LABELBEFORE)) {
const listItems = this.stepperItemList.querySelectorAll('.' + LABEL);
for (let i = 0; i < listItems.length; i++) {
const labelEle = listItems[parseInt((i).toString(), 10)];
labelEle.style.setProperty('--label-width', (this.beforeLabelWidth) + 5 + 'px');
}
}
}
}
createTextLabelElement(content, isLabelEle = false) {
const spanEle = this.createElement('span', { className: isLabelEle ? LABEL : `${TEXTCSS} ${TEXT}` });
spanEle.innerText = content;
if (isLabelEle) {
this.labelContainer = this.createElement('span', { className: STEPLABEL });
this.labelContainer.appendChild(spanEle);
}
else {
this.stepperItemContainer.appendChild(spanEle);
}
this.stepperItemContainer.classList.add(isLabelEle ? STEPSLABEL : STEPTEXT);
}
calculateProgressBarPosition() {
const isBeforeLabel = (this.element.classList.contains(LABELBEFORE)) ? true : false;
const iconOnly = (this.stepperItemContainer.classList.contains(STEPICON) &&
!this.stepperItemContainer.classList.contains(STEPTEXT) &&
!this.stepperItemContainer.classList.contains(STEPSLABEL));
const textEle = (this.stepperItemContainer.querySelector('.' + TEXTCSS));
if (textEle) {
this.textEleWidth = this.textEleWidth < textEle.offsetWidth ? textEle.offsetWidth : this.textEleWidth;
}
if (isBeforeLabel) {
const labelWidth = this.stepperItemContainer.querySelector('.' + LABEL).offsetWidth + 15;
this.beforeLabelWidth = Math.max(this.beforeLabelWidth, labelWidth);
const iconEle = this.element.querySelector('ol').lastChild.querySelector('.' + ICONCSS);
const textEle = this.stepperItemContainer.querySelector('.' + TEXTCSS);
if (iconEle || textEle) {
const itemWidth = this.beforeLabelWidth + ((this.stepperItemContainer.querySelector('.' + ICONCSS)
|| textEle).offsetWidth / 2);
this.progressBarPosition = Math.max(this.progressBarPosition, itemWidth);
}
else {
this.progressBarPosition = Math.max(this.progressBarPosition, (this.beforeLabelWidth / 2));
}
}
else {
const lastChild = this.element.querySelector('ol').lastChild;
const lastChildWidth = iconOnly ? this.stepperItemContainer.offsetWidth :
lastChild.firstChild.offsetWidth;
this.progressBarPosition = Math.max(this.progressBarPosition, lastChildWidth);
}
}
checkValidState(item, stepSpan, isLabel) {
if (item.isValid == null) {
stepSpan.classList.add('e-step-content');
if (isLabel) {
stepSpan.innerHTML = item.label;
}
else {
stepSpan.innerHTML = item.label ? item.label : item.text;
}
this.stepperItemContainer.appendChild(stepSpan);
}
else {
stepSpan.classList.add(ICONCSS);
this.stepperItemContainer.appendChild(stepSpan);
this.stepperItemContainer.classList.add(STEPICON);
}
}
updateCurrentLabel() {
const labelPos = this.labelPosition.toLowerCase();
const currentLabelPos = this.element.classList.contains(HORIZSTEP$1)
? (labelPos === 'top' ? 'before' : labelPos === 'bottom' ? 'after' : labelPos)
: (labelPos === 'start' ? 'before' : labelPos === 'end' ? 'after' : labelPos);
return currentLabelPos;
}
updateLabelPosition() {
this.clearLabelPosition();
this.labelContainer.classList.add('e-label-' + this.updateCurrentLabel());
if (this.labelPosition.toLowerCase() === 'start' && this.orientation.toLowerCase() === 'vertical') {
if (this.stepperItemContainer.firstChild) {
this.stepperItemContainer.firstChild.before(this.labelContainer);
}
else {
this.stepperItemContainer.appendChild(this.labelContainer);
}
}
else {
this.stepperItemContainer.appendChild(this.labelContainer);
}
this.element.classList.add('e-label-' + this.updateCurrentLabel());
}
clearLabelPosition() {
const removeCss = this.labelContainer.classList.value.match(/(e-label-[after|before]+)/g);
if (removeCss) {
removeClass([this.labelContainer], removeCss);
removeClass([this.element], removeCss);
}
}
checkValidStep() {
const isStepIndicator = this.element.classList.contains(STEPINDICATOR);
for (let index = 0; index < this.steps.length; index++) {
const item = this.steps[parseInt(index.toString(), 10)];
const itemElement = this.stepperItemElements[parseInt(index.toString(), 10)];
if (item.isValid !== null) {
let indicatorEle;
let iconEle;
if (isStepIndicator && !item.iconCss) {
indicatorEle = itemElement.querySelector('.' + ICONCSS);
}
else {
iconEle = itemElement.querySelector('.' + ICONCSS);
}
if (!indicatorEle && isStepIndicator && this.renderDefault(index)) {
indicatorEle = itemElement.querySelector('.' + INDICATORICON);
}
const textLabelIcon = itemElement.querySelector('.e-step-validation-icon');
const itemIcon = item.iconCss.trim().split(' ');
const validStep = itemElement.classList.contains('e-step-valid');
const validIconClass = validStep ? 'e-check' : 'e-circle-info';
if (indicatorEle) {
indicatorEle.classList.remove(INDICATORICON);
if (indicatorEle.innerHTML !== '') {
indicatorEle.innerHTML = '';
}
indicatorEle.classList.add('e-icons', validIconClass, ICONCSS);
}
if (this.renderDefault(index) && !isStepIndicator) {
const stepSpan = itemElement.querySelector('.e-step');
stepSpan.classList.add('e-icons', validIconClass, ICONCSS);
}
if (iconEle) {
if (iconEle.innerHTML !== '') {
iconEle.innerHTML = '';
}
else if (itemIcon.length > 0) {
itemIcon.forEach((icon) => { iconEle.classList.remove(icon); });
}
iconEle.classList.add('e-icons', validIconClass);
}
if (textLabelIcon) {
textLabelIcon.classList.add(validStep ? 'e-circle-check' : 'e-circle-info');
if (this.element.classList.contains(VERTICALSTEP$1)) {
const labelEle = itemElement.querySelector('.' + LABEL);
const textEle = itemElement.querySelector('.' + TEXT);
const itemWidth = textEle ? textEle.offsetWidth + textEle.getBoundingClientRect().left :
labelEle.offsetWidth + labelEle.getBoundingClientRect().left;
const validationIcon = itemElement.querySelector('.e-step-validation-icon');
validationIcon.style.setProperty('--icon-position', (itemWidth + 20) + 'px');
}
}
}
}
}
updateTooltip() {
if (this.showTooltip) {
this.tooltipObj = new Tooltip({
target: '.e-step-container', windowCollision: true,
opensOn: 'Custom', cssClass: this.cssClass ? (STEPPERTOOLTIP + ' ' + this.cssClass) : STEPPERTOOLTIP,
position: 'TopCenter'
});
this.tooltipObj.appendTo(this.stepperItemList);
}
else {
if (!isNullOrUndefined(this.tooltipObj)) {
this.tooltipObj.destroy();
this.tooltipObj = null;
}
}
}
wireItemsEvents(itemElement, index) {
EventHandler.add(itemElement, 'click', this.linearModeHandler.bind(this, itemElement, index), this);
EventHandler.add(itemElement, 'mouseover', this.openStepperTooltip.bind(this, index), this);
EventHandler.add(itemElement, 'mouseleave', this.closeStepperTooltip, this);
}
unWireItemsEvents() {
for (let index = 0; index < this.steps.length; index++) {
const itemElement = this.stepperItemElements[parseInt(index.toString(), 10)];
EventHandler.remove(itemElement, 'click', this.linearModeHandler.bind(this, itemElement, index));
EventHandler.remove(itemElement, 'mouseover', this.openStepperTooltip.bind(this, index));
EventHandler.remove(itemElement, 'mouseleave', this.closeStepperTooltip);
}
}
linearModeHandler(itemElement, index, e) {
if (this.linear) {
const linearModeValue = index - this.activeStep;
if (Math.abs(linearModeValue) === 1) {
this.stepClickHandler(index, e, itemElement);
}
}
else {
this.stepClickHandler(index, e, itemElement);
}
}
openStepperTooltip(index) {
const currentStep = this.steps[parseInt(index.toString(), 10)];
if (this.showTooltip && (currentStep.label || currentStep.text)) {
if (!this.tooltipOpen) {
this.updateTooltipContent(index);
this.tooltipObj.open(this.stepperItemElements[parseInt((index).toString(), 10)]);
if (this.stepType.toLocaleLowerCase() !== 'label' && ((this.stepType.toLocaleLowerCase() === 'indicator') ||
(currentStep.label !== '' && currentStep.iconCss !== '') || (currentStep.label === null && currentStep.iconCss === '' && currentStep.text !== ''))) {
const tooltipPopupClass = currentStep.status.toLowerCase() === 'inprogress' ?
`${STEPPERTOOLTIP} ${STEPPERIPROGRESSTIP} ${this.cssClass ? this.cssClass : ''}` : `${STEPPERTOOLTIP} ${this.cssClass ? this.cssClass : ''}`;
this.tooltipObj.setProperties({ cssClass: tooltipPopupClass.trim() });
}
this.tooltipOpen = true;
}
}
}
closeStepperTooltip() {
if (this.tooltipOpen) {
this.tooltipObj.close();
this.tooltipOpen = false;
}
}
updateTooltipContent(index) {
if (this.showTooltip) {
if (this.isReact) {
this.clearTemplate(['stepperTooltipTemplate']);
}
let content;
const currentStep = this.steps[parseInt(index.toString(), 10)];
if (this.tooltipTemplate) {
content = this.createElement('span', { className: 'e-stepper-tooltip-content' });
const templateFunction = this.getTemplateFunction(this.tooltipTemplate);
append(templateFunction({ value: currentStep }, this, 'stepperTooltipTemplate', (this.element.id + 'tooltipTemplate'), this.isStringTemplate), content);
this.tooltipObj.setProperties({ content: content }, true);
}
else {
const content = currentStep.label ? currentStep.label : currentStep.text;
this.tooltipObj.setProperties({ content: initializeCSPTemplate(() => { return content; }) }, true);
}
this.renderReactTemplates();
}
}
stepClickHandler(index, e, itemElement) {
const clickEventArgs = {
element: itemElement, event: e, previousStep: this.activeStep,
activeStep: index
};
this.trigger('stepClick', clickEventArgs);
this.navigateToStep(index, e, itemElement, true);
}
updateTemplateFunction() {
this.templateFunction = this.template ? this.getTemplateFunction(this.template) : null;
}
renderItemContent(index, isrerender) {
const listItems = this.stepperItemList.querySelectorAll('li');
if (isrerender) {
this.removeItemContent(listItems[parseInt((index).toString(), 10)]);
}
if (this.template) {
if (isrerender) {
listItems[parseInt((index).toString(), 10)].classList.add(TEMPLATE);
}
else {
this.stepperItemContainer.classList.add(TEMPLATE);
}
const item = this.steps[parseInt(index.toString(), 10)];
append(this.templateFunction({ step: item, currentStep: index }, this, 'stepperTemplate', (this.element.id + '_stepperTemplate'), this.isStringTemplate), isrerender ? listItems[parseInt((index).toString(), 10)] : this.stepperItemContainer);
}
this.renderReactTemplates();
}
removeItemContent(ele) {
ele.classList.remove(TEMPLATE);
const firstChild = ele.firstElementChild;
for (let i = 0; i < ele.childElementCount; i++) {
firstChild.remove();
}
}
updateContent() {
if (this.isReact) {
this.clearTemplate(['stepperTemplate']);
}
for (let i = 0; i < this.steps.length; i++) {
this.renderItemContent(i, true);
}
}
/**
* Gets template content based on the template property value.
*
* @param {string | Function} template - Template property value.
* @returns {Function} - Return template function.
* @hidden
*/
getTemplateFunction(template) {
if (typeof template === 'string') {
let content = '';
try {
const tempEle = select(template);
if (tempEle) {
//Return innerHTML incase of jsrenderer script else outerHTML
content = tempEle.tagName === 'SCRIPT' ? tempEle.innerHTML : tempEle.outerHTML;
}
else {
content = template;
}
}
catch (e) {
content = template;
}
return compile(content);
}
else {
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
return compile(template);
}
}
navigateToStep(index, e, itemElement, isInteracted, isUpdated) {
const eventArgs = {
element: itemElement, event: e, isInteracted: isInteracted,
previousStep: this.activeStep, activeStep: index, cancel: false
};
if (isUpdated !== false) {
const previousStep = this.activeStep;
this.trigger('stepChanging', eventArgs, (args) => {
if (args.cancel) {
return;
}
this.navigationHandler(index);
const eventArgs = {
element: itemElement, event: e, isInteracted: isInteracted,
previousStep: previousStep, activeStep: this.activeStep
};
this.trigger('stepChanged', eventArgs);
});
}
else {
this.navigationHandler(index);
}
}
navigationHandler(index, stepStatus, isUpdated) {
if (index !== this.activeStep && this.progressbar) {
this.progressbar.style.transitionDuration = this.animation.duration + 'ms';
}
index = Math.min(index, this.steps.length - 1);
const Itemslength = this.stepperItemElements.length;
if (index >= 0 && index < Itemslength - 1) {
index = this.stepperItemElements[parseInt(index.toString(), 10)].classList.contains(DISABLED$2) ? this.activeStep : index;
}
const prevOnChange = this.isProtectedOnChange;
this.isProtectedOnChange = true;
this.activeStep = parseInt(index.toString(), 10);
this.isProtectedOnChange = prevOnChange;
for (let i = 0; i < this.steps.length; i++) {
const itemElement = this.stepperItemElements[parseInt(i.toString(), 10)];
const item = this.steps[parseInt(i.toString(), 10)];
itemElement.classList.remove(SELECTED$2, INPROGRESS, COMPLETED, NOTSTARTED);
if (i === this.activeStep) {
itemElement.classList.add(SELECTED$2);
}
if (this.activeStep >= 0 && this.progressbar) {
if (this.element.classList.contains(HORIZSTEP$1)) {
this.calculateProgressbarPos();
}
else {
this.progressbar.style.setProperty(PROGRESSVALUE$1, ((100 / (this.steps.length - 1)) * index) + '%');
}
}
else if (this.activeStep < 0 && this.progressbar) {
this.progressbar.style.setProperty(PROGRESSVALUE$1, 0 + '%');
}
if (i === this.activeStep) {
itemElement.classList.add(INPROGRESS);
}
else if (this.activeStep > 0 && i < this.activeStep) {
itemElement.classList.add(COMPLETED);
}
else {
itemElement.classList.add(NOTSTARTED);
}
if (itemElement.classList.contains(INPROGRESS)) {
attributes(itemElement, { 'tabindex': '0', 'aria-current': 'true' });
}
else {
attributes(itemElement, { 'tabindex': '-1', 'aria-current': 'false' });
}
const prevOnChange = this.isProtectedOnChange;
this.isProtectedOnChange = true;
if (isUpdated !== false) {
if (i < this.activeStep || (this.steps.length - 1 === this.activeStep && item.status.toLowerCase() === 'completed')) {
item.status = StepStatus.Completed;
}
else if (i === this.activeStep) {
item.status = StepStatus.InProgress;
}
else if (i > this.activeStep) {
item.status = StepStatus.NotStarted;
}
if (stepStatus && this.activeStep === i) {
item.status = stepStatus;
}
if (item.status.toLowerCase() === 'completed') {
itemElement.classList.remove(SELECTED$2, INPROGRESS, NOTSTARTED);
itemElement.classList.add(COMPLETED);
}
if (item.status.toLowerCase() === 'notstarted') {
itemElement.classList.remove(SELECTED$2, INPROGRESS, COMPLETED);
itemElement.classList.add(NOTSTARTED);
}
}
this.isProtectedOnChange = prevOnChange;
this.updateIndicatorStatus(i, itemElement);
}
this.updateStepInteractions();
if (this.progressbar) {
this.progressbar.style.transitionDuration = '0ms';
}
}
calculateProgressbarPos() {
if ((this.element.classList.contains(LABELBEFORE) || this.element.classList.contains(LABELAFTER)) &&
!this.element.classList.contains(STEPINDICATOR) &&
this.stepperItemElements[parseInt(this.activeStep.toString(), 10)].classList.contains(STEPICON)) {
const progressPos = this.element.querySelector('.e-stepper-progressbar');
const selectedEle = this.stepperItemElements[parseInt(this.activeStep.toString(), 10)]
.firstChild;
let value = this.activeStep === 0 ? 0 : (selectedEle.offsetLeft - progressPos.offsetLeft +
(selectedEle.offsetWidth / 2)) / progressPos.offsetWidth * 100;
if (this.element.classList.contains(RTL$3)) {
value = (progressPos.getBoundingClientRect().right - selectedEle.getBoundingClientRect().right +
(selectedEle.offsetWidth / 2)) / progressPos.offsetWidth * 100;
this.progressbar.style.setProperty(PROGRESSVALUE$1, (value) + '%');
}
else {
this.progressbar.style.setProperty(PROGRESSVALUE$1, (value) + '%');
}
}
else {
let totalLiWidth = 0;
let activeLiWidth = 0;
this.stepperItemElements.forEach((element, index) => {
const itemWidth = element.offsetWidth;
totalLiWidth += itemWidth;
if (index <= this.activeStep) {
activeLiWidth += (index === this.activeStep && index !== 0) ? (itemWidth / 2) : itemWidth;
}
});
const spaceWidth = (this.stepperItemList.offsetWidth - totalLiWidth) /
(this.stepperItemElements.length - 1);
const progressValue = ((activeLiWidth + (spaceWidth * this.activeStep)) /
this.stepperItemList.offsetWidth) * 100;
this.progressbar.style.setProperty(PROGRESSVALUE$1, (progressValue) + '%');
}
}
updateIndicatorStatus(index, itemElement) {
if (this.renderDefault(index) && this.element.classList.contains(STEPINDICATOR) && !itemElement.classList.contains('e-step-valid')
&& !itemElement.classList.contains('e-step-error')) {
if (itemElement.classList.contains(COMPLETED)) {
itemElement.firstChild.classList.remove('e-icons', 'e-step-indicator');
itemElement.firstChild.classList.add(ICONCSS, 'e-icons', 'e-check');
}
else if (itemElement.classList.contains(INPROGRESS) || itemElement.classList.contains(NOTSTARTED)) {
itemElement.firstChild.classList.remove(ICONCSS, 'e-icons', 'e-check');
itemElement.firstChild.classList.add('e-icons', 'e-step-indicator');
}
}
}
updateStepInteractions() {
this.element.classList.toggle(LINEARSTEP, this.linear);
this.stepperItemElements.forEach((step, index) => {
step.classList.toggle(PREVSTEP, (index === this.activeStep - 1));
step.classList.toggle(NEXTSTEP, (index === this.activeStep + 1));
});
}
removeItemElements() {
for (let i = 0; i < this.stepperItemElements.length; i++) {
remove(this.stepperItemElements[parseInt(i.toString(), 10)]);
}
this.stepperItemElements = [];
}
/**
* Move to next step from current step in Stepper.
*
* @returns {void}
*/
nextStep() {
if (this.activeStep !== this.steps.length - 1) {
this.navigateToStep(this.activeStep + 1, null, null, false);
}
}
/**
* Move to previous step from current step in Stepper.
*
* @returns {void}
*/
previousStep() {
if (this.activeStep > 0) {
this.navigateToStep(this.activeStep - 1, null, null, false);
}
}
/**
* Reset the state of the Stepper and move to the first step.
*
* @returns {void}
*/
reset() {
if (this.activeStep === 0) {
this.updateStepInteractions();
}
else {
const isDisabled = this.stepperItemElements[0].classList.contains(DISABLED$2) ? true : false;
this.navigateToStep(isDisabled ? -1 : 0, null, null, false);
}
}
/**
* Refreshes the position of the progress bar programmatically when the dimensions of the parent container are changed.
*
* @returns {void}
*/
refreshProgressbar() {
if (this.stepperItemList && this.progressbar) {
this.setProgressPosition(this.element);
}
this.navigateToStep(this.activeStep, null, null, false, false);
}
updateElementClassArray() {
const classArray = [RTL$3, READONLY, 'e-steps-focus', LABELAFTER, LABELBEFORE, 'e-label-top',
'e-label-bottom', 'e-label-start', 'e-label-end', STEPINDICATOR, LABELINDICATOR, VERTICALSTEP$1, HORIZSTEP$1, LINEARSTEP];
removeClass([this.element], classArray);
}
/**
* Destroy the stepper control.
*
* @returns {void}
*/
destroy() {
super.destroy();
this.unWireEvents();
this.unWireItemsEvents();
// unwires the events and detach the li elements
this.removeItemElements();
this.clearTemplate();
if (this.stepperItemList) {
remove(this.stepperItemList);
}
this.stepperItemList = null;
if (this.progressStep) {
remove(this.progressStep);
}
this.progressStep = null;
this.progressbar = null;
this.progressBarPosition = null;
this.stepperItemContainer = null;
this.textContainer = null;
this.labelContainer = null;
this.updateElementClassArray();
this.element.removeAttribute('aria-label');
if (this.showTooltip) {
this.tooltipObj.destroy();
this.tooltipObj = null;
}
if (this.keyboardModuleStepper) {
this.keyboardModuleStepper.destroy();
}
this.keyboardModuleStepper = null;
}
wireKeyboardEvent() {
this.keyboardModuleStepper = new KeyboardEvents(this.element, {
keyAction: this.keyActionHandler.bind(this),
keyConfigs: this.keyConfigs,
eventName: 'keydown'
});
}
keyActionHandler(e) {
if (this.readOnly) {
return;
}
switch (e.action) {
case 'uparrow':
case 'downarrow':
case 'leftarrow':
case 'rightarrow':
case 'tab':
case 'shiftTab':
this.handleNavigation(this.enableRtl && this.element.classList.contains(HORIZSTEP$1) ? (e.action === 'leftarrow' || e.action === 'tab' || e.action === 'uparrow') : (e.action === 'rightarrow' || e.action === 'tab' || e.action === 'downarrow'), e);
break;
case 'space':
case 'enter':
case 'escape':
this.handleNavigation(null, e);
break;
case 'home':
case 'end':
this.handleNavigation(null, e, this.enableRtl);
break;
}
}
handleNavigation(isNextStep, e, isRTL) {
this.isKeyNavFocus = true;
this.element.classList.add('e-steps-focus');
let focusedEle = this.element.querySelector('.' + FOCUS$1);
if (!focusedEle) {
focusedEle = this.element.querySelector('.' + SELECTED$2);
}
const stepItems = Array.prototype.slice.call(this.stepperItemList.children);
let index = stepItems.indexOf(focusedEle);
if (e.action === 'tab' || e.action === 'shiftTab' || e.action === 'downarrow' || e.action === 'uparrow' || e.action === 'space' || e.action === 'home' || e.action === 'end') {
if ((e.action === 'tab' && index === stepItems.length - 1) || (e.action === 'shiftTab' && index === 0)) {
if (focusedEle.classList.contains(FOCUS$1)) {
this.updateStepFocus();
return;
}
}
else {
e.preventDefault();
}
}
if (e.action === 'escape') {
stepItems[parseInt(index.toString(), 10)].classList.remove(FOCUS$1);
this.element.classList.remove('e-steps-focus');
}
if (!(e.action === 'space' || e.action === 'enter')) {
const prevIndex = index;
index = isNextStep ? index + 1 : index - 1;
while ((index >= 0 && index < stepItems.length) && stepItems[parseInt(index.toString(), 10)].classList.contains(DISABLED$2)) {
index = isNextStep ? index + 1 : index - 1;
}
index = (index < 0) ? 0 : (index > stepItems.length - 1) ? stepItems.length - 1 : index;
if (stepItems[parseInt(prevIndex.toString(), 10)].classList.contains(FOCUS$1)) {
stepItems[parseInt(prevIndex.toString(), 10)].classList.remove(FOCUS$1);
}
if ((e.action === 'home' || e.action === 'end')) {
if (e.action === 'home') {
index = isRTL ? stepItems.length - 1 : 0;
}
else {
index = isRTL ? 0 : stepItems.length - 1;
}
}
if (index >= 0 && index < stepItems.length) {
stepItems[parseInt(index.toString(), 10)].classList.add(FOCUS$1);
}
}
else if ((e.action === 'space' || e.action === 'enter')) {
let isupdateFocus = false;
if (this.linear) {
const linearModeValue = this.activeStep - index;
if (Math.abs(linearModeValue) === 1) {
this.navigateToStep(index, null, null, true);
isupdateFocus = true;
}
}
else {
this.navigateToStep(index, null, null, true);
isupdateFocus = true;
}
if (isupdateFocus) {
this.updateStepFocus();
this.stepperItemElements[index].focus();
}
}
}
renderStepperItems(isUpdate, isStepType) {
this.updateElementClassArray();
this.removeItemElements();
this.element.querySelector('.e-stepper-progressbar').remove();
if (isUpdate) {
this.updatePosition();
}
if (isStepType) {
this.updateStepType();
}
if (this.readOnly && !this.element.classList.contains(READONLY)) {
this.element.classList.add(READONLY);
}
if (this.enableRtl && !this.element.classList.contains(RTL$3)) {
this.element.classList.add(RTL$3);
}
this.updateOrientaion(this.element);
this.renderItems();
this.renderProgressBar(this.element);
this.checkValidStep();
this.updateAnimation();
this.navigateToStep(this.activeStep, null, this.stepperItemElements[this.activeStep], true);
}
updateDynamicSteps(steps, prevSteps) {
if (!(steps instanceof Array && prevSteps instanceof Array)) {
const stepCounts = Object.keys(steps);
for (let i = 0; i < stepCounts.length; i++) {
const index = parseInt(Object.keys(steps)[i], 10);
const changedPropsCount = Object.keys(steps[index]).length;
for (let j = 0; j < changedPropsCount; j++) {
const property = Object.keys(steps[index])[j];
if (property === 'status') {
if (this.activeStep === index) {
this.navigationHandler(index, steps[index].status);
}
else {
this.steps[index].status = prevSteps[index].status;
}
}
else {
this.removeItemElements();
this.renderItems();
this.updateStepperStatus();
}
if (property === 'label' && (this.steps[index].iconCss || this.steps[index].text) &&
this.stepType.toLowerCase() === 'default') {
this.refreshProgressbar();
}
this.updateStepInteractions();
this.checkValidStep();
}
}
}
else {
this.renderStepperItems(true, true);
}
}
updateDynamicActiveStep(activeStep, preActiveStep) {
this.activeStep = (activeStep > this.steps.length - 1 || activeStep < -1) ? preActiveStep : this.activeStep;
if (this.activeStep >= 0 && this.stepperItemElements[parseInt(this.activeStep.toString(), 10)].classList.contains(DISABLED$2)) {
this.activeStep = preActiveStep;
}
if (this.linear) {
const linearModeValue = preActiveStep - this.activeStep;
if (Math.abs(linearModeValue) === 1) {
this.navigateToStep(this.activeStep, null, null, true);
}
}
else {
this.navigateToStep(this.activeStep, null, this.stepperItemElements[this.activeStep], true);
}
}
updateDynamicCssClass(cssClass, prevCssClass) {
if (prevCssClass) {
removeClass([this.element], prevCssClass.trim().split(' '));
}
if (cssClass) {
addClass([this.element], cssClass.trim().split(' '));
}
if (this.tooltipObj) {
this.tooltipObj.setProperties({ cssClass: this.cssClass ? (STEPPERTOOLTIP + ' ' + this.cssClass) : STEPPERTOOLTIP });
}
}
/**
* Called internally if any of the property value changed.
*
* @param {StepperModel} newProp - Specifies new properties
* @param {StepperModel} oldProp - Specifies old properties
* @returns {void}
* @private
*/
onPropertyChanged(newProp, oldProp) {
for (const prop of Object.keys(newProp)) {
switch (prop) {
case 'steps': {
this.updateDynamicSteps(newProp.steps, oldProp.steps);
break;
}
case 'orientation':
this.updateOrientaion(this.element);
this.renderStepperItems(true);
break;
case 'activeStep':
this.updateDynamicActiveStep(newProp.activeStep, oldProp.activeStep);
break;
case 'enableRtl':
this.element.classList[this.enableRtl ? 'add' : 'remove'](RTL$3);
break;
case 'readOnly':
this.element.classList[this.readOnly ? 'add' : 'remove'](READONLY);
break;
case 'cssClass':
this.updateDynamicCssClass(newProp.cssClass, oldProp.cssClass);
break;
case 'labelPosition':
this.renderStepperItems(true);
break;
case 'showTooltip':
this.updateTooltip();
break;
case 'stepType':
this.renderStepperItems(true, true);
break;
case 'template':
this.updateTemplateFunction();
this.updateContent();
break;
case 'animation':
this.updateAnimation();
break;
case 'linear':
this.updateStepInteractions();
break;
}
}
}
};
__decorate$e([
Property(0)
], Stepper.prototype, "activeStep", void 0);
__decorate$e([
Complex({}, StepperAnimationSettings)
], Stepper.prototype, "animation", void 0);
__decorate$e([
Property(false)
], Stepper.prototype, "linear", void 0);
__decorate$e([
Property(false)
], Stepper.prototype, "showTooltip", void 0);
__decorate$e([
Property('')
], Stepper.prototype, "template", void 0);
__decorate$e([
Property('')
], Stepper.prototype, "tooltipTemplate", void 0);
__decorate$e([
Property(StepLabelPosition.Bottom)
], Stepper.prototype, "labelPosition", void 0);
__decorate$e([
Property(StepType.Default)
], Stepper.prototype, "stepType", void 0);
__decorate$e([
Event()
], Stepper.prototype, "stepChanged", void 0);
__decorate$e([
Event()
], Stepper.prototype, "stepChanging", void 0);
__decorate$e([
Event()
], Stepper.prototype, "stepClick", void 0);
__decorate$e([
Event()
], Stepper.prototype, "beforeStepRender", void 0);
Stepper = __decorate$e([
NotifyPropertyChanges
], Stepper);
export { Accordion, AccordionActionSettings, AccordionAnimationSettings, AccordionItem, ActionSettings, AppBar, Breadcrumb, BreadcrumbItem, BreadcrumbOverflowMode, Carousel, CarouselItem, CarouselSwipeMode, ContextMenu, FieldSettings, FieldsSettings, HScroll, Header, Item, Menu, MenuAnimationSettings, MenuItem, NodeAnimationSettings, Sidebar, Step, StepLabelPosition, StepStatus, StepType, Stepper, StepperAnimationSettings, StepperBase, StepperOrientation, Tab, TabActionSettings, TabAnimationSettings, TabItem, Toolbar, TreeView, VScroll, addScrolling, destroyScroll };
//# sourceMappingURL=ej2-navigations.es2015.js.map