back

Tutorial: Build an Adobe AIR application using JavaScript

by Brian Rinaldi

One of the great things about Adobe AIR is that it is such an inclusive technology from a development perspective. You already know that AIR has opened up desktop development to Adobe Flex and Flash developers who may previously only have focused on the web. But you may not know that technologies like ColdFusion now have built-in support for developing AIR applications to make it easy for server-side developers to make the move to client-side desktop software development.

In this article, I discuss how Adobe AIR opens up a whole new world to yet a third type of developer — UI developers who focus on HTML, CSS, JavaScript, and Ajax. Using the same skills you have already developed to create rich web-based UIs with tools such as CSS, Ajax, and jQuery or even with Adobe Dreamweaver software, you can create desktop applications that leverage the unique capabilities of AIR APIs.

Getting started

Several IDEs are available to build AIR applications in HTML or JavaScript. For instance, the Eclipse-based Aptana IDE has offered support for creating desktop AIR applications for some time. More recently, the beta of Adobe ColdFusion Builder — the new CFML IDE — added support for creating AIR applications. For this tutorial, we use the Adobe AIR extension for Dreamweaver CS4. Assuming you already have Dreamweaver installed, you can simply download this extension and install it.

The sample application uses "The New York Times" Movie Reviews API, which enables you to search available movie reviews. You can access this API for noncommercial use. I chose this API, in part, to highlight the long list of valuable APIs "The Times" makes available as well as to make the sample application more interesting and fun. You need to get your own free API key for these examples to work.

Building the HTML code

Our application consists of a single HTML view that contains three main elements. First, it has a basic form to submit search criteria for movie reviews. The form enables users to search by several filter criteria available in "The New York Times" Movie Reviews API, including keyword, critics' picks, or DVD reviews. It also has a table listing all the results. This table is sortable and pageable without page refreshes using a jQuery plug-in called jTPS. Finally, it contains a Details section for the selected item in the table. Figure 1 shows what the application looks like.

The sample movie listing application.

Figure 1. The sample movie listing application.

To begin, create a new project in Dreamweaver, and name it whatever you like. (Mine is called "NY Times Movie App.") Next, create an index.html file in the site root. Here is the HTML code of index.html:

<html>
<head>
</head>
<body style="padding:4px;font-size:13px;">
<div id="searchForm">
Keyword: <input type="text" name="keyword" size="15" />&nbsp;|&nbsp;
Critic Pick? <input type="radio" name="critics-pick" value="Y" checked="true" />&nbsp;Yes&nbsp; <input type="radio" name="critics-pick" value="N" />&nbsp;No&nbsp;|&nbsp;
DVD? <input type="radio" name="dvd" value="Y" />&nbsp;Yes&nbsp; <input type="radio" name="dvd" value="N" checked="true" />&nbsp;No&nbsp;|&nbsp;
<input type="button" name="doSearch" id="doSearch" value="Search" onClick="doSearch()" />
</div>
<table id="demoTable" width="100%" style="font-size:13px;">
<thead>
<tr>
<th sort="decrip">Movie Name</th>
<th sort="decrip">Rating</th>
<th sort="decrip">Opening Date</th>
<th sort="decrip">Favorite</th>
</tr>
</thead>
<tbody id="movies">
</tbody>
<tfoot class="nav">
<tr>
<td colspan="4">
<div class="pagination"></div>
<div class="paginationTitle">Page</div>
<div class="selectPerPage"></div>
<div class="status"></div>
</td>
</tr>
</tfoot>
</table>
<div id="details">
<div style="float:left;font-size:11px;margin:5px;position:relative;" align="center">
<img id="thumbnail" src="" /><br />
Rated<br />
<span id="mpaa_rating" style="font-size:50px;font-weight:bold;line-height:40px;"></span>
</div>
Title: <span id="details_title"></span> <span id="fave" style="font-size:10px;"> <img src="img/star.gif" /> Favorite</span><br />
Opening Date: <span id="opening_date"></span><br />
<p id="summary"></p>
<div id="related_urls">
</div>
<div align="right">
<input type="button" name="removeFave" id="removeFave" value="Remove Favorite" onClick="removeFavorite($(this).data('id'))" />&nbsp;
<input type="button" name="saveFave" id="saveFave" value="Save Favorite" onClick="saveFavorite($(this).data('id'))" />&nbsp;
<input type="button" name="hideDetails" id="hideDetails" value="Hide Details" onClick="hideDetails()" />
</div>
</div>
</body>
</html>

