Show Thumbnail of Image Upload AJAX/PHP

Sam Deering

ajax-image-upload

Update 18/11/2012: The new version of this upload is now here JQUERY AJAX IMAGE UPLOAD THUMBNAIL EXAMPLE.

This is how you can add a file/image upload tool to your forms and have AJAX store the file with PHP and return a thumbnailed version to the user for display on the form. Nice.

How it works

  1. User selects a file/image from the form input field
  2. jQuery sends an AJAX request with the file/image
  3. PHP creates a thumbnail version and sends back the url in JSON format
  4. jQuery displays the thumbnailed version on the form

Download

  • doajaxfileupload.php
  • ajaxfileupload.php
  • jquery.php
  • form-html.php

Download Source FilesSee Live Demo

The jQuery Code – jquery.js

/*******************************************************************
  JS - PREVIEW IMAGE
*******************************************************************/
function previewImage(str) {
	//alert(str);
	ajaxFileUpload();
}

function removeImage() {
	//alert("Image Removed");
	$("#imagethumb").html('');
	$("#removebutton").hide();
	$("#supportedfiles").show();
	var tid = $("Input[name=allocatedimagename]").val();
	//remove the temporary image files created by the image
	$.get("/php/deleteblogthumb.php",{thumb_name: tid, type: 'js-blog'}, function(data){
		//alert(data);
	});

	$("Input[name=allocatedimagename]").val('');
	$("Input[name=blogpic]").val('');
}

function ajaxFileUpload() {
    //starting setting some animation when the ajax starts and completes
    $("#loading")
    .ajaxStart(function(){
        $(this).show();
    })
    .ajaxComplete(function(){
        $(this).hide();
    });
   
    /*
        prepareing ajax file upload
        url: the url of script file handling the uploaded files
                    fileElementId: the file type of input element id and it will be the index of  $_FILES Array()
        dataType: it support json, xml
        secureuri:use secure protocol
        success: call back function when the ajax complete
        error: callback function when the ajax failed
       
            */
    $.ajaxFileUpload
    (
        {
            url:'doajaxfileupload.php',
            secureuri:false,
            fileElementId:'blogpic',
            dataType: 'json',
            success: function (data, status)
            {
                if(typeof(data.error) != 'undefined')
                {
                    if(data.error != '')
                    {
                        alert(data.error);
                    }else
                    {
                        //alert(data.loc);
                        //show the preview of image
						var imageloc = '<span class="normaltext">Your uploaded image: <samp>'+data.name+'('+data.size+'kb)'+'</samp><br /><img class="small blogthumb" src="'+data.loc+'" height="40" width="40" alt="your uploaded image"/></span>';
						$("#imagethumb").html(imageloc); //add
						$("#removebutton").show();
						$("#supportedfiles").hide();
						//save the allocated image name for use with the process signup script
						$("Input[name=allocatedimagename]").val(data.loc);
                    }
                }
            },
            error: function (data, status, e)
            {
                alert(e);
            }
        }
    )
   
    return false;

}  

The jQuery Code – ajaxfileupload.js

