Create a File Uploader using jQuery and Bootstrap

October 03, 2015 | 1403 views | Comments

Oftentimes in a web application, website members are allowed to upload multiple files in the server. This can be tiring for others, thus making the process a little captivative will encourage the user to efficiently complete the uploading.

Here's the idea, in the beginning, there would only be a single upload button on the page. As soon as the user has chosen a file, a preview or information of the file selected will be added the 'previews' area and will have a cancel button below it where the user can click it to fade it out of the page. This task can be achieved with the use of jQuery and Bootstrap.

 

Step 1. Set up global vars.

var __fileName = '';
var __fileExtension = '';
var __options = [];
var __counter = 0;

These variables will be available in all methods.

 

Step 2. Create the 'createInput' function.

createInput: function(options){
    var input = $('<input/>');
    if(options.multiple == true){
        input.prop('multiple',true);
    }
    return input.attr('type', options.type).attr('name', options.name).addClass(options.cssClass).val(options.text);
}

A function that will generate an input field depending on the parameters passed.

 

Step 3. Create the showPreview function.

showPreview: function(input, prvwCntnr){
    if ($.inArray(__fileExtension, __options.allowedPreviews) != -1){
        var reader = new FileReader();
        reader.onload = function (e) {
            $('<p/>').append($('<img/>').attr('src', e.target.result).addClass('thumbnail img-responsive center-block').css({ 'max-height':'200px','max-width':'200px' })).prependTo(prvwCntnr);
        };
        reader.readAsDataURL(input);
    }
    else{
        $('<p/>').append(__fileName).addClass('well well-sm').prependTo(prvwCntnr);
    }
}

A function that will generate previews of files with content types on the allowed list. File name will be displayed otherwise.

 

Step 4. Create the updateCounter function.

updateCounter: function(){
    $('.'+__options.counter).html(__counter);
}

A function that will update the live counter for the user to view.

 

Step 5. Create the Main Function function (ccFileUploader).

ccFileUpload: function(options){ /*Many codes here...*/ }

Lots of code to handle the idea.

 

Step 5.1 Create the Main Function (ccFileUploader) function.

var _this = this;

/**
 * Default settings.
 */
var defaults = {
    name: 'file',
    previews: 'previews',
    counter: 'counter',
    columnClass: 'col-sm-3 text-center',
    allowedFiles: ['gif','png','jpg','jpeg'],
    allowedPreviews: ['gif','png','jpg','jpeg']
};

/**
 * Overwrite default settings
 * for any user set values.
 */
__options = $.extend(defaults, options);

/**
 * Create the initial file input field. 
 */
var file = _this.createInput({type:'file', name:__options.name, cssClass:'hidden', multiple:true});

/**
 * Create the button that will trigger the file field.
 */
var fileDecoy = _this.createInput({type:'button', cssClass:'button btn btn-sm', text:'Choose File'});

/**
* Get the previews id for later reference.
*/
var previewsId = $('#'+__options.previews);

 

Step 5.2 Construct the main controller.

/**
 * Construct the initial file input field
 * together with the needed functions.
 */
