oreilly.deO'Reilly Network
KontaktBestellinfosOnline-Bücher

Pfeil Suche
Pfeil Bücher A-Z
Pfeil Neuerscheinungen
Pfeil Buchreihen
Programmbereiche
Pfeil
C/C++ Programmierung
Design & Grafik
Java
Linux
Macintosh
.Net
Open Source
Oracle
Perl
Python
Sicherheit
System- & Netzwerkadministration
Unix
Visual Basic
Web & Internet
Windows
XML
Weitere Infos
Pfeil
Katalog bestellen
Mailinglisten abonnieren

ActionScript für Flash MX: Das Handbuch

Formularübermittlung mit Flash

by Colin Moock, Autor von ActionScript für Flash MX: Das Handbuch und Die Referenz
05/20/2003

In HTML erstellen Sie Formulare nach einem einfachen Rezept: Man nehme ein <form>-Tag; füge nach Geschmack User-Eingabetags hinzu; backe das Ganze eine Stunde lang bei 350 Grad, serviere und genieße.

In Flash geht das traditionell nicht ganz so einfach. Zwar hat die Veröffentlichung der Flash UI-Komponenten für Flash MX das Ganze spürbar vereinfacht, aber das Absenden von Formularen ist und bleibt dennoch in Flash kniffliger als in HTML. In HTML können Sie Formulare über einen Submit-Button oder "automagisch" über die Eingabetaste absenden. Da Flash hingegen keine integrierte Unterstützung für das Versenden mittels Eingabetaste bietet, müssen Sie diese manuell implementieren. Und genau dies wird im Rest dieses Artikels erklärt. Den Quellcode können Sie von dieser URL herunterladen.

Flash-Formulare bestehen normalerweise aus einer Ansammlung von User Interface (UI)-Komponenten. Um ein Formular an ein Skript oder Programm auf der Serverseite zu "übermitteln", müssen Sie den Wert jeder Komponente manuell in ein LoadVars- oder XML-Objekt speichern und dann die sendAndLoad()- oder send()-Methode dieses Objekts aufrufen.


ActionScript für Flash MX: Das Handbuch

Weiterführende Literatur

ActionScript für Flash MX: Das Handbuch
Von Colin Moock

ActionScript für Flash MX: Die Referenz

ActionScript für Flash MX: Die Referenz
Von Colin Moock


Diese Schritte übernimmt normalerweise eine selbst programmierte Funktion oder Methode. Nehmen Sie als Beispiel ein einfaches Anmeldeformular mit einem Textfeld für den Usernamen, einem Textfeld für das Passwort und einem Submit-Button. Die Textfelder sind einzeilige Eingabetextfelder und haben die Instanznamen username_txt und password_txt. Der Submit-Button ist ein FPushButton-Objekt namens submit_pb. Für die Formularübermittlung dient eine benutzerdefinierte submitForm()-Funktion. Der Code auf der Zeitleiste des Formulars sieht folgendermaßen aus:

// Erstellung des Datenübermittlungsobjekts.
// Der Einfachheit halber wird davon ausgegangen, dass die
// Ergebnisse der Anmeldung als Webseite im Browser
// dargestellt werden, also nicht in Flash.
var sender = new LoadVars();

// Benutzerdefinierte Funktion zur Formularübermittlung.
function submitForm () {
  // Sammele Textfeldwerte im LoadVars-Objekt.
  sender.user = username_txt.text;
  sender.pass = password_txt.text;
  // Übertrage Daten an das Skript auf der Serverseite.
  sender.send("http://www.somesite.com/cgi-bin/login.pl", "_blank", "GET");
}

Damit der Submit-Button (submit_pb) beim Anklicken die Methode submitForm() aufruft, verwenden Sie die Methode setClickHandler() der Komponente FPushButton wie folgt:

// Dieser Code muss mit einem Bild auf derselben
// Zeitleiste wie die obige submitForm()-Funktion verknüpft sein.
submit_pb.setClickHandler("submitForm");

Und nun kommt der schwierige Teil: Beim Drücken der Eingabetaste soll submitForm() aufgerufen werden, allerdings nur, wenn eines der Textfelder im Formular den Fokus hat. Zur Behandlung der Eingabetaste werden der Klasse TextField weitere benutzerdefinierte Methoden hinzugefügt. Als Erstes entwickeln wir eine neue Methode namens onKeyDown(), die nachschaut, ob die Eingabetaste gedrückt wird. Nun kann sich jede TextField-Instanz registrieren lassen, um vom integrierten Key-Objekt Benachrichtigungen über Tastendruck-Events zu empfangen.

