Web DevCenter
oreilly.comSafari Books Online.Conferences.
MySQL Conference and Expo April 14-17, 2008, Santa Clara, CA

Sponsored Developer Resources

Web Columns
Adobe GoLive
Essential JavaScript
Megnut

Web Topics
All Articles
Browsers
ColdFusion
CSS
Database
Flash
Graphics
HTML/XHTML/DHTML
Scripting Languages
Tools
Weblogs

Atom 1.0 Feed RSS 1.0 Feed RSS 2.0 Feed

Learning Lab






A Study in Flash Form Submission
Pages: 1, 2

It's not enough to detect that the Enter key was pressed. We're only interested in Enter keystrokes if a text field in the form is focused at the time of the keystroke. Let's add another method to the TextField class, isFocused(), which will tell us whether a text field has input focus. In ActionScript, the Selection object's getFocus() method returns the current focus.



TextField.prototype.isFocused = function () {
  // (The 'this' is the current text field instance.)
  if (Selection.getFocus() == targetPath(this))  {
    return true;
  }
  return false;
};

Note that the Selection.getFocus() method returns the path to the currently focused object as a string, not as an object reference. Hence, to compare the return of getFocus() to the current text field, we must use either eval() to convert getFocus()'s return to an object, or targetPath() to retrieve the fully qualified path to the text field. In our custom isFocused() method we use the targetPath() approach.

Now that isFocused() is complete, let's adjust our onKeyDown() method one last time so that it detects that the Enter key was pressed and that the text field that detected the Enter keystroke is currently focused. If both of those conditions are met, we'll invoke a custom onSubmit() method directly on the text field. The form developer is expected to provide the implementation for onSubmit().

TextField.prototype.onKeyDown = function () {
  if (Key.getCode() == Key.ENTER 
      && this.pressedOnce == undefined
      && this.isFocused()) {
    this.onSubmit();
    this.pressedOnce = true;
  }
};

TextField.prototype.onKeyUp = function () {
  if (Key.getCode() == Key.ENTER) {
    this.pressedOnce = undefined;
  }
}

That takes care of our TextField additions. Our form's text fields will now be able to respond to the Enter key. All that's left to do is wire the text fields to the submitForm() function and register them to receive Key events:

// Wire text field to submitForm().
username_txt.onSubmit = submitForm;
// Register text field to receive Key events.
Key.addListener(username_txt);
// Wire...
password_txt.onSubmit = submitForm;
// Register...
Key.addListener(password_txt);

That's it. Enter key presses in the user name and password text fields will now submit our form. Here's a look at the final code:

// ===============================================
// Augment TextField Class
// ===============================================
TextField.prototype.onKeyDown = function () {
  if (Key.getCode() == Key.ENTER
      && this.pressedOnce == undefined
      && this.isFocused()) {
    this.onSubmit();
    this.pressedOnce = true;
  }
};

TextField.prototype.onKeyUp = function () {
  if (Key.getCode() == Key.ENTER) {
    this.pressedOnce = undefined;
  }
}

TextField.prototype.isFocused = function () {
  if (Selection.getFocus() == targetPath(this))  {
    return true;
  }
  return false;
};

// ===============================================
// Implement Form
// ===============================================
// Prepare the data transfer object.
var sender = new LoadVars();

// Activate Enter key for text fields.
username_txt.onSubmit = submitForm;
Key.addListener(username_txt);
password_txt.onSubmit = submitForm;
Key.addListener(password_txt);

// Set submit button handler.
submit_pb.setClickHandler("submitForm");

// Provide custom form submission function.
function submitForm () {
  sender.user = username_txt.text;
  sender.pass = password_txt.text;
  sender.send("http://www.somesite.com/cgi-bin/login.pl", "_blank", "GET");
}

Related Reading

ActionScript for Flash MX Pocket Reference
Quick Reference for Flash MX Programmers
By Colin Moock

Further Considerations

There are some related issues worth mentioning in passing.

Handling Enter for Other Components

This article concentrated on Enter-key submission from a text field, but forms often include additional UI components such as listboxes and radio buttons. To support the Enter key with those kinds of components, you'll need to either add key and focus handling methods to them (much as we did for TextField). You could also implement a centralized key-handling strategy, where a single object detects keystrokes and then loops through the components in the form to determine whether the form should be submitted. At that level of complexity, it's probably worth creating a custom Form class to manage your forms.

Validation

Form input should always be validated in Flash before it is submitted to a server-side script or application. Like form submission, the validation process should be packaged into a function or method. For example, in our form we might have a validateForm() function that returns true if the form data is valid, and false otherwise. We'd then adjust our submitForm() function as follows:

function submitForm () {
  if (validateForm()) {
    sender.user = username_txt.text;
    sender.pass = password_txt.text;
    sender.send("http://www.somesite.com/cgi-bin/login.pl", "_blank", "GET");
  } else {
    // Provide feedback to user...
  }
}

Good OOP Form

In a strict OOP language such as Java, our approach of adding custom methods to the built-in TextField class wouldn't work. In Java you can't just add arbitrary new methods to a built-in class on a per-application basis. In our form we needed a specialized type of text field, so it would have been best to subclass TextField and add our custom methods to that subclass. Unfortunately, it's not possible to subclass TextField directly in ActionScript because all text field creation tools use the TextField class to generate text fields. There's no way to instruct, say, MovieClip.createTextField() to generate a new text field instance from a custom class rather than from TextField. Developers who are reluctant to add new methods to built-in classes can avoid the issue by wrapping a text field in a component and then adding the new methods to the component class rather than to the TextField class.

Multiline Text Fields

Our form example used single-line input text fields. For information on handling the Enter key in multiline text fields, see moock.org's technote on the subject.


O'Reilly & Associates recently released (March 2003) ActionScript for Flash MX Pocket Reference.