Ajax Image Upload with Progressbar (jQuery and PHP)

Today we are going to create an image upload and resize script with a progress bar. This is an extension of my previous tutorial about image upload and resize script using jQuery and PHP, I suggest you go though that tutorial, because only thing we are going to add here is a progress-bar.

Progress-bar requires modern browsers that support XMLHttpRequest 2. It’s HTML5 feature that adds more functionality to Ajax request, additionally we can monitor the progress of data transfers. Thankfully all modern browsers support this feature.

Ajax Image Upload and Resize with Progressbar

HTML Form

Below is our HTML form. As you can see this is exactly the same form as shown in previous example, only thing I have added here is progressbar element.

1
2
3
4
5
6
7
8
9
<div class="form-wrap">
<h3>Ajax Image Uploader</h3>
    <form action="process.php" method="post" enctype="multipart/form-data" id="upload_form">
        <input name="__files[]" type="file" multiple />
        <input name="__submit__" type="submit" value="Upload"/>
    </form>
    <div id="progress-wrp"><div class="progress-bar"></div ><div class="status">0%</div></div>
    <div id="output"><!-- error or success results --></div>
</div>

Styling Progress Bar

This CSS will transform our DIV element into a nice looking progress-bar. You are welcome to change its appearance as you prefer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#progress-wrp {
    border: 1px solid #0099CC;
    padding: 1px;
    position: relative;
    border-radius: 3px;
    margin: 10px;
    text-align: left;
    background: #fff;
    box-shadow: inset 1px 3px 6px rgba(0, 0, 0, 0.12);
}
#progress-wrp .progress-bar{
    height: 20px;
    border-radius: 3px;
    background-color: #f39ac7;
    width: 0;
    box-shadow: inset 1px 1px 10px rgba(0, 0, 0, 0.11);
}
#progress-wrp .status{
    top:3px;
    left:50%;
    position:absolute;
    display:inline-block;
    color: #000000;
}

jQuery

To bring our progress-bar in life, I’ve added behavior to XMLHttpRequest function in jQuery Ajax code. XMLHttpRequest provides us with the ability to listen to progress events while the request is being processed. We can capture the arguments passed by XMLHttpRequest function and use them to change width and text of progressbar real-time.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$.ajax({
    url : post_url,
    type: "POST",
    data : form_data,
    contentType: false,
    cache: false,
    processData:false,
    xhr: function(){
        //upload Progress
        var xhr = $.ajaxSettings.xhr();
        if (xhr.upload) {
            xhr.upload.addEventListener('progress', function(event) {
                var percent = 0;
                var position = event.loaded || event.position;
                var total = event.total;
                if (event.lengthComputable) {
                    percent = Math.ceil(position / total * 100);
                }
                //update progressbar
                $(progress_bar_id +" .progress-bar").css("width", + percent +"%");
                $(progress_bar_id + " .status").text(percent +"%");
            }, true);
        }
        return xhr;
    },
    mimeType:"multipart/form-data"
}).done(function(res){ //
    $(my_form_id)[0].reset(); //reset form
    $(result_output).html(res); //output response from server
    submit_btn.val("Upload").prop( "disabled", false); //enable submit button once ajax is done
});

Wrap up

Everything else in this script is same as Ajax Image upload, you should find rest of the code in sample file below. Good luck!

Download Demo

