Ajax Multiple Image Upload

Today I’m introducing a powerful Ajax Multiple Image Upload and will discuss how to integrate it with your web application.

First take a look at this DEMO. This is what we’re going to build.

This image uploader is written in JavaScript. However you can build the backend with whatever the language you want. Here I’m using a PHP backend. You can integrate this to Laravel too. Super simple.

Ajax multiple image uploader

Getting Started

First you need to download Ajax Multiple Image Uploader from Github.

Alright! Now let’s create some files and folders in our www folder (this depends on what localhost software you’r using). And create the folder structure as follows.


I’ll explain what these folders and files are for.

index.html is the frontend or the UI of our image uploader. We write all our html and stylings with some JavaScripts to call the image uploader backend methods.

upload.php is for uploading the image to the host. You can use any programing language to write the logic and move the uploaded file. I’m using PHP though.

form-process.php is for processing the form submit and save the image URLs to the database.

uploads folder is to save the uploaded images. Anyways, you can use this image uploader to upload images to a remote host such as S3 bucket.

I hope you get the logic already!

Before start coding, we need to include the necessary files to our application.

Open up and unzip the file you just downloaded from Github and copy all the files inside dist folder to our application’s dist folder.

Alright! Now let’s do some coding!

Start Coding

Open up the index.html and add the following lines.

<!doctype html>

<html lang="en">
    <meta charset="utf-8">

    <title>Ajax Multiple Image Uploader</title>
    <meta name="description" content="Ajax Multiple Image Uploader">
    <meta name="author" content="tharindulucky">

    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" integrity="sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp" crossorigin="anonymous">
    <link rel="stylesheet" href="dist/css/styles.css">

    <!-- Latest compiled JavaScript -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

    <!-- These are the necessary files for the image uploader -->
    <script src="dist/assets/jquery-file-upload/js/vendor/jquery.ui.widget.js"></script>
    <script src="dist/assets/jquery-file-upload/js/jquery.iframe-transport.js"></script>
    <script src="dist/assets/jquery-file-upload/js/jquery.fileupload.js"></script>


<div class="container">

    <h2>Ajax Multiple Image Uploader</h2>


    <div class="row">
        <div class="col-md-8">
            <div class="container1">
                    <form method="post" action="server/form_process.php">

                        <!-- This area will show the uploaded files -->
                        <div class="row">
                            <div id="uploaded_images">



                        <div id="select_file">
                            <div class="form-group">
                                <label>Upload Image</label>
                            <div class="form-group">
                                <!-- The fileinput-button span is used to style the file input field as button -->
                                <span class="btn btn-success fileinput-button">
                                <i class="glyphicon glyphicon-plus"></i>
                                <span>Select file...</span>
                                    <!-- The file input field used as target for the file upload widget -->
                                <input id="fileupload" type="file" name="files" accept="image/x-png, image/gif, image/jpeg" >
                                <!-- The global progress bar -->
                                <div id="progress" class="progress">
                                    <div class="progress-bar progress-bar-success"></div>
                                <!-- The container for the uploaded files -->
                                <div id="files" class="files"></div>
                                <input type="text" name="uploaded_file_name" id="uploaded_file_name" hidden>

                        <button type="submit" class="btn btn-primary" name="submit">Submit</button>




That’s the UI we’re building. I think each line of code is pretty self descriptive. Now let’s add some JavaScript to call the backend methods with Ajax.

Add the following piece of code to the very bottom of index.html file.

    /*jslint unparam: true */
    /*global window, $ */
    var max_uploads = 5
    $(function () {
        'use strict';
        // Change this to the location of your server-side upload handler:
        var url = 'server/upload.php';
            url: url,
            dataType: 'html',
            done: function (e, data) {
                if(data['result'] == 'FAILED'){
                    alert('Invalid File');
                    $('#uploaded_images').append('<div class="uploaded_image"> <input type="text" value="'+data['result']+'" name="uploaded_image_name[]" id="uploaded_image_name" hidden> <img src="server/uploads/'+data['result']+'" /> <a href="#" class="img_rmv btn btn-danger"><i class="fa fa-times-circle" style="font-size:48px;color:red"></i></a> </div>');
                    if($('.uploaded_image').length >= max_uploads){
                $('#progress .progress-bar').css(
                    0 + '%'
                $.each(data.result.files, function (index, file) {
            progressall: function (e, data) {
                var progress = parseInt(data.loaded / data.total * 100, 10);
                $('#progress .progress-bar').css(
                    progress + '%'
        }).prop('disabled', !$.support.fileInput)
            .parent().addClass($.support.fileInput ? undefined : 'disabled');
    $( "#uploaded_images" ).on( "click", ".img_rmv", function() {
        if($('.uploaded_image').length >= max_uploads){

Great! That’s all for the UI. Now we need to write some logic to upload the file to the host. Open up server/upload.php file and add the following code.


$storeFolder = 'uploads';   //2
if (!empty($_FILES)) {
    $tempFile = $_FILES['files']['tmp_name'];
    $file_name = $_FILES['files']['name'];
    $ext = pathinfo($file_name, PATHINFO_EXTENSION);
    if(filesize($tempFile) > 5000000){
        echo 'FAILED';
    if($ext == 'jpg' || $ext == 'png' || $ext == 'JPG' || $ext == 'PNG'){
        $new_file_name = time().'.'.$ext;
        $targetPath = 'uploads/';  //4
        $targetFile =  $targetPath. $new_file_name;  //5
        if ($img = @imagecreatefromstring(file_get_contents($tempFile))) {
            $upload_result = move_uploaded_file($tempFile,$targetFile); //6
            echo $new_file_name;
            echo 'FAILED';
        echo 'FAILED';

Here we’re using very straight forward logic with some image type validation with IF and setting the name of the uploaded file with the timestamp. If the file is successfully uploaded, it echoing the file name and if it fails it’s echoing ‘FAILED’. That’s it!
So, that the Ajax function can get the uploaded file name and put it in the hidden form field. Then when you’re finally press submit button of the form, all the uploaded file names/URLs are sent to backend again. That’s the logic behind this magic.

Alright, next open up server/form-process.php add some logic to save file names to the DB. Here I’m leaving that to you. It’s up to you to process the form and save these values to the DB. Should be really simple. Just a simple form submission.

    //Save to DB
    //Do whatever you want

That’s all the coding we need to do. Make sure you included all the necessary files specially Bootstrap and Jquery. Then the dist folder files as well.

If all the above steps are completed properly, this should work like a charm!

See the Working DEMO!

Checkout the Video Demonstration


Leave a Reply

Your email address will not be published. Required fields are marked *