Your IP : 18.219.40.177
/**
* Select Module
* @param {object} window global object
* @param {function} $ jQuery library
* @param {object} EventMgr EventMgr library
* @param {object} App Application
* @return {object} api
*/
App.Select = function(window, $, EventMgr, App) {
'use strict';
var UPKEY = 38,
DOWNKEY = 40,
LEFTKEY = 37,
RIGHTKEY = 39,
ENTERKEY = 13,
TABKEY = 9,
ESCKEY = 27,
SPACE = 32,
//wrapper for select
selectSelector = '.b-myselect:not(".readonly")' +
' .b-myselect__select-selected',
//wrapper for select item
selectItemSelector = '.b-myselect:not(".readonly")' +
' .b-myselect__select-li',
selectKeySelector = '.b-myselect:not(".readonly")' +
' .b-myselect__select-selected,' +
' .b-myselect:not(".readonly") .sb-input',
CACHE = {},
CACHEOPENEDSELECT = {},
dependSlistSelector = '.depend.b-myselect input[type="hidden"],' +
' .depend.b-select-ac input[type="hidden"],' +
' .depend.b-radio input[type="hidden"]';
function $body() {
return $('body');
}
function getActiveTabId() {
return ($('.tab-content_st_active').attr('data-tabid') || false);
}
//flag for active select list
function $content() {
return App.Common.selectorCache('.i-form-wr');
}
function $selectCont(id) {
if (id) {
return $('#' + id + '.b-myselect');
} else {
return $('.b-myselect');
}
}
//add /remove handler for body, for close selectlist
function addRemoveHandlerForBody(add) {
if (add) {
$body().on('click', bodyHandlerClick);
} else {
$body().off('click', bodyHandlerClick);
}
}
function closeOtherSelectList(tabId, click) {
if (!tabId) {
tabId = getActiveTabId();
}
if (CACHEOPENEDSELECT[tabId] && CACHEOPENEDSELECT[tabId].removeClass) {
CACHEOPENEDSELECT[tabId].addClass('b-myselect_st_close')
.removeClass('b-myselect_st_open');
addRemoveHandlerForBody();
}
}
function bodyHandlerClick(e) {
if (e) {
var scrElemClass = e.srcElement ?
e.srcElement.className : e.target ? e.target.className : '',
scrollFlag = scrElemClass.indexOf('scrlbr'),
highlightFlag = scrElemClass.indexOf('highlight');
if (scrollFlag === -1 && highlightFlag === -1) {
closeOtherSelectList();
}
} else {
//what is it?!
e.stopPropagation();
}
}
//click for select
function selectListHandler(e) {
e.preventDefault();
e.stopPropagation();
var id = this.getAttribute('data-id'),
$selectContVar = $selectCont(id),
ids, searchBox,
tabId = getActiveTabId(), keySymbol, r;
//check current state option list
if (!$selectContVar.hasClass('b-myselect_st_open')) {
$('body').trigger('click');
closeOtherSelectList(tabId);
$selectContVar
.removeClass('b-myselect_st_close')
.addClass('b-myselect_st_open');
//set optionlist position
App.Common.setOptionListPosition('#opt', id);
ids = $selectContVar.find('.b-myselect__select-list').attr('id');
EventMgr.trigger('updateScroll', { id: ids });
addRemoveHandlerForBody(true);
//set focus on searchbox
if (this.parentNode.className.match('sb-select')) {
searchBox = App.Dom.byId('sb-' + ids);
if (searchBox) {
//try guess symbol of pressed key
if (e && e.originalEvent) {
if (e.originalEvent.key) {
keySymbol = e.originalEvent.key;
if (keySymbol.length > 1) {
keySymbol = null;
}
}
}
searchBox.value = keySymbol || '';
setTimeout(function() {
findElemsInSelect.apply(searchBox, [{ codeKey: 'ololo' }]);
}, 1);
searchBox.focus();
//set cursor after 1st symbol
if (keySymbol) {
if (searchBox.setSelectionRange) {
searchBox.setSelectionRange(1, 1);
} else {
r = searchBox.createTextRange();
r.collapse(true);
r.select(1, 1);
}
}
window.scrollToTopLeft();
}
}
CACHEOPENEDSELECT[tabId] = $selectContVar;
} else {
$selectContVar
.removeClass('b-myselect_st_open')
.addClass('b-myselect_st_close');
delete CACHEOPENEDSELECT[tabId];
addRemoveHandlerForBody(false);
this.childNodes[1].focus();
window.scrollToTopLeft();
}
}
//select item handler
function setSelectedValue(e, sv, close) {
var self = $(this),
val = this.getAttribute('data-val'),
handlerVal = this.getAttribute('data-handler-val'),
content = self.html(),
id = self.parent().attr('data-id'),
currentSelect = $('#' + id + ' .b-myselect__select-value');
if (self.hasClass('group')) {
return;
}
const $inputValue = $('input#' + id + '-val');
const prevValue = $inputValue.val();
//вызываем change только при изменение значения, чтобы не зациклить setvalues
if (prevValue !== val) {
$inputValue.val(val)
.attr('data-handler-val', handlerVal)
.trigger('change', [sv, close]);
}
//if it clone from search - search self made it
if (!self.hasClass('b-myselect__select-li_clone_true')) {
self.addClass('selected').siblings().removeClass('selected');
} else if (!e) {
//up/down keydown
self.addClass('selected')
.siblings().removeClass('selected');
self.trigger('customclick');
content = self.siblings('.selected')
.find('.b-myselect__option-value').html();
}
currentSelect.html(content);
if (close !== false) {
$body().trigger('click');
if (e && !e.isTrigger) {
currentSelect.focus();
window.scrollToTopLeft();
}
}
EventMgr.trigger('selectChange', { id: id });
}
//идем по селекту вниз downkey
function selectListNext(e) {
var tabId = getActiveTabId(),
id = this.getAttribute('data-id'),
l,
currentLi = $('#' + id + ' li.selected'),
nextLi = currentLi.next(),
next = true,
closed = currentLi.parent()[0].offsetWidth ? false : true;
if (!currentLi[0].offsetWidth && !closed) {
currentLi = $('#' + id + ' li[style$="display: block;"]');
l = currentLi.length;
if (l > 0) {
setSelectedValue.apply(currentLi[0], [false, false, false]);
return;
}
}
while (next) {
if (nextLi.length === 0) {
return;
//detect showed elements by class 'show'
} else if (nextLi[0].offsetWidth && !closed) {
next = false;
} else if (closed && nextLi[0].className.match('b-myselect__select-li_show_yes')) {
next = false;
} else {
nextLi = nextLi.next();
}
}
setSelectedValue.apply(nextLi[0], [false, false, false]);
var offsetTop = nextLi[0].offsetTop,
scrollId = 'cont-' + id;
//if (offsetTop != 0) {
ScrollHandler.forceMoveSelectItem(scrollId, offsetTop);
//}
}
//идем по селекту вверх upkey
function selectListPrev() {
var tabId = getActiveTabId(),
id = this.getAttribute('data-id'),
l,
currentLi = $('#' + id + ' li.selected'),
prevLi = currentLi.prev(),
prev = true,
closed = currentLi.parent()[0].offsetWidth ? false : true;
if (!currentLi[0].offsetWidth && !closed) {
currentLi = $('#' + id + ' li[style$="display: block;"]');
l = currentLi.length;
if (l > 0) {
setSelectedValue.apply(currentLi[l - 1], [false, false, false]);
return;
}
}
while (prev) {
if (prevLi.length === 0) {
return;
//detect showed elements by class 'show'
} else if (prevLi[0].offsetWidth && !closed) {
prev = false;
} else if (closed && prevLi[0].className.match('b-myselect__select-li_show_yes')) {
prev = false;
} else {
prevLi = prevLi.prev();
}
}
setSelectedValue.apply(prevLi[0], [false, false, false]);
var offsetTop = prevLi[0].offsetTop,
scrollId = 'cont-' + id;
//if (offsetTop !== 0) {
ScrollHandler.forceMoveSelectItem(scrollId, offsetTop);
//}
}
//обработчик клавишных нажатий по селекту
function selectListKeyDownHandler(e) {
var codeKey = e.which || e.keyCode,
tabId = this.getAttribute('data-tabid'),
listOpened = !!CACHEOPENEDSELECT[tabId];
//by ENTER and SPACE
if ((codeKey === ENTERKEY || codeKey === SPACE) &&
!e.ctrlKey && this.type !== 'text') {
e.preventDefault();
selectListHandler.apply(this, [e]);
//by ENTER and SPACE search field
} else if (codeKey === ENTERKEY && !e.ctrlKey && this.type === 'text') {
selectFindFirstElem(this);
e.preventDefault();
//by TABKEY when openlist
} else if ((codeKey === TABKEY || codeKey === ESCKEY) && listOpened) {
// e.preventDefault();
// closeSelectList(e, true);
e.stopPropagation();
closeOtherSelectList(false, true);
//UP or LEFT when list opened
} else if ((codeKey === UPKEY || codeKey === LEFTKEY) &&
! listOpened && !e.ctrlKey && this.type !== 'text') {
e.preventDefault();
selectListPrev.apply(this, [e]);
//DOWN or RIGHT list opened
} else if ((codeKey === DOWNKEY || codeKey === RIGHTKEY) &&
! listOpened && !e.ctrlKey && this.type !== 'text') {
e.preventDefault();
selectListNext.apply(this, [e]);
//DOWN when list closed
} else if (codeKey === DOWNKEY && listOpened && !e.ctrlKey) {
e.preventDefault();
selectListNext.apply(this, [e]);
//UP when list closed
} else if (codeKey === UPKEY && listOpened && !e.ctrlKey) {
e.preventDefault();
selectListPrev.apply(this, [e]);
//Open by any symbol
} else if (this.type !== 'text' && codeKey > 32) {
selectListHandler.apply(this, [e]);
}
}
function selectFindFirstElem(self) {
var id, sElem, selElem,
currentSelect;
id = self.getAttribute('data-id');
sElem = $('#' + id);
if (sElem.length === 0) { return; }
selElem = sElem.find('li.selected:visible');
if (selElem.length !== 0) {
selElem.trigger('click');
} else {
selElem = sElem.find('li:visible:first');
if (selElem.length !== 0) {
selElem.trigger('click');
} else {
$('body').trigger('click');
}
}
//set focus on select
currentSelect = $('#' + sElem.attr('data-id') +
' .b-myselect__select-value');
currentSelect.focus();
window.scrollToTopLeft();
}
var matchesElems = {};
//поиск по селекту
function findElemsInSelect(e) {
e = e || window.event;
var codeKey = e.which || e.keyCode;
if (codeKey === UPKEY || codeKey === DOWNKEY || TABKEY === codeKey) {
return;
}
var value, id, sElem, sElems, len, regEx, words, wLen,
find, inner, searchAll = true, optListId,
curElem, selElems, tabId, matches, listParent;
value = this.value.toLowerCase();
value = App.u.escapeRegExp(value);
id = this.getAttribute('data-id');
sElem = App.Dom.byId(id);
if (!sElem) { return; }
var $sElem = $(sElem);
optListId = String(sElem.getAttribute('data-id'));
sElems = sElem.children;
len = sElems.length;
tabId = this.getAttribute('data-tabId');
//cache html nodes
if (!CACHE[tabId]) {
CACHE[tabId] = {};
}
if (!CACHE[tabId][id]) {
sElems = sElem.children;
selElems = [];
var l = sElems.length,
t1, pushed,
clone;
while (l--) {
clone = sElems[l].cloneNode(true);
clone.className += ' b-myselect__select-li_clone_true';
t1 = $(clone).find('.b-myselect__option-value');
/* jslint loopfunc:true */
pushed = selElems.push({
node: sElems[l],
clone: clone,
innerNode: t1,
inner: t1.html(),
bindClick: function() {
var $clone = $(this.clone);
$clone.bind('click', $.proxy(function(e) {
this.returnDefValue();
var $node = $(this.node);
$node.addClass('selected')
.siblings().removeClass('selected');
//for unknow reasons it doesn't bubble to parent li
//force click
if (e) {
var scrElemClass = e.srcElement ?
e.srcElement.className : e.target ? e.target.className : '';
if (scrElemClass.indexOf('highlight') === 0) {
$node.trigger('click');
}
}
}, this));
$clone.bind('customclick', $.proxy(function() {
var $node = $(this.node);
$node.addClass('selected');
}, this));
},
returnDefValue: function() {
if (this.isMatched) {
this.innerNode.html(this.inner);
}
this.isMatched = false;
}
});
/* jslint loopfunc:false */
selElems[pushed - 1].bindClick();
CACHE[tabId][id] = selElems;
}
} else {
selElems = CACHE[tabId][id];
len = selElems.length;
}
if (value === '') {
//show all elems in list
$sElem.removeClass('b-myselect__select-ul_searching_true');
hideElement(matchesElems[id]);
scrollToSelectedElement(sElem, id);
EventMgr.trigger('updateScroll', { id: 'cont-' + id });
return;
} else {
$sElem.addClass('b-myselect__select-ul_searching_true');
}
if (!searchAll) {
regEx = new RegExp('^' + value);
} else {
regEx = new RegExp(value);
}
var wordLowerCase = '';
matchesElems[id] = [];
while (len--) {
curElem = selElems[len];
curElem.returnDefValue();
inner = curElem.inner;
words = inner.split(' ');
wLen = words.length;
find = false;
while (wLen--) {
wordLowerCase = words[wLen].toLocaleLowerCase();
matches = wordLowerCase.match(regEx);
if (matches) {
selElems[len].isMatched = true;
selElems[len].searchIndex = wordLowerCase.indexOf(matches[0]) +
Math.pow(10, wLen);
find = true;
words[wLen] = addHightLight(value, words[wLen], searchAll);
matchesElems[id].push(selElems[len]);
}
}
if (!find) {
hideElement(curElem);
} else {
showElement(curElem);
curElem.innerNode.html(words.join(' '));
}
}
//sort result of find
if (matchesElems[id].length > 0) {
var lMatchesElems = matchesElems[id];
lMatchesElems.sort(sortMatches);
listParent = $(sElem);
var mLen = lMatchesElems.length;
while (mLen--) {
listParent.prepend(lMatchesElems[mLen].clone);
}
}
EventMgr.trigger('updateScroll', { id: 'cont-' + id });
ScrollHandler.scrollTo('cont-' + id, 0);
App.Common.setOptionListPosition('#opt', optListId);
}
function sortMatches(a, b) {
if (b.searchIndex === a.searchIndex) { return 0; }
if (b.searchIndex < a.searchIndex) { return 1; } else { return -1; }
}
function scrollToSelectedElement(sElem, id) {
var top,
selectedElem;
selectedElem = $(sElem)
.find('.selected:not(".b-myselect__select-li_clone_true")');
if (selectedElem.length) {
top = selectedElem[0].offsetTop;
setTimeout(function() {
ScrollHandler.scrollTo('cont-' + id, top);
}, 1);
}
}
//показываем элемент или элементы в селекте
function showElement(elem) {
if (!elem) { return; }
var len = elem.length;
if (len) {
while (len--) {
if (elem[len].clone.className.match('b-myselect__select-li_show_yes')) {
elem[len].clone.style.display = 'block';
} else {
elem[len].clone.style.display = 'none';
}
}
} else {
if (elem.clone) {
if (elem.clone.className.match('b-myselect__select-li_show_yes')) {
elem.clone.style.display = 'block';
} else {
elem.clone.style.display = 'none';
}
}
}
}
//скрываем элемент или элементы в селекте
function hideElement(elem) {
if (!elem) { return; }
var len = elem.length;
if (len) {
while (len--) {
elem[len].clone.style.display = 'none';
}
} else {
if (elem.clone) {
elem.clone.style.display = 'none';
}
}
}
//добавляем выделение
function addHightLight(rep, value, searchAll) {
var re, elemValue;
if (!searchAll) {
re = rep ? new RegExp('(^' + rep + ')', 'i') : false;
} else {
re = rep ? new RegExp('(' + rep + ')', 'i') : false;
}
elemValue = value.replace(re, '<span class="highlight">$1</span>');
return elemValue;
}
/**
* Обрабатываем зависимости при отрисовке формы
*/
function firstDependSlistHandler(e, data) {
var tabId = data.tabId;
$('#cont-' + tabId + ' tr:not(".row-error") .depend.b-myselect ' +
'input[type="hidden"],' +
' #cont-' + tabId + ' .depend.b-radio input[type="hidden"],' +
' #cont-' + tabId + ' .depend.b-select-ac input[type="hidden"]').
each(function() {
dependSlistHandler.apply(this);
});
EventMgr.trigger('updFormHeight', { tabId: tabId });
}
function dependSlistHandler() {
var value = this.value,
name = this.getAttribute('name'),
type = this.getAttribute('data-type'),
tabId = this.getAttribute('data-tabid'),
elem,
selectElem, showElem, $dependSelect;
//hide select options
$dependSelect = $('#frm-' + tabId + ' div[data-depend="' + name + '"]');
if ($dependSelect.length > 1) {
$dependSelect.each(function() {
var $self = $(this);
selectElem = $self.find('li.dependelem[data-dependkey="' + value + '"].selected.b-myselect__select-li_show_yes');
dependSlistCheckSelected(selectElem, $self);
});
} else {
selectElem = $dependSelect.find('li.dependelem[data-dependkey="' + value + '"].selected.b-myselect__select-li_show_yes');
dependSlistCheckSelected(selectElem, $dependSelect);
}
//set first value or prev key
EventMgr.trigger('updateScroll', { id: 'form-scroll-' + tabId });
}
function dependSlistCheckSelected(selectElem, $dependSelect) {
if (selectElem.length === 0) {
var id = $dependSelect.attr('id'),
prevValue = $('#' + id + '-val').val();
$dependSelect.find('li').removeClass('selected');
var elem = $dependSelect.find('li.b-myselect__select-li_show_yes[data-val="' + prevValue + '"]')[0] ||
$dependSelect.find('li.b-myselect__select-li_show_yes')[0];
if (elem) {
setSelectedValue.apply(elem);
} else {
//console.log('alarm!!! no elem');
}
}
}
/**
* Clean cache if slist changed by setvalues
* @param {object} e
* @param {object} data
*/
function cleanSlistCache(e, data) {
var id = data.id,
tabId = data.tabId;
if (CACHE && CACHE[tabId] && CACHE[tabId][id]) {
delete CACHE[tabId][id];
}
}
function init() {
//select
EventMgr.on($content(), selectSelector, 'click', selectListHandler);
EventMgr.on($content(), selectKeySelector,
'keydown', selectListKeyDownHandler);
EventMgr.on($content(), selectItemSelector, 'click', setSelectedValue);
EventMgr.on($content(), '.sb-input', 'keyup', findElemsInSelect);
EventMgr.on($content(), dependSlistSelector, 'change', dependSlistHandler);
EventMgr.bind('appendForm,appendReport,appendedFilter,forceDepend',
firstDependSlistHandler);
EventMgr.bind('cleanSlistCache', cleanSlistCache);
}
var api = {
init: init
};
return api;
} (window, $, EventMgr, App);