You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by iv...@apache.org on 2009/08/07 19:25:31 UTC

svn commit: r802097 - in /wicket/trunk: wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/ wicket-examples/src/main/java/org/apache/wicket/examples/upload/ wicket/src/main/java/org/apache/wicket/ajax/

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