Home

Awesome

jQuery Fancy File Uploader

A jQuery plugin to convert the HTML file input type into a mobile-friendly fancy file uploader. Choose from a MIT or LGPL license.

Also available in FlexForms Modules.

Screenshot

Live demo via Admin Pack (This plugin is located near the bottom of that page.)

Also used by Cool File Transfer.

Donate Discord

Features

Alternate Options

jQuery Fancy File Uploader just handles uploading of files in an environment where you plan to apply strict storage controls. However, if you need something even fancier, here are a couple of options:

If you need a general-purpose hierarchical file management and tabbed file editor solution that can be readily embedded into existing software products, check out the open source CubicleSoft PHP File Manager and Editor application.

If you need something even more powerful, flexible, and highly customizable with hierarchical directory and file structures, check out the open source CubicleSoft Folder and File Explorer zero-dependencies Javascript widget.

Getting Started

jQuery is required to use this software so hopefully that doesn't come as a surprise to anyone. Parts of this plugin require the jQuery UI widget factory. If you are already including jQuery UI on your webpage, then you already have the widget factory and don't need to do anything else. Otherwise, add this line after including jQuery:

<script type="text/javascript" src="fancy-file-uploader/jquery.ui.widget.js"></script>

Now you can include Fancy File Uploader:

<link rel="stylesheet" href="fancy-file-uploader/fancy_fileupload.css" type="text/css" media="all" />
<script type="text/javascript" src="fancy-file-uploader/jquery.fileupload.js"></script>
<script type="text/javascript" src="fancy-file-uploader/jquery.iframe-transport.js"></script>
<script type="text/javascript" src="fancy-file-uploader/jquery.fancy-fileupload.js"></script>

Let's say you have a file input element somewhere on the same page that looks like:

<input id="thefiles" type="file" name="files" accept=".jpg, .png, image/jpeg, image/png" multiple>

To transform that file input into something fancy, pass in some options to the plugin and let the magic happen:

<script type="text/javascript">
$(function() {
	$('#thefiles').FancyFileUpload({
		params : {
			action : 'fileuploader'
		},
		maxfilesize : 1000000
	});
});
</script>

Other than handling the files on the server side of things and leveraging the various callbacks, that's pretty much it for basic usage.

Server-Side Processing

The server should reply with the following JSON object format for successful uploads:

{
	"success" : true
}

The server should reply with the following JSON object format for error conditions:

{
	"success" : false,
	"error" : "Human-readable, possibly translated error.",
	"errorcode" : "relevant_error_code"
}

See FlexForms Modules, Admin Pack, and FlexForms for example usage with open source CubicleSoft products that handle Fancy File Uploader submissions.

Fancy File Uploader works with most server-side languages. For basic server-side PHP integration with Fancy File Uploader, you can use the included server-side helper class:

<?php
	require_once "fancy_file_uploader_helper.php";

	function ModifyUploadResult(&$result, $filename, $name, $ext, $fileinfo)
	{
		// Add more information to the result here as necessary (e.g. a URL to the file that a callback uses to link to or show the file).
	}

	$options = array(
		"allowed_exts" => array("jpg", "png"),
		"filename" => __DIR__ . "/images/" . $id . ".{ext}",
//		"result_callback" => "ModifyUploadResult"
	);

	FancyFileUploaderHelper::HandleUpload("files", $options);
?>

The class also contains FancyFileUploaderHelper::GetMaxUploadFileSize(), which determines the maximum allowed file/chunk upload size that PHP allows.

When using FancyFileUploaderHelper::HandleUpload(), be sure to pass fileuploader as a parameter to the server so the FancyFileUploaderHelper class will handle the request instead of ignoring it. For example:

<script type="text/javascript">
$(function() {
	$('#thefiles').FancyFileUpload({
		params : {
			fileuploader : '1'
		},
		// ...
	});
});
</script>

Additional Examples

To automatically start every upload as soon as it is added, do something similar to this:

