Author: ivaynberg
Date: Wed Feb 28 22:13:52 2007
New Revision: 513161

URL: http://svn.apache.org/viewvc?view=rev&rev=513161
Log:
bah, checking in missing files

Added:
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.html
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.java
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.js
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.properties

Added: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.html
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.html?view=auto&rev=513161
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.html
 (added)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.html
 Wed Feb 28 22:13:52 2007
@@ -0,0 +1,6 @@
+<wicket:panel>
+<input wicket:id="upload" type="file" class="wicket-mfu-field"/>
+<div wicket:id="container" class="wicket-mfu-container">
+<div wicket:id="caption" class="wicket-mfu-caption"></div>
+</div>
+</wicket:panel>
\ No newline at end of file

Added: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.java?view=auto&rev=513161
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.java
 (added)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.java
 Wed Feb 28 22:13:52 2007
@@ -0,0 +1,374 @@
+package wicket.markup.html.form.upload;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import wicket.Component;
+import wicket.Request;
+import wicket.ResourceReference;
+import wicket.markup.ComponentTag;
+import wicket.markup.html.IHeaderContributor;
+import wicket.markup.html.IHeaderResponse;
+import wicket.markup.html.WebComponent;
+import wicket.markup.html.WebMarkupContainer;
+import wicket.markup.html.basic.Label;
+import wicket.markup.html.form.Form;
+import wicket.markup.html.form.FormComponentPanel;
+import wicket.markup.html.form.upload.FileUpload;
+import wicket.markup.html.resources.JavascriptResourceReference;
+import wicket.model.AbstractReadOnlyModel;
+import wicket.model.IModel;
+import wicket.model.Model;
+import wicket.protocol.http.IMultipartWebRequest;
+import wicket.util.convert.ConversionException;
+import wicket.util.string.Strings;
+import wicket.util.upload.FileItem;
+
+/**
+ * Form component that allows the user to select multiple files to upload via a
+ * single &lt;input type=&quot;file&quot;/&gt; field.
+ * 
+ * Notice that this component clears its model at the end of the request, so 
the
+ * uploaded files MUST be processed within the request they were uploaded.
+ * 
+ * Uses javascript implementation from
+ * 
http://the-stickman.com/web-development/javascript/upload-multiple-files-with-a-single-file-element/
+ * 
+ * For customizing caption text see [EMAIL PROTECTED] #RESOURCE_LIMITED} and
+ * [EMAIL PROTECTED] #RESOURCE_UNLIMITED}
+ * 
+ * For an example of styling using CSS see the upload example in 
wicket-examples
+ * 
+ * @author Igor Vaynberg (ivaynberg)
+ */
+public class MultiFileUploadField extends FormComponentPanel implements 
IHeaderContributor
+{
+       /**
+        * 
+        */
+       private static final long serialVersionUID = 1L;
+
+
+       /**
+        * Represents an unlimited max count of uploads
+        */
+       public static final int UNLIMITED = 1;
+
+       /**
+        * Resource key used to retrieve caption message for when a limit on the
+        * number of uploads is specfied. The limit is represented via ${max}
+        * variable.
+        * 
+        * Example: wicket.mfu.caption.limited=Files (maximum ${max}):
+        */
+       public static final String RESOURCE_LIMITED = 
"wicket.mfu.caption.limited";
+
+       /**
+        * Resource key used to retrieve caption message for when no limit on 
the
+        * number of uploads is specfied.
+        * 
+        * Example: wicket.mfu.caption.unlimited=Files:
+        */
+       public static final String RESOURCE_UNLIMITED = 
"wicket.mfu.caption.unlimited";
+
+
+       private static final String NAME_ATTR = "name";
+
+       private static final String MAGIC_SEPARATOR = "_mf_";
+
+
+       private static final ResourceReference JS = new 
JavascriptResourceReference(
+                       MultiFileUploadField.class, "MultiFileUploadField.js");
+
+
+       private final WebComponent upload;
+       private final WebMarkupContainer container;
+
+       private final int max;
+
+       private transient String[] inputArrayCache = null;
+
+       /**
+        * Constructor
+        * 
+        * @param id
+        * @param model
+        */
+       public MultiFileUploadField(String id)
+       {
+               this(id, null, -1);
+       }
+
+       /**
+        * Constructor
+        * 
+        * @param id
+        * @param model
+        * @param max
+        *            max number of files a user can upload
+        */
+       public MultiFileUploadField(String id, int max)
+       {
+               this(id, null, max);
+       }
+
+       /**
+        * Constructor
+        * 
+        * @param id
+        * @param model
+        */
+       public MultiFileUploadField(String id, IModel model)
+       {
+               this(id, model, UNLIMITED);
+       }
+
+       /**
+        * Constructor
+        * 
+        * @param id
+        * @param model
+        * @param max
+        *            max number of files a user can upload
+        * 
+        */
+       public MultiFileUploadField(String id, IModel model, int max)
+       {
+               super(id, model);
+
+               this.max = max;
+
+               upload = new WebComponent("upload");
+               upload.setOutputMarkupId(true);
+               add(upload);
+
+               container = new WebMarkupContainer("container");
+               container.setOutputMarkupId(true);
+               add(container);
+
+               container.add(new Label("caption", new CaptionModel()));
+       }
+
+       /**
+        * @see 
wicket.markup.html.form.FormComponentPanel#onComponentTag(wicket.markup.ComponentTag)
+        */
+       protected void onComponentTag(ComponentTag tag)
+       {
+               super.onComponentTag(tag);
+               // remove the name attribute added by the FormComponent
+               if (tag.getAttributes().containsKey(NAME_ATTR))
+               {
+                       tag.getAttributes().remove(NAME_ATTR);
+               }
+       }
+
+       /**
+        * @see wicket.Component#internalOnAttach()
+        */
+       protected void internalOnAttach()
+       {
+               super.internalOnAttach();
+
+               // auto toggle form's multipart property
+               Form form = (Form)findParent(Form.class);
+               if (form == null)
+               {
+                       // woops
+                       throw new IllegalStateException("Component " + 
getClass().getName() + " must have a "
+                                       + Form.class.getName() + " component 
above in the hierarchy");
+               }
+               form.setMultiPart(true);
+       }
+
+
+       /**
+        * @see 
wicket.markup.html.IHeaderContributor#renderHead(wicket.markup.html.IHeaderResponse)
+        */
+       public void renderHead(IHeaderResponse response)
+       {
+               // initialize the javascript library
+               response.renderJavascriptReference(JS);
+               response.renderOnDomReadyJavascript("new MultiSelector('" + 
getInputName()
+                               + "', document.getElementById('" + 
container.getMarkupId() + "'), " + max
+                               + ").addElement(document.getElementById('" + 
upload.getMarkupId() + "'));");
+       }
+
+       /**
+        * @see wicket.markup.html.form.FormComponent#getInputAsArray()
+        */
+       public String[] getInputAsArray()
+       {
+               // fake the input array as if it contained an array of all 
uploaded file
+               // names
+
+               if (inputArrayCache == null)
+               {
+                       // this array will aggregate all input names
+                       ArrayList names = null;
+
+                       final Request request = getRequest();
+                       if (request instanceof IMultipartWebRequest)
+                       {
+                               // retrieve the filename->FileItem map from 
request
+                               final Map itemNameToItem = 
((IMultipartWebRequest)request).getFiles();
+                               Iterator it = 
itemNameToItem.entrySet().iterator();
+                               while (it.hasNext())
+                               {
+                                       // iterate over the map and build the 
list of filenames
+
+                                       final Entry entry = (Entry)it.next();
+                                       final String name = 
(String)entry.getKey();
+                                       final FileItem item = 
(FileItem)entry.getValue();
+
+                                       if (!Strings.isEmpty(name) && 
name.startsWith(getInputName() + MAGIC_SEPARATOR)
+                                                       && 
!Strings.isEmpty(item.getName()))
+                                       {
+
+                                               // make sure the fileitem 
belongs to this component and
+                                               // is not empty
+
+                                               names = (names != null) ? names 
: new ArrayList();
+                                               names.add(name);
+                                       }
+                               }
+                       }
+
+                       if (names != null)
+                       {
+                               inputArrayCache = (String[])names.toArray(new 
String[names.size()]);
+                       }
+               }
+               return inputArrayCache;
+
+       }
+
+       /**
+        * @see 
wicket.markup.html.form.FormComponent#convertValue(java.lang.String[])
+        */
+       protected Object convertValue(String[] value) throws ConversionException
+       {
+               // convert the array of filenames into a collection of FileItems
+
+               Collection uploads = null;
+
+               final String[] filenames = getInputAsArray();
+
+               if (filenames != null)
+               {
+                       final IMultipartWebRequest request = 
(IMultipartWebRequest)getRequest();
+
+                       uploads = new ArrayList(filenames.length);
+
+                       for (int i = 0; i < filenames.length; i++)
+                       {
+                               uploads.add(new 
FileUpload(request.getFile(filenames[i])));
+                       }
+               }
+
+               return uploads;
+
+       }
+
+       /**
+        * @see wicket.markup.html.form.FormComponent#updateModel()
+        */
+       public void updateModel()
+       {
+               final Object object = getModelObject();
+
+               // figure out if there is an existing model object collection 
for us to
+               // reuse
+               if (object == null)
+               {
+                       // no existing collection, push the one we created
+                       setModelObject(getConvertedInput());
+               }
+               else
+               {
+                       if (!(object instanceof Collection))
+                       {
+                               // fail early if there is something interesting 
in the model
+                               throw new IllegalStateException("Model object 
of " + getClass().getName()
+                                               + " component must be of type 
`" + Collection.class.getName() + "<"
+                                               + FileUpload.class.getName() + 
">` but is of type `"
+                                               + object.getClass().getName() + 
"`");
+                       }
+                       else
+                       {
+                               // refresh the existing collection
+                               Collection collection = (Collection)object;
+                               collection.clear();
+                               if (getConvertedInput() != null)
+                               {
+                                       
collection.addAll((Collection)getConvertedInput());
+                               }
+
+                               // push the collection in case the model is 
listening to
+                               // setobject calls
+                               setModelObject(collection);
+                       }
+               }
+       }
+
+       /**
+        * @see wicket.Component#internalOnDetach()
+        */
+       protected void internalOnDetach()
+       {
+               // cleanup any opened filestreams
+               Collection uploads = (Collection)getConvertedInput();
+               if (uploads != null)
+               {
+                       Iterator it = uploads.iterator();
+                       while (it.hasNext())
+                       {
+                               final FileUpload upload = (FileUpload)it.next();
+                               upload.closeStreams();
+                       }
+               }
+
+               // cleanup any caches
+               inputArrayCache = null;
+
+               // clean up the model because we dont want FileUpload objects 
in session
+               Object modelObject = getModelObject();
+               if (modelObject != null && (modelObject instanceof Collection))
+               {
+                       ((Collection)modelObject).clear();
+               }
+
+               super.internalOnDetach();
+       }
+
+       /**
+        * Model that will construct the caption string
+        * 
+        * @author ivaynberg
+        */
+       private class CaptionModel extends AbstractReadOnlyModel
+       {
+
+               private static final long serialVersionUID = 1L;
+
+               /**
+                * @see 
wicket.model.AbstractReadOnlyModel#getObject(wicket.Component)
+                */
+               public Object getObject(Component component)
+               {
+                       if (max == UNLIMITED)
+                       {
+                               return getString(RESOURCE_UNLIMITED);
+                       }
+                       else
+                       {
+                               return getString(RESOURCE_LIMITED, 
Model.valueOf(Collections.singletonMap("max",
+                                               Long.valueOf(max))));
+                       }
+               }
+
+       }
+}

Added: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.js
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.js?view=auto&rev=513161
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.js
 (added)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.js
 Wed Feb 28 22:13:52 2007
@@ -0,0 +1,158 @@
+/**
+ * Convert a single file-input element into a 'multiple' input list
+ *
+ * Usage:
+ *
+ *   1. Create a file input element (no name)
+ *      eg. <input type="file" id="first_file_element">
+ *
+ *   2. Create a DIV for the output to be written to
+ *      eg. <div id="files_list"></div>
+ *
+ *   3. Instantiate a MultiSelector object, passing in the DIV and an 
(optional) maximum number of files
+ *      eg. var multi_selector = new MultiSelector( document.getElementById( 
'files_list' ), 3 );
+ *
+ *   4. Add the first element
+ *      eg. multi_selector.addElement( document.getElementById( 
'first_file_element' ) );
+ *
+ *   5. That's it.
+ *
+ *   You might (will) want to play around with the addListRow() method to make 
the output prettier.
+ *
+ *   You might also want to change the line 
+ *       element.name = 'file_' + this.count;
+ *   ...to a naming convention that makes more sense to you.
+ * 
+ * Licence:
+ *   Use this however/wherever you like, just don't blame me if it breaks 
anything.
+ *
+ * Credit:
+ *   If you're nice, you'll leave this bit:
+ *  
+ *   Class by Stickman -- http://www.the-stickman.com
+ *      with thanks to:
+ *      [for Safari fixes]
+ *         Luis Torrefranca -- http://www.law.pitt.edu
+ *         and
+ *         Shawn Parker & John Pennypacker -- http://www.fuzzycoconut.com
+ *      [for duplicate name bug]
+ *         'neal'
+ */
+function MultiSelector( eprefix, list_target,max ){
+
+       // Where to write the list
+       this.list_target = list_target;
+       // How many elements?
+       this.count = 0;
+       // How many elements?
+       this.id = 0;
+       // Is there a maximum?
+       if( max ){
+               this.max = max;
+       } else {
+               this.max = -1;
+       };
+       
+       this.element_name_prefix=eprefix;
+       
+       /**
+        * Add a new file input element
+        */
+       this.addElement = function( element ){
+
+               // Make sure it's a file input element
+               if( element.tagName == 'INPUT' && element.type == 'file' ){
+
+                       // Element name -- what number am I?
+                       element.name = this.element_name_prefix + 
"_mf_"+this.id++;
+
+                       // Add reference to this object
+                       element.multi_selector = this;
+
+                       // What to do when a file is selected
+                       element.onchange = function(){
+
+                               // New file input
+                               var new_element = document.createElement( 
'input' );
+                               new_element.type = 'file';
+
+                               // Add new element
+                               this.parentNode.insertBefore( new_element, this 
);
+
+                               // Apply 'update' to element
+                               this.multi_selector.addElement( new_element );
+
+                               // Update list
+                               this.multi_selector.addListRow( this );
+
+                               // Hide this: we can't use display:none because 
Safari doesn't like it
+                               this.style.position = 'absolute';
+                               this.style.left = '-1000px';
+
+                       };
+                       // If we've reached maximum number, disable input 
element
+                       if( this.max != -1 && this.count >= this.max ){
+                               element.disabled = true;
+                       };
+
+                       // File element counter
+                       this.count++;
+                       // Most recent element
+                       this.current_element = element;
+                       
+               } else {
+                       // This can only be applied to file input elements!
+                       alert( 'Error: not a file input element' );
+               };
+
+       };
+
+       /**
+        * Add a new row to the list of files
+        */
+       this.addListRow = function( element ){
+
+               // Row div
+               var new_row = document.createElement( 'div' );
+
+               // Delete button
+               var new_row_button = document.createElement( 'input' );
+               new_row_button.type = 'button';
+               new_row_button.value = 'Delete';
+
+               // References
+               new_row.element = element;
+
+               // Delete function
+               new_row_button.onclick= function(){
+
+                       // Remove element from form
+                       this.parentNode.element.parentNode.removeChild( 
this.parentNode.element );
+
+                       // Remove this row from the list
+                       this.parentNode.parentNode.removeChild( this.parentNode 
);
+
+                       // Decrement counter
+                       this.parentNode.element.multi_selector.count--;
+
+                       // Re-enable input element (if it's disabled)
+                       
this.parentNode.element.multi_selector.current_element.disabled = false;
+
+                       // Appease Safari
+                       //    without it Safari wants to reload the browser 
window
+                       //    which nixes your already queued uploads
+                       return false;
+               };
+
+               // Set row value
+               new_row.innerHTML = element.value;
+
+               // Add button
+               new_row.appendChild( new_row_button );
+
+               // Add it to the list
+               this.list_target.appendChild( new_row );
+               
+       };
+
+};
\ No newline at end of file

Added: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.properties
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.properties?view=auto&rev=513161
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.properties
 (added)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/form/upload/MultiFileUploadField.properties
 Wed Feb 28 22:13:52 2007
@@ -0,0 +1,2 @@
+wicket.mfu.caption.unlimited=Files:
+wicket.mfu.caption.limited=Files (maximum ${max}): 
\ No newline at end of file


Reply via email to