3.5.2.1.16. FileMultiUploadField

The FileMultiUploadField component allows a user to upload files to the server. The component is a button; when it is clicked, a standard OS file picker window is shown, where the user can select multiple files for upload.

gui multipleUpload

XML name of the component: multiUpload.

Below is an example of using FileMultiUploadField.

  • Declare the component in an XML screen descriptor:

    <multiUpload id="multiUploadField" caption="Upload Many"/>
  • In the screen controller, inject the component itself, the FileUploadingAPI and DataManager interfaces.

    @Inject
    private FileMultiUploadField multiUploadField;
    @Inject
    private FileUploadingAPI fileUploadingAPI;
    @Inject
    private Notifications notifications;
    @Inject
    private DataManager dataManager;
    
    @Subscribe
    protected void onInit(InitEvent event) { (1)
    
        multiUploadField.addQueueUploadCompleteListener(queueUploadCompleteEvent -> { (2)
            for (Map.Entry<UUID, String> entry : multiUploadField.getUploadsMap().entrySet()) { (3)
                UUID fileId = entry.getKey();
                String fileName = entry.getValue();
                FileDescriptor fd = fileUploadingAPI.getFileDescriptor(fileId, fileName); (4)
                try {
                    fileUploadingAPI.putFileIntoStorage(fileId, fd); (5)
                } catch (FileStorageException e) {
                    throw new RuntimeException("Error saving file to FileStorage", e);
                }
                dataManager.commit(fd); (6)
            }
            notifications.create()
                    .withCaption("Uploaded files: " + multiUploadField.getUploadsMap().values())
                    .show();
            multiUploadField.clearUploads(); (7)
        });
    
        multiUploadField.addFileUploadErrorListener(queueFileUploadErrorEvent -> {
            notifications.create()
                    .withCaption("File upload error")
                    .show();
        });
    }
    1 In the onInit() method, add listeners which will react on successful uploads and errors.
    2 The component uploads all selected files to the temporary storage of the client tier and invokes the listener added by the addQueueUploadCompleteListener() method.
    3 In this listener, the FileMultiUploadField.getUploadsMap() method is invoked to obtain a map of temporary storage file identifiers to file names.
    4 Then, corresponding FileDescriptor objects are created by calling FileUploadingAPI.getFileDescriptor() for each map entry. com.haulmont.cuba.core.entity.FileDescriptor (do not confuse with java.io.FileDescriptor) is a persistent entity, which uniquely identifies an uploaded file and then is used to download the file from the system.
    5 FileUploadingAPI.putFileIntoStorage() method is used to move the uploaded file from the temporary client storage to FileStorage. Parameters of this method are temporary storage file identifier and the FileDescriptor object.
    6 After uploading the file to FileStorage, the FileDescriptor instance is saved in a database by invoking DataManager.commit(). The saved instance returned by this method can be set to an attribute of an entity related to this file. Here, FileDescriptor is simply stored in the database. The file will be available through the Administration > External Files screen.
    7 After processing, the list of files should be cleared by calling the clearUploads() method in order to prepare for further uploads.

Below is the list of listeners available to track the upload process:

  • FileUploadErrorListener,

  • FileUploadStartListener,

  • FileUploadFinishListener,

  • QueueUploadCompleteListener.

Maximum upload size is determined by the cuba.maxUploadSizeMb application property and is 20MB by default. If a user selects a file of a larger size, a corresponding message will be displayed, and the upload will be interrupted.

multiUpload attributes:

  • The accept XML attribute (and the corresponding setAccept() method) can be used to set the file type mask in the file selection dialog. Users still be able to change the mask to "All files" and upload arbitrary files.

    The value of the attribute should be a comma-separated list of masks. For example: *.jpg,*.png.

  • The fileSizeLimit XML attribute (and the corresponding setFileSizeLimit() method) can be used to set maximum allowed file size in bytes. This limit defines a maximum size for each file.

    <multiUpload id="multiUploadField" fileSizeLimit="200000"/>
  • The permittedExtensions XML attribute (and the corresponding setPermittedExtensions() method) sets the white list of permitted file extensions.

    The value of the attribute should be a set of string values, where each string is a permitted extension with leading dot. For example:

    uploadField.setPermittedExtensions(Sets.newHashSet(".png", ".jpg"));
  • The dropZone XML attribute allows you to specify a BoxLayout to be used as a target for drag-and-dropping files from outside of the browser. If the container style is not set, the selected container is highlighted when a user drags files over the container, otherwise the dropZone is not visible.

See Loading and Displaying Images for more complex example of working with uploaded files.