You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by "Andrew (JIRA)" <ji...@apache.org> on 2018/02/07 01:42:00 UTC

[jira] [Created] (WICKET-6532) It should be possible to cancel AjaxRequest like in jQuery beforeSend

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)