Article

Learn Adobe AIR, Part III: Beyond the Browser

Page: 1 2 3

Handling File Uploads

Now that we’ve authenticated the user and displayed the latest news, all that’s left for us to do is enable the file upload feature. The typical and most convenient approach we can take is to use a plain old form. Just as we can use Ajax file uploads on a typical web page within Safari, we can do likewise in AIR. Unfortunately, it’s not quite that simple—an Ajax file upload doesn’t actually exist; the JavaScript XMLHttpRequest object can’t handle files. Most implementations of the concept involve redirecting the form to an iframe, and as AIR places security restrictions on remote content, this isn’t a reliable option for us.

Instead, AIR provides an upload method within every File object. Given a reference to a file, we can upload with just a URLRequest object and the name of the faux form field of which the file should pretend to be a part. It will then make an HTTP request, as per the URLRequest data; the only real limitation is that we can’t handle the response—we have to make a second request to list our files after the upload.

Here’s how our form appears at this point:

<div class="form">  
 <div class="input">  
   <input type="file" name="file" id="file" />  
   <input type="submit" value="Upload" id="uploadbtn" />  
 </div>  
</div>

To implement Ajax for the file upload, we just work out when that upload button is clicked, construct a File object, construct a URLRequest object, and then upload the File object to the URLRequest. Just inside the end of the $(document).ready block in the behavior.js file, add the following:

$("#uploadbtn").click(function(){  
 filePath = $("#file").val();  
 file = air.File.userDirectory.resolvePath(filePath);  
 request = new air.URLRequest(server + 'uploadService.php');  
 request.method = air.URLRequestMethod.POST;  
 request.data = "token="+sid;  
 file.addEventListener(air.Event.COMPLETE, uploadComplete);  
 file.upload(request, "AIRfile");  
});

The form field with the id “file” has a value corresponding to the appropriate file path. The first two lines in this block calculate that file path, and give us an air.File object (in the variable: file) pointing to the file the user has chosen; it’s this File object that will manage the upload. We then construct our request variable, pointing it to our upload web service and passing in our session ID stored in sid. Finally, we bind the uploadComplete function as a callback to the air.Event.COMPLETE event and then upload the file.

Our server-side upload script

Let’s have a look at the upload service in serverfiles/uploadService.php. Here’s the PHP code:

<?php  
session_start();  
 
if (empty($_FILES['AIRfile']) && !empty($_SESSION['latestfile'])) {  
 echo "<li>$_SESSION[latestfile]</li>\n";  
}  
if (!empty($_FILES['AIRfile'])) {  
 $_SESSION['latestfile'] = $_FILES['AIRfile']['name'] .    
     ' - '  
. $_FILES['AIRfile']['size'];  
 exit;  
}  
?>  
<li><?php print_r($_REQUEST); ?></li>  
<li><a href="http://bitmeta.org/air/dump/example.txt">example.txt</a></li>  
<li>Your session token is <?=$_REQUEST['token']?></li>

This script first initializes the session handler, and checks to see if a “latestfile” variable has been stored for the current user. If so, we output it. Next, we check if any files are being uploaded—here, we don’t upload any files, as this is a demonstration server. If a file is being uploaded, we set that latestfile session variable, so that it will be visible the next time we check back; we then end the script there. If the script continues past this point:

 exit;  
}

We know that we’re not currently uploading a file, but are instead checking back after uploading a file. We then proceed to output some sample information for the end user.

Checking back after the upload

Now that we’ve uploaded the file, we need to check back to grab the current list of files from the server. We used a callback function in behavior.js here:

file.addEventListener(air.Event.COMPLETE, uploadComplete);

We now need to write that uploadComplete function. Add the following code inside the $("#uploadbtn").click(function(){ block:

function uploadComplete(event) {  
 request = new air.URLRequest(server + 'uploadService.php');  
 request.data = "token="+sid;  
 loader = new air.URLLoader();  
 loader.addEventListener(air.Event.COMPLETE, statusComplete);  try {  
   loader.load(request)  
 } catch (error) {  
   air.trace("Could not retrieve file list.");  
 }  
 
 function statusComplete(event) {  
   $("#filelist").html(event.target.data);  
 }  
}

This makes another call to uploadService.php, passing in the session ID—only this time we use a URLLoader object as we want to read the response. The uploadService.php script will output a series of <li> tags for our list, so we use the html jQuery function to take the response body—in loader.data, or event.target.data inside the callback—and place it straight into our <ul id="filelist"> on the page. When we run this script with a sample robots.txt file, the result appears as expected.

The expected result

And we’re done! You can download our completed behavior.js file from the code archive.

Further Reading

Now that we’ve completed a simple web-enabled AIR application, you’re ready to take your web applications and services beyond the browser. You might find these handy references useful in further exploring the topics we’ve covered:

Test Yourself

You can test your comprehension of this tutorial with a short quiz, and stand to receive a FREE copy of the pocket guide, Adobe AIR For JavaScript Developers, for your efforts. The guide will be delivered FREE, courtesy of Adobe Systems, but this offer is only available to the first 100 people, so get in quick! (If you do miss out, you can still download the book in PDF format for free.)

Take the quiz!

If you liked this article, share the love:
Print-Friendly Version Suggest an Article

Sponsored Links

Rate This Article

  • 1
    Poor
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
    Great

Comment on This Article

Have something to say?

Post A Comment

You need to be a member of the SitePoint Forums to comment on this post. Sign Up

Already a member? Post using your SitePoint Forums account: