Author: ivaynberg
Date: Fri Aug  7 17:25:30 2009
New Revision: 802097

URL: http://svn.apache.org/viewvc?rev=802097&view=rev
Log:
WICKET-2420: ajax handling of multipart forms. fingers crossed, damn javascript
Issue: WICKET-2420

Added:
    
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html
   (with props)
    
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java
   (with props)
Modified:
    
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
    
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/Index.html
    
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/upload/MultiUploadPage.html
    
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadPage.html
    wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js

Modified: 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java?rev=802097&r1=802096&r2=802097&view=diff
==============================================================================
--- 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
 (original)
+++ 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
 Fri Aug  7 17:25:30 2009
@@ -69,6 +69,8 @@
                mount(new HybridUrlCodingStrategy("tree/simple", 
SimpleTreePage.class));
                mount(new HybridUrlCodingStrategy("tree/table", 
TreeTablePage.class));
                mount(new HybridUrlCodingStrategy("tree/table/editable", 
EditableTreeTablePage.class));
+               mount(new HybridUrlCodingStrategy("upload", 
FileUploadPage.class));
+
        }
 
        /**

Added: 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html?rev=802097&view=auto
==============================================================================
--- 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html
 (added)
+++ 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html
 Fri Aug  7 17:25:30 2009
@@ -0,0 +1,14 @@
+<wicket:extend>
+
+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/>
+
+
+<div wicket:id="feedback"></div>
+
+<form wicket:id="form">
+       Text field: <input wicket:id="text" type="text"/><br/>
+       File field: <input wicket:id="file" type="file"/> (1MB max)<br/><br/>
+       <input type="submit" value="Regular Submit"/> <input 
wicket:id="ajaxSubmit" type="button" value="Ajax Submit"/>
+</form>
+
+</wicket:extend>
\ No newline at end of file

Propchange: 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java?rev=802097&view=auto
==============================================================================
--- 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java
 (added)
+++ 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java
 Fri Aug  7 17:25:30 2009
@@ -0,0 +1,96 @@
+/*
+ * 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.examples.ajax.builtin;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.html.form.upload.FileUpload;
+import org.apache.wicket.markup.html.form.upload.FileUploadField;
+import org.apache.wicket.markup.html.panel.FeedbackPanel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.util.lang.Bytes;
+
+/**
+ * Demos ajax handling of a multipart form
+ * 
+ * @author igor.vaynberg
+ */
+public class FileUploadPage extends BasePage
+{
+       private final FileUploadField file;
+       private final TextField<String> text;
+
+       /**
+        * Constructor
+        */
+       public FileUploadPage()
+       {
+
+               // create a feedback panel
+               final Component feedback = new 
FeedbackPanel("feedback").setOutputMarkupPlaceholderTag(true);
+               add(feedback);
+
+               // create the form
+               Form<?> form = new Form<Void>("form")
+               {
+                       /**
+                        * @see 
org.apache.wicket.markup.html.form.Form#onSubmit()
+                        */
+                       @Override
+                       protected void onSubmit()
+                       {
+                               // display uploaded info
+                               info("Text: " + text.getModelObject());
+                               FileUpload upload = file.getFileUpload();
+                               if (upload == null)
+                               {
+                                       info("No file uploaded");
+                               }
+                               else
+                               {
+                                       info("File-Name: " + 
upload.getClientFileName() + " File-Size: " +
+                                               
Bytes.bytes(upload.getSize()).toString());
+                               }
+                       }
+               };
+               form.setMaxSize(Bytes.megabytes(1));
+               add(form);
+
+               // create a textfield to demo non-file content
+               form.add(text = new TextField<String>("text", new 
Model<String>()));
+
+               // create the file upload field
+               form.add(file = new FileUploadField("file"));
+
+               // create the ajax button used to submit the form
+               form.add(new AjaxButton("ajaxSubmit")
+               {
+                       @Override
+                       protected void onSubmit(AjaxRequestTarget target, 
Form<?> form)
+                       {
+                               info("This request was processed using AJAX");
+
+                               // ajax-update the feedback panel
+                               target.addComponent(feedback);
+                       }
+
+               });
+       }
+}

Propchange: 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/Index.html
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/Index.html?rev=802097&r1=802096&r2=802097&view=diff
==============================================================================
--- 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/Index.html
 (original)
+++ 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/Index.html
 Fri Aug  7 17:25:30 2009
@@ -19,6 +19,8 @@
 <br/><br/>
 <a href="LinksPage.html">Links Example</a>: demonstrates ajax enabled links
 <br/><br/>
+<a href="FileUploadPage.html">File Upload Example</a>: demonstrates 
trasnparent ajax handling of a multipart form
+<br/><br/>
 <a href="modal/ModalWindowPage.html">Modal window</a>: javascript modal window 
example
 <br/><br/>
 <a href="OnChangeAjaxBehaviorPage.html">On Change Ajax Updater Example</a>: 
demonstrates updating page with ajax when text field value is changed      

Modified: 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/upload/MultiUploadPage.html
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/upload/MultiUploadPage.html?rev=802097&r1=802096&r2=802097&view=diff
==============================================================================
--- 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/upload/MultiUploadPage.html
 (original)
+++ 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/upload/MultiUploadPage.html
 Fri Aug  7 17:25:30 2009
