Dropupload"

From Documentation
(40 intermediate revisions by 7 users not shown)
Line 9: Line 9:
  
 
= Employment/Purpose =
 
= Employment/Purpose =
<code>Dropupload</code> use HTML5 tecnnology, can handle action user drag file in it, and upload them to server. The behavior of <code>Dropupload</code> look like traditional ZK file upload, but can provide better user experience.
+
<tt>Dropupload</tt> leverages HTML 5 technology to handle file uploading where users can simply drag and drop the file(s) they want to upload into <tt>Dropupload</tt> and the uploading process will start automatically. The behaviour and operation of this <tt>Dropupload</tt> component is similar to ZK's [http://books.zkoss.org/wiki/ZK_Component_Reference/Essential_Components/Button#File_Upload '''file upload button'''] but with better user experience and performance.
  
 
= Example =
 
= Example =
 +
Following is a typical example of its implementation, it will always show component and limit the upload file size.
 
<source lang="xml">
 
<source lang="xml">
 
<dropupload maxsize="5120" detection="none" onUpload="doSomething(event)">
 
<dropupload maxsize="5120" detection="none" onUpload="doSomething(event)">
Line 20: Line 21:
 
</dropupload>
 
</dropupload>
 
</source>
 
</source>
 +
 +
Another example, it will detect the drag action:
 +
<source lang="xml">
 +
<zk>
 +
    <vlayout>
 +
        <image id="img" />
 +
        Upload your hot shot:
 +
        <dropupload maxsize="-1" content="content" detection="browser" onUpload="img.setContent(event.media)" />
 +
    </vlayout>
 +
</zk>
 +
</source>
 +
 +
'''Drop area'''
 +
[[File:initial-run.png]]
 +
 +
'''File dragged over area'''
 +
[[File:dragged-over.png]]
 +
 +
'''Image uploaded and displayed'''
 +
[[File:uploaded-image.png]]
  
 
= Maxsize =
 
= Maxsize =
The attribute <code>maxsize</code> will limit the file size user want to upload. Notice if user drop two or more files in Dropupload, all of these file size must smaller than <code>maxsize</code> setting, or will show error message and won't upload anything.
 
  
The unit of <code>maxsize</code> is KB. Negative value means unlimited. If developer does not assign <code>maxsize</code> value, it will assign the value of <code>Configuration.getMaxUploadSize()</code> automatically.
+
The <tt>maxsize</tt> attribute is used for limiting the file size of a single file in which users are allowed to upload. Users are allowed to drag in two or more files at once but each of them has to be smaller than the size set by <tt>Maxsize</tt>. If one of the files is larger than the size set by <tt>Maxsize</tt>, an error message will occur and nothing will be uploaded.
+
 
 +
For example, in the case of the previous sample code, you can upload multiple files, say, four files that are smaller than 5120KB at once but if one of them exceeds 5120KB, then an exception will occur and none of the four files will be uploaded to the server.
 +
 
 +
The unit of <tt>MaxsizeM</tt> attribute is in KB. If it is not assigned a value, it will use the value of '''Configuration.getMaxUploadSize()''' automatically while a negative value would mean that the file size is set as unlimited.
 +
 
 
= Detection =
 
= Detection =
To collate "Drag and Drop" behavior, we are indroducing attribute <code>detection</code>. By set this attribute, when user are dragging in your application, Dropupload or it's content will show.
 
  
There are four valid value of <code>detection</code> :
+
This attribute will define what users see when they drag and drop files into the application i.e. how the <tt>Dropupload</tt> component and its content will appear according to their action.
* <code>none</code> : Ignore drag action, always show Dropupload and content.
 
* <code>browser</code> (default) : Dropupload does not show initially. When user dragging into browser, both Dropupload and content will be shown.
 
* <code>self</code> : It will show Dropupload initially. When user dragging into Dropupload, the content will be shown.
 
* id of other component : It's almost the same of <code>self</code>, but the trigger area is the component of appointed id.
 
  
The <code>content</code> value can be any HTML string, remember surround content value by <code>CDATA</code> block .
+
There are four valid values of <code>detection</code> :
 +
* <code>none</code> : Ignore users' drag action, always show <tt>Dropupload</tt> and its content.
 +
* <code>browser</code> (default setting) : <tt>Dropupload</tt> is not visible in the application initially but shows up along with the content when users drag files into the browser.
 +
* <code>self</code> : <tt>Dropupload</tt> is visible in the application initially but the content only appears when users drag files into the component.
 +
* id of another component : Behaviour of this value is almost identical to <code>self</code>, except that the trigger area is inside the component of the appointed id.  
  
'''Notice''' : The Dropupload with <code>detection="browser"</code> setting can't put together with other Dropupload that detection is not "browser". If do so, the user can't drop file on it.
+
The <code>content</code> value can be any HTML string and remember to surround the content value by <code>CDATA</code> block .
 +
 
 +
'''Note''' : A <tt>Dropupload</tt> with <code>detection="browser"</code> cannot be used with another <tt>Dropupload</tt> component that has a different <tt>detection</tt> value; users won't be able to drag a file into the component successfully.
 +
 
 +
= Anchor =
 +
    since 7.0.2
 +
This attribute allows the dropupload component to anchor to another component and overlay that component when the user drag & drops files to the browser. Much like how Gmail works when dropping attachments to emails.
 +
 
 +
== Example ==
 +
[[File:Dropupload_Anchor.png]]
 +
[[File:Dropupload_Anchor_1.png]]
 +
 
 +
<source lang="xml" high="13">
 +
<zk>
 +
<div height="100px"></div>
 +
<tabbox height="100px">
 +
<tabs>
 +
<tab id="A" label="Tab A" />
 +
<tab id="B" label="Tab B" />
 +
</tabs>
 +
<tabpanels id="tps">
 +
<tabpanel>This is panel A</tabpanel>
 +
<tabpanel>This is panel B</tabpanel>
 +
</tabpanels>
 +
</tabbox>
 +
<dropupload anchor="${tps}"></dropupload>
 +
</zk>
 +
</source>
 +
 
 +
= MaxFileCount =
 +
 
 +
Set the maximum number of files user can upload at once, -1 means no limitation, when number of upload files exceed the maxFileCount, nothing will be uploaded and onMaxFileCountExceed event will be triggered, developer can listen to onMaxFileCountExceed and get the number of upload files by calling event.getData().
 +
 
 +
Default: -1
 +
 
 +
For example (MVVM style):
 +
 
 +
<source language="xml">
 +
  <dropupload onMaxFileCountExceed="@command('maxFileCountExceed', filesCount=event.data)" />
 +
</source>
 +
<source language="java">
 +
  @Command
 +
  public void maxFileCountExceed(@BindingParam("filesCount") Integer filesCount) {
 +
    Messagebox.show(filesCount + " files exceed the number of upload files limitation.");
 +
  }
 +
</source>
 +
 
 +
= Do not Convert File =
 +
By default, ZK will convert upload file to image, audio and text file if possible. Developer can use <code>native="true"</code> to demand ZK don't convert file.
  
 
= Customized File Viewer =
 
= Customized File Viewer =
Like traditional File Upload, it will show progress when uploading file.  
+
Similar to [http://books.zkoss.org/wiki/ZK_Component_Reference/Essential_Components/Button#File_Upload '''file upload button'''], the default file viewer will show the uploading progress via a pop-up bar as illustrated below.  
  
 
[[Image:DefaultFileUploadVeiwer.JPG]]
 
[[Image:DefaultFileUploadVeiwer.JPG]]
  
Developer can design customized File Viewer. First implement a JAvaScript class handling the desplay of the uploading files. There is an example :
+
Alternatively, developers can also design customized File Viewer by implementing a JavaScript class to handle the display screen when uploading files.  
 +
Below is an example of a customized file viewer where the progress bar is shown at the bottom of the browser.
 +
 
 +
[[File:CustomizedFileUploadVeiwer.JPG]]
 +
 
 +
 
 
<source lang="javascript">
 
<source lang="javascript">
 
foo.MyFileViewer = zk.$extends(zk.Object, {
 
foo.MyFileViewer = zk.$extends(zk.Object, {
Line 77: Line 153:
 
});</source>
 
});</source>
  
There are three functions above, ''$init'', ''update'', and ''destroy''.
+
In the code snippet above, you can see that there are three functions - ''$init'', ''update'', and ''destroy''.
#'''$init(uplder, file)''': When a user selects a file from file chooser, the function will be invoked.
+
#'''$init(uplder, file)''': When the user selects a file from the file chooser, this function will be invoked.
#* ''uplder'' [[#Uploader|A uploader object]]
+
#* ''uplder'': [[#Uploader|An uploader object]]
#* ''file'' The file user upload. It is a [http://www.w3.org/TR/FileAPI/ File] object.
+
#* ''file'': The file user uploads. It is a [http://www.w3.org/TR/FileAPI/ File] object.
#'''update(send, total)''': After the uploading engine receives the uploaded size, the function will be invoked.
+
#'''update(send, total)''': After the uploading engine receives the size that has already been uploaded, this function will be invoked.
 
#* ''sent'': An integer of the uploaded size.
 
#* ''sent'': An integer of the uploaded size.
 
#* ''total'': An integer of the total uploaded size.
 
#* ''total'': An integer of the total uploaded size.
#'''destroy()''': After the uploaded file is done or a user cancels the uploading file or the uploading file causes an error, the function will be invoked.
+
#'''destroy()''': After the file has been uploaded or if the uploading has been canceled or if the uploading has caused an error, this function will be invoked.
 +
 
 +
After customizing your JavaScript class which in this case is <code>foo.MyFileViewer</code>, assign it to <tt>Dropupload</tt> using the <code>viewerClass</code> attribute as demonstrated below:
  
After finish <code>foo.MyFileViewer</code>, specify the JavaScript class in the <code>viewerClass</code> attribute.
 
 
<source lang="xml"><dropupload viewClass="foo.MyFileViewer" content="custom viewer" detection="none" /></source>
 
<source lang="xml"><dropupload viewClass="foo.MyFileViewer" content="custom viewer" detection="none" /></source>
  
 
=== Uploader ===
 
=== Uploader ===
Here is a description table of the ''Uploader'' when passed a user selected a file.
+
Below is a summarised description table of the ''Uploader'' when passed a selected file from the user.  
 
{| border="1"
 
{| border="1"
 
|-
 
|-
Line 96: Line 173:
 
|-
 
|-
 
||  getWidget
 
||  getWidget
||  Returns the widget that it belongs to.
+
||  Indicate which component the widget belongs to
 
|-
 
|-
 
||  cancel
 
||  cancel
Line 103: Line 180:
  
 
== Transforming the original File Viewer ==
 
== Transforming the original File Viewer ==
Customized File Viewers written in the past can continued to be used, only with the need to make some slight changes :
 
* The second parameter of <code>$init()</code> changes from the original <code>filenm</code> (type: String) into a <code>file</code> (type: File) object. Add <code>filenm = file.name</code> to solve it.
 
* The first parameter of <code>update()</code>, <code>send</code> would originally pass an integer value in a range from 0 to 100, representing the percentage of the uploading process. Now it will pass the amount of the already uploaded amount of data (Bytes).
 
  
= After Upload Finish =
+
Customized File Viewers written in the past can also be applied to <tt>Dropupload</tt> with only some slight changes :
The uploaded files can be retrieved from the companion event, which is an instance of <javadoc>org.zkoss.zk.ui.event.UploadEvent</javadoc>. For example,
+
* Originally,  the second parameter of <code>$init()</code> is <code>filenm</code> (type: String). To apply it to the new <tt>Dropupload</tt> component, change the second parameter to <code>file</code> (type: File) object and add another line of <code>filenm = file.name</code> to solve the issue.
 +
 
 +
<source lang="javascript">
 +
//before
 +
$init: function (uplder,  filenm) {
 +
//routine
 +
}
 +
 
 +
//after
 +
$init: function (uplder, file) {
 +
var filenm = file.name;
 +
//routine
 +
}
 +
</source>
 +
 
 +
 
 +
 
 +
* The first parameter of <code>update()</code>, <code>send</code> would originally pass an integer value ranging from 0 to 100, representing the percentage of the uploading process whereas now it will pass the value of the already uploaded size of data in Bytes.
 +
 
 +
= Customize Upload Size Exceeding Message =  
 +
Please refer to [[ZK_Component_Reference/Essential_Components/Button#Customize_Upload_Size_Exceeding_Message]]
 +
 
 +
 
 +
= Event For Completed Uploads =
 +
 
 +
After the upload is finished, the uploaded files can be retrieved from the companion event, which is an instance of <javadoc>org.zkoss.zk.ui.event.UploadEvent</javadoc>. For example,
 +
 
 
<source lang="xml">
 
<source lang="xml">
 
<zscript><![CDATA[
 
<zscript><![CDATA[
Line 124: Line 224:
  
 
= Browser Support =
 
= Browser Support =
As Dropupload uses HTML5 technology, there are several browsers that does not support it. Currently it operates normally on Firefox (v.13), Chrome (v.19) and Safari (v.5.1.x), but IE9, Opera v.11.x cannot use this function.
+
 
 +
As <tt>Dropupload</tt> leverages HTML5 technology, some browsers don't support it. Currently, it works normally on Firefox (v.13), Chrome (v.19) and Safari (v.5.1.x), but doesn't function in IE 9, Opera v.11.x, and Microsoft Edge.
  
 
Moreover, the <code>detection</code> setting cannot be displayed on some older machines.
 
Moreover, the <code>detection</code> setting cannot be displayed on some older machines.
Line 135: Line 236:
 
| <center><tt>onUpload</tt></center>
 
| <center><tt>onUpload</tt></center>
 
| '''Event:''' <javadoc>org.zkoss.zk.ui.event.UploadEvent</javadoc>
 
| '''Event:''' <javadoc>org.zkoss.zk.ui.event.UploadEvent</javadoc>
Denotes user has uploaded a file to the component
+
This event will be triggered once a user has uploaded a file.
 +
|-
 +
| <center><tt>onMaxFileCountExceed</tt></center>
 +
| '''Event:''' <javadoc>org.zkoss.zk.ui.event.Event</javadoc>
 +
This event will be triggered when number of upload files exceed the maxFileCount.
 
|}
 
|}
 
*Inherited Supported Events: [[ZK_Component_Reference/Base_Components/LabelImageElement#Supported_Events | LabelImageElement]]
 
*Inherited Supported Events: [[ZK_Component_Reference/Base_Components/LabelImageElement#Supported_Events | LabelImageElement]]
Line 157: Line 262:
 
! Version !! Date !! Content
 
! Version !! Date !! Content
 
|-
 
|-
| 6.1.0
+
| 6.5.0
 
| June, 2012
 
| June, 2012
 
| <javadoc>org.zkoss.zkmax.zul.Dropupload</javadoc> was introduced.
 
| <javadoc>org.zkoss.zkmax.zul.Dropupload</javadoc> was introduced.
 +
|-
 +
| 7.0.2
 +
| March, 2014
 +
| [http://tracker.zkoss.org/browse/ZK-2207 ZK-2207]: Dropupload support anchor
 
|}
 
|}
  
 
{{ZKComponentReferencePageFooter}}
 
{{ZKComponentReferencePageFooter}}

Revision as of 08:00, 31 May 2018

Dropupload

Employment/Purpose

Dropupload leverages HTML 5 technology to handle file uploading where users can simply drag and drop the file(s) they want to upload into Dropupload and the uploading process will start automatically. The behaviour and operation of this Dropupload component is similar to ZK's file upload button but with better user experience and performance.

Example

Following is a typical example of its implementation, it will always show component and limit the upload file size.

	<dropupload maxsize="5120" detection="none" onUpload="doSomething(event)">
		<attribute name="content"><![CDATA[
			<b>Drop Here</b><br/>
			size < 5MB
		]]></attribute>
	</dropupload>

Another example, it will detect the drag action:

<zk>
    <vlayout>
        <image id="img" />
        Upload your hot shot:
        <dropupload maxsize="-1" content="content" detection="browser" onUpload="img.setContent(event.media)" />
    </vlayout>
</zk>

Drop area Initial-run.png

File dragged over area Dragged-over.png

Image uploaded and displayed Uploaded-image.png

Maxsize

The maxsize attribute is used for limiting the file size of a single file in which users are allowed to upload. Users are allowed to drag in two or more files at once but each of them has to be smaller than the size set by Maxsize. If one of the files is larger than the size set by Maxsize, an error message will occur and nothing will be uploaded.

For example, in the case of the previous sample code, you can upload multiple files, say, four files that are smaller than 5120KB at once but if one of them exceeds 5120KB, then an exception will occur and none of the four files will be uploaded to the server.

The unit of MaxsizeM attribute is in KB. If it is not assigned a value, it will use the value of Configuration.getMaxUploadSize() automatically while a negative value would mean that the file size is set as unlimited.

Detection

This attribute will define what users see when they drag and drop files into the application i.e. how the Dropupload component and its content will appear according to their action.

There are four valid values of detection :

  • none : Ignore users' drag action, always show Dropupload and its content.
  • browser (default setting) : Dropupload is not visible in the application initially but shows up along with the content when users drag files into the browser.
  • self : Dropupload is visible in the application initially but the content only appears when users drag files into the component.
  • id of another component : Behaviour of this value is almost identical to self, except that the trigger area is inside the component of the appointed id.

The content value can be any HTML string and remember to surround the content value by CDATA block .

Note : A Dropupload with detection="browser" cannot be used with another Dropupload component that has a different detection value; users won't be able to drag a file into the component successfully.

Anchor

   since 7.0.2

This attribute allows the dropupload component to anchor to another component and overlay that component when the user drag & drops files to the browser. Much like how Gmail works when dropping attachments to emails.

Example

Dropupload Anchor.png Dropupload Anchor 1.png

<zk>
	<div height="100px"></div>
	<tabbox height="100px">
		<tabs>
			<tab id="A" label="Tab A" />
			<tab id="B" label="Tab B" />
		</tabs>
		<tabpanels id="tps">
			<tabpanel>This is panel A</tabpanel>
			<tabpanel>This is panel B</tabpanel>
		</tabpanels>
	</tabbox>
	<dropupload anchor="${tps}"></dropupload>
</zk>

MaxFileCount

Set the maximum number of files user can upload at once, -1 means no limitation, when number of upload files exceed the maxFileCount, nothing will be uploaded and onMaxFileCountExceed event will be triggered, developer can listen to onMaxFileCountExceed and get the number of upload files by calling event.getData().

Default: -1

For example (MVVM style):

  <dropupload onMaxFileCountExceed="@command('maxFileCountExceed', filesCount=event.data)" />
  @Command
  public void maxFileCountExceed(@BindingParam("filesCount") Integer filesCount) {
    Messagebox.show(filesCount + " files exceed the number of upload files limitation.");
  }

Do not Convert File

By default, ZK will convert upload file to image, audio and text file if possible. Developer can use native="true" to demand ZK don't convert file.

Customized File Viewer

Similar to file upload button, the default file viewer will show the uploading progress via a pop-up bar as illustrated below.

DefaultFileUploadVeiwer.JPG

Alternatively, developers can also design customized File Viewer by implementing a JavaScript class to handle the display screen when uploading files. Below is an example of a customized file viewer where the progress bar is shown at the bottom of the browser.

CustomizedFileUploadVeiwer.JPG


foo.MyFileViewer = zk.$extends(zk.Object, {
	updated: null,
	$init: function (uplder,  file) {
		this._uplder = uplder;
		var id = uplder.id,
			uri = zk.ajaxURI('/web/zk/img/progress2.gif', {au:true}),
			html = '<div id="' + id + '" class="viewer"><image class="float-left" src="' + uri + '"/>'
			+ '<div class="float-left">FileName: ' + file.name
			+ ' <a id="' + id + '-cancel">Cancel</a></div><div class="float-right">'
			+ msgzk.FILE_SIZE + ': <span id="' + id + '-sent">0</span> of '
			+ '<span id="' + id + '-total">0</span></div><div class="clear"></div></div>';
				
		jq(uplder.getWidget().getPage()).append(html);
			
		this.viewer = jq('#'+ id)[0];
		jq('#' + id + '-cancel').click(function() {
			uplder.cancel();
		});
	},
	update: function (sent, total) {
		jq('#'+ this._uplder.id + '-sent').html(Math.round(sent/1000) + msgzk.KBYTES);
		if (!this.updated) {
			this.updated = true;
			jq('#'+ this._uplder.id + '-total').html(Math.round(total/1024)+msgzk.KBYTES);
		}
	},
	destroy: function () {
		jq(this.viewer).remove();
	}
});

In the code snippet above, you can see that there are three functions - $init, update, and destroy.

  1. $init(uplder, file): When the user selects a file from the file chooser, this function will be invoked.
  2. update(send, total): After the uploading engine receives the size that has already been uploaded, this function will be invoked.
    • sent: An integer of the uploaded size.
    • total: An integer of the total uploaded size.
  3. destroy(): After the file has been uploaded or if the uploading has been canceled or if the uploading has caused an error, this function will be invoked.

After customizing your JavaScript class which in this case is foo.MyFileViewer, assign it to Dropupload using the viewerClass attribute as demonstrated below:

<dropupload viewClass="foo.MyFileViewer" content="custom viewer" detection="none" />

Uploader

Below is a summarised description table of the Uploader when passed a selected file from the user.

Method Usage
getWidget Indicate which component the widget belongs to
cancel Stops the uploading process.

Transforming the original File Viewer

Customized File Viewers written in the past can also be applied to Dropupload with only some slight changes :

  • Originally, the second parameter of $init() is filenm (type: String). To apply it to the new Dropupload component, change the second parameter to file (type: File) object and add another line of filenm = file.name to solve the issue.
 
//before 
$init: function (uplder,  filenm) {
	//routine
}

//after
$init: function (uplder, file) {
	var filenm = file.name;
	//routine
}


  • The first parameter of update(), send would originally pass an integer value ranging from 0 to 100, representing the percentage of the uploading process whereas now it will pass the value of the already uploaded size of data in Bytes.

Customize Upload Size Exceeding Message

Please refer to ZK_Component_Reference/Essential_Components/Button#Customize_Upload_Size_Exceeding_Message


Event For Completed Uploads

After the upload is finished, the uploaded files can be retrieved from the companion event, which is an instance of UploadEvent. For example,

<zscript><![CDATA[
public void showFileName(org.zkoss.zk.ui.event.UploadEvent event){
	org.zkoss.util.media.Media[] medias = event.getMedias();
	StringBuffer sb = new StringBuffer();
	for (org.zkoss.util.media.Media m : medias) {
		sb.append(m.getName()+"\n");
	}
	Messagebox.show(sb.toString());
}
]]></zscript>
<dropupload detection="none" onUpload="showFileName(event)" />

Browser Support

As Dropupload leverages HTML5 technology, some browsers don't support it. Currently, it works normally on Firefox (v.13), Chrome (v.19) and Safari (v.5.1.x), but doesn't function in IE 9, Opera v.11.x, and Microsoft Edge.

Moreover, the detection setting cannot be displayed on some older machines.

Supported Events

Name
Event Type
onUpload
Event: UploadEvent

This event will be triggered once a user has uploaded a file.

onMaxFileCountExceed
Event: Event

This event will be triggered when number of upload files exceed the maxFileCount.

Supported Children

*NONE

Use Cases

Version Description Example Location
     

Version History

Last Update : 2018/05/31


Version Date Content
6.5.0 June, 2012 Dropupload was introduced.
7.0.2 March, 2014 ZK-2207: Dropupload support anchor



Last Update : 2018/05/31

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.