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

W3C

XForms für HTML-Programmierer

Steven Pemberton, W3C/CWI

Datum dieser Version: 28. Oktober 2003

Einführung

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.

Inhaltsverzeichniss

  1. Ein einfaches Such-Formular
    Namensraum-Präfixe
  2. Form-Controls
    Input
    Textarea
    Radio Buttons
    Checkboxen
    Menüs
    Dateiauswahl
    Passwörter
    Buttons
    Image-Buttons
    Reset
    Optgroup
    Grouping-Controls
    Output-Controls*
    Range-Controls*
    Hidden-Controls
  3. Übertragene Daten
    Explizitmachen der Übertragungsdaten
    Initiale Werte
    Hidden-Values
    Einbinden von Instanzdaten aus externen Quellen*
    Jedes XML-Dokument 'bearbeiten'*
  4. Übertragung
    Mehrere Übertragungen*
    Übertragungsmethoden
    Nach der Übertragung*
  5. Steuerung der Form-Controls
    Disabled-Controls
    Readonly-Controls
    Required-Controls*
    Constraint-Property*
    Calculate-Property*
    Typisierung*
    Kombination von Eigenschaften*
  6. Mehr als ein Formular in einem Dokument
    Bind anstelle von Ref
  7. Hier nicht behandelte Eigenschaften

*Diese Fähigkeiten sind mit HTML-Formularen nicht möglich

Ein einfaches Such-Formular

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>

Namensraum-Präfixe

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.

Form-Controls

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.

Input

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.

Textarea

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

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.

Checkboxen

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.

Dateiauswahl

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

Passwörter

Password: <input type="password" name="pw">

wird ersetzt durch

<secret ref="pw"><label>Password:</label></secret>

Reset

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

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"

Image-Buttons

<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.)

Optgroup

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>

Grouping-Controls

<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.

Output-Controls*

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.)

Range-Controls*

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.

Hidden-Controls

Im nächsten Abschnitt wird verdeutlicht, warum in XForms keine Hidden-Controls (verdeckte Eingabefelder) benötigt werden.

Übertragene Daten

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.

Explizitmachen der Übertragungsdaten

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.)

Initiale Werte

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>

Hidden-Values

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>

Einbinden von Instanzdaten aus externen Quellen*

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.)

Jedes XML-Dokument 'bearbeiten'*

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).

Übertragung

Mehrere Übertragungen*

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>

Übertragungsmethoden

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:

Übertragungsmethoden in HTML und XForms
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.

Nach der Übertragung*

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).

Steuerung der Form-Controls

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.

Disabled-Controls

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>

Readonly-Controls

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.

Required-Controls*

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).

Constraint-Property*

Diese Eigenschaft erlaubt es zusätzliche Beschränkungen für einen Wert anzugeben. Zum Beispiel:

<bind nodeset="year" constraint=". &gt; 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 &gt; geschrieben werden).

Calculate-Property*

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, ...

Typisierung*

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:

Kombination von Eigenschaften

Wenn mehrere bind-Elemente den selben Wert referenzieren, kann man diese zu einem bind-Element zusammenfassen:

<bind nodeset="q" type="xsd:integer" required="true()"/>

Mehr als ein Formular in einem Dokument

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>

Bind anstelle von Ref

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äß.)

Hier nicht behandelte Eigenschaften

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).

Liste deutscher Übersetzungen von W3C-Dokumenten - www.w3c.org - www.zaecherl.de