Friday, June 1, 2007

Image upload and preview without a page refresh

Whenever I am asked to develop a page where content needs to be fed without a refresh, I think of AJAX. And whenever I think of Asynchronous Javascript and XML; my stomach rolls over and my eyes bulge out !!! I've been writing web apps using AJAX for more than 2 years now; but somehow I never happen to get it right in the first shot.

So, I was sitting glumly, readying myself to drum out that javascript code; when Swapna looked across my shoulder and said,
"You don't NEED ajax for that !!!"
"Huh??? You don't?"
"No... The older technologies are good enough !!!"

Yup !!! I was as surprised as you too. Let me tell you what I learnt from her.

Suppose you want to build a simple application with an image upload functionality, and you want to display the uploaded image in the preview screen soon as it is uploaded. Now, how do you do this without AJAX? With some smart programming, of course.

Let's see how...

First, you will have to have a control which will allow you to upload the image to the server.

<form name="frmUpload" id="frmUpload" enctype="multipart/form-data" action="ImageUploadView.php?strAction=upload" target="_blank" method="POST">
<h1>Test Page For file upload and access the file on the current page</h1>
<input name="strUpload" id="strUpload" type="file" value="Select Image"><br/> <br/>
<a href="javascript:void(0);" onclick="javascript:UploadImage();">Click to upload image</a>
<br />
<br />
<img id="imgUpload" name="imgUpload" src="x.jpg">
</form>



Next, we define a Javascript function UploadImage(), that will submit to the same PHP file, but in a new window.

// description : upload the image to the server
// notes : 1. open a new window
// 2. submit the form to it

function UploadImage()
{
window.open("","upload_image");
document.getElementById( 'frmUpload' ).target="upload_image";
document.getElementById( 'frmUpload' ).submit();
}



We also define another Javascript function, whose purpose is to reset the source of the image on the current page.

// description : set the src of the image to the uploaded one
function SetImageFile( pImgSrc )
{
document.getElementById( 'imgUpload' ).src=pImgSrc;
}



The image upload request is handled on the server. At the server end, we throw Javascript code that calls the function SetImageFile().
**Please note that the script will require write permissions to the directory it's residing in.**

<?php
$imagename = uniqid('ff') . ".jpg";


// move (actually just rename) the temporary file to the real name.
// write permissions are required by the script to place the image here.
move_uploaded_file ( $_FILES['strUpload']['tmp_name'], $imagename );

print ( "<script type=\"text/javascript\">" );

if(file_exists($imagename) && $_FILES['strUpload']['name'] != '')
{
print ( "self.opener.SetImageFile(\"" . $imagename . "\");" );
}

print ( "window.close();" );
print ( "</script>" );
?>


And Viola !!! The uploaded image is displayed in the page without needing a refresh.

What are we doing here? We are -
  • submitting the FORM to the server.
  • at the server, we store the image.
  • we then print javascript which is actually calling the javascript functions residing in the parent document.
  • which then, replaces the image source.
The full code is given below. Copy the code into a file, say, ImageUploadView.php, and check it out.

<?php
// file name : ImageUploadView.php
?>
<html>
<head>
<title>Image Upload and Preview without Page Refresh</title>
<script type="text/javascript">

// description : upload the image to the server
// notes : 1. open a new window
// 2. submit the form to it
function UploadImage()
{
window.open("","upload_image");
document.getElementById( 'frmUpload' ).target="upload_image";
document.getElementById( 'frmUpload' ).submit();
}

// description : set the src of the image to the uploaded one
function SetImageFile( pImgSrc )
{
document.getElementById( 'imgUpload' ).src=pImgSrc;
}

</script>
</head>
<body>

<?php
// case : show the FORM, by default
if( !isset($_REQUEST['strAction']) || $_REQUEST['strAction'] == "" )
{
?>
<form name="frmUpload" id="frmUpload" enctype="multipart/form-data" action="ImageUploadView.php?strAction=upload" target="_blank" method="POST">
<h1>Test Page For file upload and access the file on the current page</h1>
<input name="strUpload" id="strUpload" type="file" value="Select Image"><br/> <br/>
<a href="javascript:void(0);" onclick="javascript:UploadImage();">Click to upload image</a>
<br/>
<br/>
<img id="imgUpload" name="imgUpload" src="x.jpg">
</form>
<?php
}

// case : upload the file
else
{
$imagename = uniqid('ff') . ".jpg";

// move (actually just rename) the temporary file to the real name.
// write permissions are required by the script to place the image here.

move_uploaded_file ( $_FILES['strUpload']['tmp_name'], $imagename );

print ( "<script type=\"text/javascript\">" );

if(file_exists($imagename) && $_FILES['strUpload']['name'] != '')
{
print ( "self.opener.SetImageFile(\"" . $imagename . "\");" );
}

print ( "window.close();" );
print ( "</script>" );
}
?>
</body>
</html>



Neat. Ain't it? No creating requests. No opening connections. No parsing responses. No cross-browser support headaches. No Nothing.

Just Plain Simple and Neat !!!

God give Swapna a long life !!!