This is an automated email from the ASF dual-hosted git repository. reiern70 pushed a commit to branch feature/reiern70/WICKET-6750-aborting-ajax-requests-take-II in repository https://gitbox.apache.org/repos/asf/wicket.git
commit 8f8927add94ddf60c558f9cd062f18f8d0aec93f Author: reiern70 <[email protected]> AuthorDate: Sun Feb 23 09:08:57 2020 +0200 [WICKET-6750] introduce AjaxRequestMonitor that allows, for instance, to abort currently executing request for a given Ajax channel + example on how to abort AJAX upload --- .../wicket/ajax/res/js/wicket-ajax-jquery.js | 48 ++++++++++++++++++++++ .../examples/ajax/builtin/FileUploadPage.html | 2 +- .../examples/ajax/builtin/FileUploadPage.java | 48 ++++++++++++++++++++-- 3 files changed, 93 insertions(+), 5 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..ab99c0d 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 @@ -336,6 +336,54 @@ Wicket.ChannelManager.FunctionsExecuter = FunctionsExecuter; /** + * AjaxRequestMonitor allows to get hold of jqXHR during AJAX request and + * manipulate it. + */ + Wicket.AjaxRequestMonitor = Wicket.Class.create(); + + Wicket.AjaxRequestMonitor.prototype = { + initialize: function () { + this.requests = []; + }, + + init: function() { + var requests = this.requests; + Wicket.Event.subscribe('/ajax/call/beforeSend', + function(jqEvent, attributes, jqXHR, errorThrown, textStatus) { + requests [attributes.ch] = jqXHR; + } + ); + + Wicket.Event.subscribe('/ajax/call/complete', + function(jqEvent, attributes, jqXHR, errorThrown, textStatus) { + delete requests[attributes.ch]; + } + ); + }, + + getRequest: function (channel) { + var channelName = channel; + // (ajax channel) + if (typeof (channelName) !== 'string') { + channelName = '0|s'; + } + return this.requests[channelName]; + + }, + + abortRequest: function (channel) { + var jqXHR = this.getRequest(channel); + if (jqXHR) { + try { + jqXHR.abort(); + } catch (exception) { + Wicket.Log.error("Couldn't abort current AJAX request:", exception); + } + } + } + }; + + /** * The Ajax.Request class encapsulates a XmlHttpRequest. */ Wicket.Ajax = {}; 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..3ea34ca 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 @@ -80,6 +85,8 @@ public class FileUploadPage extends BasePage } }; form.setMaxSize(Bytes.megabytes(1)); + // enable in case you want to be able to test cancelling AJAX upload + //form.setMaxSize(Bytes.megabytes(500)); add(form); // create a textfield to demo non-file content @@ -105,6 +112,7 @@ public class FileUploadPage extends BasePage // ajax-update the feedback panel target.add(feedback); + target.appendJavaScript(hideCancelUploadButtonScript()); } @Override @@ -112,10 +120,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() { window.requestMonitor.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 +161,29 @@ 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); } + + @Override + public void renderHead(IHeaderResponse response) { + response.render(OnDomReadyHeaderItem.forScript("window.requestMonitor = new Wicket.AjaxRequestMonitor(); window.requestMonitor.init();")); + } + + private String showCancelUploadButtonScript() { + return "$('#" + cancelUpload.getMarkupId() + "').show();"; + } + + private String hideCancelUploadButtonScript() { + return "$('#" + cancelUpload.getMarkupId() + "').hide();"; + } }
