File validation

Validator is just a function that receives fileInfo object for each uploaded file and should throw exception if file does not meet requirements. The simplest validatior can look like this:

widget.validators.push(function(fileInfo) {
  if (fileInfo.size !== null && fileInfo.size > 1024 * 1024) {
    throw new Error("fileMaximumSize");
  }
});

It is better to wrap validators in function which receives all constants. Such validators can be reused with different widgets.

function maxFileSize(size) {
  return function(fileInfo) {
    if (fileInfo.size !== null && fileInfo.size > size) {
      throw new Error("fileMaximumSize");
    }
  };
}
// limit file size to 1 MB
widget1.validators.push(maxFileSize(1024 * 1024));
// limit file size to 2 MB
widget2.validators.push(maxFileSize(2 * 1024 * 1024));

Another step that can be taken is automatic validation based on data attributes of input element. For example if widget has data-max-size, maxFileSize validatior can be added.

$(function() {
  $('[role=uploadcare-uploader][data-max-size]').each(function() {
    var widget = uploadcare.Widget(this);
    widget.validators.push(maxFileSize($(this).data('maxSize')));
  });
});

There are some common validation cases which you may want.

Limit File Size

This example shows how to add validation for both minimal and maximal file size. Validator will be automatically added to each widget with custom attributes data-min-size and data-max-size.

function fileSizeLimit(min, max) {
  return function(fileInfo) {
    if (fileInfo.size === null) {
      return;
    }
    if (min && fileInfo.size < min) {
      throw new Error("fileMinimalSize");
    }
    if (max && fileInfo.size > max) {
      throw new Error("fileMaximumSize");
    }
  };
}
$(function() {
  $('[role=uploadcare-uploader]').each(function() {
    var input = $(this);
    if ( ! input.data('minSize') && ! input.data('maxSize')) {
      return;
    }
    var widget = uploadcare.Widget(input);
    widget.validators.push(fileSizeLimit(input.data('minSize'),
                                         input.data('maxSize')));
  });
});
  
UPLOADCARE_LOCALE_TRANSLATIONS = {
  // messages for widget
  errors: {
    'fileMinimalSize': 'File is too small',
    'fileMaximumSize': 'File is too large'
  },
  // messages for dialog’s error page
  dialog: { tabs: { preview: { error: {
    'fileMinimalSize': {
      title: 'Title.',
      text: 'Text.',
      back: 'Back'
    },
    'fileMaximumSize': {
      title: 'Title.',
      text: 'Text.',
      back: 'Back'
    }
  } } } }
};
  
<p>
  <code>data-min-size="102400"</code><br>
  <input type="hidden" role="uploadcare-uploader" data-min-size="102400">
</p>
<p>
  <code>data-max-size="1048576"</code><br>
  <input type="hidden" role="uploadcare-uploader" data-max-size="1048576">
</p>
<p>
  <code>data-multiple="true" data-min-size="102400" data-max-size="1048576"</code><br>
  <input type="hidden" role="uploadcare-uploader" data-multiple="true" data-min-size="102400" data-max-size="1048576">
</p>
  

data-min-size="102400"

data-max-size="1048576"

data-multiple="true" data-min-size="102400" data-max-size="1048576"

Restrict File Type

fileTypeLimit is another validator which is added to widgets with data-file-types attribute. Value is space-separated list of allowed files extensions.

function fileTypeLimit(types) {
  types = types.split(' ');
  return function(fileInfo) {
    if (fileInfo.name === null) {
      return;
    }
    var extension = fileInfo.name.split('.').pop();
    if (types.indexOf(extension) == -1) {
      throw new Error("fileType");
    }
  };
}
$(function() {
  $('[role=uploadcare-uploader][data-file-types]').each(function() {
    var input = $(this);
    var widget = uploadcare.Widget(input);
    widget.validators.push(fileTypeLimit(input.data('file-types')));
  });
});
  
UPLOADCARE_LOCALE_TRANSLATIONS = {
  // messages for widget
  errors: {
    'fileType': 'This type of files is not allowed.'
  },
  // messages for dialog’s error page
  dialog: { tabs: { preview: { error: {
    'fileType': {
      title: 'Title.',
      text: 'Text.',
      back: 'Back'
    }
  } } } }
};
  
<p>
  <code>data-file-types="pdf doc docx"</code><br>
  <input type="hidden" role="uploadcare-uploader" data-file-types="pdf doc docx">
