Repository: wicket
Updated Branches:
  refs/heads/WICKET-6517-multipart-ajax dfccba1f9 -> 9ba43c592


WICKET-6517 dep could be multipart too


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/9ba43c59
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/9ba43c59
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/9ba43c59

Branch: refs/heads/WICKET-6517-multipart-ajax
Commit: 9ba43c5925358de8be47ef7a93184b4ecf6c0a50
Parents: dfccba1
Author: Sven Meier <svenme...@apache.org>
Authored: Wed Jan 17 00:32:29 2018 +0100
Committer: Sven Meier <svenme...@apache.org>
Committed: Wed Jan 17 00:32:29 2018 +0100

----------------------------------------------------------------------
 .../wicket/ajax/res/js/wicket-ajax-jquery.js    |  49 ++----
 .../examples/ajax/builtin/FileUploadPage.html   |  10 +-
 .../examples/ajax/builtin/FileUploadPage.java   |  26 ++++
 .../markup/html/AjaxFileUploadBehavior.java     | 156 +++++++++++++++++++
 .../extensions/ajax/markup/html/datatransfer.js |  54 +++++++
 5 files changed, 261 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/9ba43c59/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
----------------------------------------------------------------------
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 801a47d..b2ad3a0 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
@@ -49,8 +49,7 @@
                };
        }
 
-       var createIFrame,
-               getAjaxBaseUrl,
+       var getAjaxBaseUrl,
                isUndef,
                replaceAll,
                htmlToDomDocument,
@@ -66,19 +65,6 @@
        };
 
        /**
-        * Creates an iframe that can be used to load data asynchronously or as 
a
-        * target for Ajax form submit.
-        *
-        * @param iframeName {String} the value of the iframe's name attribute
-        */
-       createIFrame = function (iframeName) {
-               // WICKET-6340 properly close tag for XHTML markup
-               var $iframe = jQuery('<iframe name="'+iframeName+'" 
id="'+iframeName+
-                       '" src="about:blank" style="position: absolute; top: 
-9999px; left: -9999px;"></iframe>');
-               return $iframe[0];
-       };
-
-       /**
         * A safe getter for Wicket's Ajax base URL.
         * If the value is not defined or is empty string then
         * return '.' (current folder) as base URL.
@@ -553,7 +539,7 @@
                                extraParam = this._asParamArray(extraParam);
                                params = params.concat(extraParam);
                        }
-                       return jQuery.param(params);
+                       return params;
                },
 
                /**
@@ -583,6 +569,8 @@
                                        'Wicket-Ajax': 'true',
                                        'Wicket-Ajax-BaseURL': getAjaxBaseUrl()
                                },
+                               
+                               url = attrs.u,
 
                                // the request (extra) parameters
                                data = this._asParamArray(attrs.ep),
@@ -658,6 +646,17 @@
                                var el = Wicket.$(attrs.c);
                                data = 
data.concat(Wicket.Form.serializeElement(el, attrs.sr));
                        }
+                       
+                       // collect the dynamic extra parameters
+                       if (jQuery.isArray(attrs.dep)) {
+                               var dynamicData = 
this._calculateDynamicParameters(attrs);
+                               if (attrs.m.toLowerCase() === 'post') {
+                                       data = data.concat(dynamicData);
+                               } else {
+                                       var separator = url.indexOf('?') > -1 ? 
'&' : '?';
+                                       url = url + separator + 
jQuery.param(dynamicData);
+                               }
+                       }
 
                        var wwwFormUrlEncoded = undefined; // default
                        if (attrs.mp) {
@@ -676,29 +675,13 @@
 
                        // execute the request
                        var jqXHR = jQuery.ajax({
-                               url: attrs.u,
+                               url: url,
                                type: attrs.m,
                                context: self,
                                processData: wwwFormUrlEncoded,
                                contentType: wwwFormUrlEncoded,
                                
                                beforeSend: function (jqXHR, settings) {
-                                       // collect the dynamic extra parameters
-                                       if (jQuery.isArray(attrs.dep)) {
-                                               var queryString,
-                                                       separator;
-
-                                               queryString = 
this._calculateDynamicParameters(attrs);
-                                               if (settings.type.toLowerCase() 
=== 'post') {
-                                                       separator = 
settings.data.length > 0 ? '&' : '';
-                                                       settings.data = 
settings.data + separator + queryString;
-                                                       
jqXHR.setRequestHeader("Content-Type", settings.contentType);
-                                               } else {
-                                                       separator = 
settings.url.indexOf('?') > -1 ? '&' : '?';
-                                                       settings.url = 
settings.url + separator + queryString;
-                                               }
-                                       }
-
                                        self._executeHandlers(attrs.bsh, attrs, 
jqXHR, settings);
                                        we.publish(topic.AJAX_CALL_BEFORE_SEND, 
attrs, jqXHR, settings);
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/9ba43c59/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html
----------------------------------------------------------------------
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 9351d4c..4642ae3 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
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" ?>
+<html>
+<body>
 <wicket:extend xmlns:wicket="http://wicket.apache.org";>
 
 Demonstrates Wicket's ability to transparently handle multipart forms via 
AJAX.<br/><br/>The only difference between this example and other non-AJAX 
upload examples is the option to trigger the form submit via an AjaxButton, 
everything else is handled transparently by Wicket.<br/><br/>
@@ -13,4 +15,10 @@ Demonstrates Wicket's ability to transparently handle 
multipart forms via AJAX.<
        <input type="submit" value="Regular Submit"/> <input 
wicket:id="ajaxSubmit" type="button" value="Ajax Submit"/>
 </form>
 
-</wicket:extend>
\ No newline at end of file
+<div wicket:id="drop" style="border: 1px dotted black; width:200px; 
height:200px;">
+       Drop file here.
+</div>
+
+</wicket:extend>
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/9ba43c59/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java
----------------------------------------------------------------------
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 e2eda2e..ca6dc70 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
@@ -16,10 +16,14 @@
  */
 package org.apache.wicket.examples.ajax.builtin;
 
+import java.util.List;
+
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.AjaxFileUploadBehavior;
 import 
org.apache.wicket.extensions.ajax.markup.html.form.upload.UploadProgressBar;
+import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.form.TextField;
@@ -110,5 +114,27 @@ public class FileUploadPage extends BasePage
                        }
 
                });
