siteuri.ro logo

www.siteuri.ro

Aceasta este traducerea in romana a documentului original in engleza realizat de Steven Pemberton. Aceasta traducere poate contine erori. In caz de neclaritati, versiunea in engleza este cea autoritativa.

Traducere de Andrei Stanescu, Aprilie 2005.

W3C

XForms pentru autori HTML

Steven Pemberton, W3C/CWI

Versiunea in engleza din: 28 October 2003

Introducere

XForms este noul limbaj pentru formularele web. Acest document este o scurta introducere in XForms si arata cum se transforma formularele HTML existente in XForms. Acesta nu este un tutorial pentru incepatori; se presupune ca aveti deja cunostinte de formulare HTML. Desi sunt mentionate facilitatile pe care XForms le are in plus fata de formularele HTML (marcate cu un asterics in titluri), acest tutorial nu acopera toate lucrurile ce pot fi facute cu XForms.

Continut

  1. Un simplu formular de cautare
    Prefixele namespace
  2. Controlurile formularului
    Input text simplu
    Textarea
    Butoane radio
    Checkbox-uri
    Meniuri
    Selector de fisier
    Parole
    Butoane
    Butoane imagini
    Reset
    Optgroup
    Gruparea controlurilor
    Controluri output*
    Controluri range*
    Controluri ascunse
  3. Valorile trimise
    Crearea explicita a valorilor trimise
    Valori initiale
    Valori ascunse
    Luarea valorilor initiale din alta parte*
    'Editarea' unui document XML*
  4. Trimiterea
    Trimiteri multiple*
    Metode de trimitere
    Viata de dupa trimitere*
  5. Controlul Controlurilor
    Controluri dezactivate
    Controluri readonly
    Controluri obligatorii*
    Proprietatea constraint*
    Proprietatea calculate*
    Tipuri*
    Combinarea proprietatilor*
  6. Mai mult de un formular pe pagina
    Bind in loc de Ref
  7. Aspecte care nu au fost discutate aici

*Caracteristici care nu sunt prezente in formularele HTML

Un simplu formular de cautare

Sa consideram acest simplu formular HTML de cautare:

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

Principala diferenta este ca in XForms valorile colectate sunt adunate in head, intr-un element numit model; numai controlurile formularului sunt puse in body. In cazul acesta trebuie adaugate urmatoarele informatii de baza in head:

<model>
   <submission action="http://example.com/search"
               method="get"
               id="s"/>
</model>

(Elementele si atributele XForms sunt scrise cu litere mici.)

Elementul <form> nu mai este necesar; controlurile formularului din body arata asa:

<input ref="q"><label>Find</label></input>
<submit submission="s"><label>Go</label></submit>

Se observa din acest exemplu ca controlurile formularului au un element-copil <label>, <input> foloseste "ref" in loc de "name", si exista un control separat submit care face legatura cu informatiile despre trimitere din head. Exemplul complet este:

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

Prefixele namespace

Alta diferenta evidenta este folosirea prefixelor h: in elementele HTML. Aceasta nu are legatura cu XForms, ci cu XML, care a fost conceput pentru a permite combinarea diferitelor limbaje. XForms este facut nu doar pentru XHTML, ci si pentru alte limbaje. Procesorul XML trebuie sa stie carui limbaj ii apartine un anumit element, desi un limbaj poate fi limbajul 'default'. In documentul de mai sus, XForms este default, desi puteam sa facem XHTML default schimband atributul xmlns in head:

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

Alegerea e a ta. Poti alege sa nu faci nici unul default, in cazul acesta fiind necesar sa pui prefix la toate elementele. Poti alege orice prefix; h: sau x: sau html: sau form:, depinde de tine.

In viitor, XHTML2 iti va permite sa scrii formularele fara prefixe.

Controlurile formularului

