217 lines
10 KiB
JavaScript
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
|
|
}
|
|
}());
|