Andrew created WICKET-6532:
------------------------------
Summary: It should be possible to cancel AjaxRequest like in
jQuery beforeSend
Key: WICKET-6532
URL: https://issues.apache.org/jira/browse/WICKET-6532
Project: Wicket
Issue Type: Improvement
Components: wicket
Affects Versions: 8.0.0-M8
Reporter: Andrew
Was already discussed in
[https://github.com/apache/wicket/pull/256#issuecomment-359985835]
A little demo [https://github.com/andruhon/WicketDragAndDropFileAjaxUpload]
(open the EventDemo page, enable slow connection emulation in your browser,
start uploading a few files, cancel an upload which didn't start yet)
Relevant changes with cancel demo:
[https://github.com/andruhon/WicketDragAndDropFileAjaxUpload/commit/7eae49467655d8a0a4573e16f5e074688c8f12f6]
I didn't find a way to cancel a request before it was actually sent,
Imagine I do drag and drop of multiple files and jquery uploads them one by
one. Normally with jQuery it is possible to return false from `beforeSend`
handle to cancel the request, however it's not a case with wicket's `bsh`. I
could do something like this:
{code:javascript}
Wicket.Ajax.ajax({
u: myUrl,
m: 'POST',
mp: true,
bsh: [
function (attributes, jqXHR, settings) {
settings.xhr = function () {
try {
if (uploadContext.cancelled) {
// cancel upload
return null;
}
if (uploadContext.item) {
/* Add progress indicator */
xhr.upload.addEventListener("progress",
function (e) {
var progress = Math.round(e.loaded /
e.total * 100);
onUploadProgress(uploadContext, attrs,
progress);
});
}
return xhr;
} catch (e) {
}
}
}
],
{code}
It does the trick, however it will cause the jQuery.send to explode with
`Cannot read property 'open' of null`
I'm not sure what the best way to do that, but probably `_executeHandlers`
could return false if any of handlers returns false, something like this:
{code:javascript}
/**
* A helper function that executes an array of handlers
(before, success, failure)
*
* @param handlers {Array[Function]} - the handlers to execute
* @private
*/
_executeHandlers: function (handlers) {
if (jQuery.isArray(handlers)) {
// cut the handlers argument
var args =
Array.prototype.slice.call(arguments).slice(1);
// assumes that the Ajax attributes is always
the first argument
var attrs = args[0];
var that = this._getTarget(attrs);
for (var i = 0; i < handlers.length; i++) {
var handler = handlers[i];
var r;
if (jQuery.isFunction(handler)) {
r = handler.apply(that, args);
} else {
r = new
Function(handler).apply(that, args);
}
if (r === false) {
return false;
}
}
}
},
//...
{code}
and
{code:javascript}
// execute the request
var jqXHR = jQuery.ajax({
url: url,
type: attrs.m,
context: self,
processData: wwwFormUrlEncoded,
contentType: wwwFormUrlEncoded,
beforeSend: function (jqXHR, settings) {
if(self._executeHandlers(attrs.bsh,
attrs, jqXHR, settings)===false) {
return false;
}
we.publish(topic.AJAX_CALL_BEFORE_SEND,
attrs, jqXHR, settings);
if (attrs.i) {
// show the indicator
Wicket.DOM.showIncrementally(attrs.i);
}
},
// ...
{code}
Preconditions checked before the jQuery.ajax is called, but what I say happens
after, but before jQuery did actually start this request.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)