Desktop Image Uploaders Using Adobe AIR and JavaScript

What makes the web fun? Is it the cool applications like Google Maps, which are neat but not particularly fun? Is it social networks like Facebook? Sure, that’s a little fun. But what really gets passed around the web? Viral video. Nothing catches our interest like video and images, which is ironic, as the HTML technology for uploading media to web sites is one of the worst parts of browsers.

To solve the upload problem, most of the big services have dedicated upload applications that run on all the different platforms. But it takes a lot of work to develop them, especially when they have to run on both Macintosh and Windows. Or is it so tough? As it turns out, Adobe AIR technology makes it possible to write applications for any platform using just HTML and JavaScript. It also offers access to cool desktop features, notably drag and drop.

In this article I’ll show you how to build an uploader in Adobe AIR using JavaScript and HTML. My first example will show the upload of a single file. Then I’ll build on that example to show how to handle uploading a batch of files. I’ll finish by extending the example to show the list of files currently available on the server after they are uploaded.

It all starts with the PHP code for the server.

The Server PHP Code

As with most things having to do with PHP, the code to handle uploading a file from a web browser is remarkably simple. The code in Listing 1 moves the uploaded file to the uploads directory.

Listing 1. basicFileUpload.php

I then put that file on my local Apache web server and create the uploads directory.

Now I want to test the file using a web client, so I write the HTML page that Listing 2 shows.

Listing 2. upload.html

Using my browser, I navigate to the upload.html web page and see the window displayed in Figure 1.

Figure 1. A basic HTML upload page

Ok, it’s not much to look at, but it gets the job done. I first choose the file (a picture of my daughter), and click the upload button. After the image is uploaded, the window looks like the one Figure 2 shows.

Figure 2. The result page after the upload

This file certainly works, but it’s not a great experience. I can’t drag and drop a bunch of files and watch them upload. I get no feedback about how the upload is proceeding. It’s really not a great way to get media up to service. So let’s use Adobe AIR technology, HTML, and JavaScript to create an uploader.

Building the Simple Adobe AIR Uploader

Developing for Adobe AIR requires downloading and installing the Adobe AIR runtime and the Adobe AIR software development kit (SDK). After they’re installed, the first step is to create an XML file that tells Adobe AIR where the root HTML file is located, and provides a name for the window, a size, the icons for the application, and so on. Listing 3 shows this file.

Listing 3. application.xml

This might look like a lot of code, but there really isn’t much to it. The most important tags are the <content> tag, which specifies the name of the HTML page, and the <width> and <height> tags, which tell Adobe AIR how big the application should be.

As I work this example through the article, this application.xml file really won’t change until the end, when I just adjust the size to give me a little more room.

The file that will be contained in the Adobe AIR window is called appSandbox.html and is shown in Listing 4.

Listing 4. appSandbox.html

There are two key elements to this file. The first is the uploadToServer method, which uploads a file to the server using the Adobe AIR Request and Uploader objects. This function also uses the Adobe AIR File object to read the contents of the file to be uploaded and format the upload request for the server. I’ve chosen to manage the file upload myself, but you can use the upload() method on the File object to upload the file.

The second important part is the IFRAME at the bottom of the page, which includes the classicSandbox.html file. That file contains the user interface for the application and the drag-and-drop code.

But before I get into that, I want to explain why there are two HTML files instead of just one. The answer is security. Because Adobe AIR applications are run on users’ desktops and have access to all their files, the applications need to be secure. That means that any JavaScript code that has direct access to the Adobe AIR APIs needs to be secure. So Adobe has wisely created a “sandbox” scheme in which the application sandbox has access to the complete Adobe AIR API but can’t “eval” the code. The JavaScript in the “classic” sandbox can run the eval command but can’t access the Adobe AIR methods that are security-critical.

That’s a really brief discussion of why there are the two files; the Adobe web site contains a lot more information about this subject. The long and the short of it is that you need two files, and Listing 5 shows the second file.

Listing 5. classicSandbox.html

This file is certainly a lot smaller because most of the hard work was done in the appSandbox.html file in Listing 4. All this code needs to do is handle dragging and dropping the file and then passing the first file reference off to the uploader code in the appSandbox.html file.

To test it, I use adl application.xml to launch the application on my desktop. I then drop a file onto it, as Figure 3 shows.

