Your IP : 18.219.40.177
/**
* Модуль кастомного мультиселекта
* @param {object} window global object
* @param {function} $ jQuery library
* @param {object} EventMgr EventMgr library
* @param {object} App Application
*/
App.MultiSelect = function(window, $, EventMgr, App) {
'use strict';
var init = function() {
EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__view-value',
'click', listOpenHandler);
EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__ul-choose li',
'click', chooseElemHandler);
EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__ul-view .b-mselect__unselect',
'click', unChooseElemHandler);
// EventMgr.on('#main-wrapper', '.mselect-av .b-input-btn_type_plus',
// 'click', selectAllHandler);
// EventMgr.on('#main-wrapper', '.mselect-av .b-input-btn_type_minus',
// 'click', unSelectAllHandler);
EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__item_select-all',
'dblclick', unSelectAllHandler);
EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__ul-view .b-mselect__item',
'mouseover', checkSize);
EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__view-value',
'keydown', keydownHandler);
EventMgr.bind('selectValues', selectValues);
EventMgr.bind('multiSelectUnselect', unSelectAllFromOut);
EventMgr.bind('mselectUnselectByDepend', unselectByDepend);
},
listWrapperIdPostfix = '-ms-list-wrapper',
listIdPostfix = '-ms-list',
chooseListIdPostfix = '-ms-view',
appDom = App.Dom,
$body = function() {
return $('body');
},
//show select options
listOpenHandler = function(e) {
var id = this.getAttribute('data-id'),
list = appDom.byId(id + listWrapperIdPostfix),
bodyHeight, elemHeight, formTop, elemTop, tabId, form;
if (e.target && e.target.className.match('scrlbr')) {
return;
}
if (list) {
if (list.offsetWidth === 0) {
//for close other list
$('body').trigger('click');
bodyHeight = window.document.body.offsetHeight;
appDom.removeClass(list, 'closed');
//calculate list options position
elemHeight = list.offsetHeight;
list.style.top = '';
elemTop = $(list).offset().top;
if ((bodyHeight - elemTop) < elemHeight) {
tabId = list.getAttribute('data-tabid');
form = $('#form-scroll-' + tabId);
formTop = form.offset().top;
if (formTop > (elemTop - elemHeight - appDom.byId(id + '-ms-view').offsetHeight)) {
list.style.top = '-' + (elemHeight / 2) + 'px';
} else {
list.style.top = '-' + elemHeight + 'px';
}
}
$body().on('click', listCloseHandler);
e.stopPropagation();
EventMgr.trigger('updateScroll', { id: id + listIdPostfix });
} else {
appDom.addClass(list, 'closed');
EventMgr.off('body', 'click');
$body().off('click', listCloseHandler);
}
}
},
//close select options
listCloseHandler = function(e) {
if (e.target) {
if (!appDom.hasClass(e.target, 'b-mselect__item') &&
!appDom.hasClass(e.target, 'scrlbr')) {
closeList();
} else {
return;
}
}
$body().off('click', listCloseHandler);
e.stopPropagation();
},
//
closeList = function(id) {
var elems, selected;
if (typeof id === 'string') {
elems = $('#' + id + '-ms-list-wrapper');
} else {
elems = $('.b-mselect__options');
}
elems.addClass('closed');
//remove selected hightlight
if (typeof id === 'string') {
selected = $('#' + id + '-ms-list-ul')
.find('.b-mselect__item_st_selected');
} else {
selected = $('.b-mselect__item_st_selected');
}
selected.removeClass('b-mselect__item_st_selected');
},
checkAllSelectedElem = function(id) {
var $items = $('#' + id + '-ms-list-ul'),
selectedCount = $items.find('.chosen').length,
allCount = $items.find('.b-mselect__item').length - 1;
return {
selectedCount: selectedCount,
allCount: allCount,
allSelected: allCount === selectedCount
};
},
chooseElemHandler = function(e, data) {
var clone = this.cloneNode(true),
id = this.parentNode.getAttribute('data-id'),
clist = App.Dom.byId(id + chooseListIdPostfix),
maxSelect = clist.getAttribute('data-maxselect'),
selectedObj = checkAllSelectedElem(id),
selectedCount = selectedObj.selectedCount,
preventChange = data ? data.preventChange ? true : false : false;
maxSelect = (maxSelect === '') ? 9999 : parseInt(maxSelect, 10);
if (selectedCount === maxSelect) {
//closeList(id);
return;
}
//check for selected
if (appDom.hasClass(this, 'b-mselect__item_select-all')) {
if (selectedObj.allSelected) {
unSelectAllValues(id);
} else {
selectAllValues(id);
}
} else if (appDom.hasClass(this, 'chosen')) {
appDom.removeClass(this, 'chosen');
$('.b-mselect__item[data-s-id="' + clone.id + '"] .b-mselect__unselect').trigger('click');
} else {
clone.setAttribute('data-s-id', clone.id);
clone.id = '';
if (!clist) { return; }
appDom.addClass(this, 'chosen');
appDom.addClass(clone, 'chosen');
clist.appendChild(clone);
setValue(id, preventChange);
}
},
unChooseElemHandler = function(e) {
var elem = this.parentNode,
sid = elem.getAttribute('data-s-id'),
sElem = appDom.byId(sid),
id = sElem.parentNode.getAttribute('data-id');
elem.parentNode.removeChild(elem);
appDom.removeClass(sElem, 'chosen');
setValue(id);
// closeList(id);
e.stopPropagation();
},
unSelectAllHandler = function(e) {
var id = this.getAttribute('data-id');
unSelectAllValues(id);
e.preventDefault();
},
unSelectAllFromOut = function(e, data) {
var id = data.id;
unSelectAllValues(id);
},
//unselect all values
unSelectAllValues = function(id) {
$('#' + id + '-ms-view .b-mselect__item.chosen').remove();
$('#' + id + '-ms-list-ul .chosen').removeClass('chosen');
setValue(id);
},
selectAllHandler = function(e) {
var id = this.getAttribute('data-id');
selectAllValues(id);
e.preventDefault();
},
//select all values
selectAllValues = function(id) {
var elems = $('#' + id + '-ms-list-ul .b-mselect__item'),
l = elems.length, clone,
clist = App.Dom.byId(id + chooseListIdPostfix),
maxSelect = clist.getAttribute('data-maxselect'),
selectedCount = $('#' + id + '-ms-list-ul li.chosen').length;
maxSelect = (maxSelect === '') ? 9999 : parseInt(maxSelect, 10);
for (var i = 0; i < l; i++) {
if (selectedCount === maxSelect) {
break;
}
if (appDom.hasClass(elems[i], 'dependelem') &&
!appDom.hasClass(elems[i], 'b-myselect__select-li_show_yes')) {
continue;
}
if (appDom.hasClass(elems[i], 'b-mselect__item_select-all')) {
continue;
}
if (!appDom.hasClass(elems[i], 'chosen')) {
clone = elems[i].cloneNode(true);
clone.setAttribute('data-s-id', clone.id);
clone.id = '';
appDom.addClass(elems[i], 'chosen');
appDom.addClass(clone, 'chosen');
clist.appendChild(clone);
selectedCount++;
}
}
setValue(id);
},
//setvalue when change
setValue = function(id, preventChange) {
var elem = appDom.byId(id + chooseListIdPostfix),
cElems = elem.children,
l = cElems.length,
val,
value = '',
input = appDom.byId(id + '-ms-value'),
wrapper = appDom.byId(id + '-ms'),
scrollId = $(wrapper).find('.b-mselect__view-value').attr('id'),
tabId = elem.getAttribute('data-tabId');
if (l !== 1) {
while (l--) {
val = cElems[l].getAttribute('data-val');
value += val;
if (l !== 1) {
value += ',';
} else {
break;
}
}
} else {
value = '';
}
input.value = value;
if (value === '') {
appDom.removeClass(wrapper, 'selected');
} else {
appDom.addClass(wrapper, 'selected');
}
if (!preventChange) {
$(input).trigger('change');
}
EventMgr.trigger('updateScroll', { id: 'form-scroll-' + tabId });
EventMgr.trigger('updateScroll', { id: scrollId });
},
//apply setvalues
selectValues = function(e, data) {
var id = data.id,
slist = data.sElems.slist,
values = data.sElems.value !== undefined ? data.sElems.value : data.sElems,
l = values.length,
elem,
maxSelect = $('#' + id + '-ms-view').attr('data-maxselect');
maxSelect = (maxSelect === '') ? 9999 : parseInt(maxSelect, 10);
if (slist) {
$('#' + id + '-ms-list-ul').html(renderMultiSelectValues(slist, id));
}
$('#' + id + '-ms').removeClass('selected');
$('#' + id + '-ms-list-ul li.chosen').removeClass('chosen');
$('#' + id + '-ms-view li.chosen').remove();
if (typeof values === 'string' && values !== '') {
elem = $('#' + id + '-ms-list-ul li[data-val="' + values + '"]')
.trigger('click');
} else {
if (maxSelect < l) { l = maxSelect; }
for (var i = 0; i < l; i++) {
if (i === l - 1) {
elem = $('#' + id + '-ms-list-ul li[data-val="' + values[i] + '"]')
.trigger('click', { 'preventChange': false });
} else {
elem = $('#' + id + '-ms-list-ul li[data-val="' + values[i] + '"]')
.trigger('click', { 'preventChange': true });
}
}
}
},
unselectByDepend = function(e, data) {
var self = data.self;
$(self).find('.b-mselect__ul-view .dependelem:not(".b-myselect__select-li_show_yes") .b-mselect__unselect').each(function() {
$(this).trigger('click');
});
},
//render options for setvalues
renderMultiSelectValues = function(slist, id) {
var html = '',
l = slist.length;
html += '<li class="b-mselect__item b-mselect__item_select-all">' + pageInfo.messages.msg_select_all + '</li>';
for (var i = 0; i < l; i++) {
html += '<li class="b-mselect__item" data-val="' +
slist[i].key + '" unselectable="on" data-handler-val="' +
hash(slist[i].key) + '" data-dependkey="' +
slist[i].depend + '" id="' + id + '-' + i + '">' +
slist[i].value + '<span class="b-mselect__unselect"></span></li>';
}
return html;
},
UPKEY = 38,
DOWNKEY = 40,
LEFTKEY = 37,
RIGHTKEY = 39,
ENTERKEY = 13,
TABKEY = 9,
ESCKEY = 27,
SPACE = 32,
keydownHandler = function(e) {
var codeKey = e.which || e.keyCode,
ctrlKey = e.metaKey || e.ctrlKey,
closed = appDom.hasClass(appDom.byId(this.getAttribute('data-id') +
listWrapperIdPostfix), 'closed');
//go up
if (codeKey === UPKEY && !closed) {
selectPrevOption.apply(this, []);
//go down
} else if (codeKey === DOWNKEY && !closed) {
selectNextOption.apply(this, []);
//close tab
} else if (codeKey === TABKEY && !closed) {
closeList();
//choose selected value & close select or not?
} else if ((codeKey === ENTERKEY || codeKey === SPACE) && !ctrlKey) {
if (closed) {
listOpenHandler.apply(this, [e]);
} else {
chooseSelected.apply(this, [e]);
}
//close list
} else if (codeKey === ESCKEY && !closed) {
e.stopPropagation();
closeList();
}
},
selectPrevOption = function() {
var id = this.getAttribute('data-id'),
$list = $('#' + id + '-ms-list-ul'),
selElem = $list.find('.b-mselect__item_st_selected'),
prev = true,
prevElem = selElem;
if (selElem.length > 0) {
while (prev) {
prevElem = prevElem.prev();
if (prevElem.length > 0) {
prev = prevElem.hasClass('chosen');
} else {
prevElem = null;
prev = false;
}
}
if (prevElem) {
selElem.removeClass('b-mselect__item_st_selected');
prevElem.addClass('b-mselect__item_st_selected');
}
} else {
selElem = $list.find('.b-mselect__item:first:not(".chosen")');
selElem.addClass('b-mselect__item_st_selected');
}
},
selectNextOption = function() {
var id = this.getAttribute('data-id'),
$list = $('#' + id + '-ms-list-ul'),
selElem = $list.find('.b-mselect__item_st_selected'),
nextElem = selElem,
next = true;
if (selElem.length > 0) {
while (next) {
nextElem = nextElem.next();
if (nextElem.length > 0) {
next = nextElem.hasClass('chosen');
} else {
nextElem = null;
next = false;
}
}
if (nextElem) {
selElem.removeClass('b-mselect__item_st_selected');
nextElem.addClass('b-mselect__item_st_selected');
}
} else {
selElem = findFirst($list);
if (selElem) {
selElem.addClass('b-mselect__item_st_selected');
}
}
},
findFirst = function($list) {
var finding = true,
first = $list.find('.b-mselect__item:first');
while (finding) {
if (first.length > 0) {
if (first.hasClass('chosen')) {
first = first.next();
finding = true;
} else {
return first;
}
} else {
return false;
}
}
},
chooseSelected = function(e) {
var id = this.getAttribute('data-id'),
selected = $('#' + id + '-ms-list-ul')
.find('.b-mselect__item_st_selected');
if (selected.length > 0) {
selected.trigger('click');
} else {
closeList(id);
}
},
checkSize = function() {
if (App.Dom.hasClass(this, 'overwidth') ||
App.Dom.hasClass(this, 'notoverwidth')) {
return;
}
if (this.scrollWidth > this.offsetWidth) {
App.Dom.addClass(this, 'overwidth');
$(this).trigger('mouseover');
} else {
App.Dom.addClass(this, 'notoverwidth');
}
};
return {
init: init
};
}(window, $, EventMgr, App);