Originally, i wanted to create a progress bar with JavaScript using Ajax as assistance to prompt the server for raw post data. But it seems like PHP doesn't provides raw post data manipulation for its users. Many uses Perl, Flash, Python and etc. which you can see where i am going (Other languages instead of PHP). PHP 5.2 onwards there is an extension to help PHP user manipulate this data but it required the end users or plugin users to adjust their PHP settings to enable certain extension and variables in the PHP setting which is not what i wanted. Therefore, this tutorial is created instead which doesn't required the end users to adjust anything and will be more welcome by programmers. (messing up the setting of PHP can result to security flaws and etc.) But the fall back of this method is that they won't be able to know the progress of upload. (in term of percentage %)
Aim
The aim of this tutorial is to demonstrate a simple method to help programmers who is dealing with iFrame or Ajax (which ever you prefer to call it) upload function to keep track of the upload completion of the file. Simple and Easy is the key objective for this tutorial.
Requirement
There are a few requirement you will need other than reading this post.
- Asynchronous upload function - Easy asynchronous upload function using iFrame
- JavaScript file - this is the main function to check whether iFrame has complete uploaded the file
- Read!
Concept
I like to have a concept sub section to make my reader understand how it work before showing out all the boring codes. In order to be informed that the upload process has completed, the iFrame will have to show certain message (error and complete message) so that our JavaScript can be informed with the process of the upload function. We will accomplish this with the following steps
- Start uploading From iFrame
- loading.gif start running
- a 'check_complete()' function is being initialize to check the iFrame for message
- iFrame shows a message, determine this message (error or success) and output the result accordingly
Asynchronous upload function
Unlike the previous tutorial on asynchronous upload function, i have updated some codes into the previous codes in order demonstrate this tutorial. (Please visit the simplify version of the Asynchronous upload function on the link if you find this complicated)
HTML
<form id="my_form" name="form" action="upload.php" method="POST" enctype="multipart/form-data" >
<div id="main">
<p>
MAX SIZE: 100kb<br/>
ALLOWED FILES EXTENSION: .png, .gif, .jpg, .jpeg<br/>
Other than the above mention rules, all other type of file upload will result in error alert.<br/></p>
<input type="hidden" name="MAX_FILE_SIZE" value="100000" />
<input name="my_files" id="my_file" size="27" type="file" />
<input type="button" name="action" value="Upload" onclick="redirect()"/>
<iframe id='my_iframe' name='my_iframe' src="">
</iframe>
</div>
<div id="loading"></div>
</form>
The only differences in this part is the instruction added for the demo to work and a div block box for the loading.gif to appear.
JavaScript
function redirect()
{
document.getElementById('my_form').target = 'my_iframe'; //'my_iframe' is the name of the iframe
document.getElementById('my_form').submit();
var iFrame = document.getElementById("my_iframe");
var loading = document.getElementById("loading");
iFrame.style.display = "none";
iFrame.contentDocument.getElementsByTagName("body")[0].innerHTML = "";
loading.style.display = "block";
checkComplete();
}
In the redirect method which is also the key to use to perform this asynchronous upload function has a few more sentences as shown above which is different from the previous method that only required the first 2 sentence. The above new codes indicate that every time the upload button is pressed, the iFrame should be reminded to be disappeared and the internal of the iFrame should be empty(no message), this sentence is there so that we can perform multiple upload without any problem. Others will required loading.gif to appear to inform the users that it is in progress and the checkComplete() method (the method is located below) is invoked to start monitor the upload completion.
PHP
<?php
$uploaddir = '/images/';
$uploadfile = $uploaddir . basename($_FILES['my_files']['name']);
$file = $_FILES['my_files'];
$allowedExtensions = array("jpg", "png", "gif", "jpeg");
if($file['error'] == UPLOAD_ERR_OK) {
if(isAllowedExtension($file['name'])) {
# Do uploading here
$uploaddir = '/images/';
$uploadfile = getcwd ().$uploaddir . basename($_FILES['my_files']['name']);
//if (move_uploaded_file($_FILES['my_files']['tmp_name'], $uploadfile)) {
echo "success";
//} else {
// echo "error";
//}
} else {
echo "Invalid file type";
}
} else die("Cannot upload");
function isAllowedExtension($fileName) {
global $allowedExtensions;
return in_array(end(explode(".", $fileName)), $allowedExtensions);
}
?>
What i have added here which is different from the previous version is that i have added a simple validation to validate extension of the files before uploading them into the server in order to demonstrate the different message of this tutorial (error and success).
CSS
Please refer to the demo files if you are interested in the CSS of this demo.
JavaScript
Here is the main method to check for the upload completion from the iFrame.
var checkComplete = function()
{
var iFrame = document.getElementById("my_iframe").contentDocument.getElementsByTagName("body")[0];
var loading = document.getElementById("loading");
if(iFrame.innerHTML == "")
{
setTimeout ( checkComplete, 2000 );
}
else
{
if(iFrame.innerHTML == "success")
{
loading.style.display = "none";
document.getElementById("my_iframe").style.display = "block";
//successful do something here!
}
else
{
loading.style.display = "none";
alert("Error: "+ iFrame.innerHTML);
}
}
}
The first few sentences take their DOM object for loading.gif and iframe into a variable. Then we check whether the iframe 'body' block contains any message. If there isn't any message we do a recursive loop by calling itself again after 2 second else we hide the loading.gif and show the iframe message if and only if the message in the iframe is 'success' all other message will result in alert to the screen.
Demo
Determine an asynchronous upload completion demo consist of the aim of this post. However, no files will be stored in the server as i am merely providing a demo site to demonstrate this concept. The condition for a success message to appear are stated in the demo site. If you are interested to look up the overall code in this demo, you can download the file at JavaScript-upload-completion-alert. (Please be reminded you will need to setup a webserver in order to test it in your own pc)
function redirect()
{
document.getElementById('my_form').target = 'my_iframe'; //'my_iframe' is the name of the iframe
document.getElementById('my_form').submit();
var iFrame = document.getElementById("my_iframe");
var loading = document.getElementById("loading");
iFrame.style.display = "none";
iFrame.contentDocument.getElementsByTagName("body")[0].innerHTML = "";
loading.style.display = "block";
checkComplete();
}