XForms are echivalente pentru toate controlurile formularelor HTML. Dar exista o diferenta majora in abordare: HTML specifica in primul rand cum trebuie sa arate controlul, pe cand XForms specifica in primul rand ce trebuie sa faca controlul. Deci in timp ce specificatia HTML spune ca elementul select creaza un meniu si valoarea radio pentru atributul type al elementului input creaza butoane radio care care permit o singura alegere, XForms are elementele select si select1, care specifica doar scopul controlului, de a alege zero sau mai multe, sau doar un singur element dintr-o lista. Cum aceste elemente sunt prezentate utilizatorului poate varia in functie de user agent sau poate fi specificat intr-un style sheet. Pe un telefon mobil unde nu exista mult spatiu pe ecran, amandoua pot fi prezentate in meniuri, in timp ce pe un ecran mai mare amandoua pot fi prezentate in butoane selectabile. Poti face o sugestie cu privire la modul de prezentare daca vrei, sau poti scrie modul de prezentare intr-un stylesheet, dar daca nu specifici nimic user agent-ul va face aceasta alegere pentru tine.

Iata cum scrii echivalentele elementelor formularelor HTML in XForms.

Input text simplu

First name: <input type="text" name="firstname">

devine

<input ref="firstname"><label>First name:</label></input>

Nu e nevoie sa indici ca acesta este pentru text: in absenta altor informatii default-ul este text (numit string in XForms).

Vezi mai jos 'valori initiale' pentru informatii despre cum sa stabilesti o valoare initiala pentru un control.

Textarea

Message: <textarea name="message" rows="20" cols="80"></textarea>

devine

<textarea ref="message"><label>Message:</label></textarea>

Inaltimea si latimea sunt setate in style sheet; de exemplu:

textarea[ref="message"] { font-family: sans-serif;
                          height: 20em; width: 80em }

Desi aceasta imita modul de afisare in HTML, nu e obligatoriu sa folosesti un font sans serif, nici sa folosesti o anumita unitate de masura:

textarea[ref="message"] { font-family: serif;
                          height: 2cm; width: 20% }

Daca vrei ca toate elementele textarea sa aiba aceleasi dimensiuni, poti folosi ceva de genul:

textarea { font-family: sans-serif;
           height: 20em; width: 80em }

Cea mai usoara metoda de a include un style sheet in document este sa adaugi aceasta la inceput:

<?xml version="1.0"?>
<?xml-stylesheet href="style.css" type="text/css"?>

unde 'style.css' este numele foii CSS.

Butoane radio

Butoanele radio selecteaza o valoare din mai multe alternative:

Gender:
<input type="radio" name="sex" value="M"> Male
<input type="radio" name="sex" value="F"> Female

devine

<select1 ref="sex">
   <label>Gender:</label>
   <item>
      <label>Male</label><value>M</value>
   </item>
   <item>
      <label>Female</label><value>F</value>
   </item>
</select1>

Tine minte ca aceasta poate fi prezentata ca butoane radio, cutie de selectie (derulabila), sau un meniu. Poti include appearance="full" in <select1> pentru a sugera ca modul de prezentare sa fie butoane radio. (Foloseste appearance="compact" pentru a sugera o cutie de selectie (derulabila) sau appearance="minimal" pentru a sugera un meniu).

Vezi mai jos 'valori initiale' pentru informatii despre cum sa stabilesti o valoare initiala pentru un control.

Checkbox-uri

Checkbox-urile selecteaza zero sau mai multe valori dintr-o lista.

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

devine

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

Vezi mai jos 'valori initiale' pentru informatii despre cum sa stabilesti o valoare initiala pentru un control.

In functie de prezenta atributului multiple in HTML, meniurile permit selectarea a zero sau mai multe valori din lista sau a unei singure valori. In XForms poti folosi <select1> pentru o singura selectie, sau <select> pentru zero sau mai multe selectii.

Month:
<select multiple name="spring">
      <option value="Mar">March</option>
      <option value="Apr">April</option>
      <option>May</option>
</select>

devine:

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

Lipsa atributului multiple in elementul HTML select este echivalenta cu folosirea select1 in XForms.

Vezi mai jos 'valori initiale' pentru informatii despre cum sa stabilesti o valoare initiala pentru un control.

Selector de fisier

<form method="post" enctype="multipart/form-data" ...>
 ...
File: <input type="file" name="attachment">

devine

<submission method="form-data-post" .../>
...
<upload ref="attachment"><label>File:</label></upload> 

Parole

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

devine

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

Reset

