I have not found the truth as to how to display the indicator message of the AJAX request in such a way that if there is an error in it, the indicator remains visible for a reasonable time that allows the user to read it. In case the request was successful, the message would disappear much faster. But I still don't know how to play with events fail
and always
AJAX. The following code is a function that is called once a node is selected, as a result it should show the central view of the app associated with the selected node. The item withid=”indicador”
serves to show the status of the request, initially it has an associated class that keeps it hidden and its html content is a glyphicon and the text Loading... The idea is that if the view is returned correctly, the indicator message disappears quickly, but if it happens an error, that is, the request falls in fail
, the indicator message, in addition to changing the class, and its text becomes the result of jqXHR.responseText, should be kept for a reasonable period of time that allows the user to read it. And finally I've tried to always
restore the indicator content so that it is available for any other AJAX calls. Wrongly because I have been using the parameter always
to compare it with 'success' but this is not true, if an error occurs,always
has a parameter jqXHR
, but if the request is successful, it simply always
receives the content returned by the server.
***** Agregando solución **************
function cargarVistaCentral(nodo) {
$.ajax({
dataType: 'html',
type: 'GET',
url: Routing.generate('app_renderVistaCentral', {'id_estructura': nodo.id}),
beforeSend: function() {
$('#indicador').addClass('cargando-satisfactorio').slideDown('fast');
}
}).done(function(data) {
$('#vistas').html(data);
}).fail(function(jqXHR) {
if (jqXHR.status === 401) {
window.location = _HOMEPAGE;
} else {
$('#indicador').removeClass('cargando-satisfactorio').addClass('cargando-error').html(jqXHR.responseText);
}
}).always(function() {
if (!$('#indicador').hasClass("cargando-satisfactorio")) {
$('#indicador').fadeOut(5500, function() {
$(this).removeClass('cargando-error').html("<span class='glyphicon glyphicon-time'></span> Cargando...");
});
} else {
$('#indicador').fadeOut('fast', function() {
$(this).removeClass('cargando-satisfactorio').html("<span class='glyphicon glyphicon-time'></span> Cargando...");
});
}
});
}
Anh, the classes loading-successful and loading-error basically what they do is apply a green or red background color to the indicator respectively, that's why I try to play with the addClass and removeClass to add and remove one or the other depending on the result of the request. And always trying to remove them at the end so that the indicator, once another request is started, does not have them applied.
Exactly, by checking if the class exists cargando-satisfactorio
in the always
AJAX you can apply more or less time to the fadeOut of the indicator.
used
.hasClass()
to know if it has the class "loading-successful"Do you really need a
if
at aalways
to define if there is an error? ifdone
it is executed when there is no error andfail
it is executed when an error occurredReading a little the JQuery documentation, because there is something that I missed, the method
always
receives 3 arguments:If the answer is satisfactory, it
.always()
will take the same arguments as.done()
, and if it fails, it will.always()
take the same arguments as.fail()
means I can have:
This way there is no need to check for the existence of the loading-successful class for the indicator element. Although it is valid for this very specific implementation, I think it is more "pretty" to check the argument
textStatus
of.always()