multiple-file-upload-reactive
Reactive icon

Reactive Multiple File Upload

icon_trusted
Stable version 2.0.2 (Compatible with OutSystems 11)
Uploaded
 on 11 August 2022
 by 
4.7
 (15 ratings)
multiple-file-upload-reactive

Reactive Multiple File Upload

Documentation
2.0.2


With this component, you can choose between 2 different ways to interact with the uploaded files:

  1. You can use a simple upload widget, FileUpload_BinaryData, that returns the uploaded Binary Files so that you can manage them on your own;
  2. Or you can use a widget that manages all the heavy lifting of the uploading part for you with a temporary table, MultipleFileUpload.


Use case 1 - You want to manage the files on your own

In this case, you'll need the FileUpload_BinaryData widget. To use it, simply put it on your page like this:

This widget has the following inputs:

  • FileType (Text) - List of accepted file types (Eg. "image/*,.pdf"). Please find more details here.
  • MaxFileSize (Long Integer) - Maximum file size in bytes (e.g., 1 MB = 1,048,576 B). Files larger than this will be ignored and the OnFileUploadError event will be triggered. All other files will still be uploaded.
  • MaxNumberOfFiles (Integer)- Number of files that can be uploaded at once. The input 0 (zero) will be ignored; instead, use the input IsEnabled to enable or disable uploading files. Please be aware that the user can upload some files, and after the upload is done, upload some more by clicking on the widget again. The MaxNumberOfFiles limit only takes into consideration one upload session at a time. If you want to limit the number of files overall, please use the IsEnabled input in conjunction with a count on your side.
  • IsEnabled (Boolean) - Controls if the input accepts files or not. True if the input should be enabled, False otherwise.


This widget has the following events:

  • OnUploadStart - Triggered when the files start to be uploaded. You can use this event to enable animations.
  • OnFileUpload - Triggered when a file has been uploaded. The event has the following inputs 
    • FileName (Text) - Name of the file uploaded by the user (Eg. "footer-icon-instagram.png");
    • FileSize (Long Integer) - Size of the uploaded file in bytes;
    • FileMimeType (Text) - Type of the file. (Eg. "image/jpeg");
    • FileBinaryData (Binary Data) - Uploaded file;
    • NumberOfFilesToUpload (Integer) - Total number of files uploaded by the user. You can use this value to know if all the files have been uploaded and disable some type of loading animation;
  • OnFileUploadError- Triggered when there is an error uploading a file. The rest of the files will still be uploaded. This event has the following inputs:
    • FileName (Text) - Name of the file uploaded by the user (Eg. "footer-icon-instagram.png");
    • FileSize (Long Integer) - Size of the uploaded file in bytes;
    • GenericErrorMessage (Text) - Message regarding the type of error. (Eg. "The file is too large" or "Uploading files is disabled");


To help you use this component, we developed a loading animation widget called LoadingAnimation. If you need, you can enable the animation via its only input IsLoading.


We also developed a Client Action called BytesToSize which you can use to convert the number of bites into a readable string like "3 KB", "476 Bytes", "2 MB" etc. This action has a single input, Bytes, which takes in the number of bites, like returned in the OnFileUpload event, and a single output ConvertedSize with the converted string like described above.



Use case 2 - You want the files to be managed and uploaded by the component with a temporary table:


In this case, you'll need the MultipleFileUpload widget. To use it, simply put it on your page like this:


This widget works in conjunction with the temporary tables found on the Module MultipleFileUploadReactive_Lib. CRUD actions for these tables are also present there. Please find more information about this later in this document.

When a file is uploaded, it is stored on a temporary table, from which you can fetch the file or refer to it in your own app.


This widget has the following inputs:

  • FileType (Text) - List of accepted file types (Eg. "image/*,.pdf"). Please find more details here.
  • MaxFileSize (Long Integer) - Maximum file size in bytes (eg. 1 MB = 1,048,576 B). Files larger than this will be ignored and the OnFileUploadError event will be triggered. All other files will still be uploaded.
  • MaxNumberOfFiles (Integer)- Number of files that can be uploaded at once. The input 0 (zero) will be ignored; instead use the input IsEnabled to enable or disable uploading files. Please be aware that the user can upload some files and after the upload is done, upload some more by clicking on the widget again. The MaxNumberOfFiles limit only takes into consideration one upload session at a time. If you want to limit the number of files overall, please use the IsEnabled input in conjunction with a count on your side.
  • IsEnabled (Boolean) - Controls if the input accepts files or not. True if the input should be enabled, False otherwise.


This widget has the following events:

  • OnFilesListUpdate - Triggered when a file as been uploaded. The event as the following input: 
    • FileId (Long Integer) - Id of the uploaded file in the FileMetadata table found in the Module MultipleFileUpload_Lib;
  • OnUploadError - Triggered when there is an error uploading a file. The rest of the files will still be uploaded. This event has the following inputs:
    • FileName (Text) - Name of the file uploaded by the user (Eg. "footer-icon-instagram.png");
    • FileSize (Long Integer) - Size of the uploaded file in bytes;
    • GenericErrorMessage (Text) - Message regarding the type of error. (Eg. "The file is too large" or "Uploading files is disabled");
  • OnFileDelete- Triggered when the user removes one of his uploaded files. The event has the following input:
    • FileId (Long Integer) - Id of the deleted file in the FileMetadata table found in the Module MultipleFileUpload_Lib;
  • OnFilesListDelete - Triggered when the user removes all uploaded files. The event has the following input:
    • FileIdsList (Long Integer List) - List of Ids of the deleted files in the FileMetadata table found in the Module MultipleFileUpload_Lib;
  • OnDeleteError - Triggered when an error occurs while the user is trying to remove a file from his uploads


