Employment/Purpose

There are two ways to use org.zkoss.zul.Fileupload as a component to upload files, or invoke org.zkoss.zul.Fileupload#get() to open a dialog to upload files.

Common Use Cases

Embedded upload button

Place <fileupload> directly on a page as a styled button. The onUpload event fires when the user selects a file:

<image id="preview" />
<fileupload label="Upload Image"
            onUpload="preview.setContent(event.getMedia())" />

Pop-up dialog (static method)

Call Fileupload.get(...) from any event listener to open the built-in upload dialog. Because the event thread is disabled by default, listen for the onUpload event on a root component (or supply an EventListener callback) to receive the uploaded media:

<div onUpload="handleUpload(event.getMedias())">
    <button label="Upload Files" onClick="Fileupload.get(-1)" />
</div>

Custom dialog template

Replace the default upload dialog with a custom ZUL template (see Template) to match your application’s look and feel. Register the template once at application startup; all subsequent Fileupload.get(...) calls will use it.

Example

Here is an example that uses org.zkoss.zul.Fileupload as a component:

<image id="img" />
Upload your hot shot:
<fileupload label="Upload" onUpload="img.setContent(event.media)" />

Use as a Component

org.zkoss.zul.Fileupload itself is a component. You can use it directly as follows.

<fileupload label="Upload">
   <attribute name="onUpload">
   org.zkoss.util.media.Media media = event.getMedia();
   //then, you can process media here
   </attribute>
</fileupload>

org.zkoss.zul.Fileupload is actually a button with upload=true. In other words, the above is equivalent to

<button label="Upload" upload="true">
...

Please refer to Button: Upload for details.

Invoke the Static Method: get

Fileupload provides a set of static methods to simplify file uploading, such as org.zkoss.zul.Fileupload#get(), org.zkoss.zul.Fileupload#get(java.lang.String, java.lang.String), and so on.

The behavior is a little bit different depending on if the event thread is enabled (default: it is disabled1).

Creating a custom template for the Static Method: get

When using the static method Fileupload.get(…) to display a generic upload popup, the popup content is defined by a ZUL file, so you could customize it by replacing it with your own implementation. It can be done easily by invoking org.zkoss.zul.Fileupload#setTemplate(java.lang.String). Notice that it affects all Fileupload popups subsequently created in an application. It is typically called when the application starts (i.e., in org.zkoss.zk.ui.util.WebAppInit#init(org.zkoss.zk.ui.WebApp) – for more information, please refer to ZK Developer’s Reference: Life Cycle Listener).

To implement a custom template, please take a look at the default template for ZK 9 or the default template for ZK 10.

Example Usage

When the event thread is disabled (default), the execution won’t be suspended when org.zkoss.zul.Fileupload#get() is called. In other words, the returned value is always null. To retrieve the uploaded files, the developer has to listen the onUpload event, which is sent when the uploading is completed.

By default, the onUpload event is sent to all root components. For example, org.zkoss.zul.Div will, in the following example, receive the onUpload event since it is the root component:

<div onUpload="processMedia(event.getMedias());">
    <zscript deferred="true"><![CDATA[
    import org.zkoss.util.media.Media;
 
    public void processMedia(Media[] media) {
        if (media != null) {
            for (int i = 0; i < media.length; i++) {
                if (media[i] instanceof org.zkoss.image.Image) {
                    image.setContent(media[i]);
                } else {
                    Messagebox.show("Not an image: " + media[i], "Error",
                            Messagebox.OK, Messagebox.ERROR);
                    break; //not to show too many errors
                }
            }
        }
    }
]]></zscript>
    <vbox>
        <button label="Upload" onClick="Fileupload.get(-1);" />
        <image id="image" />
    </vbox>
</div>

Specify the Callback Event Listener

since 6.5.3

If you prefer the event being sent to the callback event listener, specify the event listener when invoke Fileupload.get().

Note: the target of the upload event is always null.

For example:

