Custom Input File Jquery Plugin
Custom Input File is a powerful jQuery plugin that enables you to transform any input type file in your form into a friendly fully customizable file picker. Developed in javascript and HTML5, this app allows you to drag and drop multiple files at once, validate files, preview images and upload them to the server, among many other configuration options. Custom Input File also includes JQuery Jcrop Plugin to crop your pictures or to make thumbnails from them.
Custom Input File does all the work for you. In CSS you will find the simplest way to customize its appearance and, through its several configuration options, you will be able to adapt it easily to each new project. If you want to style your input files, provide greater usability to your forms or upload your files without having a headache, this amazing plugin will simplify your work.
Installation
Include JQuery js and app’s css and js files in your HTML code. Include them into <head>
or before close tag </body>
.
<!--JQuery-->
<script src="js/jquery-1.11.0.min.js"></script>
<!--JCrop (Jquery plugin for cropping images)-->
<script src="/path/js/jquery.Jcrop.min.js"></script>
<link rel="stylesheet" href="/path/css/jquery.Jcrop.min.css" type="text/css" />
<!--Custom Input File-->
<script src="/path/js/custominputfile.min.js"></script>
<link rel="stylesheet" href="/path/css/custominputfile.min.css" type="text/css" />
Document must be ready for app initalization. Also, a form and a nested input is required as basic markup. It is recommended to set form action and input id even if not required. Setting input type="file" is optional as well.
<form action="process-form.php">
<input name="input-file-1" id="input-file-1">
</form>
$(document).ready(function(e){
$('#input-file-1').customFile();
});
Configuration
Types of Pickers: images vs. all type files. Allowing and not allowing file extensions.
There are two kinds of file Picker: image file Picker and all type file Picker. Image file Picker lets you preview, crop and set proper options for selected images.
$(document).ready(function(e){
$('#input-file-1').customFile({
type : 'image' // set 'all' or just leave default settings for all-type file selector
});
});
Option type sets the kind of file Picker. It also trims file extensions allowed by app. To exclude a group of file extensions or define a limited set of them, use allowed and notAllowed. E. g.,
$('#input-file-1').customFile({
type : 'all',
notAllowed: [“exe”, “js”] // Use allowed for admitting specific ones.
});
The Image Picker. Size image validation and cropping images
Image file Picker allows you to set up minimum and maximum width and height values for images
type: 'image',
image : {
minSize : [400,300] // width, height. Default: [0,0], ie, no restrictions.
maxSize : [1080,300] // width, height. Default: [0,0], ie, no restrictions.
}
Image Picker also enables you to crop images (through Jcrop plugin). You can turn on/off cropping crop : true , set crop area size cropSize and turn on/off cropping preview area ( preview ).
type: 'image',
image : {
crop : true, // Default: false
cropSize: [320,225], // [width, height]}
preview : {
display: true, // Default: true
maxWidth: 300 // if cropSize were wider than maxWidth, only preview would be redimensioned (real crop area would not)
}
},
Once on server, you will be able to crop images or create thumbnails from form data. Form data are sent inside hidden inputs input name="your-input-file-name-x[]", input name="your-input-file-name-y[]", input name="your-input-file-name-w[]" and input name="your-input-file-name-h[]". You can read the tutorials for more information.
When image cropping option is turned on, cropSize defines minimum image size along with option minSize. If minSize is lower than cropSize, the application will only take into account cropSize width value.
Multiple files allowed vs. one by one
Set multiple: false to deactivate multiple file selection. When you turn off multiple file selection, each new file replaces the previous one, as a non HTML5 input file does.
Validating files (by amount, by weight, etc.)
Each file must pass through several validations before it is loaded completely (among which are the ones mentioned above, image size and file extension). You can set up:
allowed : 'all',// or array of allowed extensions. E.g. ["exe", "jpeg", "jpg"]
notAllowed : [], //E.g. ["exe", "jpeg", "jpg"]
maxFiles : 4, // Maximum number of files. Set 0 for no limits. Default 5
maxMB : 0, // Maximum MB for the sum of weight of files. Set 0 for no limits. Default 0
maxKBperFile: 800, // Maximum weight (in KB) for every single file. Set 0 for no limits. Default 2048
image : { // only for type: 'image'
cropSize : [320,225],
minSize : [0,0],
maxSize : [0,0]
}
Customizing error messages
Custom Input File returns an error message for each failed file validation. You can customize error messages as you wish. Next you can find every error messages: errorType, errorType, errorMaxMB , errorFileKB, errorMaxFiles , errorBigImage, errorSmallImage. Also, you can customize other error messages: errorOnReading and errorMultipleDisable ).
messages : {
errorType : 'You can’t upload this type of file',
// other messages
}
By default, popups display all apps messages. You can customize them from CSS (look for #cif-msg-wr rules). You can also deactivate autoclose or popup itself.
popup : {
active : true, // false if you don’t like popup messages
autoclose : true, // or false
delay : 10000 // delay for close (in miliseconds), of course, if autoclose is set true
},
As we shall see in event handling section, error messages can be handled in callback onError.
Customizating Item file markup and adding dynamic inputs for each item
Custom Input File enables you to customize the markup for each file item. You can include several form elements (inputs, textareas, etc.) into markup if you want to append further information about current file. Just remember to set up a name attribute for each form element.
Some file information (image itself for Image Picker or file name for All type Picker) will be added into .cif-parent node. Make sure of including this element in the markup. If you do not include it, the application will automatically generate .cif-parent wherever it judges useful.
fileWrapper : '<div class="cif-parent"></div><input type="text" name="photo_title">',
Instead of setting up a markup, you can also set up a DOM element via jQuery object to be looped in every file item.
fileWrapper : $('.my_custom_file_wrapper')
Finally, the all items container is added by default right after the input file (now replaced by the Picker). So, if you wish to specify another location in the DOM, you can do so by setting up addContainerAfter.
addContainerAfter : $('#element_before_container')
Customizing file Picker button
File Picker can be styled and a specific markup can be chosen. To custom markup, use the option configuration filePicker.
filePicker : "<h3>Custom Text</h3><div>Write what you want</div>"
CSS rules can also be edited too. Look for .cif-file-picker, .cif-file-picker:hover, .cif-file-picker.inactive, .cif-file-picker.dragover:not(.inactive) and .cif-file-picker.inactive.dragover
Handling events (callbacks)
You can handle events that are triggered during file reading. Handling events is a very powerful tool for those who need to adapt applications to suit their needs. For example, handling onSuccess enables you to upload each file automatically after successful reading, or to set up further validations for your files.
callbacks : {
onComplete : function(app){
// Function fires when all files have already read;
// You can access to app public properties like app.itemFileList or app.name
console.log('process completed. You have selected '+app.itemFileList.length+' files')
},
beforeRead : function(file){
// Function fires every time a file is about to be read. Object File is ready but it has not been validated yet, neither image has been loaded.
// Return false if you want app to stop reading this file and to continue reading next one
console.log('start to read ' + file.name);
},
onSuccess : function(item, callback){
// Function fires every time a file has been successfuly read;
// Return false if you want app to stop reading next file.
// Reading next file is callback. So, you can handle callback and fire it whenever you like (e.g., when file is already uploaded)
// item is the current ItemFile instance. You can access to its public methods and public properties.
setTimeout( callback , 2000 );
return false;
},
onError : function(file, msg){
// Function fires every time a file has been not successfuly read;
// You can handle msg error and file.
console.log(file.name + ' ERROR: '+ msg)
},
beforeRemove : function(item){
// Function fires every time an item file is just to be removed;
// You can handle item before removing it.
console.log('You are removing ' + file.name)
},
}
Public methods
The application has many public properties and methods. For more details, you can read the development code. Next, we will share the most relevant ones.
ItemFile methods
ItemFile instances generated by the application contain all the information associated with each file. There are as many ItemFile objects as files selected. Among its public properties and public methods, you will find useful:
item.file // store the File Object.
item.img // Property stores the Image Object
item.node // Property stores the entire node of this item in a JQuery object
item.serialize() // Method return a DataFile object to be send by ajax request
item.destroy() // Method destroy current item
Events beforeRemove and onSuccess let you access to each itemFile, as we have seen before. Here's an example of what you can do:
type : 'image',
callbacks : {
onSuccess : function(item){
// New validation rule is set for images:
// app displays error message if image is wider than higher and destroy current itemFile
if( item.img.width / item.img.height < 1 ){
$.customFile.popup.add('Image proportions are not allowed'); // read next about this static public function
item.destroy();
}
}
}
Serialization and ajax submitting
$.customFile.serialize(elements);
Serialize forms, inputs or pseudo-input files. It returns a DataFile object to be sent via ajax request. It only accepts as argument a string of comma separated CSS selectors (as jQuery object does) which refer to DOM forms and inputs, or app pseudo-inputs (you can select these through name attribute). See the following examples:
var dataForm_1 = $.customFile.serialize('#my-form'); // Serialize form, including inputs and files.
var dataForm_2 = $.customFile.serialize('.some-input-text, input-file-1'); // Atention: 'input-file-1' is the name attribute of original input file. No dots, no hash, nothing before, just the name for selecting it.
//
//Now, you could send dataForm_1 and dataForm_2 as you want. Also, you can simplify your work submiting form with app's public method $.customFile.ajax().
$.customFile.ajax(element, options);
Either send a complete form (including all its files and inputs), or send an input or a particular file to the server through ajax request. It accepts as first argument a string with a css selector (as JQuery object does) which selects a form or input element from the DOM, or an apps pseudo-input (via its name attribute). It also accepts an instance of ItemFile as first argument. As second argument, it accepts all JQuery $.ajax options along with the following settings:
progressBar : {
active : true, // Set false if you do not want a progress bar at all
appendTo : $('body'), // which node you want to append current progressBar to
removeAfterComplete : true,
}
$.customFile.ajax() Method does not require url option unless you have not set the action form attribute up before.
Examples:
// Submit entire form. If there are pseudo inputs files, send these too. If success, do something…
$.customFile.ajax('#my-form', {
success: function(response) {
console.log(response);
}
});
// Submit a specific input and hide progressbar
$.customFile.ajax('#some-input-no-file', {
progressBar : {
active: false
}
});
// Send all files attached to pseudo-input file (Rememeber! no dots, no hash, just the name for selecting it)
$.customFile.ajax('input-file-1');
// You can upload files one by one:
// When user selects files, each one is automatically uploaded. Once uploading is finished, it continues with next attached file.
// Also, progressbar is appended to each item node.
$('#input-file-2').customFile({
callbacks : {
onSuccess : function(item, callback){
$.customFile.ajax(item, {
url : ‘process_file.php’,
progressBar : {
appendTo: item.node,
closeAfterComplete: false
},
complete : function(){
callback();
}
});
return false; // Required for callback only fires once (when uploading is finished)
}
}
});
Popups
You can use apps popup utility for your own purpose. It is very easy to use.
Add
$.customFile.popup.add( msg, autoclose, delay, type )
It adds a new message line inside of an already opened popup (it opens popup instance automatically if it is closed).
Arguments:
msg string to be display. autoclose boolean value. It closes popup automatically if true. delay numeric value for autoclose. type icon before message line. Optional argument. It accepts: ‘error’ and ‘ok’.
Close
$.customFile.popup.close()
It closes popup. No arguments accepted.
Examples:
$.customFile.popup.close() // Close popup if it were open
$.customFile.popup.add( “hello world” , false, 0 , 'ok') // add first line
$.customFile.popup.add( “Second msg” , true, 5000 , 'error') // add second line
Demos
All type file Picker
<form action='process-form.php'>
<input name="input-file-1" id="input-file-1">
</form>
$(document).ready(function(e){
$('#input-file-1').customFile();
});
Image file type Picker
$('#input-file-2').customFile({
type : 'image'
});
Picking and cropping images
$('#input-file-3').customFile({
type : 'image',
image : {
crop : true
},
filePicker : '<h3>Drag & drop your images here</h3>'
+'<p>or click here</p>'
});
Some options
$('#input-file-4').customFile({
type : 'all',
allowed : ["pdf", "doc", "docx", "jpg"],
maxMB : 1,
maxKBperFile : 500,
maxFiles : 3,
fileWrapper : '<div class="my_custom_wr">'
+'<div class="cif-parent"></div>' // File name or image will be append here
+'<input name="my_dynamic_input" placeholder="info for the file">'
+'</div>',
callbacks: {
onSuccess : function(item){
alert(item.file.name+" OK");
}
}
});