J’ai un jqgrid (version 3.5.3) sur mon site qui tire ses résultats d’un appel ajax à un service Web. Souvent, la requête est compliquée et le chargement du résultat prend quelques secondes. Pendant le chargement, l’utilisateur voit une boîte [Loading …].
Si les utilisateurs réalisent qu’ils cherchent la mauvaise chose, le client a demandé d’append un bouton d’annulation à la grid, ce qui:
Il ne semble pas y avoir quoi que ce soit construit pour cela, donc je cherche probablement un peu de bidouille pour y parvenir.
Des idées?
En général, la demande $.ajax
renvoie l’object XMLHttpRequest
ayant la méthode abort
. Donc, si l’appel correspondant du $.ajax
serait de la forme
var lastXhr = $.ajax ({ // parameters success:function(data,st) { // do something lastXhr = null; }, error:function(xhr,st,err){ // do something lastXhr = null; } });
et nous aurions access à lastXhr
ce qui nous permettrait d’appeler lastXhr.abort()
. Je pense qu’une nouvelle méthode telle que abortAjaxRequest
dans jqGrid peut être la meilleure solution.
Sans changer le code source actuel de jqGrid, la solution pourrait ressembler à:
var lastXhr; var stopAjaxRequest(myGrid) { $('#cancel').attr('disabled', true); // disable "Cancel" button lastXhr = null; myGrid[0].endReq(); }; var grid = $("#list"); grid.jqGrid ({ // all standard options loadComplete() { stopAjaxRequest(grid); }, loadError() { stopAjaxRequest(grid); }, loadBeforeSend (xhr) { l$('#cancel').attr('disabled', false); // enable "Cancel" button lastXhr = xhr; } }); $("#cancel").click(function() { if (lastXhr) { lastXhr.abort(); } });
Dans le code, je suppose que nous avons un bouton “Annuler” avec l’id = “cancel” en dehors de jqGrid. Je dois mentionner que je n’ai pas encore testé le code ci-dessus, mais j’espère que cela fonctionnera.
Vous devez comprendre que le code ci-dessus n’abandonne que l’attente du navigateur côté client et que le processus sur le serveur sera poursuivi. Si votre serveur implémente l’abandon côté serveur, le code ci-dessus ne sera pas nécessaire et vous pourrez appeler cette méthode d’abandon du serveur directement.
Voici notre solution, qui est très similaire à celle d’Oleg. La principale différence est que nous gardons une liste de XHR pour nous assurer de nettoyer toutes les demandes.
var handlerUrl = ''; jQuery(document).ready(function() { var xhrList = []; var beforeSendHandler = function() { var cancelPendingRequests = function() { jQuery.each(xhrList, function() { this.abort(); }); xhrList = []; return false; }; var hideLoadingUI = function() { $(this).hide(); $("#load_list").hide(); }; cancelPendingRequests(); $("#load_list").show(); // some faffing around to ensure we only show one cancel button at a time if (jQuery("#cancelrequest").length == 0) { jQuery(".ui-jqgrid-titlebar").append(jQuery("").click(cancelPendingRequests).click(hideLoadingUI)); } else { jQuery("#cancelrequest").show(); }; } jQuery("#list").jqGrid({ datatype: function(postdata) { GetSearchCriteria(); //needed for the grid's filtering var xhr = $.ajax({ //we override the beforeSend so we can get at the XHRs, but this means we have to implement the default behaviour, like showing the loading message ourselves beforeSend: beforeSendHandler, dataType: "xml", data: postdata, success: function(xmlDoc) { // jQuery("#cancelrequest").hide(); $("#load_list").hide(); jQuery("#list")[0].addXmlData(xmlDoc); xhrList = []; }
…