TextField.prototype.onKeyDown = function () {
  if (Key.getCode() == Key.ENTER) {
    // Eingabetaste wurde gedrückt.
  }
};

Die neue Methode macht jedoch Probleme: Wenn der User die Eingabetaste gedrückt hält, sendet sie gleich mehrere Tastendruck-Events. Da aber nur der erste Tastendruck von Interesse ist, wird die Methode onKeyDown() jetzt so abgeändert, dass sie alle Eingabetasten-Events außer dem ersten verwirft. Sie bekommt die Eigenschaft pressedOnce, die das erste Drücken der Eingabetaste registriert, und die neue Methode onKeyUp(), mit der die Eigenschaft pressedOnce zurückgesetzt wird, wenn die Eingabetaste losgelassen wird.

TextField.prototype.onKeyDown = function () {
  if (Key.getCode() == Key.ENTER && this.pressedOnce == undefined) {
    // Notiere das Drücken der Eingabetaste. Dann brauchen wir uns
    // bei der nächsten onKeyDown-Event-Benachrichtigung nicht mehr
    // darum zu kümmern.
    this.pressedOnce = true;
  }
};

TextField.prototype.onKeyUp = function () {
  // Wenn die Eingabetaste losgelassen wird, 
  // wird die Eigenschaft pressedOnce zurückgesetzt.
  if (Key.getCode() == Key.ENTER) {
    this.pressedOnce = undefined;
  }
}

Es reicht aber nicht aus, lediglich zu entdecken, dass die Eingabetaste gedrückt wurde. Denn das Drücken der Eingabetaste ist nur dann von Belang, wenn gleichzeitig ein Textfeld im Formular den Fokus hat. Also benötigt die Klasse TextField zusätzlich die Methode isFocused(), um festzustellen, ob ein Textfeld den Eingabefokus hat. In ActionScript sagt Ihnen die Methode getFocus() des Selection-Objekts, welches Element gerade den Fokus hat.

TextField.prototype.isFocused = function () {
  // ('this' ist die aktuelle Textfeld-Instanz.)
  if (Selection.getFocus() == targetPath(this))  {
    return true;
  }
  return false;
};

Beachten Sie, dass die Methode Selection.getFocus() den Pfad zu dem fokussierten Objekt als String statt als Objektreferenz liefert. Daher müssen Sie zunächst entweder den Rückgabewert von getFocus() mit eval() in ein Objekt umwandeln, oder mit targetPath() den vollständigen Pfad zu dem Textfeld abfragen. Erst dann können Sie den Wert mit dem aktuellen Textfeld vergleichen. In unserer benutzerdefinierten isFocused()-Methode wird targetPath() verwendet.

Nun, da die Methode isFocused() fertig ist, muss die Methode onKeyDown() ein letztes Mal angepasst werden, damit sie erkennen kann, dass die Eingabetaste gedrückt wird, und das Textfeld, das diesen Tastendruck registriert hat, gleichzeitig den Fokus hat. Wenn diese Bedingungen beide erfüllt sind, wird direkt auf dem Textfeld eine benutzerdefinierte onSubmit()-Methode aufgerufen. Die Implementierung dieser Methode muss der Formularentwickler allerdings selbst liefern.

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;
  }
}

So werden TextField-Eingaben behandelt. Die Textfelder des Formulars sind jetzt in der Lage, auf das Drücken der Eingabetaste zu reagieren. Nun müssen die Textfelder nur noch mit der Funktion submitForm() verbunden und für den Empfang von Key-Events registriert werden:

// Verbinde Textfeld mit submitForm().
username_txt.onSubmit = submitForm;
// Registriere Textfeld für den Empfang von Key-Events.
Key.addListener(username_txt);
// Verbinde...
password_txt.onSubmit = submitForm;
// Registriere...
Key.addListener(password_txt);

Das ist alles. Jetzt wird das Formular abgeschickt, wenn in den Textfeldern für den Usernamen und das Passwort die Eingabetaste gedrückt wird. Die Endfassung des Codes sieht folgendermaßen aus:

// ===============================================
// Erweiterte TextField-Klasse
// ===============================================
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;
};