jQuery.extend({

    createUploadIframe: function(id, uri)
	{
			//create frame
            var frameId = 'jUploadFrame' + id;
            
            if(window.ActiveXObject) {
                var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '"></iframe>');
                if(typeof uri== 'boolean'){
                    io.src = 'javascript:false';
                }
                else if(typeof uri== 'string'){
                    io.src = uri;
                }
            }
            else {
                var io = document.createElement('iframe');
                io.id = frameId;
                io.name = frameId;
            }
            io.style.position = 'absolute';
            io.style.top = '-1000px';
            io.style.left = '-1000px';

            document.body.appendChild(io);

            return io			
    },
    createUploadForm: function(id, fileElementId)
	{
		//create form	
		var formId = 'jUploadForm' + id;
		var fileId = 'jUploadFile' + id;
		var form = $('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');	
		var oldElement = $('#' + fileElementId);
		var newElement = $(oldElement).clone();
		$(oldElement).attr('id', fileId);
		$(oldElement).before(newElement);
		$(oldElement).appendTo(form);
		//set attributes
		$(form).css('position', 'absolute');
		$(form).css('top', '-1200px');
		$(form).css('left', '-1200px');
		$(form).appendTo('body');		
		return form;
    },

    ajaxFileUpload: function(s) {
        // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout		
        s = jQuery.extend({}, jQuery.ajaxSettings, s);
        var id = new Date().getTime()        
		var form = jQuery.createUploadForm(id, s.fileElementId);
		var io = jQuery.createUploadIframe(id, s.secureuri);
		var frameId = 'jUploadFrame' + id;
		var formId = 'jUploadForm' + id;		
        // Watch for a new set of requests
        if ( s.global &amp;&amp; ! jQuery.active++ )
		{
			jQuery.event.trigger( "ajaxStart" );
		}            
        var requestDone = false;
        // Create the request object
        var xml = {}   
        if ( s.global )
            jQuery.event.trigger("ajaxSend", 1);
        // Wait for a response to come back
        var uploadCallback = function(isTimeout)
		{			
			var io = document.getElementById(frameId);
            try 
			{				
				if(io.contentWindow)
				{
					 xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
                	 xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
					 
				}else if(io.contentDocument)
				{
					 xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
                	xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
				}						
            }catch(e)
			{
				jQuery.handleError(s, xml, null, e);
			}
            if ( xml || isTimeout == "timeout") 
			{				
                requestDone = true;
                var status;
                try {
                    status = isTimeout != "timeout" ? "success" : "error";
                    // Make sure that the request was successful or notmodified
                    if ( status != "error" )
					{
                        // process the data (runs the xml through httpData regardless of callback)
                        var data = jQuery.uploadHttpData( xml, s.dataType );    
                        // If a local callback was specified, fire it and pass it the data
                        if ( s.success )
                            s.success( data, status );
    
                        // Fire the global callback
                        if( s.global )
                            jQuery.event.trigger( "ajaxSuccess", 1 );
                    } else
                        jQuery.handleError(s, xml, status);
                } catch(e) 
				{
                    status = "error";
                    jQuery.handleError(s, xml, status, e);
                }

                // The request was completed
                if( s.global )
                    jQuery.event.trigger( "ajaxComplete", 1 );

                // Handle the global AJAX counter
                if ( s.global &amp;&amp; ! --jQuery.active )
                    jQuery.event.trigger( "ajaxStop" );

                // Process result
                if ( s.complete )
                    s.complete(xml, status);

                jQuery(io).unbind()

                setTimeout(function()
									{	try 
										{
											$(io).remove();
											$(form).remove();	
											
										} catch(e) 
										{
											jQuery.handleError(s, xml, null, e);
										}									

									}, 100)

                xml = null

            }
        }
        // Timeout checker
        if ( s.timeout > 0 ) 
		{
            setTimeout(function(){
                // Check to see if the request is still happening
                if( !requestDone ) uploadCallback( "timeout" );
            }, s.timeout);
        }
        try 
		{
           // var io = $('#' + frameId);
			var form = $('#' + formId);
			$(form).attr('action', s.url);
			$(form).attr('method', 'POST');
			$(form).attr('target', frameId);
            if(form.encoding)
			{
                form.encoding = 'multipart/form-data';				
            }
            else
			{				
                form.enctype = 'multipart/form-data';
            }			
            $(form).submit();

        } catch(e) 
		{			
            jQuery.handleError(s, xml, null, e);
        }
        if(window.attachEvent){
            document.getElementById(frameId).attachEvent('onload', uploadCallback);
        }
        else{
            document.getElementById(frameId).addEventListener('load', uploadCallback, false);
        } 		
        return {abort: function () {}};	

    },

    uploadHttpData: function( r, type ) {
        var data = !type;
        data = type == "xml" || data ? r.responseXML : r.responseText;
        // If the type is "script", eval it in global context
        if ( type == "script" )
            jQuery.globalEval( data );
        // Get the JavaScript object, if JSON is used.
        if ( type == "json" )
            eval( "data = " + data );
        // evaluate scripts within html
        if ( type == "html" )
            jQuery("<div>").html(data).evalScripts();
			//alert($('param', data).each(function(){alert($(this).attr('value'));}));
        return data;
    }
})

