Bei diesem Dokument handelt es sich um die deutsche Übersetzung des englischen Titels "XForms for HTML Authors" von Steven Pemberton. Verbesserungsvorschläge werden vom Übersetzer gerne entgegengenommen.
Übersetzung: Sebastian Zächerl (sebastian@zaecherl.de - www.zaecherl.de)
URL dieser Übersetzung: http://www.zaecherl.de/xforms/xforms-fuer-html-programmierer.html
URL des englischen Originals: http://www.w3.org/MarkUp/Forms/2003/xforms-for-html-authors.html
Steven Pemberton, W3C/CWI
Datum dieser Version: 28. Oktober 2003
XForms ist die neue Auszeichnungssprache für Formulare im Web. Dieses Dokument gibt eine schnelle Einführung in XForms für Programmierer, die mit HTML-Formularen vertraut sind. Es zeigt, wie existierende HTML-Formulare in ihr XForms-Pendant konvertiert werden können. Zum Verständniss dieses Dokuments sind Kenntnisse über HTML-Formulare erforderlich. Obschon auch Fähigkeiten und Möglichkeiten von XForms, die über die Fähigkeiten von HTML-Formularen hinaus gehen (Im Inhaltsverzeichniss mit einem Stern gekennzeichnet), erwähnt werden, versteht sich dieses Dokument nicht als vollständige Anleitung zu XForms.
*Diese Fähigkeiten sind mit HTML-Formularen nicht möglich
Betrachten wir dieses einfache HTML-Formular:
<html> <head><title>Search</title></head> <body> <form action="http://example.com/search" method="get"> Find <input type="text" name="q"> <input type="submit" value="Go"> </form> </body> </html>
Der größte Unterschied besteht bei XForms-Formularen darin, daß
die Details über die Eingabedaten und die Art ihrer Übertragung im
Head-Bereich in einem Element namens model
deklariert werden. Allein
die Form-Controls werden im Body-Bereich angegeben. In diesem Beispiel könnte
man folgendes model
im Head-Bereich angeben:
<model> <submission action="http://example.com/search" method="get" id="s"/> </model>
(Elemente und Attribute werden in XForms klein geschrieben.)
Das form
-Element wird nicht mehr benötigt. Die Steuerelemente
im Body-Bereich sehen wie folgt aus:
<input ref="q"><label>Find</label></input> <submit submission="s"><label>Go</label></submit>
Aus diesem Beispiel wird ersichtlich, daß Form-Controls ein label
-Element
als Kindelement besitzen, welches zur Beschriftung des Eingabefeldes dient.
Das input
-Element benutzt "ref
" anstelle von "name
".
Weiterhin wird ein separates submit
control benutzt, das auf die
im Head-Bereich definierten Submission-Details verweist. Das komplette Beispiel
sieht nun aus wie folgt:
<h:html xmlns:h="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/2002/xforms"> <h:head> <h:title>Search</h:title> <model> <submission action="http://example.com/search" method="get" id="s"/> </model> </h:head> <h:body> <h:p> <input ref="q"><label>Find</label></input> <submit submission="s"><label>Go</label></submit> </h:p> </h:body> </h:html>
Ein weiterer, im obigen Beispiel auffälliger, Unterschied ist die Benutzung
des h:
Präfixes vor den HTML-Elementen. Dies hat nichts mit
XForms im Speziellen zu tun, sondern kommt daher, daß XML entworfen wurde
um mehere Sprachen in einem Dokument zu vereinen. XForms kann mit verschiedenen
Sprachen kombiniert werden - Nicht nur mit XHTML. XML-Prozessoren muss nun mitgeteilt
werden, zu welcher Sprache die verwendeten Elemente gehören. Dies geschieht
durch Zuordnung von Namensräumen. Hierbei kann man eine Standartsprache
(default) angeben. Dies war im obigen Beispiel XForms. Ebenso gut hätte
man XHTML durch Verändrung des xmlns
Attributes im Head-Bereich
zur Standardsprache deklarieren können:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://www.w3.org/2002/xforms"> <head> <title>Search</title> <f:model> <f:submission action="http://example.com/search" method="get" id="s"/> </f:model> </head> <body> <p> <f:input ref="q"><f:label>Find</f:label></f:input> <f:submit submission="s"><f:label>Go</f:label></f:submit> </p> </body> </html>
Dies Auswahl einer Standardsprache liegt im Ermessen des Autors. Zudem ist
es auch möglich alle Elemente mit Präfixen zu versehen, und somit
auf die Auswahl einer Standardsprache zu verzichten. Auch die Wahl des Präfixes
ist dem Autor freigestellt - Möglich wäre beispielsweise h:
und x:
oder html:
und form:
....
Zukünftig wird XHTML2 die Gestaltung von Formularen ohne die Verwendung von Präfixen ermöglichen.
XForms bietet für jedes HTML Form-Control ein entsprechendes Äquivalent.
Doch im Ansatz besteht ein großer Unterschied: Während in HTML hauptsächlich
das Aussehen des Form-Controls festgelegt wird, liegt bei XForms der
Fokus auf dem Zweck des Form-Controls. Die HTML-Spezifikation sieht beispielsweise
vor, daß ein select-
Element ein Menü generiert und ein
input-Element vom Typ radio
mehere Radio-Buttons erzeugt von denen
einer ausgewählt werden kann. Dem gegenüber hat XForms die Elemente
select
und select1
, welche lediglich die Intention des
Form-Controls festlegen - Nämlich die Auswahl von keinem, einem oder meheren
Elementen aus einer Liste.Wie diese Auswahl dem Nutzer präsentiert wird,
wird durch das verwendete Gerät und das assozierte Stylesheet bestimmt. Auf
einem Mobiltelefon könnte man aus Gründen der beschränkten Bildschirmgröße
ein Menü vorziehen, während auf größeren Bildschirmen die
Darstellung durch Radio-Buttons angenehmer ist. Dem Autor ist es möglich
Präferenzen über das gewünschte Aussehen anzugeben. Tut er dies
nicht übernimmt das ausgebende Gerät oder ein Stylesheet diese Entscheidung
für ihn.
Im Folgenden wird erklärt wie HTML Form-Controls durch ihr XForms-Pendant ersetzt werden.
First name: <input type="text" name="firstname">
wird ersetzt durch
<input ref="firstname"><label>First name:</label></input>
Es ist nicht nötig anzugeben, daß es sich um Text handelt, da dies
der Standardwert in XForms ist (genannt string
in XForms).
Im Abschnitt 'Initiale Werte' wird erklärt, wie jedem Form-Control initiale Werte übergeben werden können.
Message: <textarea name="message" rows="20" cols="80"></textarea>
wird ersetzt durch
<textarea ref="message"><label>Message:</label></textarea>
Die Gestaltung (wie etwa die Angabe von Höhe und Breite) der Textarea wird durch ein Stylesheet vorgenommen. Zum Beispiel mit einem Stylesheet, das diese Definition enthält:
textarea[ref="message"] { font-family: sans-serif; height: 20em; width: 80em }
Diese Definition ahmt die HTML-Textarea nach. Es ist aber weder nötig eine serifenlose Schrift zu verwenden, noch die Größe durch Reihen und Zeilen anzugeben. Ebenso kann dies durch die Angabe von konkreten Größen, Prozentwerten oder Ähnlichem geschehen:
textarea[ref="message"] { font-family: serif; height: 2cm; width: 20% }
Wenn alle Textareas die gleichen Abmessungen haben sollen könnte man folgende Definition benutzen:
textarea { font-family: sans-serif; height: 20em; width: 80em }
Der einfachste Weg ein Stylesheet dem Dokument hinzuzufügen ist Folgendes am Anfang des Dokumentes zu deklarieren:
<?xml version="1.0"?> <?xml-stylesheet href="style.css" type="text/css"?>
wobei 'style.css' der Name des gewünschten Stylesheets ist.
Radio-Buttons selektieren einen Wert aus eine Reihe von Alternativen:
Gender: <input type="radio" name="sex" value="M"> Male <input type="radio" name="sex" value="F"> Female
wird ersetzt durch
<select1 ref="sex"> <label>Gender:</label> <item> <label>Male</label><value>M</value> </item> <item> <label>Female</label><value>F</value> </item> </select1>
Dabei gilt zu beachten, daß dieses Form-Control als Serie von Radio-Buttons,
als (scrollbarer) Auswahlbereich oder als Menü dargestellt werden kann.
Durch Hinzufügen des Hinweises appearance="full"
als Attribut
im select1-
Element wird die Darstellung durch Radio-Buttons vorgeschlagen.
(appearance="compact"
schlägt einen Auswahlbereich und appearance="minimal"
ein Menü vor).
Der Abschnitt 'Initiale Werte' wird zeigen wie ein Wert vorausgewählt werden kann.
Mit Checkboxen können beliebig viele Werte aus einer Liste ausgewählt werden.
Flavors: <input type="checkbox" name="flavors" value="v"> Vanilla <input type="checkbox" name="flavors" value="s"> Strawberry <input type="checkbox" name="flavors" value="c"> Chocolate
wird ersetzt durch
<select ref="flavors" appearance="full"> <label>Flavors:</label> <item> <label>Vanilla</label><value>v</value> </item> <item> <label>Strawberry</label><value>s</value> </item> <item> <label>Chocolate</label><value>c</value> </item> </select>
Der Abschnitt 'Initiale Werte' erklärt wie Werte initial ausgewählt werden können.
In HTML wird durch die Angabe des multiple-
Attributs bewirkt,
daß beliebig viele (keiner oder mehr) Werte aus einer Liste von Optionen
ausgewählt werden können. In XForms benutzt man <select1>
um festzulegen, daß genau ein Wert ausgewählt werden kann. Bei Verwendung
von <select>
können beliebig viele Werte ausgewählt
werden.
Month: <select multiple name="spring"> <option value="Mar">March</option> <option value="Apr">April</option> <option>May</option> </select>
wird ersetzt durch:
<select ref="spring" appearance="minimal"> <label>Month:</label> <item><label>March</label><value>Mar</value></item> <item><label>April</label><value>Apr</value></item> <item><label>May</label><value>May</value></item> </select>
Wenn bei einem HTML-Formular im select
-Element nicht multiple
angegeben ist, sollte es im XForms-Fromular durch select1
ersetzt
werden.
Der Abschnitt 'Initiale Werte' erläutert wie Werte vorausgewählt werden können.
<form method="post" enctype="multipart/form-data" ...> ... File: <input type="file" name="attachment">
wird ersetzt durch
<submission method="form-data-post" .../> ... <upload ref="attachment"><label>File:</label></upload>
Password: <input type="password" name="pw">
wird ersetzt durch
<secret ref="pw"><label>Password:</label></secret>
Zehn Jahre Erfahrung mit HTML-Fromularen haben gezeigt, daß kaum jemand Reset-Buttons verwendet. Ein häufiges Problem ist, daß der Reset-Button mit der Beschriftung "Reset" oftmals größer ist als der mit "OK" beschriftete Button zur Formularübermittlung. Dies führt dazu, daß Nutzer versehentlich den Reset-Button statt "OK" anklicken und damit alle eingegebenen Daten löschen. Mit etwas mehr Aufwand ist es aber nach wie vor möglich einen Reset-Button zu realisieren:
<input type="reset">
wird ersetzt durch
<trigger> <label>Clear all fields</label> <reset ev:event="DOMActivate"/> </trigger>
Buttons haben kein vordefiniertes Verhalten. Ihnen wird ein ein Verhalten zugeordnet, welches ausgelöst wird, wenn der entsprechnde Event eintritt.
Das Button-Element
<input type="button" value="Show" onclick="show()">
kann ersetzt werden durch
<trigger><label>Show</label> <h:script ev:event="DOMActivate" type="text/javascript">show()</h:script> </trigger>
oder
<trigger ev:event="DOMActivate" ev:handler="#show"> <label>Show</label> </trigger>
wobei "#show
" das Element (beispielsweise ein script
-Element)
referenziert, welches das gewünschte Verahlten implementiert:
<script id="show" ...>...
In XForms sind einige Aktionen integriert, die durch einen Button ausgeführt werden können. Der oben erwähnte Reset-Button ist ein Beispiel hierfür.
Die Tatsache, daß dem event
-Attribut ein Präfix vorangestellt
ist bedeutet, daß im Head-Bereich des Dokuments ein zusätzlicher
XML Namensraum deklariert werden muss:
xmlns:ev="http://www.w3.org/2001/xml-events"
<input type="image" src="..." ...>
wird in XForms erzeugt indem man ein Bild innerhalb des label
-Elements
einfügt:
<trigger...><label><h:img src="..." .../></label></trigger>
oder indem man es in einem Stylesheet spezifiziert
<trigger id="activate" ...>
mit einer Styledefinition
trigger#activate {background-image: url(button.png); background-repeat: none}
(Dies funktionert bei submit
-Elementen ebenso.)
Drink: <select name="drink"> <option selected value="none">None</option> <optgroup label="Soft drinks"> <option value="h2o">Water</option> <option value="m">Milk</option> <option value="oj">Juice</option> </optgroup> <optgroup label="Wine and beer"> <option value="rw">Red Wine</option> <option value="ww">White Wine</option> <option value="b">Beer</option> </optgroup> </select>
wird ersetzt durch
<select1 ref="drink"> <label>Drink:</label> <item><label>None</label><value>none</value></item> <choices> <label>Soft drinks</label> <item><label>Water</label><value>h2o</value></item> <item><label>Milk</label><value>m</value></item> <item><label>Juice</label><value>oj</value></item> </choices> <choices> <label>Wine and beer</label> <item><label>Red wine</label><value>rw</value></item> <item><label>White wine</label><value>ww</value></item> <item><label>Beer</label><value>b</value></item> </choices> </select1>
<fieldset> <legend>Personal Information</legend> Last Name: <input name="lastname" type="text"> First Name: <input name="firstname" type="text"> Address: <input name="address" type="text"> </fieldset>
wird ersetzt durch
<group> <label>Personal Information</label> <input ref="lastname"><label>Last name:</label></input> <input ref="firstname"><label>First name:</label></input> <input ref="address"><label>Address:</label></input> </group>
Beachten Sie den konsistenten Einsatz des label
-Elements.
XForms enthält zwei Form-Controls, die nicht in HTML enthalten sind: output
und range
.
Das output
Form-Control erlaubt Werte innerhalb des Dokuments
als Text einzufügen.
Your current total is: <output ref="sum"/>
oder
<output ref="sum"><label>Total</label></output>
Dies kann benutzt werden um den Nutzer eine Vorschau auf die eingegebenen Daten zu ermöglichen.
Weiterhin ist auch möglich Werte zu berechnen:
Total volume: <output value="height * width * depth"/>
(Wobei height
, width
und depth
Werte
sind, die von anderen Form-Controls aufgenommen wurden.)
Dieses Form-Control ermöglichst es den Wertebereich für einen Wert zu begrenzen.
<range ref="volume" start="1" end="10" step="0.5"/>
Ein Browser würde dies als Schieberegler oder Ähnlichem darstellen.
Im nächsten Abschnitt wird verdeutlicht, warum in XForms keine Hidden-Controls (verdeckte Eingabefelder) benötigt werden.
Das ref-
Element in jedem Form-Control bindet die eingegebenen
Daten an einen Kindknoten eines instance
-Elements im XForms-Modell.
Ist im Modell kein instance
-Element definiert (wie in dem Such-Beispiel
am Anfang), wird automatisch eines erzeugt.
Obgleich es durchaus legitim ist, sich die Instanzdaten vom System erzeugen zu lassen, gibt es zahlreiche Gründe dafür die Instanzdaten selbst anzugeben. Betrachten wir erneut das Such-Beispiel:
<model> <instance><data xmlns=""><q/></data></instance> <submission action="http://example.com/search" method="get" id="s"/> </model>
In diesem Beispiel wird als Instanz ein XML-Skelett mit dem Wurzelelement date
und einem Kindelement q
deklariert. Diese Vorgehensweise bringt den Vorteil
mit sich, daß man nun genau über die Form der übertragenen Daten
informiert ist. Allerdings überprüft nun das System bei Angabe von
ref="q"
in einem Form-Control, ob sich auch wirklich in ein q
-Element
in den Instanzdaten befindet.
Es ist wichtig ein xmlns=""
in den Insatnzdaten anzugeben um dem
XML-Prozessor anzugeben, daß es sich hierbei weder um XHTML- noch um XForms-Elemente
handelt.
(Die Wahl von data
als Wurzelelement der Instanzdaten ist willkürlich,
die Wahl der Elements-Namen steht dem Autor frei.)
Um einem Form-Control initiale Werte (beispielweise angeklickte Checkboxen, ausgewählte Menüeinträge, Textfelder mit Inhalt etc.) zu übergeben, ist es lediglich nötig diese Werte innerhalb der Instanzdaten anzugeben. :
<instance><data xmlns=""><q>Keywords</q></data></instance>
würde das Textfeld initial mit dem Wort Keywords füllen.
Ebenso ist dies bei dem Beispiel aus dem Abschnitt über Checkboxen möglich:
<select ref="flavors" appearance="full"> <label>Flavors:</label> <item> <label>Vanilla</label><value>v</value> </item> <item> <label>Strawberry</label><value>s</value> </item> <item> <label>Chocolate</label><value>c</value> </item> </select>
Die Werte vanilla und strawberry könnte man nun wie folgt vor-auswählen:
<instance><data xmlns=""><flavors>v s</flavors></data></instance>
Auch im Menü-Beispiel kann man leicht Menü-Einträge vor-auswählen:
<select ref="spring" appearance="minimal"> <label>Month:</label> <item><label>March</label><value>Mar</value></item> <item><label>April</label><value>Apr</value></item> <item><label>May</label><value>May</value></item> </select>
Um March
und April
initial auszuwählen könnte
man folgendermassen vorgehen:
<instance><data xmlns=""><spring>Mar Apr</spring></data></instance>
Und im optgroup
-Beispiel:
<select1 ref="drink"> <label>Drink:</label> <item><label>None</label><value>none</value></item> <choices> <label>Soft drinks</label> <item><label>Water</label><value>h2o</value></item> <item><label>Milk</label><value>m</value></item> <item><label>Juice</label><value>oj</value></item> </choices> <choices> <label>Wine and beer</label> <item><label>Red wine</label><value>rw</value></item> <item><label>White wine</label><value>ww</value></item> <item><label>Beer</label><value>b</value></item> </choices> </select1>
Wählt man den Wert none
so aus:
<instance><data xmlns=""><drink>none</drink></data></instance>
Der Grund dafür, daß man in XForms keine Hidden-Values (verdeckte
Eingabefelder) benötigt ist, daß jeder Wert der Instanzdaten, der
nicht an ein Form-Control gebunden ist, per Definition dem Nutzer nicht angezeigt
wird. Wenn wir also dem Such-Beispiel einen "versteckten Wert" namens
results
hinzufügen möchten, könnten wir die Instantdaten
folgenderweise ändern:
<instance><data xmlns=""><q/><results>10</results></data></instance>
Es ist nicht nötig die Instanzdaten im Dokument selbst anzugeben. Es ist ebenso möglich diese Instanzdaten aus einer externen Ressource einzubinden:
<instance src="http://example.org/forms/templates/t21.xml"/>
wobei die Datei t21.xml die Instanzdaten enthält, etwa
<data><w>640</w><h>480</h><d>8</d></data>
(Die Angabe von xmlns=""
ist bei externen Instanzen nicht nötig.)
Das Einbinden externen Instanzdaten bringt immense Möglichkeiten mit sich.
Dies liegt darin begründet, daß das ref-
Attribut in
den Form-Controls nicht nur einen Identifikator auswählen kann (wie es
in HTML mit name
möglich ist), sondern vielmehr jeder XPath-Ausdruck
als ref-
Attribut zulässig ist. XPath ermöglicht es jedes
Element oder Attribut in einem XML-Dokument auszuwählen.
Dies bedeutet, daß man mittels XPath jedes XML-Dokument (natürlich
auch ein XHTML-Dokument) als Instanz angeben, Form-Controls daran binden und
die überarbeiteten Daten übertragen kann.Um beispielsweise das title
-Element
eines XHTML-Dokuments zu binden, könnte man folgenden Ausdruck benutzen:
<input ref="h:html/h:head/h:title">...
(wählt das title
-Element im head
-Element, welches
sich im html-
Element befindet. Mit Angabe des XHTML-Namensraum).
Mit
<input ref="h:html/h:body/@class">...
würde man das class
-Attribut im body
-Element
auswählen.
Stellen wir uns exemplarisch ein Geschäft mit sehr unregelmäßigen
Öffnungszeiten (möglicherweise wetterabhängig) vor. Nun möchte
das Geschäft seine Öffnungzeiten auf seiner Webseite mitteilen. Diese
Webseite enthält in unserem Beispiel nur einen Absatz im body
-Element:
<p>The shop is <strong>closed</strong> today.</p>
Anstatt allen Mitarbeitern HTML beizubringen können wir ein einfaches Formular erstellen, das die Seite bearbeitet:
<model> <instance src="http://www.example.com/shop/status.xhtml"/> <submission action="http://www.example.com/shop/status.xhtml" method="put" id="change"/> </model ... <select1 ref="/h:html/h:body/h:p/h:strong"> <label>The shop is now:</label> <item><label>Open</label><value>open</value></item> <item><label>Closed</label><value>closed</value></item> </select1> <submit submission="change"><label>OK</label></submit>
Dabei gilt zu beachten, daß die zu bearbeitende Seite in korrektem XHTML verfasst sein muss (und nicht HTML, weil nur XHTML ein XML-Dokument darstellt). Weitherhin muss der verwendete Server die "put"-Methode unterstüzen (was nicht bei allen Servern der Fall ist).
HTML erlaubt nur einen Weg, wie die Daten zum Server übertragen werden.
XForms ermöglicht es mehrere Submit-Controls an die Instanzdaten zu binden um diese Daten an verschiedene Server zu übertragen oder mehre Übertragungsarten zu ermöglichen.
Beispielsweise könnte das Such-Beispiel die Suchanfrage an mehere Suchmaschinen stellen:
<model> <instance><data xmlns=""><q/></data></instance> <submission action="http://example.com/search" method="get" id="com"/> <submission action="http://example.org/search" method="get" id="org"/> </model>
und im body
-Element:
<submit submission="org"><label>Search example.org</label></submit> <submit submission="com"><label>Search example.com</label></submit>
Ebenso wie in HTML gibt es in XForms mehere Wege die Daten zu übertragen.
In HTML wird dies durch die Attribute method
und enctype
festgelegt - In XForms benutzt man nur das method
-Attribut:
HTML | XForms |
---|---|
method="get" | method="get" |
method="post" enctype="application/x-www-form-urlencoded" |
method="urlencoded-post" |
method="post" enctype="multipart/form-data" |
method="form-data-post" |
Zusätzlich gibt es in XForms einige neue Wege zur Übertragung. Besonders
interessant sind method="post"
("postet" die Instanzdaten
als XML-Dokument) und method="put"
("putet" die Insatnzdaten
als XML-Dokument). Hieraus entstehen interessante Anwendungen wie zum Beispiel::
<submission action="file:results.xml" method="put"/>
Diese Übertragungsmethode speichert die Daten im lokalen Dateisystem mittels
file:
Schema.
Wie oben erwähnt ist es möglich mehrere Übertragungen paralell zu nutzen. Das bedeutet, daß bei großen Formularen ein "Lokal speichern"-Button und ein "Zum Server senden"-Button realisiert werden kann.
Standardmäßig wird nach einer Übertragung das komplette Dokument
durch die Antwort des Servers ersetzt - Genauso wie in HTML. Zusätzlich
gibt es in XForms weitere Optionen, die durch das replace
-Attribut
im submission
-Element gewählt werden können. Der Wert
replace="instance"
ersetzt nur die Instanzdaten und der Wert replace="none"
belässt das Dokument in seinem Zustand ohne Ersetzung.
Ein Adressänderungs-Formular einer Bank könnte beispielsweise zwei Buttons enthalten. Einen um im Formular Name und Adressdaten automatisch anhand der Kontonummer auszufüllen. Und einen zweiten Button der dazu dient die geänderten Daten zum Server zu übertragen.:
<model> <instance><data xmlns=""> <accountnumber/><name/><address/> </data></instance> <submission method="get" action="http://example.com/prefill" id="prefill" replace="instance"/> <submission method="get" action="http://example.com/change" id="change" replace="none"/> </model> ... <input ref="accountnumber"><label>Account Number</label></input> <submit submission="prefill"><label>Find</label></submit> <input ref="name"><label>Name</label></input> <textarea ref="address"><label>Address</label></textarea> <submit submission="change"><label>Submit</label></submit>
Der "Find"-Button ersetzt die Instanzdaten durch vom Server ausgefüllte Daten, die dieser mit Hilfe der Kontonummer ermittelt hat. Der "Submit"-Button überträgt die bearbeiteten Daten an den Server und belässt das Formular in seinem Zustand (So sind spätere Änderungen möglich oder die Eingabe einer anderen Kontonummer, um die zugehörigen Daten zu bearbeiten).
In HTML kann man festlegen, daß Form-Controls disabled ("ausgeschaltet" bzw. "ausgeblendet") oder read-only (schreibgeschützt) sind. Dies geht aber nur mittels Scriptsprachen.
XForms bietet einfache Wege diese Eigenschaften zu kontrollieren. Darüber hinaus gibt es zusätzliche Eigenschaften die gesteuert werden können:
Zu beachten ist, daß diese Eigenschaften an den Wert und nicht an das jeweilige Form-Control gebunden werden. Die Eigenschaft wirkt sich dann auf alle Form-Controls aus, die mit dem Wert verknüpft sind.
Diese Eigenschaften benutzen das bind-
Element, welches im model
-Element
angelegt wird. Um bind
nutzen zu können muss ein explizites
instance
-Element bestehen.
Um ein Form-Control auszuschalten bzw. auszublenden benutzt man das relevant-
Attribut.
Wenn beispielsweise erreicht werden soll, daß die Eingabe der Kreditkartennummer
nur notwendig ist, wenn auch Kreditkartenzahlung ausgewählt wurde, könnte
man folgendermassen vorgehen:
<model> <instance><data xmlns=""> <amount/><method/><cc/><expires/> </data></instance> <bind nodeset="cc" relevant="../method='credit'"/> <bind nodeset="expires" relevant="../method='credit'"/> </model>
Hier wurde festgelegt, daß die Felder cc
und expires
nur dann relevant sind, wenn das Element method
den Wert credit
hat. Für alle anderen Werte von method
sind die Felder bedeutungslos,
und die assozierten Form-Controls brauchen nicht ausgefüllt werden. In
diesem Fall muss "../method
" anstelle von method
verwendet
werden, da sich die Adressierung auf das im bind
-Element festgelgte
'Nodeset' bezieht. Die Angabe von "method"
würde ein Kindelement
von cc
oder expires
referenzieren. Man stelle sich
dies ähnlich dem Verzeichnisswechsel in einem Dateisystem vor. Neben der
relativen Adressierung durch "../method
" ist auch die Angabe eines
absoluten Pfades zum Element wie etwa "/data/method"
möglich.
Es ist dem jeweiligen Browser überlassen wie er Disabled-Controls darstellt (Zusätzlich kann die Möglichkeit bestehen dies durch ein Stylesheet zu beeinflussen). Der typische Weg wäre die Darstellung des Form-Controls in abgeschwächten Grau.
Die zugehörigen Form-Controls könnten so erzeugt werden (Form-Controls werden nicht explizit disabled. Dies wird durch den Wert bestimmt, an den sie gebunden sind):
<select1 ref="method"><label>Method of payment:</label> <item><label>Cash</label><value>cash</value></item> <item><label>Credit card</label><value>credit</value></item> </select1> <input ref="cc"><label>Card number:</label></input> <input ref="expires"><label>Expiry date:</label></input>
Werden strukturierte Instantdaten verwendet, kann man den Vorgang noch vereinfachen:
<model> <instance><data xmlns=""> <amount/><method/> <cc> <number/><expires/> </cc> </data></instance> <bind nodeset="cc" relevant="../method='credit'"/> </model>
Wobei die Form-Controls dann an die Kinder von 'cc
' gebunden werden:
<input ref="cc/number"><label>Card number:</label></input> <input ref="cc/expires"><label>Expiry date:</label></input>
Ebenso kann eine Gruppierung (grouping) benutzt werden:
<group ref="cc"> <input ref="number"><label>Card number:</label></input> <input ref="expires"><label>Expiry date:</label></input> </group>
Auf die selbe Weise kann man angeben, daß ein Wert unter bestimmten Bedingungen schreibgeschützt (read-only) ist:
<model> <instance><data xmlns=""> <variant>basic</variant><color>black</color> </data></instance> <bind nodeset="color" readonly="../variant='basic'"/> </model>
Dieses Beispiel legt für das Element color
als Standardwert
black
fest, welcher nicht verändert werden kann, wenn das
Element variant
den Wert basic
hat.
Eine nützliche, neue Eigenschaft von XForms besteht in der Möglichkeit einen Wert als required zu kennzeichnen. Dies hat zur Folge, daß das Formular nur dann übertragen werden kann, wenn dieser Wert vom Nutzer angegeben wurde. Im einfachsten Fall gibt man an, daß ein Wert immer eingegeben werden muss. Exemplarisch am Such-Beispiel:
<model> <instance><data xmlns=""><q/></data></instance> <bind nodeset="q" required="true()"/> <submission .../> </model>
Zusätzlich kann man, wie bei den readonly
und relevant
Attributen, einen XPath-Ausdruck angeben, der den Wert nur unter bestimmten
Konditionen als required kennzeichnet:
<bind nodeset="state" required="../country='USA'"/>
Diese Definition bewirkt, daß der Wert für das Element state
nur dann unbedingt eingegeben werden muss, wenn der Wert für country
auf "USA
" gesetzt ist.
Auch in diesem Fall ist es dem Browser überlassen, wie er dem Nutzer mitteilt, daß ein Wert unbedingt eingegeben werden muss (Ebenfalls könnte eine Einflußnahme per Stylesheet möglich sein).
Diese Eigenschaft erlaubt es zusätzliche Beschränkungen für einen Wert anzugeben. Zum Beispiel:
<bind nodeset="year" constraint=". > 1970"/>
beschränkt den Jahreswert auf Werte nach 1970. In XPath wird mit "." ein
Wert selbst referenziert, also in diesem Fall der Wert year
. (">" muss aufgrund
der allgemeinen XML-Regeln als > geschrieben werden).
Es ist möglich anzugeben, daß ein Wert durch andere Werte berechnet wird. Beispielweise:
<bind ref="volume" calculate="../height * ../width * ../depth"/>
Wird ein Wert auf diese Weise berechnet, so ist er automatisch schreibgeschützt
(readonly
).
Es stehen eine Reihe von Funktionen zur Berechnung von Werten bereit: Arithmetische Operationen, String-Manipulationen, Datumsfunktionen, 'if'-Operator, ...
Eine weitere, sehr nützliche Eigenschaft in XForms ist Typisierung. Es ist möglich jedem Wert einen Typ zuzuordnen. Der Browser hat dann die Möglichkeitkeit zu überprüfen ob der eingebene Wert dem geforderten Typ entspricht.
Wenn beispielsweise in unserem Such-Beispiel nur nach Nummern gesucht werden soll (z.B. zur Suche in einer Bug-Datenbank) muss nur folgendes Attribut hinzugefügt werden:
<bind nodeset="q" type="xsd:integer"/>
Das Formular kann jetzt nur dann übertragen werden, wenn der Wert vom Typ Integer ist.
(Im Root-Element muss noch der Namensraum xmlns:xsd="http://www.w3.org/2001/XMLSchema"
angegeben werden.)
Wenn in einem Eingabefeld die URL von einer Homepage angegeben werden soll, könnte man dies so festlegen:
<bind nodeset="homepage" type="xsd:anyURI"/>
Sie werden feststellen, daß manche Browser abhängig vom Datentyp eines Wertes alternative Darstellungsformen anbieten. Wenn ein Wert beispielsweise vom Typ Datum ist, so könnte der Browser einen Kalender zur Auswahl des Wertes einblenden und dem Nutzer so die Eingabe erleichtern.
Es gibt eine Reihe nützlicher, vordefinierter Datentypen, beispielsweise:
select
)Wenn mehrere bind
-Elemente den selben Wert referenzieren, kann
man diese zu einem bind
-Element zusammenfassen:
<bind nodeset="q" type="xsd:integer" required="true()"/>
Sollen mehrere Formulare in einem Dokument realisiert werden, so muß
für jedes Formular ein Modell angegeben werden. Es muss in diesem Fall
für jedes Form-Control angegeben werden zu welchem Modell es gehört.
Dies geschieht durch ein id-
Attribut pro Modell und ein model-
Attribut
für jedes Form-Control:
<model id="search"> <instance><data xmlns=""><q/></data></instance> <submission id="s" .../> </model> <model id="login"> <instance><data xmlns=""><user/><passwd/></data></instance> <submission id="l" .../> </model> ... <input model="search" ref="q"><label>Find</label></input> <submit submission="s"><label>Go</label></submit> ... <input model="login" ref="user"><label>User name</label></input> <secret model="login" ref="passwd"><label>Password</label></input> <submit submission="l"><label>Log in</label></submit>
Werden im Modell bind
-Elemente festgelegt, so kann man auch an
diese die Form-Controls binden. Dies bringt den Vorteil mit sich, daß
die Struktur der Instanzdaten verändert werden kann, ohne die Form-Controls
überarbeiten zu müssen (Modularisierung). Weiterhin erübrigt
sich in diesem Fall die Referenzierung des Modells in den Form-Controls:
<model> <instance><data xmlns=""><q/></data></instance> <submission id="s" .../> <bind id="query" nodeset="q" required="true()"/> </model> ... <input bind="query"><label>Find</label></input>
(Bitte beachten Sie, daß im bind
-Attribut die id
eines bind
-Elementes angegeben wird - Die Angabe eines XPath-Ausdruckes
ist hier nicht möglich bzw. sinngemäß.)
Wie bereits in der Einführung erwähnt, ist dies keine vollständige Anleitung zu XForms. Wichtige Eigenschaften von XForms wurden hier nicht behandelt:
Events und Actions: Wie man Events und vordefinierte Actions benutzt.
Schemen: Wie man eigene Typen definiert.
p3ptype: Wie man festlegt, daß Werte die Privatspähre des Nutzers betreffen bzw. unter den Datenschutz fallen.
Switch: Formulare in mehreren Schritten ausfüllen bzw. Formulare situationsbedingt verändern.
Repeat: Formularteile dynamisch hinzufügen bzw. entfernen (wie z.B. im Warenkorb eines Online-Shops).