@@ -14,7 +14,8 @@
 <body>
     <span wicket:id="mainNavigation"/>
 
-       The multi upload field is based on javascript found <a target="_blank" 
href="http://the-stickman.com/web-development/javascript/upload-multiple-files-with-a-single-file-element/";>here</a>.<br/>
+       The multi upload field is based on javascript found <a target="_blank" 
href="http://the-stickman.com/web-development/javascript/upload-multiple-files-with-a-single-file-element/";>here</a>.<br/><br>
+       Wicket can also handle file uploads via AJAX, please see AJAX examples 
section. AJAX Functionality is not included in this example to keep things 
simple.<br/><br/>
 
     <form wicket:id="simpleUpload">
         <fieldset>

Modified: 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadPage.html
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadPage.html?rev=802097&r1=802096&r2=802097&view=diff
==============================================================================
--- 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadPage.html
 (original)
+++ 
wicket/trunk/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadPage.html
 Fri Aug  7 17:25:30 2009
@@ -10,6 +10,8 @@
 <body>
     <span wicket:id="mainNavigation"/>
 
+       Wicket can also handle file uploads via AJAX, please see AJAX examples 
section. AJAX Functionality is not included in this example to keep things 
simple.<br/><br/>
+
     <form wicket:id="simpleUpload">
         <fieldset>
          <legend>Upload form</legend>

Modified: 
wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js?rev=802097&r1=802096&r2=802097&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js 
(original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js Fri 
Aug  7 17:25:30 2009
@@ -1046,9 +1046,20 @@
                return this.request.post(body);
        },
 
+       // Submits a form using ajax
+       submitFormById: function(formId, submitButton) {
+               var form = Wicket.$(formId);
+               if (form == null || typeof (form) == "undefined")
+                       Wicket.Log.error("Wicket.Ajax.Call.submitFormById: 
Trying to submit form with id '"+formId+"' that is not in document.");
+               return this.submitForm(form, submitButton);
+       },
+       
        // Submits a form using ajax.
        // This method serializes a form and sends it as POST body.
        submitForm: function(form, submitButton) {
+           if (this.handleMultipart(form)) {
+               return true;
+           }
            var body = function() {
                var s = Wicket.Form.serialize(form);
                if (submitButton != null) {
@@ -1058,13 +1069,76 @@
            }
            return this.request.post(body);
        },
-       
-       // Submits a form using ajax
-       submitFormById: function(formId, submitButton) {
-               var form = Wicket.$(formId);
-               if (form == null || typeof (form) == "undefined")
-                       Wicket.Log.error("Wicket.Ajax.Call.submitFormById: 
Trying to submit form with id '"+formId+"' that is not in document.");
-               return this.submitForm(form, submitButton);
+
+       // If the form contains multipart content this function will post 
+       // the form using an iframe instead of the regular ajax call
+       // and bridge the output - transparently making this work  as if it was 
an ajax call
+       handleMultipart: function (form) {
+               
+               if (form.enctype!="multipart/form-data") {
+                       // not handled, return false
+                       return false;
+               }
+                       
+               var originalFormAction=form.action;
+               var originalFormTarget=form.target;
+               
+               var iframeName="wicket-submit-"+(""+Math.random()).substr(2);
+               
+               try {
+               var iframe = document.createElement("<iframe 
name='"+iframeName+"' id='"+iframeName+"' src='about:blank'/>");
+               } catch (ex) {
+                   var iframe = document.createElement("iframe");
+                   iframe.name=iframeName;
+                       iframe.id=iframe.name;
+                       iframe.src="about:blank";
+               }
+               
+               //iframe.style.width="600px";
+               //iframe.style.height="300px";
+               iframe.style.display="none";
+               iframe.style.visibility="hidden";
+                               
+               Wicket.Event.add(iframe, "load", 
this.handleMultipartComplete.bind(this));
+               
+               document.body.appendChild(iframe);
+               
+               // reconfigure the form
+               form.target=iframe.name;
+               form.action=this.request.url;
+
+               //submit the form into the iframe, response will be handled by 
the onload callback
+               form.submit();
+
+               // handled, restore state and return true
+               form.action=originalFormAction;
+               form.target=originalFormTarget;
+               
+               return true;
+       },
+ 
+       // Completes the multipart ajax handling started via handleMultipart()
+       handleMultipartComplete: function (event) {
+               if (event==null) { event=window.event; }
+               if (event.target!=null) { var iframe=event.target; } else { var 
iframe=event.srcElement};
+
+               var envelope=iframe.contentWindow.document;
+               if (envelope.XMLDocument!=null) { 
envelope=envelope.XMLDocument; }
+       
+               // process the response
+               this.loadedCallback(envelope);
+
+               // stop the event
+               if (event.stopPropagation) { event.stopPropagation(); } else { 
event.cancelBubble=true; }
+
+               // remove the event
+               if (iframe.detachEvent)  
+                       iframe.detachEvent("onload", 
this.handleMultipartComplete);  
+               else  
+                       iframe.removeEventListener("load", 
this.handleMultipartComplete, false);
+               
+               // remove the iframe
+               setTimeout(function() { iframe.parentNode.removeChild(iframe); 
}, 250);
        },
        
        // Processes the response


Reply via email to