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)

Reply via email to