06 March 2012

Uploading file using Dojo and CGI AJAX

Sample Html file: (upload.html)

    <title>Upload file </title>
    <link href="/css/sitestyles.css" rel="stylesheet" type="text/css"/>
    <link rel="stylesheet" type="text/css" href="/js/dojo/dojo/resources/dojo.css"/>
    <link rel="stylesheet" type="text/css" href="/js/dojo/dijit/themes/tundra/tundra.css"/>
    <script type="text/javascript" src="/js/dojo/dojo/dojo.js" djConfig="parseOnLoad: true"></script>

    <script type="text/javascript">

    //using this early for the forceNoFlash test:

    // Function to upload the file to server
    function doUpload () {
        var f0 = dijit.byId('btn0');
        dojo.byId("fileToUpload").innerHTML = "uploading...";

        // If we want to send other fields along with the file
        // use submit method other use simple f0.upload() method

    dojo.addOnLoad(function() {
        var f0 = dijit.byId('btn0');
        // Show file selected in div
        // data contains list of files selected
        dojo.connect(f0, "onChange", function(data){
        console.log("DATA:", data);
        var n = dojo.byId('fileToUpload');
        n.innerHTML = "";
        dojo.forEach(data, function(d){
            n.innerHTML += d.name

        // When file upload is in progress
        // Showing status inprogress
        dojo.connect(f0, "onProgress", function(data){
        console.warn("onProgress", data);
        var n = dojo.byId('fileToUpload');
        n.innerHTML = 'Uploading file';

        // Show the uploaded image
        // on successful upload of image
        dojo.connect(f0, "onComplete", function(data){
        console.log("Uploaded file");
        var uf = dojo.byId('fileToUpload');
        var d = data[0];
        if ( d.status == "0" ) {
            uf.innerHTML = "<img src='" + data[0]['file'] + "'/>";
        } else {
            uf.innerHTML = d.message;

<body class='tundra'>

    <!-- Will show the status of file upload -->
    <table border='1' width='30%'>
    <td align='center'>
    <div id="uploadedFile"></div>

    <!-- Other data to send to server along with file -->
    <form id='logoForm' dojoType='dijit.form.Form' accept="image/gif,image/jpeg">
        <div class='disabled'>
        <input name='action' value='upload' type='input'>
    <!-- Show uploaded file -->
    <div id="fileToUpload"></div>
    <!-- File uploader dijit -->
    <div id="btn0"
        uploadOnChange=false isdebug=true htmlFieldName=orglogo
        uploadUrl="/sampleapp/upload-file" >
    <div dojoType='dijit.form.Button' label='Upload' onClick='doUpload()'></div>

HTML tag

div id btn0 is File upload dijit with following properties :
force="html" if "html" html file uploader is used to upload file.
To use flash uploader set to "flash"

uploadOnChange=false If true selected file will be uploaded as soon as selected.

htmlFieldName=orglogo Name of html field under which the file-content to send

uploadUrl="/sampleapp/upload-file" Upload URL

Java script function:

dojo.connect(f0, "onChange", function(data){

Function used to display the selected file. This function will be called when file
browser dialoug is opened and we select a file. data will look like
[{ name="icon-server.png", size=0}]

dojo.connect(f0, "onProgress", function(data){

Function will be called when file uploading is in progress data will contain the
list of files. data will look like
[{bytesLoaded=1, bytesTotal=1, name="icon-server.png", percent=100, size=0, type=""}]

dojo.connect(f0, "onComplete", function(data){

Function will be called with server finishes the file process. It doesn't mean
successful file upload. You need send correct message and need to check from
data. data will look like
[{ status=0, file="/var/tmp/icon-server.png"}]

Server should send response in following format only and the should set header
Content-type: text/html.

Response format for success

Response format for error
<textarea>{"status":1,"file":"/var/tmp/a.xcf","message":"Invalid file format"}</textarea>

Response should be written in "textarea" tag

To send other form fields along with file use
var formdomNode = dijit.byId("logoForm").domNode;

If you don't want any other field to send along file use
dijit.byId("btn0").upload() method

Sample server side code using Perl CGI
upload-file cgi

#!/usr/bin/perl -w

use strict;

use CGI;
my $result = {status => 1};

my $cgi = new CGI;
my $action = $cgi->param('action');

print "Content-type: text/html \n\n";

if ($action eq "upload") {

    # Set MAX max upload limit
    $CGI::POST_MAX = 1024 * 5000;

    my $msg;
    my $status = 0;
    my $INTERNAL_ERR = "Internal error";

    # What is field having file contain
    my $fieldname = 'orglogo0';
    my $filename = $cgi->param($fieldname);
    if (! $filename) {
    $msg = "File size exceded";

    # Get file upload handle
    my $upload_filehandle = $cgi->upload($fieldname);
    my $uploadfilepath = "/var/tmp/$filename";

    # Write the file to disk
    if (open(UPLOADFILE, ">$uploadfilepath")) {
    if (! binmode UPLOADFILE)  {
        $msg = $INTERNAL_ERR;
    } else {
        while (<$upload_filehandle>) { 
        print UPLOADFILE;
        unless (close UPLOADFILE) {
        $msg = $INTERNAL_ERR;
    } else {
    $msg = $INTERNAL_ERR;

    if ($msg) {
    $status = 1;

    # Send status to client
    my $out = {
        file => $uploadfilepath,
        status => $status, 
        message => $msg

    # To handle cross platform problem dojo need the response in following format.
    # Reference: http://dojotoolkit.org/reference-guide/dojox/form/FileUploader.html
    print "<textarea>". JSON::to_json ($out)."</textarea>";
    exit 0;


$result->{message} = "command not found";
print "<textarea>" . JSON::to_json($result) . "</textarea>"; 

No comments:

Post a Comment