Limiting the number of uploaded files

From pmusers
Jump to: navigation, search

The MultipleFile control which is labeled as "uploadfile" in the DynaForm Designer does not have a property to limit the minimum and maximum number of uploaded files. The first programming example shows how to set a fixed minimum and maximum number of files that can uploaded in a MultipleFile control. The second example shows how to dynamically change the number of uploaded files and the allowed file types.

Setting a fixed minimum and maximum number of uploaded files


DynaForm: Set min and max uploaded files.json (right click and select Save link as)
Author: Amos Batto (amos@processmaker.com)
Version: 1.0 (2018-11-12)
Tested in: ProcessMaker 3.3 Community in Debian 9.5 with Firefox 52


Create a DynaForm which has a MultipleFile control with the ID "filesForCase":

MultipleFile-MaxAndMinFilesInDesigner.png

In this example, the MultipleFile control needs to have a minimum of 3 and a maximum of 4 uploaded files. When the form is submitted, the setOnSubmit() event handler will check how many files were uploaded to the form. If it doesn't find the right number of uploaded files, which are listed in the $("#multiple-file-id").getInfo().fileCollection.models[index] array, then the event handler will display an error message to the user and prevent the submission of the Dynaform by returning false.

Add the following JavaScript to the DynaForm:

var multiFileId = 'filesForCase';  //set to ID of MultipleFile field
var minFiles = 3;                  //set to minimum number of uploaded files
var maxFiles = 4;                  //set to maximum number of uploaded files

var formId = $("form").prop("id");

$("#"+formId).setOnSubmit( function() {
  var aFiles = $("#"+multiFileId).getInfo().fileCollection;
  var validFileCount = 0;
  
  for (i=0; i < aFiles.length; i++) {
    var filename = aFiles.models[i].attributes.file.name;
    
    if (!aFiles.models[i].attributes.isValid) {
      alert("Error: file "+filename+" is invalid. Delete it.");
      return false;
    }
     
    validFileCount++;
  }
  
  if (validFileCount < minFiles) {
    alert("Only "+validFileCount+" files were uploaded.\nA minimum of "+minFiles+" files are needed.");
    return false;
  } 
  if (validFileCount > maxFiles) {
    alert("The "+validFileCount+" files uploaded exceeds the maximum of "+maxFiles+" allowed files.\n"+
          "Please delete some files.");
    return false;
  }
})

The code loops through the fileCollection to count the files and check that that each file is valid (correctly uploaded and the right type) and displays an error message to the user if it isn't valid. Then it displays an alert() message to the user if the number of uploaded files is outside the minimum and maximum number of allowed files.

If too few files are uploaded, the following error message is displayed:

MultipleFile-TooFewFilesAlert.png

If too many files are uploaded, then the following error is displayed:

MultipleFile-TooManyFilesAlert.png

The form can only be submitted if the file count is between the minimum of 3 and the maximum of 4:

MultipleFile--AllowedToSubmit.png

Validating a variable number of uploaded files and the file type

This example shows how to force the user to upload a variable number of files selected by a field in the DynaForm. It also verifies that the file is one of the file types selected in a checkgroup in the same Dynaform.


DynaForm: Validate files in MultipleFile field.json (right click and select Save link as)
Author: Amos Batto (amos@processmaker.com)
Version: 1.0 (2018-11-12)
Tested in: ProcessMaker 3.3 Community in Debian 9.5 with Firefox 52


First, create the following DynaForm:

MultipleFile-ValidateFilesInDesigner.png

This form has the following fields:

  • Dropdown with the ID "numberOfFiles" to select the number of allowed files to be uploaded,
  • Checkgroup with the ID "typesOfFiles" to select the allowed file types, which are in the list of options:
    MultipleFile-FileTypesOptions.png
  • MultipleFile with the ID "filesForCase" to upload files for the case.

Then, add the following JavaScript to the DynaForm:

var multiFileId = 'filesForCase';
var formId = $("form").prop("id");


var multiFileId = 'filesForCase';
var formId = $("form").prop("id");

$("#"+formId).setOnSubmit( function() {
  var validFileCount = 0;
  var nRequiredFiles = parseInt( $("#numberOfFiles").getValue() );
  var aFileTypes = $("#typesOfFiles").getValue();
  var aFiles = $("#"+multiFileId).getInfo().fileCollection
  
  for (i=0; i < aFiles.length; i++) {
    var filename = aFiles.models[i].attributes.file.name;
    var ext = filename.match(/\.[a-z0-9]{0,8}$/);
    if (ext) {
      ext = ext[0];
    }
    
    if (ext === null || aFileTypes.indexOf(ext) == -1) {
      alert("Error: file "+filename+" doesn't have a permitted file type.\nDelete it and upload it again.");
      return false;   
    }
    
    if (!aFiles.models[i].attributes.isValid) {
      alert("Error: file "+filename+" is invalid. Delete it.");
      return false;
    }
        
    validFileCount++;
  }
  
  if (validFileCount != nRequiredFiles) {
    alert(nRequiredFiles+" files need to be uploaded. You have "+validFileCount+" files.")
    return false;
  } 
})

Like in the previous programming example, the number of files in the fileCollection is checked when the form is submitted. It checks the extension of the uploaded filename to determine the file type. A more reliable way to check the file type is to look at the file's MIME type which is stored at $("#multiple-file-id").getInfo().fileCollection.models[index].attributes.file.type, but this information is only available if the file was just uploaded in the current form.

If all the files in the MultipleFile control were just uploaded the following code can be used to verify the file type:

    var mimeType = aFiles.models[i].attributes.file.type;
    if (aFileTypes.indexOf(mimeType) == -1) { 
      alert("Error: file "+filename+" doesn't have a permitted file type.\nDelete it and upload it again.");
      return false;   
    }