Figure 3. The simplest possible uploader

There really isn’t any feedback at this point. To see whether the file has been uploaded, I just look in the uploads directory to make sure it’s there.

Obviously, this still isn’t a great user experience. It needs to handle multiple files and provide some feedback as to how the uploads are going. So let’s add those features to the application.

Adding Some Feedback

Because most of the modifications I’m going to make are to the user interface, I’ll show the modifications to the classicSandbox.html file, as Listing 6 shows.

Listing 6. classicSandbox.html

At the bottom I wrap the Drop files here text in the <div> tag. Then, at the top of the file, I have a new function called updateFileList, which updates the <div> tag with the list of files that are waiting to be uploaded. The updateFileList function is called from the appSandbox.html file. Listing 7 shows the modifications I made to the file.

Listing 7. appSandbox.html

I used the bridge between the application sandbox and the classic sandbox to ask the uploader to update the interface as each of the files is uploaded. At the bottom of the file you can see where I hook onto the COMPLETE event to start the upload of the next file in the list and to update the interface to show which files remain in the queue.

To test this, I launch the updated code using the adl application in the Adobe AIR SDK and drag four images onto it, as Figure 4 shows.

Figure 4. An uploader that handles multiple files

I then see a list of the four files, as Figure 5 shows.

Figure 5. The list during the upload

The file names disappear one by one until the Drop files here text returns to indicate that all the files were uploaded and the application is ready to accept some more files.

But still I’m not happy because I really want to see what files are up on the server so that I can make sure my files really got there.

Listing the Uploaded Files

To get the list of files I need something on the server that I can call to get the list of files. This code, called uploadedFileList.php, is shown in Listing 8.

Listing 8. uploadedFileList.php

This is pretty simple stuff. I just scan the uploads directory and create an XML tag for each of the images in the directory.

The user interface HTML and JavaScript code need to be updated as well, and that’s shown in Listing 9.

Listing 9. classicSandbox.html

The new code includes a <div> tag at the bottom that contains the list of uploaded files. At the top of the file is a new function called updateUploadedFiles, which updates the <div> tag with the list of files returned from the server. This is the complete code for the classicSandbox.html file. Listing 10 shows the complete code for the appSandbox.html file.

Listing 10. appSandbox.html

The updateFileListInWindow function is the big new addition to this file. It makes the request of the PHP script on the server, then parses the XML response to get the URLs of the uploaded files.

To test this final version of the uploader application, I again launch it on my desktop, as Figure 6 shows.

Figure 6. An uploader with a drop region and a list of uploaded files

Now I can drop files onto the window and see then disappear from the list of files to upload and reappear in the complete list of uploaded files on the server.

Where to Go from Here

This simple example just scratches the surface of what can be done with Adobe AIR in combination with JavaScript and HTML. From here you could add code to authenticate the user against the system. Adobe AIR allows for child windows, which make building that type of functionality a lot easier. In addition, you can alert the user about the status of uploads by bouncing the dock icon on the Mac or showing icons in the system tray on Windows. In fact, almost every aspect of the local operating system is available to you through simple JavaScript objects.

I’m really excited about Adobe AIR, particularly because it uses the technologies we are already familiar with, like JavaScript and HTML, to build applications. In fact, you could re-use parts of the HTML or JavaScript code you use on your web site to build desktop applications. If you use this example as a basis for your code, which I encourage you to do, feel free to contact me either via the comments or directly, to let me know. Then we can update this article with our work to show more engineers how to use Adobe AIR.

About Cal Evans

Many moons ago, at the tender age of 14, Cal touched his first computer. (We're using the term "computer" loosely here, it was a TRS-80 Model 1) Since then his life has never been the same. He graduated from TRS-80s to Commodores and eventually to IBM PC's. For the past 10 years Cal has worked with PHP and MySQL on Linux OSX, and when necessary, Windows. He has built on a variety of projects ranging in size from simple web pages to multi-million dollar web applications. When not banging his head on his monitor, attempting a blood sacrifice to get a particular piece of code working, he enjoys building and managing development teams using his widely imitated but never patented management style of "management by wandering around". Cal is happily married to wife 1.31, the lovely and talented Kathy. Together they have 2 kids who were both bright enough not to pursue a career in IT. Cal blogs at and is the founder and host of Nomad PHP