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; }
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');
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,
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);
},
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) => {
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 } = 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);
}
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();