Skip to content
Davit Barbakadze edited this page Sep 8, 2013 · 15 revisions

Table of Contents

### Introduction

Plupload comes with a number of built-in filters that provide a way to restrict selection of files to those that meet specific requirements.

These are:

  • mime_types - a way to constrain file dialog to only specific file types,
  • max_file_size - do not let files of size larger than the maximum to the queue, and
  • prevent_duplicates - ignore files of the same name and size.

Here is the typical usage case:

filters: {
	mime_types : [
		{ title : "Image files", extensions : "jpg,gif,png" },
		{ title : "Zip files", extensions : "zip" }
	],
	max_file_size: "200mb",
	prevent_duplicates: true
}

However you might need - more! For example, restrict files by minimum size, or something even more fancier, like not allowing images that exceed specific resolution, etc. For this purpose (starting from version 2) we provide a way to define additional file filters, via a dedicated static method: plupload.addFileFilter().

### plupload.addFileFilter()

The truth is that plupload.addFileFilter() is used by the Plupload itself to define its internal file filters. For example this is how a definition for the max_file_size looks like:

plupload.addFileFilter('max_file_size', function(maxSize, file, cb) {
	var undef;

	// Invalid file size
	if (file.size !== undef && maxSize && file.size > maxSize) {
		this.trigger('Error', {
			code : plupload.FILE_SIZE_ERROR,
			message : plupload.translate('File size error.'),
			file : file
		});
		cb(false);
	} else {
		cb(true);
	}
}); 

And this is how you use it in your config:

filters: {
        max_file_size: "200mb"
}

As you see a logic is pretty simple there - the callback for the filter receives three arguments:

  • maxSize - the value from the config (in the case above - 200mb)
  • file - the file object that is being filtered
  • cb - the callback which the filter must invoke once it comes up with the check result

Additionally you have access to all the files that are already present in the queue, via this.files, because the callback is invoked in the context of the current uploader instance.

As you've probably noticed, filter is asynchronous. This is done because the check for requirements might include some asynchronous operations, like AJAX request or preloading the image (check Example: max_img_resolution below).

You can do all kind of checks on the file object and return true if it meets the requirements and false if it - doesn't. If you return false the file will be filtered out and won't be added to the queue, although we still fire the Error event with an appropriate error code and message - just in case someone wants to know if file was added or - no and - why.

Once you define the filter every consequent Plupload instance on the page will be able to use it. You can even store it in a separate js file and include after Plupload.

### Example: min_file_size

For example let's create a filter that will not allow files to the queue if they are smaller than a specific size. We'll name it - min_file_size:

plupload.addFileFilter('min_file_size', function(minSize, file, cb) {
	var undef;

	// Invalid file size
	if (file.size !== undef && minSize && file.size < minSize) {
		this.trigger('Error', {
			code : plupload.FILE_SIZE_ERROR,
			message : plupload.translate('File size error.'),
			file : file
		});
		cb(false);
	} else {
		cb(true);
	}
}); 

I bet, by now you could have come up with something like this yourself, but anyway - let's now apply our new filter in the config:

filters: {
        min_file_size: "100kb"
}

From now on every file that is smaller than 100kb will be filtered out.

### Example: max_img_resolution

As we've mentioned above, filters are asynchronous, but from the example above it is not clear why this might even come in handy. So let's try something more "complicated". Let's filter out the images for example depending on whether they exceed the specified resolution:

plupload.addFileFilter('max_img_resolution', function(maxRes, file, cb) {
	var self = this, img = new o.Image();

	function finalize(result) {
		// cleanup
		img.destroy();
		img = null;

		// if rule has been violated in one way or another, trigger an error
		if (!result) {
			self.trigger('Error', {
				code : plupload.IMAGE_DIMENSIONS_ERROR,
				message : "Resolution exceeds the allowed limit of " + maxRes  + " pixels.",
				file : file
			});
			
		}
		cb(result);
	}

	img.onload = function() {
		// check if resolution cap is not exceeded
		finalize(img.width * img.height < maxRes);
	};

	img.onerror = function() {
		finalize(false);
	};

	img.load(file.getSource());
});

Image preloading is an asynchronous operation. We do not know when it will finish loading, so we listen to the events and resolve the filter once we have it. Let's enable the filter in the config now:

filters: {
        max_img_resolution: 1000000 // 1MP = 1 million pixels
}