static/js/com/nav-tree/index.js (115 lines of code) (raw):
import $ from 'jquery';
import './index.scss'
class NavTree {
constructor(elem) {
this.elem = elem;
this.id = elem.getAttribute('id');
this.STORAGE_KEY = 'nav_items';
this._events = {};
this._initEvents();
this.restoreItemsState();
}
on(eventName, callback) {
this._events[eventName] = callback;
};
fireEvent(eventName) {
if (eventName in this._events) {
const args = Array.prototype.slice.call(arguments, 1);
return this._events[eventName].apply(this, args);
}
};
_initEvents() {
$(this.elem.querySelectorAll('.js-item-title')).on('click', (e) => {
const elem = e.currentTarget,
branchElem = e.currentTarget.parentNode,
$branch = $(branchElem),
itemId = $branch.attr('data-id'),
isActive = $(elem).hasClass('is_active'),
isLeaf = $branch.hasClass('js-leaf');
if (isLeaf) {
this._selectLeaf(elem, e);
return;
}
if (isActive) {
this._closeBranch(elem, e);
}
else {
this._openBranch(elem, e);
}
if (itemId) {
let states = this.getItemsStateInfo();
states = states === null ? {} : states;
states[itemId] = !isActive;
this.setItemsStateInfo(states);
}
});
};
_selectLeaf(leafElem, e, branchElem) {
$(this.elem).find('.js-leaf-title').each((i, elem) => {
let $elem = $(elem),
isActive = $elem.hasClass('is_active');
if (elem === leafElem) {
if (!isActive) {
this.fireEvent('selectLeaf', e, branchElem, elem);
$elem.addClass('is_active');
}
} else {
$elem.removeClass('is_active');
}
});
return true;
};
getItemsStateInfo() {
const storageKey = this.STORAGE_KEY + '_' + this.id;
const savedState = JSON.parse(sessionStorage.getItem(storageKey));
if (savedState) {
return savedState
}
const activeItem = $('.js-leaf-title.is_active').closest('.js-branch').attr('data-id');
const defaultState = {};
if (activeItem) {
defaultState[activeItem] = true;
}
return defaultState;
};
setItemsStateInfo(info) {
const storageKey = this.STORAGE_KEY + '_' + this.id;
sessionStorage.setItem(storageKey, JSON.stringify(info));
};
restoreItemsState() {
const states = this.getItemsStateInfo();
if (!states) {
return;
}
$(this.elem.querySelectorAll('.js-item-title')).each((_, elem) => {
const $elem = $(elem),
$parent = $elem.parent(),
itemId = $parent.attr('data-id');
if (itemId in states) {
if (states[itemId] === true)
this._openBranch(elem);
else
this._closeBranch(elem);
} else {
this._closeBranch(elem)
}
})
};
_openBranch(branchTitleElem, e) {
const $elem = $(branchTitleElem),
$parent = $elem.parent();
$elem.addClass('is_active');
$parent.addClass('_opened');
$parent.removeClass('_closed');
this.fireEvent('openBranch', e, branchTitleElem.parentNode, branchTitleElem);
};
_closeBranch(branchTitleElem, e) {
const $elem = $(branchTitleElem),
$parent = $elem.parent();
$elem.removeClass('is_active');
$parent.addClass('_closed');
$parent.removeClass('_opened');
this.fireEvent('closeBranch', e, branchTitleElem.parentNode, branchTitleElem);
};
}
export default NavTree;