const _inforSearch = { url: window.location.origin, instances: {}, request: null, timout: null, container: null, search_index: null, response: [], get: (id) => { return _inforSearch.instances[id]; }, instanceByContainer: container => { const id = container.attr('id'); return _inforSearch.get(id); } } function initInforSearch() { if (typeof __infor_base === 'undefined') { console.log('infor-base.js is not included!'); return; } $('infor-search').each(function () { const container = $(this); const initiated = container.attr('data-initiated'); if(initiated !== undefined){ return true; } const display_prefill = container.attr('data-display-prefill'); const value_prefill = container.attr('data-value-prefill'); container.removeAttr('data-display-prefill'); container.removeAttr('data-value-prefill'); container.append(`
`); const input_display = container.find('[data-infor-search-input-display]'); const input_hidden = container.find('[data-infor-search-input-hidden]'); const params_location = container.attr('data-params') || null; const id = container.attr('id') || randomString(10); const api = container.attr('data-api'); 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('id'); let error_callback = container.attr('data-errors'); container.removeAttr('data-errors'); const name = container.attr('name'); input_hidden.attr('name', name); 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); } const all_results = input_display.attr('data-all-results'); container.attr('id', id); container.attr('data-initiated', true); _inforSearch.instances[id] = { container: container, name: name, id: id, api: api, input: container.find('[data-infor-search-input-hidden]'), params_location: params_location, error_callback: error_callback, livewire: livewire, livewireEmit: value => { if(!livewire){ return } if(typeof Livewire !== 'object' && typeof Livewire.emit !== 'function'){ return } Livewire.emit(livewire, value, parseInforLivewireParams(livewire_params)); }, getValue: () => { return { name: input_display.val(), value: input_hidden.val(), } }, setValue: options => { const clear_button = container.find('[data-clear]'); input_display.val(options.name || ''); input_hidden.val(options.value || '').trigger('change'); clear_button.removeAttr('data-active'); if(options.value){ clear_button.attr('data-active', true); } if (options.value === '*') { options.value = []; _inforSearch.response.map(record => { options.value.push(record.id); }) } _inforSearch.get(id).onchange(options.value); _inforSearch.get(id).livewireEmit(options.value); }, is_loading: () => { return container.find('[data-infor-search-results]').find('[data-infor-search-spinner]').length >= 1; }, input_hidden: () => { return container.find('[data-infor-search-input-hidden]') }, input_display: () => { return container.find('[data-infor-search-input-display]') }, clear_button: () => { return container.find('[data-clear]') }, results: () => { return container.find('[data-infor-search-results]') }, results_focused: () => { return container.find('[data-infor-search-result][data-focused]') }, results_options: () => { return container.find('[data-infor-search-result]') }, results_container: () => { return container.find('[data-infor-search-results-container]') }, all_results_option: all_results == 'true', onchange: value => {} } }); } function requestinforSearchResults(instance){ const { api, input_display, is_loading, results, results_container, results_options, params_location, container, error_callback } = instance; const search_string = input_display().val(); if (_inforSearch.request) { _inforSearch.request.abort(); _inforSearch.request = null; } if(_inforSearch.timeout){ clearTimeout(_inforSearch.timeout); _inforSearch.timeout = null; } if (!is_loading()) { results().html(`
`); } results_container().css({ display: 'block' }); _inforSearch.search_index = null; results_options().remove() const params = _window(params_location, {}); const data = { search: search_string } Object.assign(data, params); _inforSearch.timeout = setTimeout(() => { _inforSearch.request = _ajax(api, data); _inforSearch.request .then(response => { _inforSearch.container = container; _inforSearch.response = response; fillInforSearchResults(); }) .catch(err => { if(err?.status === 0){ return } results().html(`
Er is iets fout gegaan!
`); const err_fn = _window(error_callback, function (e){console.log(e); }, false); err_fn(err); }) }, 100); } function fillInforSearchResults() { const container = _inforSearch.container; const response = _inforSearch.response; const instance = _inforSearch.instanceByContainer(container); const { results, results_container, input_display } = instance; let content = input_display().attr('data-content'); let sub_content = input_display().attr('data-sub-content'); results().empty(); results_container().find(`[data-infor-search-result="*"]`).remove(); if (!response.length) { results().html(`
Geen resultaten gevonden
`); return; } for (const row of response) { const reformatContent = (row, content) => { if(typeof window[content] == 'function'){ return window[content](row); } const options = (content || '').split('||'); for(let option of options){ content = option.replaceAll(',', ''); const option_keys = option.replaceAll(' ', '').split(','); for(const key of option_keys){ content = content.replace(key, (row[key] || '')); } if(content){ break; } } return content; } let row_content = reformatContent(row, content); let row_sub_content = reformatContent(row, sub_content); results().append(`
${row_content}
${row_sub_content}
`); } if (instance.all_results_option) { results_container().append(`
Alle resultaten ( ${response.length} )
`); } } $(document).keydown(function(event){ const { container, search_index } = _inforSearch; if(!container){return;} const instance = _inforSearch.instanceByContainer(container); const { results_options, results_focused, results } = instance; const { key } = event; if(key != "ArrowUp" && key != "ArrowDown" && key != "Enter"){return;} if(event.key == "Enter"){ event.preventDefault(); event.stopPropagation(); results_options().eq(_inforSearch.search_index).click(); return false; } results_options().removeAttr('data-focused'); if(event.key == 'ArrowDown'){ if(search_index === null || search_index === (results_options().length - 1)){ _inforSearch.search_index = 0; } else{ _inforSearch.search_index += 1; } } else if(event.key == 'ArrowUp'){ if(search_index === null || search_index === 0){ _inforSearch.search_index = (results_options().length - 1); } else{ _inforSearch.search_index += -1; } } results_options().eq(_inforSearch.search_index).attr('data-focused', true); const container_height = results().height(); const scroll_offset = results().scrollTop(); const top_offset = results_focused().position().top; const focused_option_height = (results_focused().outerHeight() / 2); if(top_offset > container_height){ results().scrollTop(top_offset - container_height + scroll_offset + focused_option_height + 20); } else if(top_offset < 0){ results().scrollTop(scroll_offset - Math.abs(top_offset) - 10); } }); $(document).on('input', 'infor-search [data-infor-search-input-display]', function () { const container = findContainerByTag('infor-search', this); const instance = _inforSearch.instanceByContainer(container); const { input_display, input_hidden, clear_button, results, results_container, results_options, params_location, getValue, onchange, livewireEmit } = instance; const search_string = input_display().val(); const value_before_input = getValue().value; clear_button().removeAttr('data-active'); input_hidden().val(''); if (!search_string) { results_container().css({ display: '' }); input_hidden().val('').trigger('change'); instance.onchange(null); return; } if(value_before_input){ onchange(null); livewireEmit(null); } requestinforSearchResults(instance); }) $(document).on('click', 'infor-search [data-infor-search-result]', function () { const container = findContainerByTag('infor-search', this); const instance = _inforSearch.instanceByContainer(container); const { setValue } = instance; const result = $(this); const content = result.find('[data-infor-search-result-content]').text(); let value = result.attr('data-infor-search-result'); setValue({ name: content, value: value, }); }) $(document).on('click', 'infor-search [data-infor-search-input-display]', function () { hideInforSearchables(); if (!this.value) { return; } const container = findContainerByTag('infor-search', this); const instance = _inforSearch.instanceByContainer(container); requestinforSearchResults(instance); }) $(document).on('click', 'infor-search [data-clear]', function(){ const container = findContainerByTag('infor-search', this); const instance = _inforSearch.instanceByContainer(container); const { setValue } = instance; setValue({ name: null, value: null }); }); $(document).click(function(event) { if (!$(event.target).is('[data-infor-search-input-display]')) { hideInforSearchables() } }); function hideInforSearchables(){ if (_inforSearch.request) { _inforSearch.request.abort(); _inforSearch.request = null; } _inforSearch.container = null; _inforSearch.search_index = null; $('infor-search').find('[data-infor-search-results-container]').css({ display: '' }) $('infor-search').find('[data-infor-search-results]').empty() $('infor-search').find('[data-infor-search-result="*"]').remove(); $.each(_inforSearch.instances, (id, instance) => { if(!instance.input_hidden().val()){ instance.input_display().val(''); } }) } initInforSearch();