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') %}