How to Limit Attachments by Type, Size, or Quantity

You may wish to enforce that only a certain type or size of file is uploaded into an attachment field. This can be done by using validation constraints.

Note: As with all validation actions, validation constraints are used during submit to validate the form. If you wish to perform these actions on change or on blur, you can create events or code for that using the same condition you would put in the validation constraint. You could also leverage K('form').validate() on change to use the validation constraints on change.

  1. Select your attachment field and expand the Validation section.

attachmentsvalidation1

  1. Set the Custom Constraint value to Enabled.

blankvalidationconstraint

  1. Once you have Enabled the Custom Constraint, you will see the Expression and Message fields. This is where you will enter the necessary details to restrict your attachment(s).

attachmentconstraintsblank

Say you are expecting a specific spreadsheet be uploaded. To allow only XLS attachments enter the following in the Expression field:

    value.filter(function(item) { return !item.name.match(/\.xls$/i) }).length === 0

Enter your own custom Message into the Message field such as:

Please upload only .xls spreadsheets into this field.

The expression works like this: filter the values of this field. If any of the item names don’t end in xls (case insensitive), fail the condition.

The JavaScript function match uses regular expressions, so if you wanted to check for .xls OR .xlsx files, you would use:

    value.filter(function(item) { return !item.name.match(/\.xls(x)*$/i) }).length === 0

If you want to allow for .xls, .xlsx, .doc, or .docx, you would use this:

    value.filter(function(item) { return !item.name.match(/\.(xls(x)*|doc(x)*)$/i) }).length === 0

Here is a similar constraint to not allow files over 5 MB. Note that the file size is represented in bytes, but the logic is essentially the same.

    value.filter(function(item) { return item.size > 5242880 }).length === 0

So if you wanted to allow .xls, .xlsx, .doc, or .docx files under 5 MB, the expression would just be:

    value.filter(function(item) { return !item.name.match(/\.(xls(x)*|doc(x)*)$/i) }).length === 0 && value.filter(function(item) { return item.size > 5242880 }).length === 0

Now, you may have noticed this wonderful feature that allows users to upload multiple attachments into one field.

attachmentdetailsmultiple

This means that you don’t have to know in advance exactly how many attachments are appropriate or show lots of additional attachments fields when a few are needed but not necessarily all of them.

This feature does not affect the use of the above constraints at all, but it does add a new possibility. Let's say you want to allow up to 3 files maximum. You can do this with constraints as well. For attachments, the answer is going to contain all of the attachments and you can check it’s size. So the constraint expression to allow a maximum of 3 files would be:

    value.length < 4

Similarly, if you must have 2 logs uploaded, you can require at least 2 files:

    value.length > 1

Putting a few of these constraints together, you could require at least 2 files with extenstion .log:

    value.length > 1 && value.filter(function(item) { return !item.name.match(/\.log$/i) }).length === 0