The PHP Code – doajaxfileupload.php

$ratio2)	{
          $thumb_w=$new_w;
          $thumb_h=$old_y/$ratio1;
        }
        else	{
          $thumb_h=$new_h;
          $thumb_w=$old_x/$ratio2;
        }

          // we create a new image with the new dimmensions
        $dst_img=ImageCreateTrueColor($thumb_w,$thumb_h);

        // resize the big image to the new created one
        imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y);

        // output the created image to the file. Now we will have the thumbnail into the file named by $filename
        if(!strcmp("png",$ext))
          imagepng($dst_img,$filename);
        else
          imagejpeg($dst_img,$filename);

          //destroys source and destination images.
        imagedestroy($dst_img);
        imagedestroy($src_img);
       }

       // This function reads the extension of the file.
       // It is used to determine if the file is an image by checking the extension.
       function getExtension($str) {
               $i = strrpos($str,".");
               if (!$i) { return ""; }
               $l = strlen($str) - $i;
               $ext = substr($str,$i+1,$l);
               return $ext;
       }

        //reads the name of the file the user submitted for uploading
       $image=$_FILES[$fileElementName]['name'];

 	// if it is not empty
 	if ($image)
 	{
 		// get the original name of the file from the clients machine
 		$filename = stripslashes($_FILES[$fileElementName]['name']);

 		// get the extension of the file in a lower case format
 	 	$extension = getExtension($filename);
 		$extension = strtolower($extension);
 		// if it is not a known extension, we will suppose it is an error, print an error message
 		//and will not upload the file, otherwise we continue
 		if (($extension != "jpg")  &amp;&amp; ($extension != "jpeg") &amp;&amp; ($extension != "png"))
 		{
 			$error .= 'Unknown extension!';
 			$errors=1;
 		}
 		else
 		{
 			// get the size of the image in bytes
 			// $_FILES['image']['tmp_name'] is the temporary filename of the file in which
			//the uploaded file was stored on the server
 			$size=getimagesize($_FILES[$fileElementName]['tmp_name']);
 			$sizekb=filesize($_FILES[$fileElementName]['tmp_name']);

 			//compare the size with the maxim size we defined and print error if bigger
 			if ($sizekb > MAX_SIZE*1024)
 			{
 				$error .= 'You have exceeded the size limit!';
 				$errors=1;
 			}
 			else {

              //we will give an unique name, for example the time in unix time format
            $image_name=time().'.'.$extension;
            //the new name will be containing the full path where will be stored (images folder)
            $newname="/images/masters/".$image_name;
            $copied = copy($_FILES[$fileElementName]['tmp_name'], $newname);
            //we verify if the image has been uploaded, and print error instead
            if (!$copied)
            {
              $error .= 'Copy unsuccessfull!';
              $errors=1;
            }
            else
            {
              // the new thumbnail image will be placed in images/thumbs/ folder
              $thumb_name='/images/thumbs/thumb_'.$image_name;
              // call the function that will create the thumbnail. The function will get as parameters
              //the image name, the thumbnail name and the width and height desired for the thumbnail
              $thumb=make_thumb($newname,$thumb_name,40,40);

              //also add the users pic
              $thumb_name='/images/thumbs/thumb_'.$image_name;
              $thumb=make_thumb($newname,$thumb_name,110,110);

            }}
        }
 			}

      //--------- END SECOND SCRIPT --------------------------------------------------------------------

      //return variables to javascript
			$filename = $_FILES[$fileElementName]['name'];
			$filesize = round(($sizekb/1000), 0);
			$fileloc = $thumb_name;
			//for security reason, we force to remove all uploaded file
			@unlink($_FILES[$fileElementName]);
	}
	$return_JSON = "";
	$return_JSON .= "{";
	$return_JSON .=				"error: '" . $error . "',n";
	$return_JSON .=				"name: '" . $filename . "',n";
	$return_JSON .=				"size: '" . $filesize . "',n";
	$return_JSON .=				"loc: '" . $fileloc . "'n";
	$return_JSON .= "}";
	echo $return_JSON;