<script type="text/javascript">
$(function() {
	$('#thefiles').FancyFileUpload({
		params : {
			action : 'fileuploader'
		},
		edit : false,
		maxfilesize : 1000000,
		added : function(e, data) {
			// It is okay to simulate clicking the start upload button.
			this.find('.ff_fileupload_actions button.ff_fileupload_start_upload').click();
		}
	});
});
</script>

It is possible to add a button to the screen to start all of the uploads at once that are able to be started:

<button type="button" onclick="$('#thefiles').next().find('.ff_fileupload_actions button.ff_fileupload_start_upload').click(); return false;">Upload all files</button>

The specialized function data.ff_info.RemoveFile() can be used at any time to remove a file from the list which will immediately abort any upload in progress, remove the associated UI elements, and clean up internal structures:

<script type="text/javascript">
$(function() {
	var token;

	$('#thefiles').FancyFileUpload({
		params : {
			action : 'fileuploader'
		},
		maxfilesize : 1000000,
		startupload : function(SubmitUpload, e, data) {
			$.ajax({
				'url' : 'gettoken.php',
				'dataType' : 'json',
				'success' : function(tokendata) {
					token = tokendata;

					SubmitUpload();
				}
			});
		},
		continueupload : function(e, data) {
			var ts = Math.round(new Date().getTime() / 1000);

			// Alternatively, just call data.abort() or return false here to terminate the upload but leave the UI elements alone.
			if (token.expires < ts)  data.ff_info.RemoveFile();
		},
		uploadcompleted : function(e, data) {
			data.ff_info.RemoveFile();
		}
	});
});
</script>

To use chunked uploads for handling large file transfers, read up on jQuery File Upload chunked file uploads and do something like:

<script type="text/javascript">
$(function() {
	$('#thefiles').FancyFileUpload({
		params : {
			action : 'fileuploader'
		},
		fileupload : {
			maxChunkSize : 1000000
		}
	});
});
</script>

Enable the microphone and webcam/camera recording buttons:

<script type="text/javascript">
$(function() {
	$('#thefiles').FancyFileUpload({
		params : {
			action : 'fileuploader'
		},
		recordaudio : true,
		recordvideo : true
	});
});
</script>

To remove the widget altogether and restore the original file input, call: $('#thefiles').FancyFileUpload('destroy');

In order to be able to remove the widget later, data('fancy-fileupload') is used to store information alongside the object. Modifying various options after initial creation is possible but tricky. Accessing these internal options is at your own, probably minimal, risk:

Example usage to access the hidden file input element after creating it (e.g. to change its accept attribute):

<script type="text/javascript">
$('#thefiles').each(function() {
	var $this = $(this);

	// Find the associated file input.
	var fileinput = $this.data('fancy-fileupload').form.find('input[type=file]');

	// Do something with the file input.
	fileinput.attr('accept', '.png; image/png');

	$this.data('fancy-fileupload').settings.accept = ['png'];

	// Can even alter the underlying jQuery File Uploader (e.g. inject a canvas PNG blob).
	fileinput.fileupload('add', { files: [ new Blob(...) ] });
});
</script>

Options

This plugin accepts the following options:

All callbacks have a this containing the jQuery object for the current UI table row. Use the jQuery this.find(selector) syntax to locate relevant UI elements.

The default settings can be adjusted before creating any instances via $.FancyFileUpload.defaults. The most common use-case is to apply a set of translation strings to langmap.

Translations

To translate this plugin to another language, open jquery.fancy-fileupload.js in a text editor and locate strings passed to the Translate() function. In a new .js file, create a mapping between English and the target language:

$.FancyFileUpload.defaults.langmap = {
	'File is too large.  Maximum file size is {0}.': 'Translation goes here...'
};

Some strings contain {0}, {1}, etc. which are placeholders for FormatStr() to fill in. Load your .js file after loading jquery.fancy-fileupload.js.

Under the Hood

jQuery Fancy File Uploader uses the core plugin from blueimp jQuery File Upload and then wraps the core plugin up in the custom user interface that users interact with.