All uploaded files using this widget are stored on the table FileMetadata and its extension table BinaryFile, both found on the Module MultipleFileUpload_Lib. The tables look as follows:

By default, a timer runs every day at 1 AM that deletes all files older than 60 minutes, as you can see below:


You can adjust the time and frequency at which this timer runs.

You can also adjust the time span, which determines what files are deleted, by changing the Site Property DeleteTimeSpan, which gets a value in minutes that is 60 minutes by default.


To access the uploaded files, you can Query the tables or use the Service Action GetFileById, which takes in the FileId and returns the following:

  • File- Structure with all data about the file:
    • FileName (Text) - Name of the file uploaded by the user (Eg. "footer-icon-instagram.png");
    • FileSize (Long Integer) - Size of the uploaded file in bytes;
    • FileMimeType (Text) - Type of the file. (Eg. "image/jpeg");
    • FileBinaryData (Binary Data) - Uploaded file;
  • GenericResponse- Structure with Error information:
    • HasError (Boolean) - True if an error occurred;
    • ErrorMessage (Text) - Error message if an error occurred (Eg. "Unable to retrieve file");

 

On our backlog:

  • MaxNumberOfFiles consider all files uploaded and not just one session at a time;
  • Add NumberOfFilesToUpload to the OnUploadStart event instead of the OnFileUpload event;
  • Naming convention changes


Instructions for the demo:

Multiple File Upload

1. Make Sure the component is available in your application

Download and install the component on your environment, and manage your dependencies; you should have access to the web blocks on the _CW module and two Entities and service actions on the _Lib Module. Make sure they are all available for you to use.

Make sure you manage your dependencies so the component is available.


2. Use the Multiple File Upload available web block

Drag and drop the MultipleFileUpload widget to your screen; the web block will ask you to define four parameters and five event handlers for its triggers:

FileType (Mandatory) - Specify with a string the type of files you want to upload to your DB (Ex: "image/*, .pdf"). More info here.

MaxFileSize - Specify the max size possible for uploading a file (in bytes).

MaxNumberOfFiles - The maximum number of files that can be uploaded at one given time.

IsEnable - Boolean to activate or deactivate the deactivate feature, create logic in your application around it (True by default).


While using this component. You will always have to fill in these mandatory fields.


3. Define actions for handling the web block triggers.

This web block is designed to send multiple files that you choose to its two entities (BinaryFile and FileMetadata). This logic is encapsulated on the web block. After that, the block triggers to notify its parent (screen) what actions to take: this is why we have to define these event handlers (OnFileDelete, onFileListDelete, and OnFileListUpdate being mandatory). Define screen actions to deal with these triggers (e.g., the demo creates an extra entity that references these two entities that work with the block, so when a user uploads files or deletes them, the handler must have the CRUD action of the extra entity so they can delete or update files accordingly).

Entities used by the component (make sure you have them available).



Example of a screen action to handle the OnFilesListUpdate trigger, notice the CRUD action to update files in other entities besides the web block entities. Manage this logic as you want.


Multiple File Upload Binary

This block allows you to get the binary files and manage the upload on your own application without storing them on this component's temporary table.

1. Make Sure the component is available in your application

Download and install the component on your environment, and manage your dependencies; you should have access to the web blocks on the _CW module and two Entities and service actions on the _Lib Module. Make sure they are all available for you to use.

Make sure you manage your dependencies so the component is available.


2. Use the Multiple File Upload Binary available web block

Drag and drop the FileUpload_BinaryData widget to your screen; the web block will ask you to define four parameters and three event handlers for its triggers:

FileType (Mandatory) - Specify with a string the type of files you want to upload to your DB (Ex: "image/*, .pdf").

MaxFileSize - Specify the max size possible for uploading a file (in bytes).

MaxNumberOfFiles - The maximum number of files that can be uploaded at one given time.

IsEnable - Boolean to activate or deactivate the upload feature. (True by default).


3. Define actions for handling the web block triggers.

We need to define the actions that will activate when the web block triggers; in this case, we need to define what happens when we start to upload a file or when an error occurs. In the demo case, we are simply adding the binary files to a List of type Binary Data List, so the action to deal with the upload trigger will do an append to that list.


Example of an action flow to deal with the OnFileUpload trigger


4. Implement a loading feature

This component comes with an extra web block called LoadingAnimation; in the case of the FileUpload_Binary, it is not incorporated with the component as it is with the MultipleFileUpload so you need to :

Drag and drop the LoadingAnimation to your screen, filling the isLoading mandatory input with a boolean variable set to false as default.

In the handler of the OnUploadStart event, change the isLoading boolean to true, and set the NumberOfUploadedFiles to 0.


Now that the animation is visible, we must stop it as soon as the last upload finishes. This should be done with an assignment on the action that handles the OnFileUpload trigger.