There really isn't anything special about this HTML. This is a standard HTML page as far as Dreamweaver is concerned. If you'd like to see what this page will look like in Adobe AIR, simply choose File > Preview in Browser > Preview in Adobe AIR.

Integrating Ajax and jQuery

As many front-end developers know, jQuery can be an enormously powerful JavaScript framework. It allows you to easily parse the DOM, manipulate CSS, and make remote Ajax calls. You can use these features as well as jQuery's built-in event model to add some more advanced functionality to your application. To learn more and download the framework, visit jquery.com. (NOTE: following the writing of this article, version 1.4 of jQuery was released; however our application uses 1.3.2 because of compatibility issues with some code and plug-ins.)

jQuery is also famous for the extensive number of plug-ins available to expand on the built-in features. For the sample application, you want to use a prebuilt jQuery plug-in called jTPS to create a sortable table.

There's really no difference between including JavaScript libraries such as jQuery in an AIR application and a standard HTML page; simply add the links in the head of your page as follows:

<script language="javascript" type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
<script language="javascript" type="text/javascript" src="js/jTPS.js"></script>

The one caveat is that external files need to be included when you package your application. I discuss that process in more depth later in this article. However, once included, you can use jQuery in the same manner you normally would. For instance, if you want to add an initial movie search call when the page loads to populate the table data, you can use jQuery to bind a function call to the document.ready event:

$(document).ready(function () {
doSearch();
});

Our doSearch() method will actually make an external Ajax call to load the movie data via the jQuery getJSON() method. ("The New York Times" Movie Reviews API makes data available in several formats, but JSON is the easiest to use within JavaScript, in my opinion.) One interesting side note is that under normal circumstances, you would encounter some browser issues trying to load data from a different domain. However this isn't an issue within AIR; therefore, if you tried to run the following script to load movie data in the browser, the result would fail:

function doSearch() {
hideDetails();
$("#movies").html("");
$.getJSON("http://api.nytimes.com/svc/movies/v2/reviews/search.json?api-key=" + nyt_api_key + "&critics-pick=" + $("input:radio[name=critics-pick]:checked").val() + "&dvd=" + $("input:radio[name=dvd]:checked").val() + "&query=" + $("input[name=keyword]").val() + "&order=by-opening-date",
function(data){
$.each(data.results, function(i,item){
rowHtml = "<td>" + item.display_title + "</td>";
rowHtml += "<td>" + item.mpaa_rating + "</td>"
rowHtml += "<td>" + item.opening_date + "</td>"
rowHtml += "<td>" + isFavorite(item.nyt_movie_id) + "</td>"
$("<tr/>").data("entry",item).html(rowHtml).appendTo("#movies");
});
$('#demoTable').jTPS( {perPages:[10]} );
$('#movies tr').click(viewMovie);
});
}

Let's examine this code line by line. The hideDetails() method simply ensures that any open movie details are closed because you are performing a new search. Next, you need to clear the contents of the table containing the movie data. Following that, you assemble the API call, including the API key and all the values from the search form. Then you bind an anonymous function call to the result of that Ajax call that then populates the table rows with the results. Next you reinitialize the jTPS plug-in for the paged and sorted table data to display 10 records on each page. Finally, you add a click event to each row that will call the viewMovie method to populate the Details view.

Debugging JavaScript in AIR

Once you start working in JavaScript and using tools such as jQuery and Ajax, you need a way to debug difficult-to-diagnose issues such as those with data or event bindings. For instance, you might be familiar with Firebug in Firefox. Thankfully, AIR provides us with the AIR Introspector for exactly this purpose.

Dreamweaver doesn't automatically include this file for you, however, but it is included in the AIR SDK files, and you can copy it into your project files. Once you do, you simply include it as you would any other JavaScript library within your document head:

<script language="javascript" type="text/javascript" src="AIRIntrospector.js"></script>

Now, you can dump data to the Introspector console, among other places. For example, in the above doSearch() method, you can log the data to the provided console using the following line of script:

air.Introspector.Console.log(data);

Within the Introspector console, you can expand the results and view all the array elements and objects, making the whole process of JavaScript development in AIR much easier.

Adding AIR specific functionality

On top of living on the desktop and functioning as a native application, AIR applications also provide several additional features such as support for working with windows, PDF files, clipboards, file systems, and the embedded SQL database. Let's take a quick look at adding embedded database functionality to the sample application.

To begin, you need to be sure to include the AIRAliases.js file that provides JavaScript aliases for calling the AIR APIs, just as the name implies. Much like the AIRIntrospector.js, this file is not automatically included via Dreamweaver, so follow the same process for locating the file in the SDK folder and placing it in your project:

<script language="javascript" type="text/javascript" src="AIRAliases.js"></script>

The database enables users to save favorite movies that the application will remember. To start this feature, you need to add several JavaScript functions to create the database and tables when the application starts up. Call openDB() from the document.ready function discussed earlier to create the physical file for the database and open a synchronous connection to the database. (For more information about asynchronous vs. synchronous connections in Adobe AIR, refer to the AIR documentation.) Once the connection is open, execute a SQL statement to create the table for storing favorites if it doesn't already exist:

function openDB() {
var db = air.File.applicationStorageDirectory.resolvePath("movies.db");
conn.open(db);
createTables();
}

function createTables() {
var sqlStm = new air.SQLStatement();
sqlStm.text = "CREATE TABLE IF NOT EXISTS movies (" +
"nyt_movie_id INTEGER PRIMARY KEY)";
sqlStm.sqlConnection = conn;

sqlStm.execute();
}

Now that you have created the database and table, you can add favorites, remove favorites, and query favorites pretty easily. For example, here is the function for adding favorites called by the Save Favorite button in the design above:

function saveFavorite(nyt_movie_id) {
if (!isFavorite(nyt_movie_id)) {
var sqlStm = new air.SQLStatement();
sqlStm.text = "INSERT INTO movies (nyt_movie_id) VALUES (:id)";
sqlStm.parameters[":id"] = nyt_movie_id;
sqlStm.sqlConnection = conn;

sqlStm.execute();
onFavoriteSelected();
}
}

You can download the code (46K, ZIP) associated with this article to see the rest of the code for the functions to remove and query favorites.

Compiling and releasing

Once you are finished creating your AIR application and it seems to be working as you expected, you are ready to compile and release it to the world. There are actually a few steps to this process. First, you need to configure all the application settings by choosing Site > AIR Application Settings. Figure 2 shows how I set up my application. Don't forget to include any necessary JavaScript, CSS, and image files and folders in the Included Files section of this dialog box. Finally, you need to create a new digital signature to sign the application. The application does a good job of walking you through that step.

Configuring the AIR application and installer settings.

Figure 2. Configuring the AIR application and installer settings.

Once you have configured the settings, you can compile your installer by clicking the Create AIR File button on the AIR Application Settings dialog box or by choosing Site > Create AIR File. When users open this AIR file, it will walk them through the process of installing the application.

Going forward

Obviously, I have skimmed only the surface of what is possible with JavaScript in AIR, but I hope you can see that creating applications in AIR isn't much different from creating web-based HTML/JavaScript applications. If you download the code for this article, here are some ideas for expanding this application:

To learn more about working with HTML and JavaScript in Adobe AIR, check out Adobe's documentation on this topic, Developing Adobe AIR 1.5 Applications with HTML and Ajax. I also recommend Adobe AIR 1.5 Cookbook by David Tucker et al. (O'Reilly). Nearly every example in this book covers how to accomplish specific tasks in AIR via Flex or JavaScript. It's an invaluable reference when developing AIR applications.

‹ Back


Brian Rinaldi is as a Content and Community Manager for the Adobe Developer Center team, where he helps drive content strategy for HTML5 and JavaScript developer content. Brian blogs regularly at http://remotesynthesis.com and is a unreformed twitter addict @remotesynth.