<zk>
    <vbox>
       <button label="Upload">
            <attribute name="onClick">
                Fileupload.get(new EventListener(){
                    public void onEvent(UploadEvent event) {
                        org.zkoss.util.media.Media media = event.getMedia();
                        if (media instanceof org.zkoss.image.Image) {
                            org.zkoss.image.Image img = (org.zkoss.image.Image) media;
                            if (img.getWidth() > img.getHeight()){
                                if (img.getHeight() > 300) {
                                    pics.setHeight("300px");
                                    pics.setWidth(img.getWidth() * 300 / img.getHeight() + "px");
                                }
                            }
                            if (img.getHeight() > img.getWidth()){
                                if (img.getWidth() > 400) {
                                    pics.setWidth("400px");
                                    pics.setHeight(img.getHeight() * 400 / img.getWidth() + "px");
                                }
                            }
                            image.setContent(img);
                        } else {
                            Messagebox.show("Not an image: "+media, "Error", Messagebox.OK, Messagebox.ERROR);
                        }
                    }
                })
            </attribute>
        </button>
        <image id="image" />
    </vbox>
</zk>

Specify the Target Component

since 5.0.2

If you prefer the event being sent to a particular component, specify the component in the desktop’s attribute called org.zkoss.zul.Fileupload.target.

For example, we could have the button to receive the onUpload event as follows:

<zk>
    <zscript deferred="true"><![CDATA[
    import org.zkoss.util.media.Media;

    Executions.getCurrent().getDesktop().setAttribute(
            "org.zkoss.zul.Fileupload.target", uploadBtn);

    public void processMedia(Media[] media) {
        if (media != null) {
            for (int i = 0; i < media.length; i++) {
                if (media[i] instanceof org.zkoss.image.Image) {
                    image.setContent(media[i]);
                } else {
                    Messagebox.show("Not an image: " + media[i], "Error",
                            Messagebox.OK, Messagebox.ERROR);
                    break; //not to show too many errors
                }
            }
        }
    }
]]></zscript>
    <vbox>
        <button id="uploadBtn" label="Upload"
            onUpload="processMedia(event.getMedias());"
            onClick="Fileupload.get(-1);" />
        <image id="image" />
    </vbox>
</zk>

Event Thread Enabled (deprecated)

If the event thread is enable, the uploaded file will be returned directly by org.zkoss.zul.Fileupload#get() and other static methods, such as:

<zk>
    <button label="Upload">
    <attribute name="onClick">{
        org.zkoss.util.media.Media[] media = Fileupload.get(-1);
        if (media != null) {
            for (int i = 0; i &lt; media.length; i++) {
                if (media[i] instanceof org.zkoss.image.Image) {
                    org.zkoss.zul.Image image = new org.zkoss.zul.Image();
                    image.setContent(media[i]);
                    image.setParent(pics);
                } else {
                    Messagebox.show("Not an image: "+media[i], "Error", Messagebox.OK, Messagebox.ERROR);
                    break; //not to show too many errors
                }
            }
        }
    }</attribute>
    </button>
    <vbox id="pics" />
</zk>

As shown, org.zkoss.zul.Fileupload#get(int) won’t return until the end user uploads the files (and/or closes the dialog).

Temporary File Created During Uploading

This component depends on Apache Commons Fileupload (DiskFileItemFactory), so org.apache.commons.io.FileCleanerTracker will delete those temporary files created during uploading. Please refer to Resource cleanup

You can verify this cleanup by enforcing garbage collecting with JVisualVM.

Properties

Template

Default Value: ~./zul/html/fileuploaddlg.zul

Sets the ZUL template used to create the upload modal dialog opened by Fileupload.get(...). The URI must not be empty. The template must follow the structure of the default template — you may adjust labels and layout but must keep the same component IDs. This is a class-level (static) setting; it affects all subsequent Fileupload.get(...) dialogs in the application and has no effect when <fileupload> is used as an embedded component.

Because setTemplate is a static method, the value cannot be passed as a ZUL attribute. Call it once at application startup (e.g., in a WebAppInit):

<!-- fileuploaddlg.zul — customised template (keep component IDs intact) -->
<window id="fileuploaddlg" border="normal" width="500px">
    <!-- your custom layout here -->
</window>

Then register the template path in Java at startup:

// in WebAppInit.init(WebApp)
Fileupload.setTemplate("~./WEB-INF/zul/myupload.zul");

Supported Events

  • Inherited Supported Events: Button

Supported Children

*NONE

  1. Prior to 5.0, it is default to enabled. Refer to ZK Configuration Reference: disable-event-thread