// Search
const _inforSelectSearch = {
instances: {},
container: null,
search_index: null,
get: (id) => {
return _inforSelectSearch.instances[id];
},
instanceByContainer: container => {
const id = container.attr('id');
return _inforSelectSearch.instances[id];
}
}
function initInforSelectSearch(){
validateInforBase();
$('infor-select-search').each((index, element) =>{
const container = $(element);
const initiated = container.attr('data-initiated');
if(initiated){return true}
const options = container.find('infor-select-option').detach();
container.append(`
`);
const options_container = container.find('[data-infor-select-options-container]');
const input_display = container.find('[data-infor-select-input-display]');
const input_hidden = container.find('[data-infor-select-input-hidden]');
const hidden_attributes_container = container.find('infor-select-search-hidden-attr');
const id = container.attr('id') || randomString(10);
const name = container.attr('name');
const livewire = container.attr('data-livewire');
const livewire_params = container.attr('data-livewire-params');
container.removeAttr('livewire');
container.removeAttr('livewire-params');
container.removeAttr('name');
input_hidden.attr('name', name);
const attributes = container.get(0).attributes;
$.each(attributes, function () {
input_display.attr(this.name, this.value);
});
while (attributes.length) {
container.removeAttr(attributes[0].name);
}
if(hidden_attributes_container.length){
const hidden_attributes = hidden_attributes_container.get(0).attributes;
$.each(hidden_attributes, function () {
input_hidden.attr(this.name, this.value);
});
hidden_attributes_container.remove();
}
let selected_value = null;
options.each((index, option) => {
option = $(option);
const value = option.attr('data-value');
const name = option.attr('data-name') || option.text();
const html = option.html();
if(option.attr('data-selected') !== undefined){ selected_value = value; }
options_container.append(`${html}
`)
})
container.attr('data-initiated', 'true');
container.attr('id', id);
_inforSelectSearch.instances[id] = {
container: container,
id: id,
name: name,
input: container.find('[data-infor-select-input-hidden]'),
livewire: livewire,
livewireEmit: value => {
if(!livewire){ return }
if(typeof Livewire !== 'object' && typeof Livewire.emit !== 'function'){ return }
Livewire.emit(livewire, value, parseInforLivewireParams(livewire_params));
},
onchange: value => {},
getValue: () => {
const value = container.find('[data-infor-select-input-hidden]').val();
const name = container.find(`[data-infor-select-option][data-value="${value}"]`).attr('data-name');
return {
name: name || '',
value: value || '',
}
},
setValue: value => {
container.find(`[data-infor-select-option][data-value="${value}"]`).trigger('silent_click');
},
prefillValue: value => {
const option = container.find(`[data-infor-select-option][data-value="${value}"]`);
if(!option.length){ return }
const name = option.attr('data-name');
container.find('[data-infor-select-input-hidden]').val(value);
container.find('[data-infor-select-input-display]').val(name);
},
clear_button: () => { return container.find('[data-clear]'); },
input_hidden: () => { return container.find('[data-infor-select-input-hidden]') },
input_display: () => { return container.find('[data-infor-select-input-display]') },
input_search: () => { return container.find('[data-infor-select-input-search]') },
options_container: () => { return container.find('[data-infor-select-options-container]') },
options: () => { return container.find('[data-infor-select-option]') },
visible_options: () => { return container.find('[data-infor-select-option]').not('[data-hide]') },
focused_option: () => { return container.find('[data-infor-select-option][data-focused]') },
disable: () => {
container.attr('data-disabled', true);
},
enable: () => {
container.removeAttr('data-disabled');
},
isActive: () => {
const disabled = container.attr('data-disabled') === 'true';
return !disabled;
}
}
if(selected_value){
_inforSelectSearch.instances[id].prefillValue(selected_value);
}
});
}
$(document).keydown(function(event){
const { container, search_index } = _inforSelectSearch;
if(!container){return;}
const instance = _inforSelectSearch.instanceByContainer(container);
const { visible_options, options_container, focused_option} = instance;
const { key } = event;
if(key != "ArrowUp" && key != "ArrowDown" && key != "Enter"){return;}
visible_options().removeAttr('data-focused');
if(event.key == "Enter"){
event.preventDefault();
event.stopPropagation();
visible_options().eq(_inforSelectSearch.search_index).trigger('silent_click');
return false;
}
if(event.key == 'ArrowDown'){
if(search_index === null || search_index === (visible_options().length - 1)){ _inforSelectSearch.search_index = 0; }
else{ _inforSelectSearch.search_index += 1; }
}
else if(event.key == 'ArrowUp'){
if(search_index === null || search_index === 0){ _inforSelectSearch.search_index = (visible_options().length - 1); }
else{ _inforSelectSearch.search_index += -1; }
}
visible_options().eq(_inforSelectSearch.search_index).attr('data-focused', true);
const container_height = options_container().height();
const scroll_offset = options_container().scrollTop();
const top_offset = focused_option().position().top;
const focused_option_height = (focused_option().outerHeight() / 2);
if(top_offset > container_height){
options_container().scrollTop(top_offset - container_height + scroll_offset + focused_option_height + 10);
}
else if(top_offset < 0){
options_container().scrollTop(scroll_offset - Math.abs(top_offset) - 10);
}
});
$(document).on('click', 'infor-select-search [data-infor-select-input-display]', function () {
hideInforSelectables();
const container = findContainerByTag('infor-select-search', this);
const instance = _inforSelectSearch.instanceByContainer(container);
const { input_search, options_container, options, isActive } = instance;
if(!isActive()){ return; }
options_container().css({display: 'block', width: container.outerWidth()});
input_search().val('').focus();
options().removeAttr('data-hide data-focused');
_inforSelectSearch.search_index = null;
_inforSelectSearch.container = container;
});
$(document).on('click silent_click', 'infor-select-search [data-infor-select-option]', function () {
const option = $(this);
const container = findContainerByTag('infor-select-search', this);
const instance = _inforSelectSearch.instanceByContainer(container);
const { input_display, input_hidden, clear_button, onchange, livewireEmit } = instance;
const content = option.attr('data-name');
const value = option.attr('data-value');
input_display().val(content)
input_hidden().val(value).trigger('change');
onchange(value);
livewireEmit(value);
clear_button().removeAttr('data-active');
if(value){
clear_button().attr('data-active', true);
}
hideInforSelectables();
});
$(document).on('input', 'infor-select-search [data-infor-select-input-search]', function (event) {
const input = $(this);
const words = input.val().toLowerCase().replaceAll(__infor_base.regex_ignore, '').split(' ');
const container = findContainerByTag('infor-select-search', this);
const instance = _inforSelectSearch.instanceByContainer(container);
const { options } = instance;
const { key } = event;
if(key == 'ArrowUp' || key == 'ArrowDown'){ return; }
options().removeAttr('data-hide');
if(!words.length){ return; }
options().each((index, element) => {
const option = $(element);
const text = option.text().toLowerCase().replaceAll(__infor_base.regex_ignore, '');
for(const word of words){
if(text.includes(word)){ continue; }
option.attr('data-hide', 'true');
}
})
_inforSelectSearch.search_index = null;
options().removeAttr('data-focused');
});
$(document).on('click', 'infor-select-search [data-clear]', function(){
const container = findContainerByTag('infor-select-search', this);
const instance = _inforSelectSearch.instanceByContainer(container);
const { input_hidden, input_display, clear_button, onchange, livewireEmit, isActive } = instance;
if(!isActive()){ return; }
clear_button().removeAttr('data-active');
input_display().val('');
input_hidden().val('').trigger('change');
onchange(null);
livewireEmit(null);
});
// Multiple
const _inforSelectMultiple = {
instances: {},
container: null,
search_index: null,
get: (id) => {
return _inforSelectMultiple.instances[id];
},
instanceByContainer: container => {
const id = container.attr('id');
return _inforSelectMultiple.instances[id];
}
}
function initInforSelectMultiple(){
validateInforBase();
$('infor-select-multiple').each((index, element) =>{
const container = $(element);
const initiated = container.attr('data-initiated');
if(initiated){return true}
const options = container.find('infor-select-option').detach();
container.append(`
`);
const options_container = container.find('[data-infor-select-options-container]');
const input_display = container.find('[data-infor-select-input-display]');
const id = container.attr('id') || randomString(10);
const name = container.attr('name');
const livewire = container.attr('data-livewire');
const livewire_params = container.attr('data-livewire-params');
container.removeAttr('livewire');
container.removeAttr('livewire-params');
container.removeAttr('name');
const attributes = container.get(0).attributes;
$.each(attributes, function () {
input_display.attr(this.name, this.value);
});
while (attributes.length) {
container.removeAttr(attributes[0].name);
}
options.each((index, option) => {
option = $(option);
const value = option.attr('data-value');
const display_name = option.attr('data-name') || option.text();
const html = option.html();
const selected = option.attr('data-selected') !== undefined;
option.removeAttr('data-value data-name data-selected');
const attributes = option.get(0).attributes
let attributes_string = '';
for(const attr of attributes){
attributes_string += `${attr.name}="${attr.value}" `;
}
options_container.append(`
`)
})
container.attr('data-initiated', 'true');
container.attr('id', id);
_inforSelectMultiple.instances[id] = {
container: container,
id: id,
name: name,
input: container.find('[data-infor-select-checkbox]'),
livewire: livewire,
livewireEmit: values => {
if(!livewire){ return }
if(typeof Livewire !== 'object' && typeof Livewire.emit !== 'function'){ return }
Livewire.emit(livewire, values, parseInforLivewireParams(livewire_params));
},
onchange: value => {},
onchangeOption: object => {},
getValues: () => {
return container.find('[data-infor-select-checkbox]:checked').map(function() {
return {
name: $(this).attr('data-name'),
value: $(this).attr('value')
};
}).get();
},
setValues: (values, deselect_remaining = true) => {
container.find('[data-infor-select-option]').each((index, element) => {
const option = $(element);
const input = option.find('[data-infor-select-checkbox]');
const checked = input.is(':checked');
const select = values.find(value => value == input.attr('value'));
if( (select && !checked) || (!select && checked && deselect_remaining) ){
input.prop('checked', !checked).trigger('change');
}
})
},
refreshIndicators: () => {
let not_empty = false;
const options = container.find('[data-infor-select-option]');
options.each((index, element) => {
const option = $(element);
const checked = option.find('[data-infor-select-checkbox]').is(':checked');
option.attr('data-infor-select-option', (checked ? 'active' : ''));
if(checked){ not_empty = true; }
});
const names = container.find('[data-infor-select-checkbox]:checked').map(function() { return $(this).attr('data-name'); }).get();
container.find('[data-infor-select-input-display]').val(names.join(', '));
container.find('[data-clear]').removeAttr('data-active');
if(not_empty){
container.find('[data-clear]').attr('data-active', true);
}
},
clear_button: () => { return container.find('[data-clear]'); },
input_display: () => { return container.find('[data-infor-select-input-display]') },
input_search: () => { return container.find('[data-infor-select-input-search]') },
options_container: () => { return container.find('[data-infor-select-options-container]') },
options: () => { return container.find('[data-infor-select-option]') },
visible_options: () => { return container.find('[data-infor-select-option]').not('[data-hide]') },
focused_option: () => { return container.find('[data-infor-select-option][data-focused]') },
disable: () => {
container.attr('data-disabled', true);
},
enable: () => {
container.removeAttr('data-disabled');
},
isActive: () => {
const disabled = container.attr('data-disabled') === 'true';
return !disabled;
}
}
_inforSelectMultiple.instances[id].refreshIndicators();
});
}
$(document).keydown(function(event){
const { container, search_index } = _inforSelectMultiple;
if(!container){return;}
const instance = _inforSelectMultiple.instanceByContainer(container);
const { visible_options, options_container, focused_option} = instance;
const { key } = event;
if(key != "ArrowUp" && key != "ArrowDown" && key != "Enter"){return;}
if(event.key == "Enter"){
event.preventDefault();
event.stopPropagation();
const checkbox = visible_options().eq(_inforSelectMultiple.search_index).find('[data-infor-select-checkbox]');
const target_state = !checkbox.prop('checked');
checkbox.prop('checked', target_state).trigger('change');
return false;
}
visible_options().removeAttr('data-focused');
if(event.key == 'ArrowDown'){
if(search_index === null || search_index === (visible_options().length - 1)){ _inforSelectMultiple.search_index = 0; }
else{ _inforSelectMultiple.search_index += 1; }
}
else if(event.key == 'ArrowUp'){
if(search_index === null || search_index === 0){ _inforSelectMultiple.search_index = (visible_options().length - 1); }
else{ _inforSelectMultiple.search_index += -1; }
}
visible_options().eq(_inforSelectMultiple.search_index).attr('data-focused', true);
const container_height = options_container().height();
const scroll_offset = options_container().scrollTop();
const top_offset = focused_option().position().top;
const focused_option_height = (focused_option().outerHeight() / 2);
if(top_offset > container_height){
options_container().scrollTop(top_offset - container_height + scroll_offset + focused_option_height + 10);
}
else if(top_offset < 0){
options_container().scrollTop(scroll_offset - Math.abs(top_offset) - 10);
}
});
$(document).on('click', 'infor-select-multiple [data-infor-select-input-display]', function () {
hideInforSelectables();
const container = findContainerByTag('infor-select-multiple', this);
const instance = _inforSelectMultiple.instanceByContainer(container);
const { input_search, options_container, options, isActive } = instance;
if(!isActive()){ return; }
options_container().css({display: 'block', width: container.outerWidth()});
input_search().val('').focus();
options().removeAttr('data-hide data-focused');
_inforSelectMultiple.search_index = null;
_inforSelectMultiple.container = container;
});
$(document).on('change', 'infor-select-multiple [data-infor-select-checkbox]', function () {
const container = findContainerByTag('infor-select-multiple', this);
const instance = _inforSelectMultiple.instanceByContainer(container);
const { refreshIndicators, getValues, onchange, onchangeOption, livewireEmit } = instance;
const name = $(this).attr('data-name');
const value = $(this).attr('value');
const checked = $(this).prop('checked');
refreshIndicators();
onchange(getValues());
onchangeOption({ name: name, value: value, checked: checked });
livewireEmit(getValues());
});
$(document).on('input', 'infor-select-multiple [data-infor-select-input-search]', function (event) {
const input = $(this);
const words = input.val().toLowerCase().replaceAll(__infor_base.regex_ignore, '').split(' ');
const container = findContainerByTag('infor-select-multiple', this);
const instance = _inforSelectMultiple.instanceByContainer(container);
const { options } = instance;
const { key } = event;
if(key == 'ArrowUp' || key == 'ArrowDown'){ return; }
options().removeAttr('data-hide');
if(!words.length){ return; }
options().each((index, element) => {
const option = $(element);
const text = option.text().toLowerCase().replaceAll(__infor_base.regex_ignore, '');
for(const word of words){
if(text.includes(word)){ continue; }
option.attr('data-hide', 'true');
}
})
_inforSelectMultiple.search_index = null;
options().removeAttr('data-focused');
});
$(document).on('click', 'infor-select-multiple [data-clear]', function(){
const container = findContainerByTag('infor-select-multiple', this);
const instance = _inforSelectMultiple.instanceByContainer(container);
const { setValues, clear_button, livewireEmit, isActive } = instance;
if(!isActive()){ return; }
clear_button().removeAttr('data-active');
setValues([], true);
livewireEmit([]);
});
// Edit
const _inforSelectEdit = {
instances: {},
container: null,
search_index: null,
get: (id) => {
return _inforSelectEdit.instances[id];
},
instanceByContainer: container => {
const id = container.attr('id');
return _inforSelectEdit.instances[id];
}
}
function initInforSelectEdit(){
validateInforBase();
$('infor-select-edit').each((index, element) =>{
const container = $(element);
const initiated = container.attr('data-initiated');
if(initiated){return true}
const options = container.find('infor-select-option').detach();
container.append(`
`);
const options_container = container.find('[data-infor-select-options-container]');
const input_display = container.find('[data-infor-select-input-display]');
const id = container.attr('id') || randomString(10);
const name = container.attr('name');
const livewire = container.attr('data-livewire');
const livewire_params = container.attr('data-livewire-params');
container.removeAttr('livewire');
container.removeAttr('livewire-params');
container.removeAttr('name');
const attributes = container.get(0).attributes;
$.each(attributes, function () {
input_display.attr(this.name, this.value);
});
while (attributes.length) {
container.removeAttr(attributes[0].name);
}
let selected_value = null;
options.each((index, option) => {
option = $(option);
const value = option.attr('data-value');
const name = option.attr('data-name') || option.text();
const html = option.html();
if(option.attr('data-selected') !== undefined){ selected_value = value; }
options_container.append(`${html}
`)
})
container.attr('data-initiated', 'true');
container.attr('id', id);
_inforSelectEdit.instances[id] = {
container: container,
id: id,
name: name,
input: container.find('[data-infor-select-input-hidden]'),
livewire: livewire,
inputValueTimeout: null,
livewireEmit: value => {
if(!livewire){ return }
if(typeof Livewire !== 'object' && typeof Livewire.emit !== 'function'){ return }
Livewire.emit(livewire, value, parseInforLivewireParams(livewire_params));
},
onchange: value => {},
getValue: () => {
const value = container.find('[data-infor-select-input-hidden]').val();
const name = container.find(`[data-infor-select-option][data-value="${value}"]`).attr('data-name');
return {
name: name || '',
value: value || '',
}
},
setValue: value => {
const instance = _inforSelectEdit.get(id);
instance.input_display().val(value);
instance.onchange(value);
instance.livewireEmit(value);
},
setTimeoutValue: value => {
const instance = _inforSelectEdit.get(id);
if(instance.inputValueTimeout){
clearTimeout(instance.inputValueTimeout);
instance.inputValueTimeout = null;
}
instance.inputValueTimeout = setTimeout(instance.setValue, 250, value);
},
prefillValue: value => {
const option = container.find(`[data-infor-select-option][data-value="${value}"]`);
if(!option.length){ return }
const name = option.attr('data-name');
container.find('[data-infor-select-input-hidden]').val(value);
container.find('[data-infor-select-input-display]').val(name);
},
clear_button: () => { return container.find('[data-clear]'); },
input_display: () => { return container.find('[data-infor-select-input-display]') },
options_container: () => { return container.find('[data-infor-select-options-container]') },
options: () => { return container.find('[data-infor-select-option]') },
visible_options: () => { return container.find('[data-infor-select-option]').not('[data-hide]') },
focused_option: () => { return container.find('[data-infor-select-option][data-focused]') },
disable: () => {
container.attr('data-disabled', true);
container.find('[data-infor-select-input-display]').prop('readonly', true);
},
enable: () => {
container.removeAttr('data-disabled');
container.find('[data-infor-select-input-display]').prop('readonly', false);
},
isActive: () => {
const disabled = container.attr('data-disabled') === 'true';
return !disabled;
}
}
if(selected_value){
_inforSelectEdit.instances[id].prefillValue(selected_value);
}
});
}
$(document).keydown(function(event){
const { container, search_index } = _inforSelectEdit;
if(!container){return;}
const instance = _inforSelectEdit.instanceByContainer(container);
const { visible_options, options_container, focused_option} = instance;
const { key } = event;
if(key != "ArrowUp" && key != "ArrowDown" && key != "Enter"){return;}
visible_options().removeAttr('data-focused');
if(event.key == "Enter"){
event.preventDefault();
event.stopPropagation();
visible_options().eq(_inforSelectEdit.search_index).trigger('silent_click');
return false;
}
if(event.key == 'ArrowDown'){
if(search_index === null || search_index === (visible_options().length - 1)){ _inforSelectEdit.search_index = 0; }
else{ _inforSelectEdit.search_index += 1; }
}
else if(event.key == 'ArrowUp'){
if(search_index === null || search_index === 0){ _inforSelectEdit.search_index = (visible_options().length - 1); }
else{ _inforSelectEdit.search_index += -1; }
}
visible_options().eq(_inforSelectEdit.search_index).attr('data-focused', true);
const container_height = options_container().height();
const scroll_offset = options_container().scrollTop();
const top_offset = focused_option().position().top;
const focused_option_height = (focused_option().outerHeight() / 2);
if(top_offset > container_height){
options_container().scrollTop(top_offset - container_height + scroll_offset + focused_option_height + 10);
}
else if(top_offset < 0){
options_container().scrollTop(scroll_offset - Math.abs(top_offset) - 10);
}
});
$(document).on('click', 'infor-select-edit [data-infor-select-input-display]', function () {
hideInforSelectables();
const container = findContainerByTag('infor-select-edit', this);
const instance = _inforSelectEdit.instanceByContainer(container);
const { options_container, options, isActive } = instance;
if(!isActive()){ return; }
options_container().css({display: 'block', width: container.outerWidth()});
options().removeAttr('data-hide data-focused');
_inforSelectEdit.search_index = null;
_inforSelectEdit.container = container;
});
$(document).on('click silent_click', 'infor-select-edit [data-infor-select-option]', function () {
const option = $(this);
const container = findContainerByTag('infor-select-edit', this);
const instance = _inforSelectEdit.instanceByContainer(container);
const { input_display, clear_button, onchange, livewireEmit } = instance;
const value = option.attr('data-value');
input_display().val(value)
onchange(value);
livewireEmit(value);
clear_button().removeAttr('data-active');
if(value){
clear_button().attr('data-active', true);
}
hideInforSelectables();
});
$(document).on('input', 'infor-select-edit [data-infor-select-input-display]', function (event) {
const value = this.value;
const words = value.toLowerCase().replaceAll(__infor_base.regex_ignore, '').split(' ');
const container = findContainerByTag('infor-select-edit', this);
const instance = _inforSelectEdit.instanceByContainer(container);
const { options, visible_options, options_container, setTimeoutValue, clear_button } = instance;
const { key } = event;
if(key == 'ArrowUp' || key == 'ArrowDown'){ return; }
//search
options().removeAttr('data-hide');
if(!words.length){ return; }
options().each((index, element) => {
const option = $(element);
const text = option.text().toLowerCase().replaceAll(__infor_base.regex_ignore, '');
for(const word of words){
if(text.includes(word)){ continue; }
option.attr('data-hide', 'true');
}
})
//options
_inforSelectEdit.search_index = null;
options().removeAttr('data-focused');
options_container().css({
display: visible_options().length ? 'block' : '',
});
//Trigger value
setTimeoutValue(value);
//Clear button
clear_button().removeAttr('data-acitve');
if(value){
clear_button().attr('data-active', true);
}
});
$(document).on('click', 'infor-select-edit [data-clear]', function(){
const container = findContainerByTag('infor-select-edit', this);
const instance = _inforSelectEdit.instanceByContainer(container);
const { input_display, clear_button, onchange, livewireEmit, isActive } = instance;
if(!isActive()){ return; }
clear_button().removeAttr('data-active');
input_display().val('');
onchange(null);
livewireEmit(null);
});
//Global
$(document).click(function(event) {
if (!$(event.target).is('[data-infor-select-input-display], [data-infor-select-options-container] *')) {
hideInforSelectables();
}
});
function hideInforSelectables(){
_inforSelectSearch.container = null;
_inforSelectMultiple.container = null;
$('[data-infor-select-options-container]').css({display: ''});
}
function validateInforBase(){
if(typeof __infor_base === 'undefined'){
throw new Error('Please include infor-base.js!');
}
}
pageInteractive(() => {
initInforSelectSearch();
initInforSelectMultiple();
initInforSelectEdit();
})