Wednesday, February 17, 2021

AJAX Style File Upload

Easily Upload Files Without Refressing The Page

Ever wanted to upload files using AJAX without reloading the page? There are a number of sites that describe how this can be achieved. For the most part, the effect is achieved using iframes and javascript. This tutorial will go through the process of creating a file upload AJAX form and a PHP script which will return a status of 'success' or 'error', as well as, a few other details about the upload. To simplify the whole process, I found that using jQuery and the jQuery Form Plugin is the easiest and best solution for getting this done quickly.

Try the DEMO for this tutorial.

This exurb from the jQuery website provides a good starting point and overview of what we want to achieve.

The jQuery Form Plugin allows you to easily and unobtrusively upgrade HTML forms to use AJAX. The main methods, ajaxForm and ajaxSubmit, gather information from the form element to determine how to manage the submit process. Both of these methods support numerous options which allows you to have full control over how the data is submitted. Submitting a form with AJAX doesn’t get any easier than this!



 

Basically, we are going to create a form that lets us gather some basic information and select a file for upload. If any of the fields are left blank, we will receive an error message. If the file is not an image file, we will also receive an error message. If everything goes right, the file is uploaded and the file name, ext are returned. While uploading, the screen will display a message box advising that a file is being uploaded and we should wait.

So, let's get right to it.

Creating The Form

This is a basic form which gathers some information, allows us to select a file to upload, and provides an 'upload' button. Quite simple.

<h3>AJAX Style Upload</h3>
<div style="padding-bottom:15px;">
    <p>This is an simple example of an ajax-style upload using ajaxform.js, json and plain, old css.<br>
    To test, just upload an image file.<br><i>Note: Files will be erased immediately after upload.</i></p>
</div>
<div style="float:left;background-color:#eeeeee;border:solid 1px #cccccc;padding:8px;">
    <form method="post" action="uploadimage.php" id="upload">
    <div style="display:none" id="upload-message"></div>
    <div style="display:none" id="filename"></div>
    <div style="display:none" id="filetype"></div>
    <div>
        <div class="label">Name</div>
        <input type="text" name="name" size="30" />
    </div>
    <div>
        <div class="label">City</div>
        <input type="text" name="city" size="30" />
    </div>
    <div>
        <div class="label">Image</div>
        <input type="file" name="uploadimage" size="50" />
    </div>
    <div>
         <div class="label"> </div>
         <input type="submit" value="Upload..." />
         <input type="reset" value="Reset" />
    </div>
    <div id="wait" class="wait"><br>Uploading image. Please wait...<br><br style="line-height:4px;"><img src="images/progress.gif" border="0" height="16" width="16"></div>
    </form>
</div>
<div class="image" id="upload-image"></div>

Here we have input fields for a Name, City and File to upload. There are four hidden sections which our jQuery code will use to display the response from the PHP code. An error or success message will be displayed in the "upload-message" div. On success, the file name will be displayed in the "filename" div and the file type will by displayed in the "filetype" div. Also, on success, the image will be displayed in the "upload-image" div.

We also have a div called "wait". This section is hidden, but will be displayed while the uploading is occurring to alert the user that something is happening. I think this looks better than just displaying a "Loading..." message, as many other examples do.

CSS Code

To create a pretty form and control the divs, we need to add some CSS. I've done this in the HTML file itself, rather than a separate CSS file just to make the code more concise. You could easily link this code to the page as well. 

<style>
  body {font-family:tahoma,arial;font-size:13px;}
  div {padding-top:3px;}
  input {font-size:13px;}
  h3 {font-size:16px;font-weight:bold;padding-bottom:0px;margin-bottom:0px;}
  .label {width:80px;float:left;}
  .image {clear:both;padding-top:20px;display:none;}
  .wait {
      position:absolute;
      top:36%;
      left:50%;
      margin-left:-150px;
      height:70px;
      width:300px;
      background: #ebebeb;
      border:solid 3px #636363;
      display:none;
      -moz-border-radius: 4px;
      -webkit-border-radius: 4px;
      border-radius: 4px;
      text-align:center;
  }
</style>

 Note that the display attribute for the "wait" div is set to none.

jQuery Link

We need to link in the jQuery libraries.

<script src="js/jquery.js" type="text/javascript"></script>
<script src="js/jquery.form.js" type="text/javascript"></script>

jQuery Code

This is where all the magic happens. We will create a function to initialize the form and place this code at the end of the HTML. The function is called after the page loads.

<script>

