This is an automated email from the ASF dual-hosted git repository. reiern70 pushed a commit to branch improvement/reiern70/WICKET-6750-client-side-abortion-of-ajax-requests in repository https://gitbox.apache.org/repos/asf/wicket.git
commit 46bc76f86bd0c013e2d44f37e6d8d5d9b9610508 Author: reiern70 <[email protected]> AuthorDate: Sun Feb 23 09:08:57 2020 +0200 [WICKET-6750] allow to abort currently executing request for a given Ajax channel + example --- .../wicket/ajax/res/js/wicket-ajax-jquery.js | 61 ++++++++++++++++++++-- .../examples/ajax/builtin/FileUploadPage.html | 2 +- .../examples/ajax/builtin/FileUploadPage.java | 44 ++++++++++++++-- 3 files changed, 97 insertions(+), 10 deletions(-) diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js index 3ee9f3b..401ad41 100644 --- a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js +++ b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js @@ -278,6 +278,20 @@ } }, + // aborts current request is there is any running + abort: function () { + if (isUndef(this.jqXHR)) { + Wicket.Log.debug("There is no executing request for channel " + this.name) + } else { + // if request has not finished yet, then abort it + if (this.jqXHR.readyState !== 4) { + this.jqXHR.abort(); + } else { + Wicket.Log.debug("There is no executing request for channel " + this.name) + } + } + }, + done: function () { var callback = null; @@ -306,8 +320,8 @@ this.channels = {}; }, - // Schedules the callback to channel with given name. - schedule: function (channel, callback) { + // creates or retirves a channel + _createOrGetChanel: function (channel) { var parsed = new Wicket.Channel(channel); var c = this.channels[parsed.name]; if (isUndef(c)) { @@ -316,7 +330,22 @@ } else { c.type = parsed.type; } - return c.schedule(callback); + return c; + }, + + // Schedules the callback to channel with given name. + schedule: function (channel, callback) { + return this._createOrGetChanel(channel).schedule(callback); + }, + + // registers current jqXHR with channel using it + registerCurrentAjaxRequest: function(channel, jqXHR) { + this._createOrGetChanel(channel).jqXHR = jqXHR; + }, + + // aborts the current request for channel with name channel + abortCurrentRequestForChannel: function(channel) { + this._createOrGetChanel(channel).abort(); }, // Tells the ChannelManager that the current callback in channel with given name @@ -547,7 +576,6 @@ */ ajax: function (attrs) { this._initializeDefaults(attrs); - var res = Wicket.channelManager.schedule(attrs.ch, Wicket.bind(function () { this.doAjax(attrs); }, this)); @@ -555,6 +583,23 @@ }, /** + * Aborts current AJAX request, if any is running, for default channel. + * WARNING! Mind that this does not implies and server immediately will know about + * request being aborted and server side processing (and page lock night continue). + * This method might prove useful, for instance, in order to abort big AJAX + * uploads. + */ + abortRequest: function (channel) { + var attr = {}; + if (isUndef(channel) || typeof(channel) !== 'string') { + this._initializeDefaults(attr); + } else { + attr.ch = channel; + } + Wicket.channelManager.abortCurrentRequestForChannel(attr.ch); + }, + + /** * Is an element still present for Ajax requests. */ _isPresent: function(id) { @@ -696,6 +741,9 @@ contentType: wwwFormUrlEncoded, beforeSend: function (jqXHR, settings) { + if (attrs.async) { + Wicket.channelManager.registerCurrentAjaxRequest(attrs.ch, jqXHR); + } self._executeHandlers(attrs.bsh, attrs, jqXHR, settings); we.publish(topic.AJAX_CALL_BEFORE_SEND, attrs, jqXHR, settings); @@ -1645,6 +1693,11 @@ return Wicket.Ajax.ajax(attrs); }, + // aborts an AJAX request + abortRequest: function(channel) { + var call = new Wicket.Ajax.Call(); + call.abortRequest(channel); + }, ajax: function(attrs) { diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html index 3d54b24..d95be48 100644 --- a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html +++ b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html @@ -12,7 +12,7 @@ Demonstrates Wicket's ability to transparently handle multipart forms via AJAX.< Text field: <input wicket:id="text" type="text"/><br/> File field: <input wicket:id="file" type="file"/> (<span wicket:id="max"></span> max)<br/><br/> <div wicket:id="progress"></div> - <input type="submit" value="Regular Submit"/> <input wicket:id="ajaxSubmit" type="button" value="Ajax Submit"/> + <input type="submit" value="Regular Submit"/> <input wicket:id="ajaxSubmit" type="button" value="Ajax Submit"/> <a wicket:id="cancelUpload">Cancel AJAX upload</a> </form> <div wicket:id="drop" class="drop-zone"> diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java index 598efee..f7ace30 100644 --- a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java +++ b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java @@ -21,9 +21,13 @@ import java.util.List; import org.apache.commons.fileupload.FileUploadException; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.attributes.AjaxRequestAttributes; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.extensions.ajax.AjaxFileDropBehavior; import org.apache.wicket.extensions.ajax.markup.html.form.upload.UploadProgressBar; +import org.apache.wicket.markup.ComponentTag; +import org.apache.wicket.markup.head.IHeaderResponse; +import org.apache.wicket.markup.head.OnDomReadyHeaderItem; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Form; @@ -46,6 +50,7 @@ public class FileUploadPage extends BasePage private final FileUploadField file; private final TextField<String> text; + private WebMarkupContainer cancelUpload; /** * Constructor @@ -79,7 +84,8 @@ public class FileUploadPage extends BasePage } } }; - form.setMaxSize(Bytes.megabytes(1)); + ///form.setMaxSize(Bytes.megabytes(1)); + form.setMaxSize(Bytes.megabytes(500)); add(form); // create a textfield to demo non-file content @@ -105,6 +111,7 @@ public class FileUploadPage extends BasePage // ajax-update the feedback panel target.add(feedback); + target.appendJavaScript(hideCancelUploadButtonScript()); } @Override @@ -112,10 +119,30 @@ public class FileUploadPage extends BasePage { // update feedback to display errors target.add(feedback); + target.appendJavaScript(hideCancelUploadButtonScript()); } + @Override + public void renderHead(IHeaderResponse response) + { + String script = "$('#" + getMarkupId() +"').on('click', function() { "+ showCancelUploadButtonScript() +" });"; + response.render(OnDomReadyHeaderItem.forScript(script)); + response.render(OnDomReadyHeaderItem.forScript(hideCancelUploadButtonScript())); + } }); - + + cancelUpload = new WebMarkupContainer("cancelUpload") + { + @Override + public void renderHead(IHeaderResponse response) + { + String script = "$('#" + cancelUpload.getMarkupId() +"').on('click', function() { Wicket.Ajax.abortRequest(); });"; + response.render(OnDomReadyHeaderItem.forScript(script)); + } + }; + cancelUpload.setOutputMarkupId(true); + form.add(cancelUpload); + WebMarkupContainer drop = new WebMarkupContainer("drop"); drop.add(new AjaxFileDropBehavior() { protected void onFileUpload(AjaxRequestTarget target, List<FileUpload> files) { @@ -133,17 +160,24 @@ public class FileUploadPage extends BasePage } } - target.add(feedback); + target.add(feedback, cancelUpload); } @Override protected void onError(AjaxRequestTarget target, FileUploadException fux) { info(fux.getMessage()); - - target.add(feedback); + target.add(feedback,cancelUpload); } }); add(drop); } + + private String showCancelUploadButtonScript() { + return "$('#" + cancelUpload.getMarkupId() + "').show();"; + } + + private String hideCancelUploadButtonScript() { + return "$('#" + cancelUpload.getMarkupId() + "').hide();"; + } }