Zece ani de experinta cu formularele HTML a aratat ca aproape nimeni nu foloseste butoanele reset, dar totusi acestea sunt prezente in multe formulare web. O problema o reprezinta faptul ca un buton reset cu textul "Reset" este de obicei mai mare decat un buton de trimitere cu textul "OK", cu rezultatul ca utilizatorii apasa uneori pe Reset cand de fapt vroiau sa apese pe OK, uneori pierzand multa munca (putine browsere ofera un undo). Prin urmare, este posibil sa creezi un astfel de buton in XForms, dar acest lucru e mai greu de facut, tocmai pentru a descuraja folosirea lui:

<input type="reset">

devine

<trigger>
   <label>Clear all fields</label>
   <reset ev:event="DOMActivate"/>
</trigger>

Butoane

Butoanele nu fac nimic prestabilit, dar au o actiune asociata cu ele care are loc dupa un anumit eveniment.

Elementul buton

<input type="button" value="Show" onclick="show()">

devine

<trigger><label>Show</label>
   <h:script ev:event="DOMActivate" type="text/javascript">show()</h:script>
</trigger>

sau

<trigger ev:event="DOMActivate" ev:handler="#show">
    <label>Show</label>
</trigger>

unde "#show" defineste elementul (spre exemplu un element script) care implementeaza actiunea:

<script id="show" ...>...

XForms are un numar de actiuni prestabilite care pot fi activate de un buton; vezi butonul reset de mai sus pentru un exemplu.

Faptul ca atributul event are un prefix inseamna ca trebuie sa adaugi urmatorul Namespace XML in head:

xmlns:ev="http://www.w3.org/2001/xml-events"

Butone imgini

<input type="image" src="..." ...>

este realizat prin punerea unei imagini in elementul <label>:

<trigger...><label><h:img src="..." .../></label></trigger>

sau prin specificarea ei in stylesheet

<trigger id="activate" ...>

cu o regula de genul

trigger#activate {background-image: url(button.png);
                  background-repeat: none}

(Exemplul e valabil si pentru <submit>.)

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>

devine

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

Gruparea controlurilor

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

devine

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

Observa folosirea consistenta a elementului <label>.

Controluri output*

XForms are doua controluri care nu sunt in HTML, output si range.

Controlul output iti permite sa incluzi valori ca text in document.

Your current total is: <output ref="sum"/>

sau

<output ref="sum"><label>Total</label></output>

Aceasta poate fi folosita pentru a-i permite vizitatorului sa vada informatia pe care a introdus-o inainte de a o trimite.

Poti efectua si calcule:

Total volume: <output value="height * width * depth"/>

(unde height, width si depth sunt valori colectate de alte controluri.)

Controluri range*

Acesta iti permite sa specifici constrangeri pentru o valoare.

<range ref="volume" start="1" end="10" step="0.5"/>

Un user agent poate reprezenta aceasta cu ajutorul unei bari de deplasare.

Controluri ascunse

Dupa cum vei vedea in sectiunea urmatoare, in XForms nu e nevoie de controluri ascunse.

Valorile trimise

Atributul ref in fiecare control se refera la un copil al unui element instanta din model, unde valorile sunt adunate inaintea trimiterii. Daca nu exista un element instanta (ca in exemplul de mai sus), atunci este creat unul.

Crearea explicita a valorilor trimise

Desi este permis sa lasi sistemul sa creeze o instanta pentru tine, exista motive pentru care sa creezi chiar tu una, ca in exemplul de mai jos:

<model>
    <instance><data xmlns=""><q/></data></instance>
    <submission action="http://example.com/search"
                method="get" id="s"/>
</model>

Din aceasta iti poti da seama imediat ca singura valoare trimisa se numeste "q". Un avantaj evident este ca poti vedea ce este trimis, dar si sistemul va putea verifica daca exista un q in instanta atunci cand scrii ref="q".

Din motive pe care nu le voi discuta in detaliu aici, este esential sa pui xmlns="" in instanta, pentru a-i spune procesorului ca elementele din instanta nu sunt elemente XHTML sau XForms.

