shimatta-kenkyusho/shimatta_kenkyusho/static/js/autocomplete.js

127 lines
4.5 KiB
JavaScript

const autocomplete_query_delay_ms = 60;
class AutocompleteCustomUi {
static create_media_div(img_src, text_nodes) {
var ui = document.createElement('div');
ui.setAttribute('class', 'd-flex align-items-center');
var img_div = document.createElement('div');
img_div.setAttribute('class', 'flex-shrink-0');
var img = document.createElement('img');
if (img_src != null && img_src != undefined && img_src != '') {
img.setAttribute('src', img_src);
img.setAttribute('class', 'component-img-small');
} else {
img.setAttribute('src', fallback_img_path);
img.setAttribute('class', 'component-img-def-small');
}
img_div.appendChild(img);
ui.appendChild(img_div);
var text_div = document.createElement('div');
text_div.setAttribute('class', 'ms-3');
if (text_nodes != undefined) {
for (var i = 0; i < text_nodes.length; i++) {
text_div.appendChild(text_nodes[i]);
}
}
ui.appendChild(text_div)
return ui
}
constructor(text_id, dropdown_id, query_function)
{
this.text_id = text_id;
this.dropdown_id = dropdown_id;
this.query_callback = query_function.bind(this);
document.getElementById(text_id).addEventListener("keyup", this.ac_delay(function(event) {
if (event.key != 'Enter') {
this.query_callback(document.getElementById(this.text_id).value, this);
}
}, autocomplete_query_delay_ms).bind(this));
this.dropdown_data = {};
}
/**
*
* @param {*} nodes_to_add A list of dictionaries containing the shown objects and the data called when clicked.
*
* The list: {{'ui': <nodes>, 'data': 'my_data'}, {}, ...}
*
*/
show_results(nodes_to_add, data_clicked_callback) {
var ul = document.getElementById(this.dropdown_id);
ul.innerHTML = '';
this.select_data = {};
this.dropdown_data = {};
for (var i = 0; i < nodes_to_add.length; i++) {
var ui = nodes_to_add[i]['ui'];
var data = nodes_to_add[i]['data']
var dropdown_node = document.createElement('li');
dropdown_node.dataset.ac_clicked = i;
this.dropdown_data[i] = data;
dropdown_node.addEventListener('click',
(e) => {
data_clicked_callback(this.dropdown_data[e.currentTarget.dataset.ac_clicked]);
var text_box = document.getElementById(this.text_id);
var dropdown = bootstrap.Dropdown.getOrCreateInstance(text_box);
dropdown.hide();
});
dropdown_node.setAttribute('class', 'dropdown-item');
dropdown_node.appendChild(ui);
ul.appendChild(dropdown_node);
}
var dropdown = bootstrap.Dropdown.getOrCreateInstance(document.getElementById(this.text_id));
dropdown.show();
}
ac_delay(callback, ms) {
var timer = 0;
return function() {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
callback.apply(context, args);
}, ms || 0);
};
}
}
class AutocompleteText extends AutocompleteCustomUi {
show_results(results) {
var ul = document.getElementById(this.dropdown_id);
ul.innerHTML = '';
for (var i = 0; i < results.length; i++) {
var node = document.createElement('li');
node.setAttribute('class', 'dropdown-item');
node.appendChild(document.createTextNode(results[i]));
ul.appendChild(node);
node.addEventListener('click',
(e) => {
var element = e.target;
var text_box = document.getElementById(this.text_id);
text_box.value = element.innerHTML;
var dropdown = bootstrap.Dropdown.getOrCreateInstance(text_box);
dropdown.hide();
}
);
}
if (results.length == 0) {
var node = document.createElement('li');
node.setAttribute('class', 'dropdown-item text-danger');
node.appendChild(document.createTextNode('No results'));
ul.appendChild(node);
}
var dropdown = bootstrap.Dropdown.getOrCreateInstance(document.getElementById(this.text_id));
dropdown.show();
}
}