2010-10-25 5 views
3

J'ai un jqgrid (version 3.5.3) sur mon site qui obtient ses résultats d'un appel ajax à un service web. Souvent, la requête est compliquée et il faut quelques secondes pour charger le résultat. Pendant le chargement, l'utilisateur voit une boîte [Chargement en cours ...].Comment ajouter un bouton d'annulation à mon jqgrid?

Dans le cas où les utilisateurs se rendent compte qu'ils recherchent la mauvaise chose, le client a demandé d'ajouter un bouton d'annulation de la grille, qui:

  1. faire la grille oublier les données qu'il est juste demandé
  2. conservent les résultats déjà chargés de la recherche précédente

Il ne semble pas être quelque chose construit pour cela, donc je suis probablement à la recherche d'un peu un hack pour y parvenir.

Des idées?

+0

Il est va être plus que "un peu un hack". Votre plus gros problème va être d'annuler la demande au serveur. S'il existe un moyen de déterminer si la demande va prendre beaucoup de temps, vous pourrez peut-être empêcher la longue requête de commencer. De toute façon, c'est beaucoup de travail, même si l'annulation d'une demande était possible. – Gregg

Répondre

0

Voici notre solution, ce qui est très similaire à Oleg de, la principale différence est que nous enregistrons une liste de requêtes XHR pour vous assurer que nous nettoyons toutes les demandes jusqu'à

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("<button id='cancelrequest'>Cancel</button>").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 = []; 
       } 

...

2

En général $.ajax demande renvoie XMLHttpRequest objet ayant la méthode abort. Donc, si l'appel correspondant de la $.ajax serait avoir 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 accès à la valeur lastXhr alors nous pourrions être en mesure d'appeler lastXhr.abort(). Je pense qu'une nouvelle méthode comme abortAjaxRequest dans jqGrid peut être la meilleure solution.

Sans changement du code source de courant de jqGrid la solution pourrait ressemble à la suite

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 = « annuler » à l'extérieur de jqGrid . Je devrais mentionner, que je n'ai pas encore examiné le code ci-dessus, mais j'espère que cela devrait fonctionner.

Vous devez comprendre, car le code ci-dessus interrompt uniquement l'attente du navigateur côté client et le processus sur le serveur se poursuit. Si votre serveur mettra en œuvre l'annulation du côté serveur, le code ci-dessus ne sera plus nécessaire et vous pourrez appeler cette méthode d'abandon de serveur directement.

+0

Merci pour la réponse complète! Nous avons fini par implémenter quelque chose de similaire, je le posterai probablement quand nous l'aurons mis en ordre –

+0

En version 4.5.4, endReq() s'appelle like: myGrid [0] .grid.endReq(); –

+0

@AlexeyF: La réponse a été écrite il y a presque 4 ans. Il y a beaucoup de changements dans jqGrid depuis le temps. 'endReq' est déplacé dans' myGrid [0] .grid.endReq() '(voir [les lignes] (https://github.com/tonytomov/jqGrid/blob/v4.6.0/js/grid.base.js # L2927-L2928) de code jqGrid) – Oleg

Questions connexes