Article
Learn Adobe AIR, Part II: Build a Customer Management App
Creating New Records
Now that we have a stable interface with which to view our data, we need to be able to create records. As a business, it’s important to be able to attach existing data to a customer record. AIR’s native drag-and-drop functionality is great for this—using pure JavaScript, our application can accept multiple files quite easily. Once we have the files, we can copy or move them, read them, upload them to a server, or even display them in our application. In this example, we’re just reading a text file, but we could easily extend this as needed for more complex file types.
In the previous article, we built a simple creation form as part of our Note Storage application, and the logic is much the same for this app. We’ll read data from text fields, construct an SQL INSERT statement, and execute it against our database. To implement the drag-and-drop functionality, though, we need to specify a target area, or drop zone, for our files. A drop zone is an area on the window that responds to certain mouse events (such as a group of files being dropped onto it). We’ll build this drop zone so that it stores the data received in a variable for later use.
The AIR APIs allow us to explicitly check for files being dropped onto the target area (as opposed to plain text, URLs, HTML, or other Clipboard data). These files then become available for us to manipulate as air.File objects. Similar to the way in which we manipulated our database file, we can manipulate these “dropped” files using a set of generic interfaces.
Open the new_behaviour.js file in your editor, and add the following:
notes = "";
dbConn = null;
function receiveDb(dbFromParent) {
dbConn = dbFromParent;
}
$(document).ready(function(){
$("#create").click(function(){ create(); });
$("#clear").click(function(){ clear(); });
var dropbox = document.getElementById("filedrop");
dropbox.addEventListener("dragenter", dragEnterOver);
dropbox.addEventListener("dragover", dragEnterOver);
dropbox.addEventListener("drop", dropHandler);
});
The important part of this code is the various interface-related functions that we’ve bound to specific events. We’ll create those functions in a moment; for now let’s build our drop zone.
Open up the new_customer.html file, and take a quick look at the structure of the document. You’ll see that we have a div with an id of ”filedrop” that contains an empty span element. As a user drags files onto the application page, AIR asks each of the DOM elements that form part of the page if they will accept a file drop; this gives our div the opportunity to tell AIR that it will!
There are actually three events here, but the first two (dragenter and dragover) can be handled by the same event handler. Here’s the code for that function:
function dragEnterOver(event) {
for (var t = 0; event.dataTransfer.types && t < event.dataTransfer.types.length; t++)
{
if (event.dataTransfer.types[t] == "application/x-vnd.adobe.air.file-list")
{
event.preventDefault();
}
}
}
The code above will simply confirm that the drop zone is receiving a list of files and using the appropriate MIME type (there are a few other options documented on the Adobe help pages). If the drop zone is indeed going to accept any files dragged onto it, we need to first disable the default event that rejects the file drop. This will allow the operating system to display a nice “drop allowed” visual indicator: on Windows Vista, this indicator is a blue plus symbol (+), while a red X indicates that the drop is not allowed.
Next we need to handle the actual drop:
function dropHandler(event) {
var files = event.dataTransfer.getData("application/x-vnd.adobe.air.file-list");
for (var num = 0; num < files.length; num++) {
fileStream = new air.FileStream();
fileStream.addEventListener(air.Event.COMPLETE, readFile);
fileStream.openAsync(files[num], air.FileMode.READ);
}
}
function readFile(event) {
notes = fileStream.readMultiByte(fileStream.bytesAvailable, "iso-8859-1");
$("#filedrop span").text(notes.substr(0,100) + "...");
}
Just as we did for the HTMLLoader COMPLETE event, we’ve used a handler for the FileStream event that indicates that the opening of a file is complete. As you can see from the code above, we’re listening for this event asynchronously. We’re taking this approach because reading a file can take a while, and we don’t want to lock up the application in the meantime.
As you can see, we use the callback for the event listener to read data directly from the file into a string object. The manual has further information on file read/write workflow and FileStream’s open modes.
We need to specify a character encoding type here—for plain text, the option we’ve used (Western European – ISO) is usually appropriate; check out the AIR manual’s list of supported character sets.
It’s always good to give the user some indication that their action has been successful. In this case, we’re displaying a sample of the file that they dropped (the first 100 characters) to let them know that their files were dropped successfully.
Finally, we need our actual record creation routine, and the clear method to which we referred earlier. Add the following code to the end of your new_behaviour.js file:
function create() {
dbQuery = new air.SQLStatement();
dbQuery.sqlConnection = dbConn;
dbQuery.text = "INSERT INTO customers (name,phone,notes) VALUES (:name,:phone,:notes)";
dbQuery.parameters[":name"] = $("#name").val();
dbQuery.parameters[":phone"] = $("#phone").val();
dbQuery.parameters[":notes"] = notes;
try { dbQuery.execute(); } catch (error) {
air.trace("Could not create new customer record.");
}
}
function clear() {
notes = ""; $("#filedrop span").text("");
}
The majority of this code should be fairly familiar to you by now—an SQL INSERT statement, with named parameters. Note that we used a JavaScript escaping routine in our previous AIR article; such steps are not necessary here, as this functionality is taken care of by using named parameters.
To test the app, try dragging a sample data file onto the drop zone: customerdata.txt, which exists in the project folder, has been included in the skeleton code archive for this purpose.
And We’re Done!
Save all open files in Aptana and select your project name from the Run button menu, and your CRM app should appear. Try adding an entry (via the File menu) and refreshing the main screen to view your newly-created record.
You can download my completed project files (including Aptana project data) here.
Further Reading
If you’re interested in further exploring the topics covered in this article, Adobe has a number of fantastic online resources that you may find handy:
- Drag and drop
- Working with native windows
- Reading and writing files
- AIR 1.1 HTML/AJAX guide for developers
- AIR 1.1 HTML/AJAX Language Reference
If you aren’t quite sure about any of the code samples in this article, feel free to post a comment below and I’ll see how I can help.
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 for a limited time only.)