?>

The HTML Code

          <label for="blogpic">Blog Thumbnail Picture:</label>
          <input type="file" size="23" id="blogpic" name="blogpic" onChange="javascript:previewImage(this.value)"/>
          <div id="preview-image">
              <div id="imagethumb"></div>
              <input type="text" id="allocatedimagename" name="allocatedimagename" />
              <div id="loading" style="visibility:hidden"><img src="/images/loading.gif" alt="loading" title="loading" /></div>
              <div id="supportedfiles"><p class="nomargin">Supported file types: jpg, jpeg, png (max 1mb) <br />Your image will be resized to 110 by 110 px (40 by 40 for blog thumbs)</p></div>

              <div id="removebutton"><button id="buttonremove" onclick="javascript:removeImage()">Remove</button></div>
          </div>
Sam Deering

Sam Deering is a Front-end Web Developer who specialises in JavaScript & jQuery. Sam is driven and passionate about sharing his knowledge to educate others.

Win an Annual Membership to Learnable,

SitePoint's Learning Platform

  • Pingback: Show Thumbnail of Image Upload AJAX/PHP « Big Engine Media

  • kailash malav

    Code is great according to functionality , but not correctly running in my local host please give suggestion how to use that code…..thanks for sharing it with us .

  • jquery4u

    Hi Kailash,

    Yes it seems i have missed something in the download package. When i get some spare time i’ll update the demo files and fix it up.

    Very sorry about this.

    Cheers
    Sam

    • mike

      any word on the fix yet? i was reading through the code and dont see anything wrong.

      • jquery4u

        Hi Mike, there’s nothing wrong with the code. It is working on my BLOGOOLA site. I just need to recompile the download package. Also I can’t post my recapcha keys as they are private so when you download you’d have to add in your own keys.

    • sartaj

      the idea is very nice.
      this is what i want but i too want it in my local system what are the keys i changed? please help me!

  • Sankars

    hi..

    nice script.
    this is only single image how do it multiple image?

    • jquery4u

      Hi Sankers, I guess it would be possible to do a multiple image version. If I was to do one I would probably just store and array (an object of key-value pairs of data) using jQuery.data() and this would contain key value pairs for timestamp and image url respectively. The image url would be the temporary place you stored it on your server using PHP. From there you could just keep appending as many images as you like into the HTML form. Maybe add a small remove button for each image so the user could add and remove as they please. Hope this helps. If I get the time i’ll draw up an example. Cheers. Sam

      • Fish

        hello jQuery4u,
        After I downloaded your code, I modified codes to upload (multi-image) and review uploaded image , save it to database and delete image. But I have something error. For eg. when i upload 3 images, it is ok for show as 3 thumbnails and save them to file. when i delete one of them, it is also ok for delete it (it is really delete in file) but it’s not still to show another 2 thumbs (it is not delete in file). I think they should be see as thumbnails.
        Here is my code. Pls check for me.

        index.php –
        function removeImage(e) {

        var fid = $(e).attr(“fileid”);
        alert(fid);
        var tid = $(e).attr(“location”);
        //alert(tid);

        $(“#supportedfiles”).show();

        //remove the temporary image files created by the image

        $imagethumb = tid;
        $.ajax({
        type: ‘POST’,
        data: {
        action: ‘deleteimage’,
        //imagefile: $imagefile,
        imagethumb: $imagethumb,
        },
        url: ‘script.php’,
        success: function() {
        $(‘. ‘+fid).remove();
        }

        })

        return false;
        }

        script.php –

        And I want to send u my codes with email because I want to share my modified codes to other ppl from your website via you.
        You are my teacher !!! :D thank you very much …. and sry for my weak english.

        • Fish

          i missed script.php code ..

  • dmitry

    doesn’t work on local, missing some files (deleteblogthumb.php)

    • jquery4u

      Hi dmitry,
      I have uploaded the missing file: deleteblogthumb.php for you.
      When I have time I will update the whole package. It’s a pretty complex bit of coding.
      Cheers
      Sam

      • Mursel

        Hi jquery4u,

        Nice and Great script. I am Waiting for the updated package.

      • Fish

        Hi jquery4u,
        is it missing file : phpfunc-myinclude.php (require_once(“phpfunc-myinclude.php”); in phpfunc-deleteblogthumb.php)?
        And my script is not working. pls check. thanks..
        function removeImage(e) {
        //alert(“Image Removed”);
        //alert(e);
        var fid = $(e).attr(“fileid”);
        //alert(fid);
        var tid = $(e).attr(“location”);
        alert(tid);
        /*$(‘.’+fid).remove();*/
        $(“#supportedfiles”).show();
        //var tid = $(e).attr(“location”);
        //remove the temporary image files created by the image
        $.get(“phpfunc-deleteblogthumb.php”,{thumb_name: tid, type: ‘js-blog’}, function(data){
        alert(data);
        });

        //return false;
        }

  • abyz

    hi
    you are great …
    ++

  • Mike

    Hi, this doesn’t work for me, it just shows a textarea under the file input, am i doing something wrong?

    • jquery4u

      @abyz – thanks!

      @Mike – have you got an example of what you mean? whats your website?

      • Mike

        Thanks for replying, yeah i’m trying testing it using xampp, i kept all the folders on here in htc doc and added a folder called images and a subfolder called thumbs.
        Is there anything i have to add to the code? pls help me out.

  • http://www.saifulbd.com Saiful Islam

    Hi Grate, these script does not works in my local machine.
    I am using wampp.

    My folder contains,
    1.ajaxfileupload.js
    2.doajaxfileupload.php
    3.form-html.php
    4.jquery.js
    5.phpfunc-deleteblogthumb.php

  • http://www.winkelcenrum.nl Arnout

    I can not get it to work ;-(
    The form is showing, but not the image when selected.
    What am I doing wrong? Please advice…
    see: http://www.winkelcenrum.nl/form-html.php

    Many thanks

    • jquery4u

      @Arnout – Doesn’t look like you have a change event on your browser box! So when the image is selected it calls the upload script.

  • http://karuppasamy11486.wordpress.com Karuppasamy

    Hi,

    i have a one problem when integrate your code to mine also when i run your code individual also i got the error

    when integrate to mine i got the javascript error
    like $.ajaxfileupload is not a function in jquery.js

    when run ur code individual i got the error alert like “SyntaxError: missing } in XML expression”

    please help what is the error

    • http://karuppasamy11486.wordpress.com Karuppasamy

      Hi i fix the problem now and i have another problem today. when i upload a png images the “imagecreatefrompng” through the error also i can’t able to upload the gif images .

      • jquery4u

        @Karuppasamy – Whats the error message say? Is the error in PHP or front-end?

        • http://- amelia

          hi sir i have same problem to SyntaxError: missing } in XML expression, what should i do?

          • http://- amelia

            sorry finally i fix the problem, just put ; after $(“#loading”) …. but now i have new problem same as mr. arnout form is showing, but not the image when selected. am i miss something? emm Is this because of my browser (fire fox) didn’t read event onChange=”javascript:previewImage(this.value)”?
            sorry for my english.. thangkyu sir

  • Lukas

    Hello.
    Can anybody give me an advice how to solve this issue with by using the given script? Or don’t you know whether it is somewhere solved?
    I have four images – each in another part of layout (so it shouldn’t be a multiple upload with using arrays of information).
    I would like to upload thumbnail of none, 1, 2, 3 or 4 of them into a form, that is then send normally by PHP.
    I tried to use 4 instances of given scripts but this made me a lot of troubles.
    Can anybody help me?
    Lukas

  • http://followmesticker.com Stuart

    I get a “{error: ‘No file was uploaded..’, name: ”, size: ”, loc: ” }” above the choose file button, and a strange input box below:
    see: http://d.pr/2Krb

    What can I do?

  • pietro

    it’s possible hava a complete working necessary? (all files?)

  • http://www.hackandlearn.com Pukchu Time

    helped me a lot in my website…
    ajax is tricky
    so i used

    here is a demo
    http://www.hackandlearn.com/viewarticle.php?id=05e83abacf987bbd02cebc24484f273a1316041045

  • http://www.hackandlearn.com Pukchu Time

    but i still cannot find ways to improve the image quality…

  • pushpa

    I used the same plugin. Images are uploading in firefox but it is not happening in other browsers. I am not getting the file parameters in other browsers. What might be the issue?

    • jquery4u

      @pushpa,

      Have you got an example mate? I would start by checking the data that is returned by the PHP. Check the syntax as Firefox may be able to handle a slight syntax error. Also how are you appending the images to the page?

      Cheers

  • http://www.site-stats.info Site Status

    I have a problem. It’s not working on IE. It doesn’t upload the image at all.

    • jquery4u

      @Site Status,

      It’s does work in all versions of IE. Have you got the url where your trying to do this?

      Cheers

      • http://mindair.com robby

        Hi,
        Plugin is great, but it doesn’t work in IE. First image is uploading and show in browser, but i can’t change it on another. I have used IETester. Results equal for local and your demo.

  • Pingback: 10 jQuery File Uploads | jQuery4u

  • mayfield

    hi, i have javascripts problem:
    – cannot read property ‘body’ of undefined
    – cannot read property ‘error’ of undefined

    what might be the issue?
    thanks

    • http://jquery4u.com/ jQuery4u

      Hi Mayfield, never seen that before! What code are you using? Can you share a screeshot?

  • Natalia

    Hello!
    This looks like a very nice script. I haven’t tried it yet, but already have a question :)
    I am using Zend framework and Smarty templates. I have a file upload that is in the form, and right now everything works fine, meaning the file is getting saved to a proper location as the other inputs form a form. I need to add a thumbnail preview of an image. My question is, will the AJAX upload, the way it is here, interfere with the saving of the file that I have now. I will be trying anyway, so will let you know whatever is happening :)
    I hope I explained well enough :)
    Thank you for your time.

    • http://jquery4u.com/ jQuery4u

      Hi Natalia, yes the file upload method here works differently, it uploads the image and creates a thumbnail which the url is returned and displayed to the user. Then on form submit the image url is passed to the backend where the uploaded image is renamed and filename stored in the database. I have used Smarty heaps before and it will work well with this image upload method. I’ll see if I can piece together some code for you.
      Sam

  • fucku

    this is so useless

  • Zohra S

    Sam, there are multiple issues here for the newest IEs, and one even for chrome.

    IE freaks out for the createUploadFrame function, because it just doesn’t understand this:

    var io = document.createElement(”);

    And, the second issue is if you’re using this script just to display a resized version of the image, the initial form doesn’t send in the actual image in IE or Chrome. The field becomes empty.

    Any clues?

    • http://jquery4u.com/ jQuery4u

      Hi Zohra, I’ve done a revised version of this script and will post on the blog in next couple of days. It should resolve these issues.
      Sam

  • inearza

    open demo site have trojan ?

  • sean

    hello to all, I’ve tried to use this scipt in my post ad form, it is not working.

  • kaore

    I just wrote up an article describing how to do this without jquery and using an iframe here: http://tech.cibul.net/upload-and-display-an-image-without-a-page-refresh/

    • http://jquery4u.com/ jQuery4u

      no demo mate?

  • arminder

    hi …

    nice script

    thanks a lot