May 16, 2006

XML Flash Actionscript Tools

You will find other articles relevant to this document in these sections:
Cameron Manderson @ 11:15 am

A while ago helped out a designer (Sacha Jerrems) with some ActionScript XML functions that helped him retrieve nodes and node values instead of using firstChild etc.

Instead of using for loops to locate child nodes, and then go into them, we can make simple function calls to do the work for us.

Example Use

Say we have a valid XHTML document, with a node named ‘title’. To get its value we could simple call:

trace(getValue(getNode('title', xhtmlDoc)));

This method allows us to pipe the results without needing to assign them to variables etc. It can typically compress your code from 10s of lines down to a single assignment.

The Actionscript

/**
 * Searches through an XMLNode's children to locate a particular child node
 * 
 * @param String nodeName The nodeName to locate
 * @param XMLNode parent The parent to search through
 * @returns Found node or null if it could unable to locate a match
 * @author Cameron Manderson <cameronmanderson@gmail.com>
 */
function getChild(nodeName, parent) {
  return getNode(nodeName, parent, false);
}
 
/**
 * Searches Recursively through an XMLNode to locate a particular 
 * child node
 *
 * @param String nodeName The nodeName to locate
 * @param XMLNode parent The parent to search through
 * @param boolean recursive Whether to search recrusively
 * @returns Found node or null if it could unable to locate a match
 * @author Cameron Manderson <cameronmanderson@gmail.com>
 */
function getNode(nodeName, parent, recursive) {
  // Check that we are not looking through or for undefined variables
  if(nodeName == undefined || parent == undefined) {
    return null;
  }
  if(recursive == undefined) recursive = false;
  var i = 0; var locatedNode = null;
  // Check parent for match
  if(parent.nodeName == nodeName) { 
    return parent;
  }
  // Check through the child nodes until the particular child node is located
  for(var i = 0; parent.childNodes && i < parent.childNodes.length; i++) {
    // look to see if the child is what we want
    if(parent.childNodes[i].nodeName == nodeName) {
      return parent.childNodes[i]; 
    }
    // if we are recursing, recurse into child
    if(recursive) {
      locatedNode = getChild(nodeName, parent.childNodes[i], recursive);
    }
    if(locatedNode !== null) {
      return locatedNode;
    }
  }
  return null;
}

You could also then use a simple getValue() function such as below to help you retrieve a node value.

function getValue(node) {
  if (node && node.firstChild) {
    return node.firstChild.nodeValue;
  }
  return "";
}

Hopefully this helps you quickly find the power of XML with Flash

P.S. I request that you leave my name in the functions if you use them. Code is released under our standard LGPL. Which means it is free for you to use, but you must leave the code intact. If you make changes to the code, you should email them back to me. I wrote this a while back and it is probably time for me to make it AS2, but atleast it is more backward compatible.

April 11, 2006

Flash: LoadVars Objects

You will find other articles relevant to this document in these sections:
Richard Lee @ 12:32 pm

The great thing about flash is its ability to communicate with serverside scripts.

Flash’s LoadVars class makes this an easy task. Lets take a look at a simple example:

Create 2 LoadVars objects, ‘request_lv’ to package the Flash application data to send to your script, and ‘response_lv’ to load the response from your script - Typically you want to send data to a script based on an event such as a form submission, so let’s encapsulate the remainder of the script in a onRelease event handler:

response_lv = new LoadVars();

request_lv = new LoadVars();

send_btn.onRelease = function() {

Initialise the request_lv object with variables that represent the relative form data - it’s like putting items into a parcel. We’ll also create an action variable to refer to in our php script to determine what script to execute - a good way to keep the app flexible:

request_lv.name = name_txt.text;

request_lv.email = email_txt.text;

request_lv.subject = subject_txt.text;

request_lv.message = message_txt.text;

request_lv.action = ’send’;

Now we want to make a request to our target php script, in turn sending the contents of the request_lv object and loading the response into the response_lv object. To do this we can use the LoadVars() sendAndLoad function:

request_lv.sendAndLoad(”email.php”, response_lv, “post”);// Can use POST or GET

}// end function
We need to make sure the response was loaded correctly otherwise we could start trying to access undefined variables. Luckily Flash has a solution for this too, just use the onLoad() event handler and valiate the success parameter to check if the load phase completed successfuly (true) OR failed (false).

response_lv.onLoad = function(success) {

if (success) {

status_txt.text = “SUCCESS: Message Sent”;

} else {

status_txt.text = “ERROR: Unable to send message”;

Good idea in this case to offer user an alternative such as loading their own mail client (eg Outlook Express) using Flash’s getURL and ‘mailto’:

getURL(”mailto:enquiries@yoursite.com.au?subject=”+request_lv.subject+”&body=”+request_lv.message);

}
}// end function

Ok so we’ve sorted out the Flash side of the application, let’s look at the target php script.

We need to run a condition to check for a request from our Flash app, in our case we can just check for the presence of the ‘action’ variable:

//email.php
if (isset($_POST[’action’])) {

Since the value of the ‘action’ variable will determine the action of the rest of the script I use a php switch() statement :

switch ($_POST[’action’]) {

case ’send’:

// Send email

break;

default:

// Use default to capture ‘undefined’ actions

break;

}

Pretty self explanatory right? If the value of action is ’send’ we run the script within the ’send’ case, and if we cannot determine the value php reverts to the default case.

Here’s how it looks with the mail script:

switch ($_POST[’action’]) {

case ’send’:

$to = ‘enquiries@yoursite.com.au’;
$subject = $_POST[’subject’];
$message = $_POST[’message’];
// NB: Good idea to test for header injection if your inserting form vars directly into the header - refer to my article on mail header injection
$headers = ‘From: webmaster@yoursite.com.au’ . “\r\n” .
$headers .= ‘Reply-To: ‘.$_POST[’email’] . “\r\n”;
$headers .= ‘X-Mailer: PHP/’ . phpversion();

$sent = @mail($to, $subject, $message, $headers);

// Print the variables to the output in order to let flash read them

echo ’sent=’.$sent;

break;

default:

// Print the variables to the output in order to let flash read them

echo ‘error=no%data’;

break;

}

}

You should notice the echo statements as well - as commented - this is how we pass variables back to Flash (Be careful of spaces and newlines here, as EVERYTHING will be url-encoded!). For the ’send’ case we pass back the success of php mail() - being FALSE on failure (NB: Warnings are hidden using ‘@’).

Within the Flash app, in addition to evaluating the success of the LoadVars load event we also test for the success of mail () by reading the ’sent’ variable which will be a string of the original boolean:

response_lv.onLoad = function(success) {

if (success) {

if (this.sent == ‘true’) {

status_txt.text = “SUCCESS: Message Sent”;

} else {

status_txt.text = “FAILURE: Server unable to send message”;

}

} else {

status_txt.text = “ERROR: Unable to send message”;

}

}// end function

Anyway I hope this gives you a good introduction on what is possible with LoadVars() objects, please refer to your ActionScript Dictionary and Macromedia LiveDocs for more information

« Previous Page