_this.append(file.bind('change',function(){
    /**
     * Get the file properties.
     */
    var fileProps = $(this).get(0);
    
    /**
     * Loop through all the chosen files.
     */
    for(var i=0; i<fileProps.files.length; i++){
        /**
         * Get the file extension and check if is allowed.
         * Do nothing if true.
         */
        __fileExtension = fileProps.files.item(i).name.split('.').pop().toLowerCase();
        if($.inArray(__fileExtension, __options.allowedFiles) == -1){
            return false;
        }
        
        /**
         * Clear previews container on first file select.
         */
        if(__counter==0){
            previewsId.empty();
        }
    
        /**
         * Get the file name.
         */
        __fileName = fileProps.files.item(i).name.split('\\').pop();
        
        /**
         * Create the preview container.
         */
        var prvwCntnr = $('<div/>');
        
        /**
         * Call the 'showPreview' function.
         * @param: Selected file properties (fileProps.files[i]).
         * @param: Preview container element (prvwCntnr)
         */
        _this.showPreview(fileProps.files[i], prvwCntnr);
        
         /**
          * Construct the preview.
          */
        previewsId.prepend(
                prvwCntnr.addClass(__options.columnClass)
                   .append($('<p/>')
                           .append(_this.createInput({type:'button', name:'button', cssClass:'btn btn-xs btn-danger', text:'Cancel'})
                                   .bind('click',function(){
                                            $(this).parent().parent().fadeOut(200,function(){
                                                $(this).remove(); __counter--; _this.updateCounter();
                                            });
                                        })
                                    )
                                )
                .append(_this.createInput({type:'file',name:__options.name,cssClass:'file hidden', multiple:true}))
        );
        
         /**
          * Increment file counter.
          */
        __counter++;
         
         /**
          * Show to the user the updated file counter.
          */
        _this.updateCounter();
    }
}));

 

Step 5.3 Append the 'decoy' button.

/**
 * Append the 'decoy' button with a function
 * that will trigger the input field on click.
 */
_this.append(fileDecoy.bind('click', function(e){ e.preventDefault();
    file.trigger('click');
}));

The end-user will see a beautifully-designed button instead of the typical upload file field.

 

Step 5.4 Create the initial message, and last, return constructed functions..

/**
 * Create the initial message.
 */
previewsId.html($('<div/>').addClass('text-center text-muted').append('<h1>No file chosen...</h1>'));

return _this;

 

Step 5.5 Create the HTML form.

Do not forget to include the HTML5 tag on the HTML page.

<form method="post" enctype="multipart/form-data" action="">
<div class="col-xs-12">
    <div id="consistentCoder" class="text-center"></div>
</div>
<div class="col-xs-12">
    <span class="label label-info pull-right"><span class="countMe">0</span> files ready to upload.</span>
    <hr>
    <div id="stage" style="max-height:400px; overflow-y:scroll"></div>
    <hr>
</div>
<div class="col-xs-12 text-center">
    <input type="submit" value="Upload" class="btn btn-primary">
</div>
</form>

 

These are the only important HTML code. The design can be fully customized.

  • <div id="consistentCoder" class="text-center"></div>
  • Where the initial file upload field will be constructed. id="consistentCoder" will be the parameter that will be set for the plugin to look into. It can also be changed.
  • <div id="stage" style="max-height:400px; overflow-y:scroll"></div>
  • Where the previews will be shown. id="stage" is the parameter that should be set when the plugin is initialized. This can also be changed.

The counter code will show live record update, but it is just an option.

<span class="countMe">0</span>

 

Step 5.6 Initialize the plugin.

var options = {
                'name':'myFile',
                'previews':'stage',
                'counter':'countMe',
                'columnClass':'col-md-4 text-center',
                'allowedFiles':['gif','png','jpg','jpeg','xlsx'],
                'allowedPreviews':['jpg','jpeg']
              };
$("#consistentCoder").ccFileUpload(options);

Notice how "consistentCoder" and stage" from the HTML were used.

  • Field name was set to "myFile". Will produce
    'name':'file'
  • The div where the previews will be shown is set to the div with ID "stage".
    'previews':'stage'
  • Live file counter will be displayed on the span element with ID "consistentCoder-counter". 0
    'counter':'countMe'
  • Design the previews area where it will have three (3) columns (col-md-4) based on bootstraps grid system (max 12, so 12/4=3), and center it's contents text-center.
    'columnClass':'col-md-4 text-center'
  • List all the allowed file types. "'gif','png','jpg','jpeg','xlsx'".
    'allowedFiles':['gif','png','jpg','jpeg','xlsx']
  • Another option: List all the file types that will generate previews.
    'allowedPreviews':['jpg','jpeg']

 

That's all!

A jQuery file upload plugin with Bootrap design was develop.

 

Related Tutorials


Must Read

 
 

Source Code