I've got a jqgrid (version 3.5.3) on my site which gets its results from an ajax call to a web service. Often the query is complicated and it takes a few seconds to load the result. While it is loading the user sees a box [Loading...].
In case the users realise they're s开发者_Go百科earching for the wrong thing, the client has asked to add a cancel button to the grid, which would:
- make the grid forget about the data it's just requested
- retain the results already loaded from the previous search
There doesn't seem to be anything built in for this, so I'm probably looking for a bit of a hack to achieve this.
Any ideas?
In general $.ajax
request returns XMLHttpRequest
object having abort
method. So if the corresponding call of the $.ajax
would be have the form
var lastXhr = $.ajax ({
// parameters
success:function(data,st) {
// do something
lastXhr = null;
},
error:function(xhr,st,err){
// do something
lastXhr = null;
}
});
and we would have access to the lastXhr
valuable then we could be able to call lastXhr.abort()
. I think that a new method like abortAjaxRequest
in jqGrid can be the best solution.
Without changing of the current source code of jqGrid the solution could looks like following
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();
}
});
In the code I suppose, that we have a "Cancel" button with the id="cancel" outside of jqGrid. I should mention, that I don't yet tested the code above, but I hope it should work.
You should understand, of cause, that the code above aborts only the waiting of the browser on the client side and the process on the server will be continued. If your server will be implement the server side aborting, then the code above will be not needed and you will be able to call this server aborting method directly.
Here's our solution, which is very similar to Oleg's, the main difference is that we keep track of a list of XHRs to make sure we clean all requests up
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 = [];
}
...
精彩评论