+               
+               WebMarkupContainer drop = new WebMarkupContainer("drop");
+               drop.add(new AjaxFileUploadBehavior() {
+                       protected void onFileUpload(AjaxRequestTarget target, 
List<FileUpload> files) {
+                           
+                               // display uploaded info
+                               if (files == null || files.isEmpty())
+                               {
+                                       info("No file uploaded");
+                               }
+                               else
+                               {
+                                   for (FileUpload file : files) {
+                                       info("File-Name: " + 
file.getClientFileName() + " File-Size: " +
+                                               
Bytes.bytes(file.getSize()).toString());
+                                   }
+                               }
+                               
+                               target.add(feedback);
+                       }
+               });
+               add(drop);
        }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/9ba43c59/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/AjaxFileUploadBehavior.java
----------------------------------------------------------------------
diff --git 
a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/AjaxFileUploadBehavior.java
 
b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/AjaxFileUploadBehavior.java
new file mode 100644
index 0000000..3801c62
--- /dev/null
+++ 
b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/AjaxFileUploadBehavior.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.extensions.ajax.markup.html;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxEventBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes.Method;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
+import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
+import org.apache.wicket.markup.html.form.upload.FileUpload;
+import org.apache.wicket.protocol.http.servlet.MultipartServletWebRequest;
+import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
+import org.apache.wicket.request.resource.PackageResourceReference;
+import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.util.lang.Args;
+import org.apache.wicket.util.lang.Bytes;
+
+/**
+ * Uploads files from a drop event.
+ * 
+ * @author svenmeier
+ */
+public class AjaxFileUploadBehavior extends AjaxEventBehavior
+{
+
+       private static final ResourceReference JS = new 
PackageResourceReference(AjaxFileUploadBehavior.class, "datatransfer.js");
+
+       /**
+        *  Maximum size of all uploaded files in bytes in a request.
+        */
+       private Bytes maxSize;
+
+       /**
+        *  Maximum size of file of upload in bytes (if there are more than 
one) in a request.
+        */
+       private Bytes fileMaxSize;
+
+       private String parameterName = "f";
+       
+       public AjaxFileUploadBehavior()
+       {
+               super("drop");
+       }
+       
+       @Override
+       public void renderHead(Component component, IHeaderResponse response)
+       {
+               super.renderHead(component, response);
+               
+               response.render(JavaScriptHeaderItem.forReference(JS));
+               
+               // default must be prevented for dragover event, otherwise 
browser will consume the dataTransfer
+               
response.render(OnDomReadyHeaderItem.forScript(String.format("jQuery('#%s').on('dragover',
 function(e) { e.preventDefault(); });", component.getMarkupId())));
+       }
+
+       @Override
+       protected void updateAjaxAttributes(AjaxRequestAttributes attributes)
+       {
+               super.updateAjaxAttributes(attributes);
+
+               attributes.setMultipart(true);
+               attributes.setMethod(Method.POST);
+               // default must be prevented, otherwise browser will consume 
the dataTransfer
+               attributes.setPreventDefault(true);
+
+               attributes.getDynamicExtraParameters().add(
+                       String.format("return 
Wicket.DataTransfer.getFilesAsParamArray(attrs.event.originalEvent, '%s');", 
parameterName)
+               );
+       }
+
+       @Override
+       protected void onEvent(AjaxRequestTarget target)
+       {
+               try
+               {
+                       ServletWebRequest request = 
(ServletWebRequest)getComponent().getRequest();
+                       final MultipartServletWebRequest multipartWebRequest = 
request.newMultipartWebRequest(
+                               getMaxSize(), getComponent().getPage().getId());
+                       multipartWebRequest.setFileMaxSize(getFileMaxSize());
+                       multipartWebRequest.parseFileParts();
+
+                       // TODO: Can't this be detected from header?
+                       
getComponent().getRequestCycle().setRequest(multipartWebRequest);
+                       
+                       ArrayList<FileUpload> fileUploads = new ArrayList<>();
+
+                       // Get the item for the path
+                       final List<FileItem> fileItems = 
multipartWebRequest.getFile(parameterName);
+
+                       if (fileItems != null)
+                       {
+                               for (FileItem item : fileItems)
+                               {
+                                       fileUploads.add(new FileUpload(item));
+                               }
+                       }
+                       
+                       onFileUpload(target, fileUploads);
+               }
+               catch (final FileUploadException fux)
+               {
+                       onError(fux);
+               }
+       }
+
+       public Bytes getMaxSize()
+       {
+               return maxSize;
+       }
+
+       public void setMaxSize(Bytes maxSize)
+       {
+               Args.notNull(maxSize, "maxSize");
+               this.maxSize = maxSize;
+       }
+
+       public Bytes getFileMaxSize()
+       {
+               return fileMaxSize;
+       }
+
+       public void setFileMaxSize(Bytes fileMaxSize)
+       {
+               this.fileMaxSize = fileMaxSize;
+       }
+       
+       protected void onFileUpload(AjaxRequestTarget target, List<FileUpload> 
files)
+       {
+       }
+
+       protected void onError(FileUploadException fux)
+       {
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/9ba43c59/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/datatransfer.js
----------------------------------------------------------------------
diff --git 
a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/datatransfer.js
 
b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/datatransfer.js
new file mode 100644
index 0000000..05ff68a
--- /dev/null
+++ 
b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/datatransfer.js
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+;(function (undefined) {
+       'use strict';
+
+       if (typeof(Wicket) === "undefined") {
+               window.Wicket = {};
+       }
+
+       if (Wicket.DataTransfer) {
+               return;
+       }
+
+       Wicket.DataTransfer = {
+               getFilesAsParamArray : function(ev, name) {
+                       var files = [];
+                               
+                       function pushFile(file) {
+                               files.push({'name' : name, 'value' : file}); 
+                       };
+
+                       var dataTransfer = ev.dataTransfer; 
+                       var i;
+                       if (dataTransfer.items) { 
+                         for (i = 0; i < dataTransfer.items.length; i++) { 
+                           if (dataTransfer.items[i].kind == 'file') { 
+                             pushFile(dataTransfer.items[i].getAsFile()); 
+                           } 
+                         } 
+                       } else { 
+                         for (i = 0; i < dataTransfer.files.length; i++) { 
+                           pushFile(dataTransfer.files[i]); 
+                         } 
+                       }
+                       
+                       return files;
+               }
+       };
+})();

Reply via email to