// ===============================================
// Formularimplementierung
// ===============================================
// Erstelle das Datenübermittlungsobjekt.
var sender = new LoadVars();

// Aktiviere Eingabetaste für Textfelder.
username_txt.onSubmit = submitForm;
Key.addListener(username_txt);
password_txt.onSubmit = submitForm;
Key.addListener(password_txt);

// Richte Handler für den Submit-Button ein.
submit_pb.setClickHandler("submitForm");

// Benutzerdefinierte Funktion für die Formularübermittlung.
function submitForm () {
  sender.user = username_txt.text;
  sender.pass = password_txt.text;
  sender.send("http://www.somesite.com/cgi-bin/login.pl", "_blank", "GET");
}

Zum Abschluss

Einige verwandte Themen verdienen es, besonders erwähnt zu werden.

Die Eingabetaste im Zusammenspiel mit anderen Komponenten

Der obige Artikel stellt die Formularübermittlung per Eingabetaste aus einem Textfeld in den Mittelpunkt, doch Formulare bergen häufig auch noch andere UI-Komponenten wie beispielsweise Listenfelder und Optionsfelder. Um die Eingabetaste auch für diese Komponenten zu aktivieren, müssen Sie der Komponente entweder Handler-Methoden für Tastendrücke und Fokus hinzufügen, wie es im voliegenden Fall bei TextField getan wurde, oder eine zentrale Strategie zur Behandlung von Tastendrücken, wobei ein einzelnes Objekt Tastendrücke erkennt und dann die Komponenten im Formular durchläuft, um zu ermitteln, ob das Formular übermittelt werden soll. Doch wenn es derart komplex wird, dann könnten Sie auch gleich eine eigene Formularklasse kreieren.

Validierung

Formulareingabe sollte in Flash vor der Übermittlung an ein serverseitiges Skript oder Programm grundsätzlich validiert werden. Ebenso wie die Formularübertragung sollte auch die Validierung in eine Funktion oder Methode gepackt werden. Das Formular könnte beispielsweise eine validateForm()-Funktion haben, die bei gültigen Daten true und bei ungültigen false zurückgibt. Die submitForm()-Funktion könnte folgendermaßen umgeschrieben werden:

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 {
    // User-Feedback...
  }
}

Guter OOP-Stil

In einer streng objektorientierten Sprache wie Java würde es nicht funktionieren, der integrierten Klasse TextField benutzerdefinierte Funktionen hinzuzufügen, wie es oben beschrieben wird. In Java können Sie einer eingebauten Klasse nicht einfach für einzelne Programme nach Belieben neue Funktionen beigeben. Da im obigen Beispiel eine spezielle Art von Textfeld benötigt wird, wäre es besser gewesen, eine Unterklasse von TextField zu bilden und die neuen Methoden dieser Unterklasse hinzuzufügen. Doch leider ist es nicht möglich, von TextField direkt in ActionScript eine Unterklasse zu erstellen, da alle Werkzeuge zur Textfelderstellung ihrerseits die Klasse TextField für diesen Erstellungsprozess benutzen. Es gibt keine Möglichkeit, etwa die Methode MovieClip.createTextField() zu veranlassen, eine neue Textfeldinstanz statt aus TextField aus einer anderen, benutzerdefinierten Klasse zu erzeugen. Wer sich scheut, eingebauten Klassen neue Methoden hinzuzufügen, kann ein Textfeld in eine Komponente hüllen und die neuen Methoden dann dieser Komponentenklasse statt der TextField-Klasse selbst beigeben.

Mehrzeilige Textfelder

Im obigen Formularbeispiel ging es um einzeilige Eingabetextfelder. Informationen über die Behandlung der Eingabetaste in mehrzeiligen Textfeldern finden Sie in der Technote zu diesem Thema unter moock.org.


Weitere bei O'Reilly erschienene Veröffentlichungen zu ActionScript für Flash MX :

Sehen diese Seiten zu fade bzw. langweilig aus? Wenn ja, dann liegt das daran, daß unsere Seiten CSS verwenden! Entweder Ihr Browser unterstützt CSS nicht oder Sie haben CSS deaktiviert.
Netscape 4.x-Benutzer: Deaktivierung von JavaScript bewirkt leider, daß auch CSS deaktiviert ist!


O'Reilly Home | O'Reilly-Partnerbuchhandlungen | Bestellinformationen
Kontakt | Über O'Reilly | Datenschutz

© 2003, O'Reilly Verlag