4.5.2.1.13. FileUploadField

The FileUploadField component allows a user to upload files to the server. The component can contain a caption, a link to uploaded file, and two buttons: for uploading and for clearing the selected file. When the upload button is clicked, a standard OS file picker window is shown, where the user can select a file. In order to upload multiple files, use FileMultiUploadField.

gui upload

XML name of the component: upload.

gui FileUploadField dia

The component is implemented for Web Client and Desktop Client.

  • FileUploadField is automatically used inside FieldGroup for entity attributes of type FileDescriptor. In this case, the field looks as shown above and does not require additional configuration. An uploaded file is immediately stored in file storage and the corresponding FileDescriptor instance is saved to the database.

  • You can use the component outside FieldGroup and connect it to a datasource. For example, here we suppose that the personDs datasource contains an entity with the photo attribute which is a reference to FileDescriptor:

    <upload fileStoragePutMode="IMMEDIATE"
            datasource="personDs"
            property="photo"/>
  • You can also control the saving of file and FileDescriptor programmatically.

    • Declare the component in an XML screen descriptor:

      <upload id="uploadField"
              fileStoragePutMode="MANUAL"/>
  • In the screen controller, inject the component itself, the FileUploadingAPI and DataSupplier interfaces. In the init() method, add listeners which will react on successful uploads and errors:

    @Inject
    private FileUploadField uploadField;
    @Inject
    private FileUploadingAPI fileUploadingAPI;
    @Inject
    private DataSupplier dataSupplier;
    
    @Override
    public void init(Map<String, Object> params) {
        uploadField.addFileUploadSucceedListener(event -> {
            FileDescriptor fd = uploadField.getFileDescriptor();
            try {
                // save file to FileStorage
                fileUploadingAPI.putFileIntoStorage(uploadField.getFileId(), fd);
            } catch (FileStorageException e) {
                throw new RuntimeException("Error saving file to FileStorage", e);
            }
            // save file descriptor to database
            dataSupplier.commit(fd);
            showNotification("Uploaded file: " + uploadField.getFileName(), NotificationType.HUMANIZED);
        });
    
        uploadField.addFileUploadErrorListener(event ->
                showNotification("File upload error", NotificationType.HUMANIZED));
    }

    The component will upload the file to the temporary storage of the client tier and invoke the listener added by the addFileUploadSucceedListener() method. In this listener, a FileDescriptor object is requested from the component. com.haulmont.cuba.core.entity.FileDescriptor is a persistent entity, which uniquely identifies an uploaded file and is used to download the file from the system.

    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. Both of these parameters are provided by FileUploadField.

    After uploading the file to FileStorage, the FileDescriptor instance is saved in the database by invoking DataSupplier.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 AdministrationExternal Files screen.

    The listener added by the addFileUploadErrorListener() method will be invoked if an error occurs when uploading a file to the temporary storage of the client tier.

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

    • AfterValueClearListener,

    • BeforeValueClearListener,

    • FileUploadErrorListener,

    • FileUploadFinishListener

    • FileUploadStartListener,

    • FileUploadSucceedListener,

    • ValueChangeListener.

  • The fileStoragePutMode XML attribute defines how the file and the corresponding FileDescriptor are stored. In the IMMEDIATE mode it is done right after uploading file to the temporary storage of the client tier. In the MANUAL mode, you should do it programmatically in a FileUploadSucceedListener. The IMMEDIATE mode is selected by default when FileUploadField is used inside FieldGroup. Otherwise, the default mode is MANUAL.

  • The uploadButtonCaption, uploadButtonIcon and uploadButtonDescription XML attributes allows you to set the properties of the upload button.

  • The showClearButton XML attribute controls whether the clear button is visible. It is false by default.

  • The clearButtonCaption, clearButtonIcon and clearButtonDescription XML attributes allows you to set the properties of the clear button if it is visible.

  • 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.

  • 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.

  • The fileSizeLimit XML attribute (and the corresponding setFileSizeLimit() method) can be used to set maximum allowed file size specified in bytes.

    <upload id="uploadField" fileSizeLimit="2000"/>
  • The permittedExtensions XML attribute (and the corresponding setPermittedExtensions() method) can be used to set permitted extensions of uploaded files. If the attribute is set, users will not be able to upload files with not permitted extensions.

    The value of the attribute should be a comma-separated list of extensions with leading dots. For example: .jpg,.jpeg,.png,.gif.

  • 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. The dropZone can cover the whole layout of a dialog window. The selected container is highlighted when a user drags a file over the container, otherwise it is not visible.

    <layout spacing="true"
            width="100%">
        <vbox id="dropZone"
              height="AUTO"
              spacing="true">
            <textField id="textField"
                       caption="Title"
                       width="100%"/>
            <textArea id="textArea"
                      caption="Description"
                      width="100%"
                      rows="5"/>
            <checkBox caption="Is reference document"
                      width="100%"/>
            <upload id="upload"
                    dropZone="dropZone"
                    showClearButton="true"
                    showFileName="true"/>
        </vbox>
        <hbox spacing="true">
            <button caption="mainMsg://actions.Apply"/>
            <button caption="mainMsg://actions.Cancel"/>
        </hbox>
    </layout>
    gui dropZone

    To make a dropZone static and display it permanently, assign the predefined dropzone-container style to its container. In this case the container should be empty with only the label component inside:

    <layout spacing="true"
            width="100%">
        <textField id="textField"
                   caption="Title"
                   width="100%"/>
        <checkBox caption="Is reference document"
                  width="100%"/>
        <upload id="upload"
                dropZone="dropZone"
                showClearButton="true"
                showFileName="true"/>
        <vbox id="dropZone"
              height="150px"
              spacing="true"
              stylename="dropzone-container">
            <label stylename="dropzone-description"
                   value="Drop file here"
                   align="MIDDLE_CENTER"/>
        </vbox>
        <hbox spacing="true">
            <button caption="mainMsg://actions.Apply"/>
            <button caption="mainMsg://actions.Cancel"/>
        </hbox>
    </layout>
    gui dropZone static

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