</p>
<p>
  <code>data-file-types="avi mp4 ogv mov"</code><br>
  <input type="hidden" role="uploadcare-uploader" data-file-types="avi mp4 ogv mov">
</p>
  

data-file-types="pdf doc docx"

data-file-types="avi mp4 ogv mov"

Image Dimensions

For images you can define maxDimensions validator which will be added to widgets with data-max-width or data-max-height attributes. Please note that maxDimensions checks dimensions only for images and accepts files that are not images. It can be combined with data-images-only attribute to change this.

function maxDimensions(width, height) {
  return function(fileInfo) {
    var imageInfo = fileInfo.originalImageInfo;
    if (imageInfo === null) {
      return;
    }
    var heightExceeded = height && imageInfo.height > height;
    if (width && imageInfo.width > width) {
      if (heightExceeded) {
        throw new Error('maxDimensions');
      } else {
        throw new Error('maxWidth');
      }
    }
    if (heightExceeded) {
      throw new Error('maxHeight');
    }
  };
}
$(function() {
  $('[role=uploadcare-uploader]').each(function() {
    var input = $(this);
    if ( ! input.data('maxWidth') && ! input.data('maxHeight')) {
      return;
    }
    var widget = uploadcare.Widget(input);
    widget.validators.push(maxDimensions(input.data('maxWidth'),
                                         input.data('maxHeight')));
  });
});
  
UPLOADCARE_LOCALE_TRANSLATIONS = {
  // messages for widget
  errors: {
    'maxDimensions': 'This image exceeds max dimensions.',
    'maxWidth': 'This image exceeds max width.',
    'maxHeight': 'This image exceeds max height.'
  },
  // messages for dialog’s error page
  dialog: { tabs: { preview: { error: {
    'maxDimensions': {
      title: 'Title.',
      text: 'Text.',
      back: 'Back'
    },
    'maxWidth': {
      title: 'Title.',
      text: 'Text.',
      back: 'Back'
    },
    'maxHeight': {
      title: 'Title.',
      text: 'Text.',
      back: 'Back'
    }
  } } } }
};
  
<p>
  <code>data-max-width="1024" data-max-height="1024"</code><br>
  <input type="hidden" role="uploadcare-uploader" data-max-width="1024" data-max-height="1024">
</p>
<p>
  <code>data-images-only="true" data-max-width="1024" data-max-height="1024"</code><br>
  <input type="hidden" role="uploadcare-uploader" data-images-only="true" data-max-width="1024" data-max-height="1024">
</p>
  

data-max-width="1024" data-max-height="1024"

data-images-only="true" data-max-width="1024" data-max-height="1024"

Image Orientation

This validator will deny landscape images with data-portrait-only="true" attribute and portrait images with data-landscape-only="true" attribute. There is no sense in setting both attributes on same widget.

function imageOrientation(portrait) {
  return function(fileInfo) {
    var imageInfo = fileInfo.originalImageInfo;
    if (imageInfo === null || imageInfo.width == imageInfo.height) {
      return;
    }
    if (imageInfo.width < imageInfo.height != portrait) {
      throw new Error(portrait ? 'landscape' : 'portrait');
    }
  }
}
$(function() {
  $('[role=uploadcare-uploader]').each(function() {
    var input = $(this);
    if ( ! input.data('portraitOnly') && ! input.data('landscapeOnly')) {
      return;
    }
    var widget = uploadcare.Widget(input);
    widget.validators.push(imageOrientation(!! input.data('portraitOnly')));
  });
});
  
UPLOADCARE_LOCALE_TRANSLATIONS = {
  // messages for widget
  errors: {
    'portrait': 'This image exceeds max dimensions.',
    'landscape': 'This image exceeds max width.'
  },
  // messages for dialog’s error page
  dialog: { tabs: { preview: { error: {
    'portrait': {
      title: 'Title.',
      text: 'Text.',
      back: 'Back'
    },
    'landscape': {
      title: 'Title.',
      text: 'Text.',
      back: 'Back'
    }
  } } } }
};
  
<p>
  <code>data-portrait-only="true"</code><br>
  <input type="hidden" role="uploadcare-uploader" data-portrait-only="true">
</p>
<p>
  <code>data-landscape-only="true"</code><br>
  <input type="hidden" role="uploadcare-uploader" data-landscape-only="true">
</p>
  

data-portrait-only="true"

data-landscape-only="true"

Questions?

We're always happy to help with code or other questions you might have! Search our site for more information or send us an email!