84 Comments Add Comment

  • no working in freebsd using nginx booo!!!

     Reply
  • Hello Saran,
    Thanks for the great work!
    You’ve saved my lot of time.
    Regards
    Mark

     Reply
  • website development

    it works nicely on firefox and chrome, but IE shows some problem. it doesn’t make progress. Is there any other work around ?

     Reply
  • hi guys
    I try this code but The progress bar is not loading. Don’t pass 0% any ideias?

     Reply
  • Thanks, Good use of GD library and ajax

     Reply
  • Hi, I’ve a problem with this code on Internet Explorer.
    on function beforeSubmit(){
    //check whether browser fully supports all File API
    statement if (window.File && window.FileReader && window.FileList && window.Blob)
    returns for me false only on IE. I’m using Win 8.1, IE 11 so it should support file API.
    Is it possible to use this code on IE?

     Reply
  • Thank you from ─░stanbul! :)

     Reply
  • is this resizing photos on client-Side? or after upload? thanks in advance.

     Reply
  • Hi Saran. If you test it with Google Chrome on iPad or iPhone with iOS 8 you will realize that the Progress Bar isn’t shown because it seems Google Chrome has a bug that doesn’t let the “Upload OnProgress” callback get fired. I’m using my own Ajax Uploader, and I’m hardly trying to figure it out what’s the reason of this. I’ll appreciate any feedback in case you test it and find out why the progress bar isn’t being shown on Chrome-Ipad. Have a good day.

     Reply
  • this works great on chrome and on my ipad, however on my iphone, the progress bar won’t go above 1% and the file never seems to actually upload. Like i said it seems to work fine on Ipad but not on mine or my gfs iphone. any suggestions as to why this might be happening?

     Reply
  • Please help i can’t download it. even i subscribe

     Reply
  • Man I love you so much I kiss you…
    Have been trying for ages to get a progress bar for my video uploads, but the built-in php functions just weren’t working, this has made my day ^^

     Reply
  • Thanks so much … ^_^

     Reply
  • The Download bundle has a bad index.php. It declares the input variable for the “image_file” as “ImageFile”. This ends up breaking the processupload.php, which just says that the file isn’t found (because it expects it in $_FILES[‘image_file’].

    Anyway… quick fix once I found it. Anyone else having this issue? Just edit the index.php to ensure that the file input field is named “input_file”.

     Reply
  • ReferenceError: beforeSubmit is not defined index.php:132

    Not sure why console is throwing this error. Can’t seem to upload an image :(

     Reply
  • Hi
    How I can use this script if If have more than one file field?

     Reply
  • Hi Saran,
    Love this script. Only just discovered it. Well done! My question is, how do you use the progress bar scripting but bypass your “processupload.php” page in favour of our own file validation page? I really only want to use the stylish progress bar part of the script and pass the files to my own page where sorting and descriptions can be added. I have tried modifying the form action to “addimage.php” but when the progress bar reaches 100% the little uploading GIF keeps spinning and the browse button reverts to its ‘choose” state.

     Reply
    • Make sure “addimage.php” is responding, check Ajax output using developer tools like “firebug”.

  • this is nice nice nice nicenice
    you are very very very very very good

    excuse me
    beacuse i can’t speak in english good but i Want say you, this post is very very nice

     Reply
  • Thanks Man,

    It was really simple to implement and looked very nice.

    Saved me a lot of time and energy to make one
    Thanks again

     Reply
  • Hey how come that the .gif pictures are not animated after upload?

     Reply
    • I guess it’s because of the image conversion. Go into the code and comment the conversion

  • Great stuff, works nicely, EXCEPT:

    how do I get it to insert the re-sized images into my MySQL DB? I’ve been unable to get that to work.

     Reply
  • I’m getting progress bar box in IE9 Only. Not the process percentage in my IE9. Chrome and FF are works fine.

    Any Suggestions?

     Reply
  • What does this error mean? I am very new to Ajax.

    “Data wasn’t sent though ajax!”

     Reply
  • akhter ali ansari

    Hi dear,

    I am getting this error after download your zip,complete file is not their.
    Not Found
    The requested URL /ajax-upload/upload.php was not found on this server.

     Reply
  • how to have maintained the original size of the image? and climb as original image without Resize?

     Reply
  • thanks bro udah mau share…
    beginilah indahnya berbagi :)

     Reply
  • Thanks for posting this material, but does not work with images of 5 megs, Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 17152 bytes) in … any suggestions?

     Reply
  • URL /ajax project/ajax-upload-with-progressbar-v-1-0/upload.php was not found on this server.

     Reply
  • Hi Saaraan,
    I am done this for to upload video but i am getting error while uploading error is internal Server Error
    The server encountered an internal error or misconfiguration and was unable to complete your request.
    Please contact the server administrator, [email protected] and inform them of the time the error occurred, and anything you might have done that may have caused the error.
    More information about this error may be available in the server error log.
    Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
    Can you plz help me with this problem?

     Reply
  • Warning: imagejpeg() [function.imagejpeg]: Unable to open ‘/imgUpload/uploads/desert-8587226350.jpg’ for writing: No such file or directory

    i get this error

     Reply
  • Can i use form validation ? Such as check empty field before upload executed?

     Reply
    • yes sure you can.

    • How Can I do that ? Can you help me?

    • This is my code, it works but it makes the progress bar doesn’t showed.
      $(document).ready(function() {
      //elements
      var progressbox = $(‘#progressbox’);
      var progressbar = $(‘#progressbar’);
      var statustxt = $(‘#statustxt’);
      var submitbutton = $(“#SubmitButton”);
      var myform = $(“#UploadForm”);
      var output = $(“#output”);
      var completed = ‘0%’;

      var numbers = /^[0-9]+$/;
      if(document.getElementById(‘name’).value == “”){
      return false;
      } else if(!document.getElementById(‘price’).value.match(numbers)){
      return false;
      } else if(document.getElementById(‘category_id’).value 50)
      {
      statustxt.css(‘color’,’#fff’); //change status text to white after 50%
      }
      },
      complete: function(response) { // on complete
      myform.resetForm(); // reset form
      submitbutton.removeAttr(‘disabled’); //enable submit button
      progressbox.hide(); // hide progressbar
      window.location = “stores/manage”;
      }
      });
      });

  • this do not work in IE9

    Any suggestion?

    Tks

     Reply
  • The progressbar is not working in ie 8.
    Plz help.

     Reply
    • Most of the features in HTML5 isn’t supported by IE8.

    • But i want it in ie 8 bcoz my client required this functionality in ie 8 i have another uploader which perfectly run in other browsers but at the end ie 8 support is important.

  • Hi guys thanks for your answers, i was able to fix the script and i could also copy the cropped images into two different folders customizing it a little bit. It a very clear script, compliments. Just one suggest i have for you…it would be nice, if it loads the image just when i release the button on input file text (like facebook style) I see my image loaded and then just in a second moment, i can press the submit button and send the form to db…in this way it’s less useful have the preload, because after have submitted a form i don’t need to see my image loaded, or i could do also refreshing my page without ajax…
    i try in case to customize it more, maybe i could do two loops on ajax file, i have no idea yet…thanks a lot anyways!…

     Reply
  • Hello,
    please can I ask for following advice? If I want after uploading be redirected to form action, how to do it?

    I mean, for example in form is “action=’/test/'”. I dont want see the output of /test/ on original page, but I want be redirected to /test/, as common form does.

    Please can you help me?

     Reply
    • If I understood you correctly, you don’t need any jQuery code, you can achieve that with normal form.

    • What I would like to use is progress bar – this progress bar is nice and work as I need. So if would be possible to see progress bar while files are uploading and then go to form action, it would be nice …

  • I saaraan i have tried my script today but i have a problem: it says to me “The requested URL /scripts/upload/upload.php was not found on this server.” the problem is i dont see it in my zip file…what’s wrong with it?

    thanks

    Alessandro

     Reply
    • you need to change this line “action=”upload.php”” with “action=”processupload.php”” in index.php.

  • Hey;
    thumb image working but not my request type. normal image fine but thumb image looking middle part of image means buttom and top cropped this looks bad .how can i fix that.

     Reply
  • I tried and it worked so fine!…Thanks a lot!

     Reply
  • Thanks very much. This really helped me a lot. I’ve been searching very hard for how to upload images via ajax although I can send text entered in forms via ajax but with uploading images or any other file, it was very difficult. Thanks again, dude.

     Reply
  • Warning: imagejpeg(/home/ajax-image-upload-progressbar/uploads/6-621637111.jpg): failed to open stream: No such file or directory in C:xampphtdocsimagesprocessupload.php on line 144

    Warning: imagejpeg(/home/ajax-image-upload-progressbar/uploads/thumb_6-621637111.jpg): failed to open stream: No such file or directory in C:xampphtdocsimagesprocessupload.php on line 191

    Warning: getimagesize(/home/ajax-image-upload-progressbar/uploads/6-621637111.jpg): failed to open stream: No such file or directory in C:xampphtdocsimagesprocessupload.php on line 84

    i facing problem with this error in both the codings and working in the local.
    Please do reply soon

     Reply
    • change path in “processupload.php” at line 14:
      $DestinationDirectory=’/home/ajax-image-upload-progressbar/uploads/’;

      to your destination, my case:
      $DestinationDirectory=’c:/wamp/www/test/uploads’;

  • Thanks a lot for this. Really made by project quicker to complete. Just a little typo error in your commenting on line 20 of index.php (beforeSend: function() { //brfore sending form). But sincerely, it’s a great piece of work to use. Thanks.

     Reply
  • Salam
    Thanks.This code is nice,simple and useful.
    Best Regard.

     Reply
  • Progress bar works fine, but after complete it returns me the “404 not found” error.

    Thanks!

     Reply
  • hello,
    If I insert the imaged uploaded to mysql database successfull.
    How can it redirect to that image automatically?
    Thank you

     Reply
  • This works great from a desktop/laptop PC using Chrome, however there is a problem using mobile Safari (iPhone) to upload images. Image uploading via iphone only works the very first time. Subsequent uploads fail and the previously uploaded image is shown. It’s like it’s somehow caching the first upload. I’ve tried 3 differentiphones now and all exhibit the same behaviour. First upload works great, all uploads from then on fail. Closing the window or quitting Safari and reloading does not fix this, neither does a hard reset on the phone. I don’t know where to even start looking to solve a bug like this..

     Reply
    • Scott, I have the *exact* same issue.
      I’ve found that if you set the iPhone to private browsing mode, then kill all tabs, then reload the page — the first upload works again, but all subsequent uploads fail (until you kill all private windows again).
      So far, it appears that the uploadProgress (or complete, or anything) function is not being called at all on mobile Safari (it works fine on desktop safari). beforeSend() seems to be the last thing executed (happily too, I’ll add). I was looking into ways to debug this, but you can only access debugging tools (like the JavaScript console) by connecting the iPhone to your Mac computer with a cable, and setting it up to interface with Desktop Safari 6 for Mac. I have Windows (safari 6 dropped windows support), and the Macs I have aren’t running the latest Mac OS X that Safari 6 requires. So I’m out of luck. If anyone has the same issue and is equipped to debug it, please let me and Scott know what’s up.
      Otherwise, I might just shit all over jquery.form.js’s source code with a ton of alerts to hack this down the ol’ fashion way. If I figure anything out, I’ll post back :)
      //Chase.

    • Hey.
      I found the issue.
      Google “iPhone Post Caching”.
      Will be fixed in iOS 6.1.
      Workaround: add a timestamp parameter to the querystring to kill the caching.
      //Chase.

  • I managed to get this 100% working, but then I ran into problems uploading images from an iPhone. PHP would give memory errors when trying to upload, but only when sending photos from an iPhone, not from a computer. I thought maybe the photo was too large (3-4 MB), but even sending a small screenshot (less than 1 MB) same problem. Sending photos from a regular computer works fine. Then I ran into a caching problem where uploading photos would just zip the progress bar to 100% instantly and then display the first file I uploaded instantly. Again, only on the iphone – maybe because the files are all named the same (ie – photo.jpg) coming from iphone. It’s possible I need to modify the PHP script to add on the random number to the filename earlier in the script. I spent the entire day yesterday trying to get it working, and it’s a very cool piece of code, just has a couple major bugs. If/when I find a solution, I will post it here. Thanks Saaraan for posting this.

     Reply
  • Thank you for this form.
    Like others, I have a problem with the copy of the picture, with this famous message : Unable to open ‘images/’… for writing.
    I read the code, and I was unable to find the part where you copy the image.
    Can you light me ?
    Thanks !

     Reply
  • Melvin, you need to check that GD is installed on your server…..And version 1.8 or above but im sure it will be if it is installed correctly.

     Reply
  • Hi,

    I am getting the following erro can you please advise

    1
    2
    3
    4
    5
    6
    javax.servlet.ServletException: java.lang.RuntimeException: PHP Fatal error:  Call to undefined function imagecreatefromjpeg() in C:Program FilesApache Software FoundationTomcat 7.0webappslihiuserfilesprocessupload.php on line 47

        php.java.servlet.fastcgi.FastCGIServlet.handle(FastCGIServlet.java:499)
        php.java.servlet.fastcgi.FastCGIServlet.doPost(FastCGIServlet.java:509)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

    root cause

    1
    2
    3
    4
    5
    6
    7
    8
    java.lang.RuntimeException: PHP Fatal error:  Call to undefined function imagecreatefromjpeg() in C:Program FilesApache Software FoundationTomcat 7.0webappslihiuserfilesprocessupload.php on line 47

        php.java.servlet.fastcgi.FastCGIServlet.parseBody(FastCGIServlet.java:409)
        php.java.servlet.fastcgi.FastCGIServlet.execute(FastCGIServlet.java:433)
        php.java.servlet.fastcgi.FastCGIServlet.handle(FastCGIServlet.java:481)
        php.java.servlet.fastcgi.FastCGIServlet.doPost(FastCGIServlet.java:509)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
     Reply
  • Hello, thank you for the amazing script, I like it very much. I have tried to upload multiple files. I have changed the input into . But the php file works only with one image, how does it work with multiple images? Best regards, Marc

     Reply