(Am folosit tagul <data> aici, dar poti folosi orice tag vrei.

Valori initiale

Pentru initializarea controlurilor, inclusiv initializarea checkbox-urilor, selectarea itemurilor din liste etc., trebuie sa creezi o instanta care contine deja valorile respective, spre exemplu:

<instance><data xmlns=""><q>Keywords</q></data></instance>

ar crea valoarea initiala Keywords pentru controlul text.

Analog, pentru exemplul cu checkbox-uri, care arata asa:

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

poti selecta casutele vanilla si strawberry in felul urmator:

<instance><data xmlns=""><flavors>v s</flavors></data></instance>

Iar pentru meniuri, care aratau asa:

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

poti pre-selecta March si April asa:

<instance><data xmlns=""><spring>Mar Apr</spring></data></instance>

Si pentru optgroup:

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

Selecteaza valoarea none asa:

<instance><data xmlns=""><drink>none</drink></data></instance>

Valori ascunse

Motivul pentru care in XForms nu e nevoie de controluri ascunse este ca valorile dintr-o instanta la care nu se leaga nici un control sunt ascunse prin definitie. Deci daca vrem sa adaugam o valoare ascunsa results la formularul de cautare, vom schimba instanta in:

<instance><data xmlns=""><q/><results>10</results></data></instance>

Luarea valorilor initiale din alta parte*

Nu esti obligat sa scrii instanta initiala in document, pentru ca o poti incarca dintr-o sursa externa in felul urmator:

<instance src="http://example.org/forms/templates/t21.xml"/>

si documentul t21.xml va contine datele:

<data><w>640</w><h>480</h><d>8</d></data>

(Nu e nevoie de xmlns="" in instante externe, desi nu strica daca il incluzi oricum.)

'Editarea' unui document XML*

Incarcarea instantelor externe iti da o putere imensa, deoarece atributul ref nu doar selecteaza un identificator, ca atributul name in HTML, ci poate fi orice expresie XPath. XPath iti permite sa selectezi orice element sau atribut intr-un document XML.

Aceasta inseamna ca odata ce ai invatat XPath, il poti folosi in orice document XML ca instanta, chiar si un document XHTML; apoi poti lega controluri de el si le poti trimite. Spre exemplu, pentru a lega de elementul <title> intr-un document XHTML, poti folosi:

<input ref="h:html/h:head/h:title">...

(adica elementul title din elementul head din elementul html, toate in namespace-ul XHTML), sau

<input ref="h:html/h:body/@class">...

care este atributul class al elementului body.

Spre exemplu, sa presupunem ca un magazin are un orar imprevizibil (poate depinde de vreme), si proprietarii vor sa faca o pagina pe care clientii sa vada daca magazinul este deschis. Sa presupunem ca pagina are un singur paragraf in elementul body:

<p>The shop is <strong>closed</strong> today.</p>

Decat sa invatam angajatii sa scrie HTML pentru a modifica pagina, putem face un formular care sa modifice pagina:

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

Pentru ca aceasta sa mearga, pagina in cauza trebuie sa fie XHTML corect, (si nu HTML, deoarece doar XHTML este un document XML), si serverul trebuie sa accepte metoda "put" (nu toate serverele fac acest lucru).

Trimiterea

Trimiteri multiple*

HTML iti permite sa trimiti datele unui singur server, intr-un singur mod.

XForms iti permite sa ai controluri diferite, care leaga la elemente submission diferite in head, care trimit datele la servere diferite, cu metode diferite.

Spre exemplu, in exemplul de mai sus cu cautarea, putem trimite datele la mai multe motoare de cautare:

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

si in body:

<submit submission="org"><label>Search example.org</label></submit>
<submit submission="com"><label>Search example.com</label></submit>

Metode de trimitere

La fel ca in HTML, exista mai multe metode de a trimite datele. In HTML, aceasta poate fi exprimata cu doua atribute, method si enctype; in Xforms exista numai method:

Metode de trimitere in HTML si echivalentele 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"

Exista si noi metode de trimitere; cele mai interesante sunt method="post" care trimite rezultatul ca document XML, si method="put" care insereaza rezultatul ca document XML. Un mod interesant de folosire al acestuia este:

<submission action="file:results.xml" method="put"/>

care salveaza rezultatul intr-un fisier folosind schema file:.

Deoarece poti avea mai mult de o trimitere pentru un formular, poti avea si mai multe butoane 'salveaza pe disc' sau 'trimite'.

Viata de dupa trimitere*

Ca default, cand valorile sunt trimise rezultatul creat de server ilocuieste tot documentul, la fel ca in HTML. Totusi, exista si alte optiuni, specificate in atributul replace al elementului submission. Valoarea replace="instance" inlocuieste numai instanta, replace="none" lasa documentul formularului asa cum este - fara sa il inlocuiasca.

Spre exemplu, intr-un formular pentru schimbarea adresei pentru o banca, poti crea doua butoane, unul pentru a pre-completa formularul cu numele si adresa pe baza numarului de cont, iar celalalt pentru a trimite datele schimbate:

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

Butonul 'find' va inlocui instanta cu una noua, continand detaliile persoanei cu numarul de cont, care pot fi schimbate apoi; butonul 'submit' va trimite instanta schimbata inapoi, lasand formularul asa cum este in browser pentru a permite trimiterea altor schimbari sau a unui nou numar de cont.

Controlul Controlurilor

In HTML poti specifica ca unele controluri sunt disabled, sau read-only dar apoi nu poti schimba aceste proprietati decat cu scripting.

XForms ofera o metoda usoara de a controla aceste proprietati, dar are si alte proprietati pe care le poti specifica:

In XForms valoarea colectata are proprietatea, si nu controlul, dar proprietatea se aplica tuturor controlurilor legate de valoare.

Aceste proprietati folosesc un element <bind> in elementul <model>. Pentru a folosi bind, trebuie sa ai un element <instance> explicit.

Controluri dezactivate

Pentru a dezactiva un control folosim proprietatea relevant. Spre exemplu, pentru a exprima ca un numar de carte de credit trebuie completat numai daca persoana plateste cu cartea de credit, poti scrie:

<model>
   <instance><data xmlns="">
      <amount/><method/><cc/><expires/>
   </data></instance>
   <bind nodeset="cc" relevant="../method='credit'"/>
   <bind nodeset="expires" relevant="../method='credit'"/>
</model>

Aceasta exprima ca campurile cc si expires sunt relevante numai cand method are valoarea credit, si deci va fi dezactivat pentru alte valori ale method. Trebuie sa precizezi "../method" si nu doar method, pentru ca intr-un bind te referi la lucrul specificat in nodeset (care si el poate fi un element structurat). Este ca si cum ai fi executat o comanda 'change directory' la acel element. Daca ai fi scris doar "method", te-ai fi referit la un element-copil al cc sau expires. Poti folosi si o adresa absoluta, ca /data/method, care in acest caz are acelasi efect ca ../method.

Un browser e liber sa decida cum sunt prezentate controlurile dezactivate (si poate lua aceasta informatie dintr-un stylesheet creat de tine), dar in mod normal vor fi prezentate in gri.

Controlurile ar putea fi scrise asa (observa ca nu exista nici o indicatie ca sunt dezactivate: aceasta proprietate este mostenita de la valoarea la care le refera):

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

Daca am folosi o instanta structurata, am putea simplifica codul:

<model>
   <instance><data xmlns="">
      <amount/><method/>
      <cc>
        <number/><expires/>
      </cc>
   </data></instance>
   <bind nodeset="cc" relevant="../method='credit'"/>
</model>

si apoi controlurile se leaga la copiii elementelor 'cc':

<input ref="cc/number"><label>Card number:</label></input>
<input ref="cc/expires"><label>Expiry date:</label></input>

desi gruparea poate fi folosita pentru a reseta contextul ref-urilor:

<group ref="cc">
   <input ref="number"><label>Card number:</label></input>
   <input ref="expires"><label>Expiry date:</label></input>
</group>

Controluri readonly

Asemanatoare cu relevant, poti specifica o conditie pentru care o valoare este read-only. Spre exemplu:

<model>
   <instance><data xmlns="">
      <variant>basic</variant><color>black</color>
   </data></instance>
   <bind nodeset="color" readonly="../variant='basic'"/>
</model>

Acest exemplu spune ca valoarea default a color este black, si ca nu poate fi schimbata daca variant are valoarea basic.

Controluri obligatorii*

O noua proprietate folositoare a XForms ne permite sa stabilim ce valori trebuie completate inainte de trimiterea formularului. Cel mai simplu caz este cand o valoare este intotdeauna obligatorie, ca in exemplul urmator:

<model>
   <instance><data xmlns=""><q/></data></instance>
   <bind nodeset="q" required="true()"/>
   <submission .../>
</model>

dar la fel ca pentru atributele readonly si relevant, poti folosi orice expresie XPath pentru a face o valoare obligatorie numai in anumite cazuri:

<bind nodeset="state" required="../country='USA'"/>

care spune ca valoarea pentru state este obligatorie doar cand valoarea country este "USA".

Depinde de browser cum arata ca o valoare este obligatorie, dar iti poate si permite si sa stabilesti tu acest lucru in stylesheet.

Proprietatea constraint*

Aceasta proprietate iti permite sa asociezi constrangeri unei valori. Spre exemplu:

<bind nodeset="year" constraint=". &gt; 1970"/>

constrange valoarea la un an mai mare de 1970. XPath foloseste "." pentru a specifica "aceasta valoare". (">" trebuie scris ca &gt; datorita regulilor XML, dar probabil te-ai obisnuit deja cu asta).

Proprietatea calculate*

Poti indica ca o valoare din instanta este calculata din alte valori. Spre exemplu:

<bind ref="volume" calculate="../height * ../width * ../depth"/>

Cand o valoare este calculata asa, devine automat readonly.

Exista mai multe functii pe care le poti folosi, printre care functii aritmetice, care manipuleaza string-uri si date, si conditionale cu 'if'.

Tipuri*

Alt lucru folositor este ca poti stabili un tip pentru o valoare. Browserul va verifica daca valorile introduse sunt de tipul cerut.

Spre exemplu, daca in exemplul cu cautarea nu sunt cautate decat numere (spre exemplu cautarea intr-o baza de date de bug-uri), trebuie sa adaugam:

<bind nodeset="q" type="xsd:integer"/>

Aceasta va asigura ca valoarea trimisa e un numar intreg.

(Va fi nevoie sa adaugi xmlns:xsd="http://www.w3.org/2001/XMLSchema" la radacina elementului.)

Daca vrei sa colectezi URL-ul paginii cuiva, atunci trebuie sa scrii:

<bind nodeset="homepage" type="xsd:anyURI"/>

Vei observa ca unii user agents fac lucruri speciale cand stiu tipul unei valori. Spre exemplu, cand stiu ca valoarea este o data, creeaza un meniu din care poti sa alegi o data (in loc sa trebuiasca sa scrii caracterele manual).

Exista mai multe tipuri de valori pe care le poti alege:

Combinarea proprietatilor

Daca ai mai multe bind-uri pentru aceeasi valoare, le poti combina:

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

Mai mult de un formular pe pagina

Daca ai mai multe formulare, e nevoie de cate un model pentru fiecare, dar acum va fi nevoie sa asociezi controlurile cu un anumit formular. Poti face acest lucru cu un atribut id pentru fiecare model, si un atribut model pentru fiecare 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 in loc de Ref

Daca exista un bind in model, te poti referi la el din control in loc de instanta valorii. Aceasta iti permite sa schimbi detaliile structurarii instantei fara a fi nevoit sa schimbi controlurile. De asemenea, inseamna ca nu trebuie sa specifici despre ce model este vorba:

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

(Se observa ca atributul bind se refera la id-ul elementului bind; nu este o expresie XPath)

Aspecte care nu au fost discutate aici

Cum am mentionat in introducere, acesta nu este un tutorial complet. Urmatoarele sunt cele mai importante aspecte pe care nu le-am discutat aici:

Evenimente si actiuni: cum sa lucrezi cu evenimentele si actiunile predefinite.

Scheme: cum sa iti definesti tipurile tale.

p3ptype: identificarea valorilor private.

Switch: completarea formularelor in etape.

Repeat: comportament de tip cos de cumparaturi, itemuri ce pot fi adaugate si sterse.