EinsatzOnline/resources/js/search2.js

217 lines
10 KiB
JavaScript

Handlebars.registerHelper('search2', function (arguments) {
var args = new Map();
//Map arguments to args Map.
Object.keys(arguments.hash).forEach(key => {
var escapedKey = Handlebars.escapeExpression(key);
var escapedValue = Handlebars.escapeExpression(arguments.hash[key]);
// Remove pairs with empty values
if (escapedValue) {
args.set(escapedKey, escapedValue);
}
});
//Check if type argument is set
if (!args.get("type")) {
console.error("Missing type for search2 Helper!");
return new Handlebars.SafeString("<span style=\"color: red\">Konnte Suchfunktion nicht laden!</span>");
}
var search_html = '<div class="search2">\n' +
' <div class="input-group search2-search-input-group" ' + (args.get("value") && args.get("value_id") ? 'style="display: none;"' : '') + '>\n' +
' <input autocomplete="off" class="form-control search2-searchbar" data-search-type="' + args.get("type") + '" type="text">\n' +
' <span class="input-group-append">\n' +
' <span class="btn btn-outline-secondary" type="button">\n' +
' <svg width="16" height="16" fill="currentColor">\n' +
' <use xlink:href="/img/bootstrap-icons.svg#search"></use>\n' +
' </svg>\n' +
' </span>\n' +
' </span>\n' +
' </div>\n' +
' <div class="search2-result-overlay" style="display: none;">\n' +
' <ul class="search2-result-overlay-list"></ul>\n' +
' </div>\n' +
' <div class="input-group search2-selected-input-group" ' + (!args.get("value") || !args.get("value_id") ? 'style="display: none;"' : '') + '>\n' +
' <input disabled class="form-control qsf search2-selected ' + (args.get("classname") ? args.get("classname") : '') + '" type="text" ' + (args.get("value") && args.get("value_id") ? 'data-value-id="' + args.get("value_id") + '" value="' + args.get("value") + '"' : '') + '>\n' +
' <span class="input-group-append">\n' +
' <span class="btn btn-outline-secondary search2-remove-value-btn" type="button">\n' +
' <svg width="16" height="16" fill="currentColor">\n' +
' <use xlink:href="/img/bootstrap-icons.svg#pencil-square"></use>\n' +
' </svg>\n' +
' </span>\n' +
' </span>\n' +
' </div>\n' +
'</div>';
return new Handlebars.SafeString(search_html);
});
Search2 = (function () {
let setup = function () {
$(".search2-remove-value-btn").off("click").on("click", remove_value);
//Hide search result overlay when user clicks
$('body').off("click").on("click", function (evt) {
if ($(evt.target).hasClass("search2-searchbar") || $(evt.target).closest(".search2-result-overlay").length)
return;
hide_overlay();
});
//Setup event handlers for typing, clicking the searchbar, etc.
$(".search2-searchbar").off("click").on("click", searchbar_onclick).off("keyup paste cut").on("keyup paste cut", searchbar_typing).off("mouseenter focusin").on("mouseenter focusin", show_overlay);
};
let remove_value = function () {
let search = $(this).closest(".search2");
search.find(".search2-selected").val("").removeAttr("data-value-id"); //Remove stored value
search.find(".search2-selected-input-group").hide();
search.find(".search2-search-input-group").show();
//Fire change event manually to help detect changes
const event = new Event('change');
search.find(".search2-selected")[0].dispatchEvent(event);
};
let hide_overlay = function (target) {
if (!target) { //Hide all overlays
$(".search2-result-overlay").hide();
} else { //Hide only specific overlay
let searchbar = $(target);
searchbar.closest(".search2").find(".search2-result-overlay").hide();
}
};
let show_overlay = function () {
let searchbar = $(this);
searchbar.closest(".search2").find(".search2-result-overlay").show();
};
let searchbar_onclick = function () {
let searchbar = $(this);
searchbar.val("");
searchbar.closest(".search2").find(".search2-result-overlay").show();
};
let searchbar_typing = function () {
let searchbar = $(this);
let type = searchbar.data("search-type");
let search = $(this).closest(".search2");
let overlay_list = search.find(".search2-result-overlay-list");
if (!searchbar.val().trim() || searchbar.val().trim() === "")
return;
let res_map = new Map();
let options = {};
if (type === "member") {
options.url = "/api/members/";
options.get_data = {
"name": searchbar.val()
};
options.res_handler = function (data) {
$.each(data.members, function (index, value) {
res_map.set(value.entity_id, value);
overlay_list.append("<span tabindex=\"0\" class=\"search2-result-overlay-list-entry\" data-entity-id=\"" + value.entity_id + "\"><li class='list-group-item'><span class=\"badge badge-secondary\">Hinzufügen:</span> " + value.firstname + " " + value.lastname + "</li></span>");
});
};
options.overlay_click_handler = function () {
let res = res_map.get($(this).data("entity-id"));
setValue(this, res.entity_id, res.firstname + " " + res.lastname);
};
} else if (type === "position") {
options.url = "/api/events/units/positions/";
options.get_data = {
"q": searchbar.val()
};
options.res_handler = function (data) {
$.each(data.positions, function (index, value) {
res_map.set(value.entity_id, value);
overlay_list.append("<span tabindex=\"0\" class=\"search2-result-overlay-list-entry\" data-entity-id=\"" + value.entity_id + "\"><li class='list-group-item' title='" + value.description + "'><span class=\"badge badge-secondary\">Hinzufügen:</span> " + value.name + "</li></span>");
});
};
options.overlay_click_handler = function () {
let res = res_map.get($(this).data("entity-id"));
setValue(this, res.entity_id, res.name);
};
}else if (type === "template") {
options.url = "/api/events/units/templates/";
options.get_data = {
"q": searchbar.val()
};
options.res_handler = function (data) {
$.each(data.templates, function (index, value) {
res_map.set(value.entity_id, value);
overlay_list.append("<span tabindex=\"0\" class=\"search2-result-overlay-list-entry\" data-entity-id=\"" + value.entity_id + "\"><li class='list-group-item' title='" + value.description + "'><span class=\"badge badge-secondary\">Hinzufügen:</span> " + value.name + "</li></span>");
});
};
options.overlay_click_handler = function () {
let res = res_map.get($(this).data("entity-id"));
setValue(this, res.entity_id, res.name);
};
} else if (type === "vehicle") {
options.url = "/api/resources/vehicles/";
options.get_data = {
"q": searchbar.val()
};
options.res_handler = function (data) {
$.each(data.vehicle_list, function (index, value) {
res_map.set(value.entity_id, value);
overlay_list.append("<span tabindex=\"0\" class=\"search2-result-overlay-list-entry\" data-entity-id=\"" + value.entity_id + "\"><li class='list-group-item' title='" + value.description + "'><span class=\"badge badge-secondary\">Hinzufügen:</span> " + value.identifier + "("+value.numberplate+")</li></span>");
});
};
options.overlay_click_handler = function () {
let res = res_map.get($(this).data("entity-id"));
setValue(this, res.entity_id, res.identifier+" ("+res.numberplate+")");
};
}else {
console.error("Unknown search type: " + type);
return;
}
$.ajax({
url: options.url,
type: 'GET',
data: options.get_data,
contentType: 'application/json',
success: function (data) {
if (is_ok(data)) {
overlay_list.empty(); //Remove old overlay list entries
show_overlay();
options.res_handler(data);
//select search result on click
overlay_list.find(".search2-result-overlay-list-entry").off("click").on("click", options.overlay_click_handler);
//select search result on enter key press
overlay_list.find(".search2-result-overlay-list-entry").off("keyup").on("keyup", function (e) {
if (e.keyCode === 13) {
options.overlay_click_handler(this);
}
});
}
},
timeout: 3000,
error: function () {
alert("Verbindung zum Server unterbrochen!");
}
});
};
let setValue = function (context, value_id, value) {
let search = $(context).closest(".search2");
search.find(".search2-selected").val(value).data("value-id", value_id);
search.find(".search2-selected-input-group").show();
search.find(".search2-search-input-group").hide();
hide_overlay(context);
search.find(".search2-result-overlay-list").empty();
search.find(".search2-searchbar").val("");
//Fire change event manually on input to detect changes more easily
const event = new Event('change');
search.find(".search2-selected")[0].dispatchEvent(event);
}
return {
setup
}
}());