// 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('data-livewire'); container.removeAttr('data-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('data-livewire'); container.removeAttr('data-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'); const value = container.attr('data-value'); container.removeAttr('data-livewire'); container.removeAttr('data-livewire-params'); container.removeAttr('data-value'); 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') || option.text(); const html = option.html(); 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, livewireEmit: value => { if(!livewire){ return } if(typeof Livewire !== 'object' && typeof Livewire.emit !== 'function'){ return } Livewire.emit(livewire, value, parseInforLivewireParams(livewire_params)); }, onchange: value => {}, getValue: () => { return container.find('[data-infor-select-input-display]').val(); }, setValue: value => { const instance = _inforSelectEdit.get(id); instance.input_display().val(value); instance.onchange(value); instance.livewireEmit(value); instance.setClearButton(); hideInforSelectables(); }, setClearButton: () => { const instance = _inforSelectEdit.get(id); instance.clear_button().removeAttr('data-active'); if(instance.getValue()){ instance.clear_button().attr('data-active', true); } }, 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(value){ _inforSelectEdit.instances[id].setValue(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 } = instance; const value = option.attr('data-value'); input_display().val(value).trigger('change'); }); $(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 } = 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' : '', }); }); $(document).on('change', 'infor-select-edit [data-infor-select-input-display]', function (event) { const value = this.value; const container = findContainerByTag('infor-select-edit', this); const instance = _inforSelectEdit.instanceByContainer(container); const { setValue } = instance; setValue(value, false) }); $(document).on('click', 'infor-select-edit [data-clear]', function(){ const container = findContainerByTag('infor-select-edit', this); const instance = _inforSelectEdit.instanceByContainer(container); const { isActive, input_display } = instance; if(!isActive()){ return; } input_display().val('').trigger('change'); }); //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(); })