diff --git a/Core/Assets/JS/ListFilterAutocomplete.js b/Core/Assets/JS/ListFilterAutocomplete.js
index 1d0cc2dd7e..137022e6fa 100644
--- a/Core/Assets/JS/ListFilterAutocomplete.js
+++ b/Core/Assets/JS/ListFilterAutocomplete.js
@@ -16,6 +16,10 @@
* along with this program. If not, see .
*/
+function listFilterAutocompleteMsg(key) {
+ return (typeof i18n !== 'undefined' && i18n[key]) ? i18n[key] : key;
+}
+
function listFilterAutocompleteGetData(formId, formData, term) {
var rawForm = $("form[id=" + formId + "]").serializeArray();
$.each(rawForm, function (i, input) {
@@ -44,18 +48,42 @@ $(document).ready(function () {
data: listFilterAutocompleteGetData(formId, data, request.term),
dataType: "json",
success: function (results) {
- var values = [];
- results.forEach(function (element) {
- if (element.key === null || element.key === element.value) {
- values.push(element);
- } else {
- values.push({key: element.key, value: element.key + " | " + element.value});
+ try {
+ if (!Array.isArray(results)) {
+ throw new Error('response is not an array');
}
- });
- response(values);
+ var values = [];
+ results.forEach(function (element) {
+ if (!element || element.key === undefined || element.value === undefined || element.value === null) {
+ console.warn('filter-autocomplete: invalid element ignored', element);
+ return;
+ }
+ if (element.key === null || element.key === element.value) {
+ values.push(element);
+ } else {
+ values.push({key: element.key, value: element.key + " | " + element.value});
+ }
+ });
+ response(values);
+ } catch (e) {
+ console.error('filter-autocomplete: invalid JSON response', e);
+ alert(listFilterAutocompleteMsg('autocomplete-error-invalid-response'));
+ response([]);
+ }
},
- error: function (msg) {
- alert(msg.status + " " + msg.responseText);
+ error: function (msg, textStatus, errorThrown) {
+ console.error('filter-autocomplete AJAX error | status:', msg.status, '| textStatus:', textStatus, '| errorThrown:', errorThrown);
+ console.error('filter-autocomplete responseText:', msg.responseText);
+ if (msg.status === 0) {
+ alert(listFilterAutocompleteMsg('autocomplete-error-network'));
+ } else if (msg.status === 400) {
+ alert(listFilterAutocompleteMsg('autocomplete-error-bad-request'));
+ } else if (msg.status >= 500) {
+ alert(listFilterAutocompleteMsg('autocomplete-error-server'));
+ } else {
+ alert(listFilterAutocompleteMsg('autocomplete-error-generic'));
+ }
+ response([]);
}
});
},
diff --git a/Core/Assets/JS/WidgetAutocomplete.js b/Core/Assets/JS/WidgetAutocomplete.js
index 7f1555dcfe..450f1eb220 100644
--- a/Core/Assets/JS/WidgetAutocomplete.js
+++ b/Core/Assets/JS/WidgetAutocomplete.js
@@ -16,6 +16,10 @@
* along with this program. If not, see .
*/
+function widgetAutocompleteMsg(key) {
+ return (typeof i18n !== 'undefined' && i18n[key]) ? i18n[key] : key;
+}
+
function widgetAutocompleteGetData(formId, formData, term) {
var rawForm = $("form[id=" + formId + "]").serializeArray();
$.each(rawForm, function (i, input) {
@@ -45,23 +49,42 @@ $(document).ready(function () {
data: widgetAutocompleteGetData(formId, data, request.term),
dataType: "json",
success: function (results) {
- var values = [];
- results.forEach(function (element) {
- if (element.key === null || element.key === element.value) {
- values.push(element);
- } else {
- values.push({key: element.key, value: element.key + " | " + element.value});
+ try {
+ if (!Array.isArray(results)) {
+ throw new Error('response is not an array');
}
- });
- response(values);
+ var values = [];
+ results.forEach(function (element) {
+ if (!element || element.key === undefined || element.value === undefined || element.value === null) {
+ console.warn('widget-autocomplete: invalid element ignored', element);
+ return;
+ }
+ if (element.key === null || element.key === element.value) {
+ values.push(element);
+ } else {
+ values.push({key: element.key, value: element.key + " | " + element.value});
+ }
+ });
+ response(values);
+ } catch (e) {
+ console.error('widget-autocomplete: invalid JSON response', e);
+ alert(widgetAutocompleteMsg('autocomplete-error-invalid-response'));
+ response([]);
+ }
},
error: function (msg, textStatus, errorThrown) {
- console.log('widget-autocomplete AJAX ERROR');
- console.log('status:', msg.status);
- console.log('textStatus:', textStatus);
- console.log('errorThrown:', errorThrown);
- console.log('responseText:', msg.responseText);
- alert(msg.status + " " + msg.responseText);
+ console.error('widget-autocomplete AJAX error | status:', msg.status, '| textStatus:', textStatus, '| errorThrown:', errorThrown);
+ console.error('widget-autocomplete responseText:', msg.responseText);
+ if (msg.status === 0) {
+ alert(widgetAutocompleteMsg('autocomplete-error-network'));
+ } else if (msg.status === 400) {
+ alert(widgetAutocompleteMsg('autocomplete-error-bad-request'));
+ } else if (msg.status >= 500) {
+ alert(widgetAutocompleteMsg('autocomplete-error-server'));
+ } else {
+ alert(widgetAutocompleteMsg('autocomplete-error-generic'));
+ }
+ response([]);
}
});
},
diff --git a/Core/Translation/en_EN.json b/Core/Translation/en_EN.json
index f8be43c908..f818dfe2bc 100644
--- a/Core/Translation/en_EN.json
+++ b/Core/Translation/en_EN.json
@@ -150,6 +150,11 @@
"authentication": "Authentication",
"auto": "Auto",
"auto-apply-to": "Automatically apply to",
+ "autocomplete-error-bad-request": "Bad request to the server. Please reload the page.",
+ "autocomplete-error-generic": "An error occurred while loading options. Please try again.",
+ "autocomplete-error-invalid-response": "The server response is not valid. Please reload the page.",
+ "autocomplete-error-network": "Could not connect to the server. Please check your internet connection.",
+ "autocomplete-error-server": "Internal server error. Please try again.",
"automatic": "Automatic",
"available": "Available",
"average": "Average",
diff --git a/Core/Translation/es_ES.json b/Core/Translation/es_ES.json
index a4a84da986..c7cff166eb 100644
--- a/Core/Translation/es_ES.json
+++ b/Core/Translation/es_ES.json
@@ -150,6 +150,11 @@
"authentication": "Autenticación",
"auto": "Auto",
"auto-apply-to": "Aplicar automáticamente a",
+ "autocomplete-error-bad-request": "Solicitud incorrecta al servidor. Por favor, recarga la página.",
+ "autocomplete-error-generic": "Ha ocurrido un error al cargar las opciones. Por favor, inténtalo de nuevo.",
+ "autocomplete-error-invalid-response": "La respuesta del servidor no es válida. Por favor, recarga la página.",
+ "autocomplete-error-network": "No se ha podido conectar con el servidor. Comprueba tu conexión a internet.",
+ "autocomplete-error-server": "Error interno del servidor. Por favor, inténtalo de nuevo.",
"automatic": "Automático",
"available": "Disponible",
"average": "Media",
diff --git a/Core/View/Master/MenuTemplate.html.twig b/Core/View/Master/MenuTemplate.html.twig
index 6c632fc285..c981e4c3fd 100644
--- a/Core/View/Master/MenuTemplate.html.twig
+++ b/Core/View/Master/MenuTemplate.html.twig
@@ -64,6 +64,16 @@
{% endblock %}
+ {# Global translations for JS #}
+
{# Adds custom JS assets #}
{% for js in assetManager.get('js') %}