function initAjaxForm(form_id, form_validations){
    var form = '#' + form_id;
    var form_message = form + '-message';

    /* enable/disable submit button */
    var disableSubmit = function(val){
        $(form + ' input[type=submit]').attr('disabled', val);
    };

    /* setup jQuery Plugin 'ajaxForm' */
    var options = {
        dataType: 'json',
        beforeSubmit: function() {
            /* run form validations if they exist */
            if(typeof form_validations == "function" && !form_validations()) {
                /* this will prevent the form from being subitted */
                return false;
            }
        disableSubmit(true);
        /* you can use these methods to access element style or css */
        $(form_message).attr('style','display:none');
        $('#filename').attr('style','display:none');
        $('#filetype').attr('style','display:none');
        $('#upload-image').attr('style','display:none');
        $(".wait").css("display", "block");
        },
        success: function(json) {
            /*
            * The response from AJAX request will look something like this:

            * status : success or error,
            * message : File uploaded successfully.
            * file : filename
            * type : image file type

            * Once the jQuery Form Plugin receives the response, it evaluates the string into a JavaScript object, allowing you to access
            * object members as demonstrated below.
            */
            $(".wait").css("display", "none");
            disableSubmit(false);
            if(json.status == 'error') {
                $(form_message).attr('style','display:block');
                $(form_message).html('<span style="color:#FF0000;font-weight:bold;">' + json.message + '</span>');
            } else {
                $(form_message).attr('style','display:block');
                $('#filename').attr('style','display:block');
                $('#filetype').attr('style','display:block');
                $('#upload-image').attr('style','display:block');
                $(form_message).html(json.message);
                $('#filename').html('File Name: ' + json.filename);
                $('#filetype').html('File Type: ' + json.filetype);
                $('#upload-image').html('<img src="' + json.filename + '" border="0">');
            }
            if(json.status == 'success') {
                $(form).clearForm(); /* clears the form but this does not clear the file input field */
                $("form")[ 0 ].reset(); /* or you can use this to clear all the fields */

            }
        }
    };
    $(form).ajaxForm(options);
}

$(document).ready(function() {
    new initAjaxForm('upload');
});

</script>

 When the form is initialized, three options are set:

dataType: set to 'json'

beforeSubmit: checks validations if any; disables the 'Upload' button; hides any existing messages (either error or success); displays the wait messages.

success: success here does not mean the file has been uploaded. It refers to the PHP script successfully returning a response.If status is an error, the error message is displayed in red. If the file uploaded successfully, a success message is displayed as well as the file name and type. The image is also displayed.

The code will show you how to change in-line style attributes and linked style attributes (css). Also show a couple of examples of combining the json response with HTML code to control the display style.

Also on success, the form is cleared. There are two methods presented. I found that the default 'clearForm()' function did not clear the file input filed. Using reset will clear this field.

PHP Code

That takes care of our basic form. Now we will look at the PHP server-side script when uploads the file and creates the appropriate response.

<?php
include('upload.php');

$response = array();

if($_POST){
    try {
        /* do some sort of data validations, very simple example below */
        $required_fields = array('name','city');
        foreach($required_fields as $field){
            if(empty($_POST[$field])){
               throw new Exception('Required field "'.ucfirst($field).'" cannot be blank.');
            }
        }
    } catch(Exception $e) {
        $response['status'] = 'error';
        $response['message'] = $e->getMessage();
        echo json_encode($response);
        exit;
    }
} else {
    $response['status'] = 'error';
    $response['message'] = 'POST data not received';
    echo json_encode($response);
    exit;
}

$target_path = "upload/";
list($file,$error) = upload('uploadimage',$target_path,'jpg,gif,bmp,png',false);
if($error) {
    $response['status'] = 'error';
    $response['message'] = $error;
    echo json_encode($response);
    exit;
}

$file_arr = explode(".",basename($file));
$ext = strtolower($file_arr[count($file_arr)-1]); /* get the last extension */

$response['status'] = 'success';
$response['message'] = 'Image file has uploaded successfully.';
$response['filename'] = $file;
$response['filetype'] = $ext;
echo json_encode($response);

?>

First we load in the PHP Upload class that controls this process for us. You can find more information on the upload class here.

If there is no POST information, we return with an error. Also, if one of the fields is blank, we return with an error.

Assuming we made it this far, we attempt to upload the file using the upload class. We supply the name of the input field from our form, the directory the file will be uploaded into (if the directory does not exist, it will be created by our class), the allowed file types by extension, and whether or not to over-write the filename if it already exists in the upload directory. If there is an error, it is returned. On success, we return the file name and type.

That's it. That's all there is to making a simple AJAX-style upload form.


 

delicious digg facebook stumble twitter myspace linkedin technorati reddit google springpad blogger | addthis Share More...

speak your mind

If you have something to say, we would love to hear from you.

Name:
Comments:
 
Speak

 

categories

Popular

Archive

newsletter

Get occasional email updates from kidmoses

donate

Donations of any size to this website are greatly appreciated.

Donate
copyright © 2004 to the present day | web design by Top Place Web Solutions
privacy | terms | login | contact