2019-04-02 15:56:50 +08:00
|
|
|
|
/* global PerfectScrollbar */
|
2019-02-22 23:40:33 +08:00
|
|
|
|
$.fn.extend({
|
|
|
|
|
select2Multiple: function(config = {}) {
|
2019-04-09 15:08:27 +08:00
|
|
|
|
var placeholder;
|
|
|
|
|
var templateSelection;
|
|
|
|
|
var select2;
|
2019-04-26 21:38:33 +08:00
|
|
|
|
var templateResult;
|
2019-04-09 15:08:27 +08:00
|
|
|
|
|
2019-03-28 17:55:48 +08:00
|
|
|
|
if (this.length === 0) return this;
|
2019-02-22 23:40:33 +08:00
|
|
|
|
// Adding ID to each block
|
2019-04-09 15:08:27 +08:00
|
|
|
|
placeholder = this[0].dataset.placeholder || '';
|
2019-03-15 22:52:30 +08:00
|
|
|
|
if (this.next().find('.select2-selection').length > 0) return this;
|
2019-04-23 16:31:37 +08:00
|
|
|
|
templateSelection = (state, parent) => {
|
2019-03-06 16:18:45 +08:00
|
|
|
|
if (config.colorField !== undefined) {
|
2019-04-23 17:11:22 +08:00
|
|
|
|
parent.css('background', state[config.colorField] || state.element.dataset[config.colorField]);
|
2019-03-06 16:18:45 +08:00
|
|
|
|
}
|
2019-02-22 23:40:33 +08:00
|
|
|
|
return $('<span class="select2-block-body" data-select-id="' + state.id + '">'
|
|
|
|
|
+ (config.customSelection !== undefined ? config.customSelection(state) : state.text)
|
|
|
|
|
+ '</span>');
|
|
|
|
|
};
|
2019-04-26 21:38:33 +08:00
|
|
|
|
|
|
|
|
|
templateResult = (state) => {
|
|
|
|
|
if (config.templateResult) {
|
|
|
|
|
return config.templateResult(state);
|
|
|
|
|
}
|
|
|
|
|
return state.text;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2019-04-09 15:08:27 +08:00
|
|
|
|
select2 = this.select2({
|
2019-02-22 23:40:33 +08:00
|
|
|
|
multiple: true,
|
|
|
|
|
ajax: config.ajax,
|
2019-03-27 18:19:58 +08:00
|
|
|
|
placeholder: placeholder,
|
2019-03-27 17:33:33 +08:00
|
|
|
|
templateSelection: templateSelection,
|
2019-04-26 21:38:33 +08:00
|
|
|
|
templateResult: templateResult,
|
|
|
|
|
closeOnSelect: config.closeOnSelect || false,
|
|
|
|
|
tags: config.dynamicCreation || false,
|
|
|
|
|
tokenSeparators: config.dynamicCreationDelimiter || [','],
|
2019-03-27 17:33:33 +08:00
|
|
|
|
sorter: function(data) {
|
2019-04-26 21:38:33 +08:00
|
|
|
|
if (data.length === 0) return data;
|
2019-03-27 17:33:33 +08:00
|
|
|
|
return data.sort(function(a, b) {
|
|
|
|
|
var from = a.text.toLowerCase();
|
|
|
|
|
var to = b.text.toLowerCase();
|
|
|
|
|
var result = 0;
|
|
|
|
|
if (from > to) {
|
|
|
|
|
result = 1;
|
|
|
|
|
} else if (from < to) {
|
|
|
|
|
result = -1;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
});
|
|
|
|
|
}
|
2019-02-22 23:40:33 +08:00
|
|
|
|
});
|
2019-03-06 17:34:04 +08:00
|
|
|
|
// Add dynamic size
|
|
|
|
|
select2.next().css('width', '100%');
|
|
|
|
|
|
2019-04-02 15:56:50 +08:00
|
|
|
|
// Placeholder fix for ajax fields
|
|
|
|
|
if (config.ajax) {
|
2019-04-23 17:11:22 +08:00
|
|
|
|
setTimeout(() => {
|
|
|
|
|
select2.next().find('.select2-search__field').css('width', 'auto');
|
|
|
|
|
}, 0);
|
2019-03-29 16:04:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-04-15 16:30:08 +08:00
|
|
|
|
// Check that group select correctly
|
|
|
|
|
function select2CheckGroups() {
|
|
|
|
|
var select2Object = $('select[data-select-by-group="true"][data-open-dropdown="true"]');
|
|
|
|
|
var groups = $('.select2-dropdown').find('.select2-results__group');
|
|
|
|
|
$.each(groups, (i, e) => {
|
|
|
|
|
var groupChildrens = $(select2Object).find('optgroup[label="' + e.innerHTML + '"] option');
|
|
|
|
|
$(e).parent()[0].dataset.customGroup = 'true';
|
|
|
|
|
$(e).parent()[0].dataset.toogle = 'none';
|
|
|
|
|
if ($(select2Object).find('optgroup[label="' + e.innerHTML + '"] option:selected').length === groupChildrens.length) {
|
|
|
|
|
$(e).parent()[0].dataset.toogle = 'all';
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function select2ScrollToSelectedElement() {
|
|
|
|
|
var activeElement;
|
|
|
|
|
var sel = $('.select2-results .select2-results__option[role="treeitem"]');
|
|
|
|
|
var parent;
|
|
|
|
|
var activeElementTopPosition;
|
|
|
|
|
var parentActiveElementTopPosition;
|
|
|
|
|
var fullTopPosition;
|
|
|
|
|
var containerRealPosition;
|
|
|
|
|
var containerScrollPosition = $('.select2-results__options').scrollTop();
|
|
|
|
|
var containerHeight = $('.select2-results__options').height();
|
|
|
|
|
if ($('.select2-results').length > 0 && $('.select2-results')[0].dataset.lastSelected !== 'false') {
|
|
|
|
|
activeElement = sel[parseInt($('.select2-results')[0].dataset.lastSelected, 10)];
|
|
|
|
|
} else {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
parent = $(activeElement).parents('.select2-results__option[role="group"]');
|
|
|
|
|
if (parent.length === 0) return;
|
|
|
|
|
activeElementTopPosition = $(activeElement).position().top;
|
|
|
|
|
parentActiveElementTopPosition = parent.position().top;
|
|
|
|
|
fullTopPosition = activeElementTopPosition + parentActiveElementTopPosition;
|
|
|
|
|
containerRealPosition = containerScrollPosition - containerHeight;
|
|
|
|
|
$('.select2-results__options').scrollTop(fullTopPosition + containerRealPosition + 130);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// listen for keyups dropdown
|
|
|
|
|
$('body').off('keyup', '.select2')
|
|
|
|
|
.on('keyup', '.select2', function(e) {
|
|
|
|
|
var keys = { up: 38, down: 40 };
|
|
|
|
|
var sel = $('.select2-results');
|
|
|
|
|
var childSelector = '.select2-results__option[role="treeitem"]';
|
|
|
|
|
var startElement = sel.find(childSelector + '.arrow_pointer');
|
|
|
|
|
var startPosition = 0;
|
|
|
|
|
var newPosition;
|
|
|
|
|
var newElement;
|
|
|
|
|
if (e.keyCode !== keys.up && e.keyCode !== keys.down) {
|
|
|
|
|
select2CheckGroups();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
sel.blur();
|
|
|
|
|
|
|
|
|
|
sel.find(childSelector).each((i, child) => {
|
|
|
|
|
if (child.className.includes('arrow_pointer')) startPosition = i;
|
|
|
|
|
});
|
|
|
|
|
if (startElement.length === 0) {
|
|
|
|
|
if ($('.select2-results')[0].dataset.lastSelected !== 'false') {
|
|
|
|
|
startPosition = parseInt($('.select2-results')[0].dataset.lastSelected, 10);
|
|
|
|
|
} else {
|
|
|
|
|
startElement = sel.find(childSelector).first().addClass('arrow_pointer');
|
|
|
|
|
$('.select2-results')[0].dataset.lastSelected = startPosition;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (e.keyCode === keys.down && !e.altKey) {
|
|
|
|
|
if ((startPosition + 1) === sel.find(childSelector).length) return;
|
|
|
|
|
newPosition = startPosition + 1;
|
|
|
|
|
} else if (e.keyCode === keys.up) {
|
|
|
|
|
if ((startPosition - 1) === -1) return;
|
|
|
|
|
newPosition = startPosition - 1;
|
|
|
|
|
}
|
|
|
|
|
newElement = sel.find(childSelector)[newPosition];
|
|
|
|
|
newElement.className += ' arrow_pointer';
|
|
|
|
|
$('.select2-results')[0].dataset.lastSelected = newPosition;
|
|
|
|
|
startElement.removeClass('arrow_pointer');
|
|
|
|
|
select2ScrollToSelectedElement();
|
|
|
|
|
select2CheckGroups();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$('.select2').find('input, .select2-selection__rendered').off('keydown').on('keydown', function(e) {
|
|
|
|
|
var activeElement = $('.select2-results .arrow_pointer');
|
|
|
|
|
var groupElement = activeElement.find('.select2-results__group');
|
|
|
|
|
if (e.keyCode === 13) {
|
|
|
|
|
if (groupElement.length > 0) {
|
|
|
|
|
groupElement.click();
|
|
|
|
|
} else {
|
|
|
|
|
activeElement.mouseup();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
select2CheckGroups();
|
|
|
|
|
}, 0);
|
|
|
|
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
}
|
2019-04-26 21:38:33 +08:00
|
|
|
|
if ([37, 38, 39, 40].indexOf(e.keyCode) > -1) {
|
2019-04-15 16:30:08 +08:00
|
|
|
|
select2ScrollToSelectedElement();
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2019-04-23 17:11:22 +08:00
|
|
|
|
// Add dynamic size
|
2019-03-06 16:18:45 +08:00
|
|
|
|
select2.next().css('width', '100%');
|
|
|
|
|
|
2019-04-23 17:11:22 +08:00
|
|
|
|
// unlimited size
|
2019-03-06 17:34:04 +08:00
|
|
|
|
if (config.unlimitedSize) {
|
|
|
|
|
this[0].dataset.unlimitedSize = true;
|
|
|
|
|
select2.next().find('.select2-selection').css('max-height', 'none');
|
|
|
|
|
select2.next().find('.select2-selection .select2-selection__rendered').css('width', '100%');
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-26 23:49:12 +08:00
|
|
|
|
// Create arrow
|
2019-04-23 17:11:22 +08:00
|
|
|
|
if (!(config.withoutArrow)) {
|
|
|
|
|
$('<div class="select2-arrow"><span class="caret"></span></div>').appendTo(select2.next())
|
|
|
|
|
.click(() => select2.next().find('.select2-selection').click());
|
|
|
|
|
}
|
2019-02-22 23:40:33 +08:00
|
|
|
|
// select all check
|
|
|
|
|
this[0].dataset.singleDisplay = config.singleDisplay || false;
|
|
|
|
|
if (this[0].dataset.selectAll === 'true') {
|
|
|
|
|
$.each($(this).find('option'), (index, e) => { e.selected = true; });
|
|
|
|
|
this.trigger('change');
|
|
|
|
|
}
|
|
|
|
|
if (config.singleDisplay) {
|
|
|
|
|
$(this).updateSingleName();
|
|
|
|
|
}
|
|
|
|
|
return select2
|
|
|
|
|
// Adding select all button
|
|
|
|
|
.on('select2:open', function() {
|
|
|
|
|
var selectElement = this;
|
2019-03-26 22:29:21 +08:00
|
|
|
|
var groups;
|
|
|
|
|
var groupChildrens;
|
2019-03-28 17:55:48 +08:00
|
|
|
|
var leftPosition = -310;
|
2019-04-15 16:30:08 +08:00
|
|
|
|
var perfectScroll = new PerfectScrollbar($('.select2-results__options')[0], {
|
|
|
|
|
wheelSpeed: 0.5,
|
|
|
|
|
handlers: ['click-rail', 'drag-thumb', 'wheel', 'touch']
|
|
|
|
|
});
|
2019-04-02 15:56:50 +08:00
|
|
|
|
setTimeout(() => {
|
|
|
|
|
perfectScroll.update();
|
|
|
|
|
}, 300);
|
2019-04-15 16:30:08 +08:00
|
|
|
|
$('.select2-results')[0].dataset.lastSelected = false;
|
|
|
|
|
selectElement.dataset.openDropdown = 'true';
|
2019-04-26 21:38:33 +08:00
|
|
|
|
$('.select2-dropdown').removeClass('custom-group').addClass(selectElement.id + '-dropdown');
|
2019-02-22 23:40:33 +08:00
|
|
|
|
$('.select2-selection').scrollTo(0);
|
|
|
|
|
$('.select2_select_all').remove();
|
2019-03-26 22:29:21 +08:00
|
|
|
|
// Adding select_all_button
|
2019-02-22 23:40:33 +08:00
|
|
|
|
if (selectElement.dataset.selectAllButton !== undefined) {
|
|
|
|
|
$('<div class="select2_select_all btn btn-default"><strong>' + selectElement.dataset.selectAllButton + '</strong></div>').prependTo('.select2-dropdown').on('click', function() {
|
2019-03-26 22:29:21 +08:00
|
|
|
|
var scrollTo = $('.select2-results__options').scrollTop();
|
2019-02-22 23:40:33 +08:00
|
|
|
|
var elementsToSelect = $.map($(selectElement).find('option'), e => e.value);
|
2019-03-29 16:04:58 +08:00
|
|
|
|
if (
|
|
|
|
|
$(selectElement).find('option:selected').length === elementsToSelect.length
|
|
|
|
|
|| config.ajax
|
|
|
|
|
) elementsToSelect = [];
|
2019-02-22 23:40:33 +08:00
|
|
|
|
$(selectElement).val(elementsToSelect).trigger('change');
|
|
|
|
|
$(selectElement).select2('close');
|
|
|
|
|
$(selectElement).select2('open');
|
2019-03-26 22:29:21 +08:00
|
|
|
|
$('.select2-results__options').scrollTo(scrollTo);
|
2019-02-22 23:40:33 +08:00
|
|
|
|
});
|
|
|
|
|
}
|
2019-03-25 20:56:32 +08:00
|
|
|
|
|
|
|
|
|
if (selectElement.dataset.dropdownPosition === 'left') {
|
|
|
|
|
$('.select2-dropdown').parent().addClass('left-position');
|
2019-03-26 23:49:12 +08:00
|
|
|
|
if (selectElement.dataset.selectAllButton === undefined) {
|
|
|
|
|
$('.select2-dropdown').parent().addClass('full');
|
|
|
|
|
}
|
2019-03-28 17:55:48 +08:00
|
|
|
|
if (window.innerWidth < 1200) {
|
|
|
|
|
$('.select2-dropdown').css('left', '');
|
|
|
|
|
} else {
|
|
|
|
|
$('.select2-dropdown').css('left', leftPosition);
|
|
|
|
|
}
|
|
|
|
|
$(window).on('resize', () => {
|
|
|
|
|
if (window.innerWidth < 1200) {
|
|
|
|
|
$('.select2-dropdown').css('left', '');
|
|
|
|
|
} else {
|
|
|
|
|
$('.select2-dropdown').css('left', leftPosition);
|
|
|
|
|
}
|
|
|
|
|
});
|
2019-03-25 20:56:32 +08:00
|
|
|
|
}
|
2019-03-26 22:29:21 +08:00
|
|
|
|
// Adding select all group members event
|
|
|
|
|
if (selectElement.dataset.selectByGroup === 'true') {
|
2019-03-26 23:49:12 +08:00
|
|
|
|
$('.select2-dropdown').addClass('custom-group');
|
2019-03-26 22:29:21 +08:00
|
|
|
|
setTimeout(() => {
|
|
|
|
|
groups = $('.select2-dropdown').find('.select2-results__group');
|
2019-04-15 16:30:08 +08:00
|
|
|
|
groups.off('click').click(e => {
|
2019-03-26 22:29:21 +08:00
|
|
|
|
var newSelection = [];
|
|
|
|
|
var scrollTo = $('.select2-results__options').scrollTop();
|
|
|
|
|
var group = e.currentTarget;
|
|
|
|
|
var childrens = $(selectElement).find('optgroup[label="' + group.innerHTML + '"] option');
|
|
|
|
|
childrens = $.map(childrens, act => act.value);
|
|
|
|
|
newSelection = ($(selectElement).val() || []).filter(function(i) {
|
|
|
|
|
return childrens.indexOf(i) < 0;
|
|
|
|
|
});
|
|
|
|
|
if ($(selectElement).find(
|
|
|
|
|
'optgroup[label="' + group.innerHTML + '"] option:selected'
|
|
|
|
|
).length !== childrens.length) {
|
|
|
|
|
newSelection = newSelection.concat(childrens);
|
|
|
|
|
}
|
|
|
|
|
$(selectElement).val(newSelection).trigger('change');
|
|
|
|
|
$(selectElement).select2('close');
|
|
|
|
|
$(selectElement).select2('open');
|
|
|
|
|
$('.select2-results__options').scrollTo(scrollTo);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$.each(groups, (index, e) => {
|
|
|
|
|
groupChildrens = $(selectElement).find('optgroup[label="' + e.innerHTML + '"] option');
|
|
|
|
|
$(e).parent()[0].dataset.customGroup = 'true';
|
|
|
|
|
$(e).parent()[0].dataset.toogle = 'none';
|
|
|
|
|
if ($(selectElement).find('optgroup[label="' + e.innerHTML + '"] option:selected').length === groupChildrens.length) {
|
|
|
|
|
$(e).parent()[0].dataset.toogle = 'all';
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}, 0);
|
|
|
|
|
}
|
2019-02-22 23:40:33 +08:00
|
|
|
|
})
|
2019-04-15 16:30:08 +08:00
|
|
|
|
.on('select2:close', function() {
|
|
|
|
|
this.dataset.openDropdown = 'false';
|
|
|
|
|
})
|
2019-02-22 23:40:33 +08:00
|
|
|
|
// Prevent shake bug with multiple select
|
|
|
|
|
.on('select2:open select2:close', function() {
|
2019-03-06 17:34:04 +08:00
|
|
|
|
$('.select2-selection').scrollTo(0);
|
2019-02-22 23:40:33 +08:00
|
|
|
|
})
|
|
|
|
|
// Prevent opening window when deleteing selection
|
|
|
|
|
.on('select2:unselect', function() {
|
|
|
|
|
var resultWindow = $('.select2-container--open');
|
|
|
|
|
if (resultWindow.length === 0) {
|
|
|
|
|
$(this).select2('open');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
// Fxied scroll bug
|
|
|
|
|
.on('select2:selecting select2:unselecting', function(e) {
|
|
|
|
|
$(e.currentTarget).data('scrolltop', $('.select2-results__options').scrollTop());
|
|
|
|
|
$('.select2-selection').scrollTo(0);
|
|
|
|
|
})
|
|
|
|
|
// Fxied scroll bug
|
2019-04-15 16:30:08 +08:00
|
|
|
|
.on('change', function(e) {
|
2019-03-26 22:29:21 +08:00
|
|
|
|
var groups;
|
|
|
|
|
var groupChildrens;
|
2019-02-22 23:40:33 +08:00
|
|
|
|
$('.select2-selection').scrollTo(0);
|
|
|
|
|
$('.select2-results__options').scrollTop($(e.currentTarget).data('scrolltop'));
|
|
|
|
|
if (this.dataset.singleDisplay === 'true') {
|
|
|
|
|
$(this).updateSingleName();
|
|
|
|
|
}
|
2019-03-26 22:29:21 +08:00
|
|
|
|
|
|
|
|
|
if (this.dataset.selectByGroup === 'true') {
|
|
|
|
|
groups = $('.select2-dropdown').find('.select2-results__group');
|
|
|
|
|
$.each(groups, (index, act) => {
|
|
|
|
|
groupChildrens = $(this).find('optgroup[label="' + act.innerHTML + '"] option');
|
|
|
|
|
$(act).parent()[0].dataset.toogle = 'none';
|
|
|
|
|
if ($(this).find('optgroup[label="' + act.innerHTML + '"] option:selected').length === groupChildrens.length) {
|
|
|
|
|
$(act).parent()[0].dataset.toogle = 'all';
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2019-04-15 16:30:08 +08:00
|
|
|
|
setTimeout(() => {
|
|
|
|
|
select2ScrollToSelectedElement();
|
|
|
|
|
}, 0);
|
2019-02-22 23:40:33 +08:00
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
select2MultipleClearAll: function() {
|
|
|
|
|
$(this).val([]).trigger('change');
|
|
|
|
|
},
|
|
|
|
|
// Create from multiple blocks single one with counter
|
|
|
|
|
updateSingleName: function() {
|
|
|
|
|
var template = '';
|
|
|
|
|
var selectElement = this;
|
|
|
|
|
var selectedOptions = selectElement.next().find('.select2-selection__choice');
|
|
|
|
|
var optionsCounter = selectedOptions.length;
|
|
|
|
|
var allOptionsSelected = this.find('option').length === optionsCounter;
|
|
|
|
|
var optionText = allOptionsSelected ? this[0].dataset.selectMultipleAllSelected : optionsCounter + ' ' + this[0].dataset.selectMultipleName;
|
|
|
|
|
if (optionsCounter > 1) {
|
|
|
|
|
selectedOptions.remove();
|
|
|
|
|
template = '<li class="select2-selection__choice">'
|
|
|
|
|
+ '<span class="select2-selection__choice__remove" role="presentation">×</span>'
|
|
|
|
|
+ optionText
|
|
|
|
|
+ '</li>';
|
|
|
|
|
$(template).prependTo(selectElement.next().find('.select2-selection__rendered')).find('.select2-selection__choice__remove')
|
|
|
|
|
.click(function() { selectElement.select2MultipleClearAll(); });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|