Sunteți pe pagina 1din 28

Community

Trog
Copyright notice:
This article is copyright Melonfire, 2014. All rights reserved.
All source code, brand names, trademarks and other content contained herein is proprietary to
Melonfire, 2014. All rights reserved.
ource code !ithin this article is provided !ith "# $A%%A"T& $'AT#()(%. *t is meant for
illustrative purposes only, and is "#T recommended for use in production environments.
+opyright infringement is a violation of la!.
,rinted from http-..!!!.melonfire.com.community.columns.trog.article.php/id0224
XForms Basics (part 1)
Use XForms to manage the display, input and processing of form data on the We!
X "its The #pot
A year or t!o ago, 1M2 !as heard about more often than it !as seen, a technology that !as
sufficiently arcane enough to keep all but the most hardened geeks at bay. "o more is this the case3
today, 1M2 is most definitely in the mainstream, and proving its mettle by making all kinds of ne!
and uni4ue applications possible 5!itness the success of Ama6on.com7s A$ service, or the 8oogle
A,*s, both based on 1M2 technology9.
1M2 isn7t resting on its laurels, though. As the technology is becoming more and more popular, 1M2
development groups operating under the aegis of the $orld $ide $eb +onsortium are rapidly
inventing ne! and interesting !ays to use it. #ne of the more interesting ideas is 1:orms, !hich
uses 1M2 to manage the display, input and processing of user;inputted data on the $eb.
*f you7re at all serious about using 1M2, you7re going to need to understand 1:orms. And over the
course of this tutorial, *7m going to assist you in this endeavour by e<plaining the fundamentals of
the 1:orms data model, together !ith some e<amples of ho! it can be used.
=efore !e get going, though, a fe! disclaimers-
:irst, * don7t claim to be an e<pert on 1:orms. Much of the material in this tutorial is based on my
o!n research !ith the 1:orms specifications and varied 1:orms implementations, or gleaned from
late;night email conversations over beer and stale pi66a. *n other !ords ; caveat emptor>
econd, as ne! 1M2 standards are proposed and disposed, the material here may become invalid3
you should al!ays refer to the most current standard or recommendation for up;to;date
information. This tutorial is based on the $?+7s 1:orms 1.0 recommendation dated 14 #ctober
200?, at http-..!!!.!?.org.T%.200?.%(+;<forms;200?1014.
"o! that * have that off my chest ; let7s get started>
$ut With The $ld!!!
=efore getting into the details of ho! 1:orms !orks, it7s important to understand the conte<t in
!hich it !as developed, and the need and rationale behind it.
&ou kno! that 'TM2 already allo!s user interaction !ith a $eb application, through the use of
forms and associated form controls like te<t entry fields, checkbo<es and radio buttons. 'o!ever,
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=224
1 of 9 4/22/2014 8:14 AM
although 'TM2 forms are simple to understand and easy to use, they do have a couple of
dra!backs-
1. 'TM2 forms can usually be vie!ed 5and used9 only in a $eb bro!ser ; they don7t render too !ell
on handhelds, cellphones or other devices.
2. ,rocessing form input in the $eb !orld usually re4uires the services of a programmer, !ho must
code the business logic need for form data validation, input parsing and further data manipulation
and processing.
?. @nless you put in a great deal of thought at the design stage 5and sometimes not even then9,
'TM2 forms cannot be easily reused across different applications, or even !ithin an application.
These dra!backs might seem trivial in the conte<t of today7s *nternet ; it ain7t broke, you7re
probably thinking, so !hy fi< it/ ; but they assume serious proportions in the conte<t of an 1M2
!orld, !hich is built around data and the relationships inherent in it.
!!!%n With The &e'
1:orms !as designed to address these dra!backs, and also breathe fresh life into traditional
approaches to handling user input in a client;server paradigm.
*f you take a look at the re4uirements document for 1:orms ; it7s available online at
http-..!!!.!?.org.T%.<html;forms;re4 ; you7ll see that 1:orms !as designed to enable the
Aseparation of the data being collected from the markup of the controls collecting the individual
valuesA. %ight at the outset, then, the 1:orms specification makes a clear distinction bet!een the
form model 5!hat the form does9 and its controls 5!hat it looks like9.
A simple e<ample of this might be a form !hich asks for your gender ; in a $eb bro!ser, you7d be
presented !ith radio buttons or a drop;do!n list, !hile on a cellphone, you7d be asked to enter a
particular number corresponding to the choices. This distinction bet!een form 5no pun intended9
and function makes it possible to use a single form model on multiple platforms and devices, by
defining !hat the form is supposed to do once, and then further defining the user interface for each
device or platform to be supported separately.
1:orms also come !ith built;in data typing capabilities and event handlers, making it possible to
validate user input !ithout having to resort to comple< scripting or server;side business logic.
1:orms can even be integrated !ith the validation rules laid do!n in 1M2 chemas, to further
centrali6e application logic and reduce the impact of changes in business rules.
Another good thing about 1:orms, especially as !e move to a more 1M2;centric !orld, is its native
support for the 1M2 standard. Bata entered into an 1:orm is usually submitted to the receiving
application in 1M2 format. This simplifies integration !ith third;party tools 5!hich are gradually
becoming 1M2;a!are9 and also reduces the need for comple< data processing and manipulation
routines, as the submitted data can easily be parsed using standard A1 or B#M interfaces.
There7s only one problem ; !hile the theory is certainly e<citing, practical implementation still
leaves a lot to be desired. The $?+7s 1:orms site at http-..!!!.!?.org.Mark@p.:orms. lists a
number of different 1:orms implementations, but the technology has yet to make an appearance in
any popular bro!ser3 this makes it harder to test and research.
#f the different implementations available, the e<amples in this tutorial !ere tested !ith
:orms,layer 5http-..!!!.formsplayer.com.9, though you !ill also get good results !ith 1;miles, a
Cava bro!ser 5http-..!!!.<;smiles.org.9 and "ovell7s 1:orms 5http-..!!!.novell.com.<forms9.
(<pect to spend some time !ith the documentation for each of these implementations to get your
1:orms development environment up and running 5tip- * found :orms,layer to be the simplest to
install, as it integrates directly !ith *nternet (<plorer D.09
What(s %n ) &ame*
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=224
2 of 9 4/22/2014 8:14 AM
2et7s start !ith a simple e<ample that demonstrates the functionality of 1:orms.
<html xmlns="http://www.w3.org/1999/xhtml"; xmlns:xforms="http://www.w3.org
/2002/xforms/cr">;
<head>
<!-- define the form model -->
<xforms:model id="enter">
<xforms:instance>
<user>
<name />
</user>
</xforms:instance>
</xforms:model>
<basefont face="Arial">
</head>
<body>
<font size="+1">What's In A Name?</font><br /><br />
<!-- define the form interface -->
<xforms:input id="txtname" model="enter" ref="/user/name">
<xforms:label>Name</xforms:label>
<xforms:hint>Enter your name, then press TAB</xforms:hint>
</xforms:input>
<br />
<!-- do something with the input -->
Welcome to XForms, <xforms:output model="enter" ref="/user/name" />
</body>
</html>
2et7s look at this line by line.
The first basic rule !hen dealing !ith 1:orms is that they cannot e<ist as independent entities3
instead, they7re designed to be integrated !ith 1'TM2 5or other markup9 documents. That7s !hy the
1:orm above is enclosed !ithin a regular 1'TM2 document, and !hy the 1'TM2 namespace has
been referenced at the top.
<html xmlns="http://www.w3.org/1999/xhtml"; xmlns:xforms="http://www.w3.org
/2002/xforms/cr">;
...
</html>
"ote that in addition to the 1'TM2 namespace, !hen dealing !ith 1:orms, you7ll also need to
specify the 1:orms namespace, !hich is currently Ahttp-..!!!.!?.org.2002.<forms.crA3.
<!-- define the form model -->
<xforms:model id="enter">
...
</xforms:model>
The second basic rule !hen !orking !ith 1:orms is this- every 1:orm consists of t!o primary
components, a form model 5!hich specifies functionality9 and one or more form controls 5!hich
handles presentation9.
The form model, indicated by the E<forms-modelF element, defines !hat the form does. This model
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=224
3 of 9 4/22/2014 8:14 AM
defines the data to be captured.modified by the form as !ell as the logical components that govern
ho! the form behaves on user interaction 5including !here the form should be submitted and ho!
to handle the various form events9. The model also includes information on the bindings bet!een
the form controls and the instance data, and can optionally link to e<ternal 1M2 chemas for
validation purposes.
The E<forms-modelF element is usually accompanied !ith an AidA attribute, !hich contains a name
for the model3 this name is used by the form controls in order to link the interface section of the
form to the correct form model. #bviously, this also means that you can have multiple models !ith
a single 1'TM2 file, and link to each one by its name. Additionally, since the form model only
defines ho! the form !orks and has nothing to do !ith its presentation, it can easily be reused,
either !ithin the same application or in other applications or platforms.
Typically, the E<forms-modelF element appears !ithin the EheadF of the document, and encloses
an E<forms-instanceF element.
<!-- define the form model -->
<xforms:model id="enter">
<xforms:instance>
<user>
<name />
</user>
</xforms:instance>
</xforms:model>
The E<forms-instanceF element defines the Ainstance dataA for the form. This instance data is an
1M2 tree representation of the values associated !ith the form, and it can be defined inline 5as
above9 or imported from an e<ternal 1M2 file. *n this case, the 1M2 structure is pretty simple ; a
single root element called EuserF encompassing one child element called EnameF.
"ormally, the E<forms-modelF element !ould also contain information on !here the form is to be
submitted via the E<forms-submissionF element, data bindings via the E<forms-bindF element and
event handlers via the E<forms-actionF element ; *7ll be discussing those shortly, so don7t !orry too
much about them for the moment.
#nce the form model has been defined, it7s time to define the other half of the pu66le ; the form
controls, or ho! the form looks. 1:orms provides a bunch of elements to accomplish this ; by and
large, they map neatly into the 'TM2 form controls you7re already familiar !ith, and appear !ithin
the EbodyF of the document.
<!-- define the form interface -->
<xforms:input id="txtname" model="enter" ref="/user/name">
<xforms:label>Name</xforms:label>
<xforms:hint>Enter your name, then press TAB</xforms:hint>
</xforms:input>
The first 5and simplest9 of these controls is the E<forms-inputF element, !hich represents a te<t
entry field. "ote my use of the AmodelA attribute to tell the 1:orms processor !hich form model this
control belongs to, and the ArefA attribute to tell it !hich node in the instance data tree this
particular value maps to. 1,ath e<pressions are used in the latter ; in case you don7t kno! !hat
those are, take a look at http-..!!!.melonfire.com.community.columns.trog.article.php/id0G? and
they should make a little more sense to you.
<!-- do something with the input -->
Welcome to XForms, <xforms:output model="enter" ref="/user/name" />
Another useful 5though not often used9 form control is the E<forms-outputF element, !hich is used
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=224
4 of 9 4/22/2014 8:14 AM
to display the value of a particular node from the 1M2 instance data tree. "ote again my usage of
the AmodelA and ArefA attributes to link the control to the model and instance data tree defined in
the EheadF of the document.
*f you !ere to try vie!ing the 1:orm above in an 1:orms;capable bro!ser, you7d see something like
this-
,retty cool, huh/
Welcome To &o'here
The previous e<ample demonstrated t!o of the form controls available in 1:orms. 'o!ever, there
are lots more ; here7s a brief list-
<xforms:input> a single-line text entry field
<xforms:secret> a single-line text entry field which masks user input, good for
passwords
<xforms:select> a list field allowing multiple selection
<xforms:select1> a list field allowing selection of only a single item from the
list
<xforms:textarea> a multi-line text entry field
<xforms:upload> a file upload field
<xforms:range> a field which restricts entry to a range of values
<xforms:submit> a form submission field
<xforms:output> a field for displaying values from the instance data
*n addition, the 1:orms specification also defines the follo!ing elements, !hich may be attached to
the controls above-
<xforms:label> descriptive information for the corresponding control
<xforms:help> help information for the corresponding control
<xforms:hint> brief usage information for the corresponding control
'ere7s an e<ample demonstrating some of them in action-
<html xmlns="http://www.w3.org/1999/xhtml"; xmlns:xforms="http://www.w3.org
/2002/xforms/cr">;
<head>
<!-- form model -->
<xforms:model id="immigration">
<xforms:instance src="immigration.xml" />
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=224
5 of 9 4/22/2014 8:14 AM
</xforms:model>
<basefont face="Arial">
</head>
<body>
<!-- define interface controls -->
<table cellspacing="5" cellpadding="5" border="0">
<tr>
<td colspan="2" align="center"><font color="red" size="4">Welcome to
Immigration</font></td>
</tr>
<tr>
<td>
<xforms:input id="txtname" model="immigration" ref="/immigrant/name">
<xforms:label>Name</xforms:label>
<xforms:hint>Enter your name here</xforms:hint>
</xforms:input>
</td>
</tr>
<tr>
<td>
<xforms:input id="txtcitizenship" model="immigration" ref="/immigrant
/citizenship">
<xforms:label>Citizenship</xforms:label>
<xforms:hint>Enter your country of origin here</xforms:hint>
</xforms:input>
</td>
</tr>
<tr>
<td align="left">
<xforms:select1 model="immigration" ref="/immigrant/purpose" appearance="full">
<xforms:label>Purpose of visit</xforms:label>
<xforms:hint>Please state the purpose of your visit</xforms:hint>
<xforms:item>
<xforms:label>Business</xforms:label>
<xforms:value>B</xforms:value>
</xforms:item>
<xforms:item>
<xforms:label>Pleasure</xforms:label>
<xforms:value>P</xforms:value>
</xforms:item>
<xforms:item>
<xforms:label>Other</xforms:label>
<xforms:value>O</xforms:value>
</xforms:item>
</xforms:select1>
</td>
</tr>
<tr>
<td align="left">
<xforms:select model="immigration" ref="/immigrant/immunization"
appearance="full">
<xforms:label>Immunization</xforms:label>
<xforms:hint>Please select the diseases that you have been immunized
against</xforms:hint>
<xforms:item>
<xforms:label>Smallpox</xforms:label>
<xforms:value>100</xforms:value>
</xforms:item>
<xforms:item>
<xforms:label>Malaria</xforms:label>
<xforms:value>113</xforms:value>
</xforms:item>
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=224
6 of 9 4/22/2014 8:14 AM
<xforms:item>
<xforms:label>Yellow fever</xforms:label>
<xforms:value>56</xforms:value>
</xforms:item>
<xforms:item>
<xforms:label>Typhoid</xforms:label>
<xforms:value>174</xforms:value>
</xforms:item>
</xforms:select>
</tr>
<tr>
<td align="left">
<xforms:textarea model="immigration" ref="/immigrant/address">
<xforms:label>Address in home country</xforms:label>
</xforms:textarea>
</td>
</tr>
</table>
</body>
</html>
:irst up, the definition of the 1:orms model. @nlike the previous e<ample, *7ve defined the instance
data tree in a separate file and imported it via the AsrcA attribute.
<!-- form model -->
<xforms:model id="immigration">
<xforms:instance src="immigration.xml" />
</xforms:model>
<basefont face="Arial">
'ere7s !hat Aimmigration.<mlA looks like-
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- immigration.xml -->
<immigrant>
<name />
<citizenship />
<purpose />
<immunization />
<address />
</immigrant>
&ou7ve already seen ho! to use an E<forms-inputF element in previous e<amples, so * !on7t go into
the details again. Bo note, ho!ever, my usage of the E<forms-labelF and E<forms-hintF elements
!ithin it ; these come in handy to provide descriptive human;readable information about the
control.
<xforms:input id="txtname" model="immigration" ref="/immigrant/name">
<xforms:label>Name</xforms:label>
<xforms:hint>Enter your name here</xforms:hint>
</xforms:input>
The E<forms-select1F element allo!s the user to select one item from a series of options-
<xforms:select1 model="immigration" ref="/immigrant/purpose" appearance="full">
<xforms:label>Purpose of visit</xforms:label>
<xforms:hint>Please state the purpose of your visit</xforms:hint>
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=224
7 of 9 4/22/2014 8:14 AM
<xforms:item>
<xforms:label>Business</xforms:label>
<xforms:value>B</xforms:value>
</xforms:item>
<xforms:item>
<xforms:label>Pleasure</xforms:label>
<xforms:value>P</xforms:value>
</xforms:item>
<xforms:item>
<xforms:label>Other</xforms:label>
<xforms:value>O</xforms:value>
</xforms:item>
</xforms:select1>
$ithin the E<forms-select1F element, the list of available choices are defined via one or more
E<forms-itemF elements, each of !hich must have a label and value3 the former is displayed to the
user and the latter is passed to the server on submission.
A special AappearanceA attribute in the E<forms-select1F element can be used to control the display
of the element in the bro!ser 5AfullA for a list of all values, AminimalA for a minimum number of
values, and AcompactA for a scrollable list9.
imilar, though not identical to the above, is the E<forms-selectF element, !hich allo!s the user to
select more than one value from the options available.
<xforms:select model="immigration" ref="/immigrant/immunization"
appearance="full">
<xforms:label>Immunization</xforms:label>
<xforms:hint>Please select the diseases that you have been immunized
against</xforms:hint>
<xforms:item>
<xforms:label>Smallpox</xforms:label>
<xforms:value>100</xforms:value>
</xforms:item>
<xforms:item>
<xforms:label>Malaria</xforms:label>
<xforms:value>113</xforms:value>
</xforms:item>
<xforms:item>
<xforms:label>Yellow fever</xforms:label>
<xforms:value>56</xforms:value>
</xforms:item>
<xforms:item>
<xforms:label>Typhoid</xforms:label>
<xforms:value>174</xforms:value>
</xforms:item>
</xforms:select>
As before, the choices are defined via a series of E<forms-labelF and E<forms-valueF elements,
!hile the AappearanceA attribute can be used to control the appearance of the control 5AfullA for a
list of all values, AminimalA for a minimum number of values, and AcompactA for a scrollable list9.
:inally, the E<forms-te<tareaF element is used to display a multi;line te<t entry bo<, suitable for
use !ith large blocks of te<t.
<xforms:textarea model="immigration" ref="/immigrant/address">
<xforms:label>Address in home country</xforms:label>
</xforms:textarea>
And here7s !hat it all looks like-
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=224
8 of 9 4/22/2014 8:14 AM
"o!, all this is fine and dandy ; but ho! about submitting the form and actually doing something
!ith the user7s data/
$ell, that7s a !hole ne! kettle of fish, one !hich involves Humping through a complicated series of
hoops involving the E<sd-submissionF element. * don7t plan to discuss it no! ; instead, *7m going to
defer it to the second segment of this tutorial and instead encourage you to spend the interim
playing !ith the various form controls to understand ho! they !ork. (ach control comes !ith
specific properties that can be used to customi6e its behaviour ; so take a look at the specification,
get comfortable !ith them, try out a couple of implemetations, and come back ne<t !eek to take
the ne<t step in our 1:orms Hourney>
"ote- (<amples are illustrative only, and are not meant for a production environment. Melonfire
provides no !arranties or support for the source code described in this article. &MM)>
Copyright notice:
This article is copyright Melonfire, 2014. All rights reserved.
All source code, brand names, trademarks and other content contained herein and proprietary to
Melonfire, 2014. All rights reserved.
ource code !ithin this article is provided !ith "# $A%%A"T& $'AT#()(%. *t is meant for
illustrative purposes only, and is "#T recommended for use in production environments.
+opyright infringement is a violation of la!.
,rinted from http-..!!!.melonfire.com.community.columns.trog.article.php/id0224
Copyright 1998-2014 Melonfire. All rights reserved
Terms and Conditions | Feedback
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=224
9 of 9 4/22/2014 8:14 AM


Community

Trog
Copyright notice:
This article is copyright Melonfire, 2014. All rights reserved.
All source code, brand names, trademarks and other content contained herein is proprietary to
Melonfire, 2014. All rights reserved.
ource code !ithin this article is provided !ith "# $A%%A"T& $'AT#()(%. *t is meant for
illustrative purposes only, and is "#T recommended for use in production environments.
+opyright infringement is a violation of la!.
,rinted from http-..!!!.melonfire.com.community.columns.trog.article.php/id0221
XForms Basics (part 2)
Find out how to submit XForms data to a server-side script or save it to a local client ile!
"evving #p
*n the first part of this series, * gave you a 2uick introduction to the ne!ly3released 45orms 1.0
specification, by e6plaining the fundamental concepts of the 45orms model. * sho!ed you ho! to
define an 45orms model and form instance data, as !ell as the logical components that govern ho!
the form behaves on user interaction. * also took you on a !hirl!ind tour of the various input
controls available in 45orms 1.0 3 as you !ill have seen, these controls correspond closely !ith the
controls available in traditional 'TM7, and then some.
"o!, all this is fine and dandy 3 but ho! about submitting the form and actually doing something
!ith the user8s data/ $ell, that8s !here this article comes in. #ver the ne6t fe! pages, *8m going to
ans!er this ve6ing 2uestion, sho!ing you ho! to handle form submissions on both the server and
the client. 45orms offers the creative developer an immense amount of control over the process,
primarily by doing a!ay !ith the traditional name0value submission format in favour of standard
4M7 markup for user data.
* !on8t 9ust stop there, though. #nce you8ve understood ho! to store user data on the server !ith
45orms, *8ll sho! you ho! to control the 2uality of that data by having 45orms validate user input
at the time of submission. As you8ll see, 45orms8 built3in support for data validation means you don8t
need :avacript or server3side logic any more. *nstead, you can 2uality3control user input through
built3in 45orms constructs or 3 if you !ant to get really advanced 3 hook your 45orms up to an 4M7
chema to enforce more sophisticated validation and typing rules.
(6cited/ * hope so.
$elcome To %mmigration
*8ll begin !ith a simple 45orm, one that you8re already familiar !ith from the previous segment of
this tutorial-
<html xmlns="http://www.w3.org/1999/xhtml"; xmlns:xforms="http://www.w3.org
/2002/xforms/cr">;
<head>
<!-- form model -->
<xforms:model id="immigration">
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=226
1 of 12 4/22/2014 8:13 AM
<xforms:instance src="immigration.xml" />
<xforms:submission id="submit" action="/tmp/immigrant.xml" method="put" />
</xforms:model>
<basefont face="Arial">
</head>
<body>
<!-- define interface controls -->
<table cellspacing="5" cellpadding="5" border="0">
<tr>
<td colspan="2" align="center"><font color="red" size="4">Welcome to
Immigration</font></td>
</tr>
<tr>
<td>
<xforms:input id="txtname" model="immigration" ref="/immigrant/name">
<xforms:label>Name</xforms:label>
<xforms:hint>Enter your name here</xforms:hint>
</xforms:input>
</td>
</tr>
<tr>
<td>
<xforms:input id="txtcitizenship" model="immigration" ref="/immigrant
/citizenship">
<xforms:label>Citizenship</xforms:label>
<xforms:hint>Enter your country of origin here</xforms:hint>
</xforms:input>
</td>
</tr>
<tr>
<td align="left">
<xforms:select1 model="immigration" ref="/immigrant/purpose" appearance="full">
<xforms:label>Purpose of visit</xforms:label>
<xforms:hint>Please state the purpose of your visit</xforms:hint>
<xforms:item>
<xforms:label>Business</xforms:label>
<xforms:value>B</xforms:value>
</xforms:item>
<xforms:item>
<xforms:label>Pleasure</xforms:label>
<xforms:value>P</xforms:value>
</xforms:item>
<xforms:item>
<xforms:label>Other</xforms:label>
<xforms:value>O</xforms:value>
</xforms:item>
</xforms:select1>
</td>
</tr>
<tr>
<td align="left">
<xforms:select model="immigration" ref="/immigrant/immunization"
appearance="full">
<xforms:label>Immunization</xforms:label>
<xforms:hint>Please select the diseases that you have been immunized
against</xforms:hint>
<xforms:item>
<xforms:label>Smallpox</xforms:label>
<xforms:value>100</xforms:value>
</xforms:item>
<xforms:item>
<xforms:label>Malaria</xforms:label>
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=226
2 of 12 4/22/2014 8:13 AM
<xforms:value>113</xforms:value>
</xforms:item>
<xforms:item>
<xforms:label>Yellow fever</xforms:label>
<xforms:value>56</xforms:value>
</xforms:item>
<xforms:item>
<xforms:label>Typhoid</xforms:label>
<xforms:value>174</xforms:value>
</xforms:item>
</xforms:select>
</tr>
<tr>
<td align="left">
<xforms:textarea model="immigration" ref="/immigrant/address">
<xforms:label>Address in home country</xforms:label>
</xforms:textarea>
</td>
</tr>
</table>
<xforms:submit submission="submit">
<xforms:label>Save</xforms:label>
<xforms:hint>Save the information entered above to a local file</xforms:hint>
</xforms:submit>
</body>
</html>
7ooks familiar/ *t should 3 this is the same form * used to demonstrate the various input controls
earlier, !ith one important addition- the ability to actually do something !ith the data once it has
been entered by the user.
The 45orms specification defines an ;6forms-submission< element, that specifies ho! form
submission is to be handled. Typically, this element appears in the ;head< of the document, !ithin
an ;6forms-model< element, and contains information on the =%7 to !hich the form is to be
submitted, the method of submission, and the format and structure of the submitted 4M7. 'ere8s an
e6ample-
<xforms:submission id="submit" action="/tmp/immigrant.xml" method="put" />
This is similar to the data that appears in the standard 'TM7 ;form< tag. "ote the addition of an
>id> element 3 this is used to link the ;6forms-submission< element !ith the actual form submit
button 3 and the method used ?,=T, because in this first e6ample, *8ll be !riting the form data to a
local file, not a server storage engine@.
The ;6forms-submission< element is only part of the puAAle. The other half is the submit button
itself, represented by the ;6forms-submit< input control ?remember this from last time8s lesson/@.
'ere8s !hat it looks like-
<xforms:submit submission="submit">
<xforms:label>Save</xforms:label>
<xforms:hint>Save the information entered above to a local file</xforms:hint>
</xforms:submit>
,retty standard, this 3 like other input controls, it contains optional ;6forms-label< and
;6forms-hint< elements to give the user additional information on !hat it8s supposed to do. The
novel thing here, though, is the additional >submission> attribute, !hich associates this submit
button !ith the ;6forms-submission< element defined in the 45orms model. Because of this link,
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=226
3 of 12 4/22/2014 8:13 AM
the ;6forms-submit< element !ill trigger the >action> specified in the ;6forms-submission<
element !hen invoked.
"o!, let8s give it a !hirl to see it if !orks as advertised. (nter some data into the form and hit the
>ave> button. Then, navigate to the location specified in the >action> attribute and open up the
target file in a te6t editor. &ou should see the data you entered, formatted in 4M7 as per your form
model. 'ere8s an e6ample-
<!-- immigration.xml-->
<immigrant><name>Chewbacca</name><citizenship>Tatooine</citizenship>
<purpose>B</purpose><immunization>56 113 100</immunization><address>Planet
Tatooine</address></immigrant>
Behind the scenes, here8s !hat happens !hen the form is submitted-
1. An >6forms3submit> event is triggered ?more on events shortly@.
2. The instance data tree beginning at the root specified in the ;6forms-submission< element is
selected. *f no root is specified ?as in the e6ample above@, the entire instance data tree is selected.
C. The selected instance data is validated as per validation rules that may be specified in the 45orm.
*f an error occurs in validation, processing stops and an e6ception is generated.
4. *f the data passes all the validation tests, it is serialiAed and submitted using the information
provided in the >method> and >action> attributes of the ;6forms-submission< element.
&ata 'verload
The previous e6ample sho!ed you ho! to store the information provided by the user in a local file
on the client. Though this seems interesting at first glance, it isn8t very useful in real life ?!hen !as
the last time you !anted to do this/@ Most often, you !ould !ant the data to be sent to the server,
safe and secure in a database or other storage engine. 'o! does 45orms stand up to this challenge/
,retty !ell, actually 3 and it even adds some interesting attributes to control the data being
submitted.
*n order to demonstrate, *8ll revise the previous e6ample to submit the user data to a server3side
script, !hich takes care of adding it to a MyD7 database. *n this e6ample, the database is called
>db1>, the table is called >immigrants>, and the D7 code to create the table looks like this-
CREATE TABLE `immigrants` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(30) NOT NULL default '',
`citizenship` varchar(50) NOT NULL default '',
`purpose` char(1) NOT NULL default '',
`immunization` varchar(50) NOT NULL default '',
`address` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`)
)
As you can see, this is pretty straightfor!ard stuff, !ith each field of the table mapping to a node in
the 4M7 file created in the previous e6ample.
"e6t up, altering the 45orm model to point to a server3side ,', script instead of a local file-
<!-- form model -->
<xforms:model id="immigration">
<xforms:instance src="immigration.xml" />
<xforms:submission id="submit" action="/scripts/register.php" method="post" />
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=226
4 of 12 4/22/2014 8:13 AM
</xforms:model>
"otice that no change is needed to the form input controls, or any other section of the 45orm 3 this
is an e6ample of the separation bet!een form and function that 45orms promises.
5inally, here8s the ,', script that takes the submitted form data and converts it into an *"(%T
2uery-
<?php
// initialize some variables;
$currentTag = "";
$values = array();
$allowedFields = array("name", "citizenship", "purpose", "immunization", "address");
// database parameters
$host = "localhost";
$usr = "john";
$pwd = "doe";
$db = "db1";
// handlers
function startElementHandler($parser, $name, $attributes)
{
global $currentTag;
$currentTag = $name;
}
function endElementHandler($parser, $name)
{
global $values, $currentTag;
global $connection, $table;

if(strtolower($name) == "immigrant")
{
// generate SQL
$query = "INSERT INTO immigrants";
$query .= "(name, citizenship, purpose, immunization, address)";
$query .= "VALUES(\"" . join("\",\"",$values) . "\");";

// uncomment for debug purposes
// print $query;

// execute query
$result = mysql_query($query) or die("Error in query: $query. " .
mysql_error());

// reset variables
$values = array();
$currentTag = "";
}
}
function characterDataHandler($parser, $data)
{
global $currentTag, $values, $allowedFields;

$currentTag = strtolower($currentTag);

if(in_array($currentTag, $allowedFields) && trim($data) != "")
{
$values[$currentTag] = mysql_escape_string($data);
}

}
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=226
5 of 12 4/22/2014 8:13 AM
$parser = xml_parser_create();
// get the XML data
$data = $HTTP_RAW_POST_DATA;
// set SAX parser options
xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);
// set element handlers
xml_set_element_handler($parser, "startElementHandler", "endElementHandler");
xml_set_character_data_handler($parser, "characterDataHandler");
// connect to database
$conn = mysql_connect($host, $usr, $pwd) or die("Unable to connect to the database");
mysql_select_db($db) or die("Unable to select database");
// parse XML
if (!xml_parse($parser, $data ))
{
die(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
}
// clean up
xml_parser_free($parser);
mysql_close();
?>
"o! try it out and see for yourself 3 enter some data into the form, submit it and then check the
database to see if your values !ere inserted correctly. 'ere8s !hat you might see-
mysql> SELECT * FROM immigrants;
+----+-----------+-------------+---------+--------------+-----------------+
| id | name | citizenship | purpose | immunization | address |
+----+-----------+-------------+---------+--------------+-----------------+
| 1 | Chewbacca | Tatooine | B | 56 113 | Planet Tatooine |
+----+-----------+-------------+---------+--------------+-----------------+
1 row in set (0.00 sec)
'o! did this happen/ $ell, unlike traditional forms, !hich submit data using name3value pairs,
45orms submits data as a !ell3formed 4M7 document. This document can then be parsed using
either a E#M or A4 parser, or even transferred directly to any other application that understands
4M7.
,', comes !ith a built3in A4 parser, !hich is !hat *8ve used in the e6ample above to parse the
4M7 document. A4, or the imple A,* for 4M7, is one of the most common methods of parsing an
4M7 document. (ssentially, a A4 parser reads the 4M7 document se2uentially, triggering specific
user3defined functions !hen it finds an opening tag, character data, closing tag, +EATA block and so
on. *n the e6ample above, these user3defined functions are called start(lement'andler?@,
end(lement'andler?@ and characterEata'andler?@.
$parser = xml_parser_create();
xml_set_element_handler($parser, "startElementHandler", "endElementHandler");
xml_set_character_data_handler($parser, "characterDataHandler");
#f these, the ma9or !ork in the script above is done by the characterEata'andler?@ function 3 this
reads the various values entered by the user from the 4M7 document tree and builds the D7 2uery
after using the mys2lFescapeFstring?@ function to make the values ready for insertion in the
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=226
6 of 12 4/22/2014 8:13 AM
database.
function characterDataHandler($parser, $data)
{
global $currentTag, $values, $allowedFields;

$currentTag = strtolower($currentTag);

if(in_array($currentTag, $allowedFields) && trim($data) != "")
{
$values[$currentTag] = mysql_escape_string($data);
}

}
The script above !on8t make much sense to you unless you8ve played a little !ith A4. *n case you
haven8t, drop by http-..!!!.melonfire.com.community.columns.trog.article.php/id0G1 and find out
!hat you missed, then come back here and revie! the script again. &ou can also read more about
A4 at http-..!!!.sa6pro9ect.org. and http-..!!!.6mlphp.com.
&ou can also parse the 4M7 document submitted by the 45orm using the E#M 3 * leave that to you
as an e6ercise.
( Custom )ob
*n addition to the attributes you8ve already seen, the ;6forms-submission< element also comes !ith
a bunch of others, !hich can assist in customiAing the manner in !hich the form data is submitted.
'ere8s a brief list-
>ref> 3 specifies the node to use as root !hen submitting instance data, defaults to .
>version> 3 specifies 4M7 version to use !hen submitting form data
>indent> 3 toggles indenting of 4M7 data in form submission
>encoding> 3 specifies 4M7 encoding to use !hen submitting form data
>omit36ml3declaration> 3 toggles 4M7 declaration !hen submitting form data
>standalone > 3 toggles standalone declaration !hen submitting form data
>replace> 3 specifies !hat to do !ith the response to the submission
+onsider the follo!ing e6ample, !hich demonstrates some of these in action-
<html xmlns="http://www.w3.org/1999/xhtml"; xmlns:xforms="http://www.w3.org
/2002/xforms/cr">;
<head>
<!-- form model -->
<xforms:model id="information">
<xforms:instance>
<user>
<name />
<email />
<age />
</user>
</xforms:instance>
<xforms:submission id="submit" ref="/user/name" action="/tmp/user.xml"
method="put" indent="yes" omit-xml-declaration="no" />
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=226
7 of 12 4/22/2014 8:13 AM
</xforms:model>
<basefont face="Arial">
</head>
<body>
<!-- define interface controls -->
<table cellspacing="5" cellpadding="5" border="0">
<tr>
<td>
<xforms:input id="txtname" model="information" ref="/user/name">
<xforms:label>Name</xforms:label>
<xforms:hint>Enter your name here</xforms:hint>
</xforms:input>
</td>
</tr>
<tr>
<td>
<xforms:input id="txtemail" model="information" ref="/user/email">
<xforms:label>Email address</xforms:label>
<xforms:hint>Enter your email address here</xforms:hint>
</xforms:input>
</td>
<td>
<xforms:input id="txtage" model="information" ref="/user/age">
<xforms:label>Age</xforms:label>
<xforms:hint>Enter your age here</xforms:hint>
</xforms:input>
</td>
</table>
<xforms:submit submission="submit">
<xforms:label>Save</xforms:label>
<xforms:hint>Save the information entered above to a local file</xforms:hint>
</xforms:submit>
</body>
</html>
*n this case, *8ve e6plicitly told the 45orms processor to include the 4M7 declaration in the final form
submission, but to only include that part of the instance data tree beginning !ith the element
;name<. 'ere8s the output-
<?xml version="1.0" encoding="ISO-8859-1"?><name>Harish</name>
*t8s important to note, also, that 45orms supports submitting data in more than 9ust ,=T and ,#T
methods, and that if you really need to, you can even replicate the behaviour of traditional 'TM7
forms by submitting your data in the standard name0value format. The method atribute of the
;6forms-submission< element can take any of the values >post>, >get>, >put>, >multipart3post> and
>form3data3post> 3 take a look at the specification to see !hat each one of these does.
*ot +y Type
peak to any $eb developer, and they8re sure to complain about the need to !rite comple6
:avacript code to carry out elementary data validation on form input. $ith 45orms, they are no
longer hostage to :avacript 3 45orms is closely integrated !ith 4M7 chema, and can use 4M7
chema datatypes to perform both simple and comple6 form validation. Take a look at the ne6t
e6ample, !hich illustrates-
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=226
8 of 12 4/22/2014 8:13 AM
<html xmlns="http://www.w3.org/1999/xhtml"; xmlns:xforms="http://www.w3.org
/2002/xforms/cr">;
<head>
<!-- define the form model -->
<xforms:model id="enter">
<xforms:instance>
<user xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xmlns:xsd="http://www.w3.org/2001/XMLSchema">;
<name xsi:type="xsd:string" />
<age xsi:type="xsd:integer" />
<dob xsi:type="xsd:date" />
<height xsi:type="xsd:float" />
<weight xsi:type="xsd:decimal" />
<immunizaton xsi:type="xsd:boolean" />
</user>
</xforms:instance>
</xforms:model>
<basefont face="Arial">
</head>
<body>
<font size="+1">So you wanna join The Army?</font><br /><br />
<!-- form controls -->
<xforms:input id="txtname" model="enter" ref="/user/name">
<xforms:label>Name</xforms:label>
<xforms:hint>Enter your name</xforms:hint>
<xforms:alert>Haven't you got a name, mate?</xforms:alert>
</xforms:input>
<xforms:input id="txtage" model="enter" ref="/user/age">
<xforms:label>Age</xforms:label>
<xforms:hint>Enter your age in years</xforms:hint>
<xforms:alert>Can't you read? Tell me your age!</xforms:alert>
</xforms:input>
<xforms:input id="txtdob" model="enter" ref="/user/dob">
<xforms:label>Date of birth</xforms:label>
<xforms:hint>Enter your date of birth</xforms:hint>
<xforms:alert>You can forget your birthday gift, brother!</xforms:alert>
</xforms:input>
<xforms:input id="txtheight" model="enter" ref="/user/height">
<xforms:label>Height</xforms:label>
<xforms:hint>Enter your height in feet and inches</xforms:hint>
<xforms:alert>Don't have a measuring tape, do you?</xforms:alert>
</xforms:input>
<xforms:input id="txtweight " model="enter" ref="/user/weight">
<xforms:label>Weight</xforms:label>
<xforms:hint>Enter your weight in pounds</xforms:hint>
<xforms:alert>Come on fatso, 'fess up!</xforms:alert>
</xforms:input>
<xforms:input id="boolimmunization" model="enter" ref="/user/immunization">
<xforms:label>Have you been immunized against major diseases?</xforms:label>
<xforms:hint>Enter your immunization status</xforms:hint>
<xforms:alert>Don't lie, we have syringes with large needles!</xforms:alert>
</xforms:input>
</body>
</html>
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=226
9 of 12 4/22/2014 8:13 AM
At first glance, the above e6ample looks much like the e6amples !e have discussed so far. But a
closer inspection of the model reveals a subtle difference...
<xforms:model id="enter">
<xforms:instance>
<user xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xmlns:xsd="http://www.w3.org/2001/XMLSchema">;
<name xsi:type="xsd:string" />
<age xsi:type="xsd:integer" />
<dob xsi:type="xsd:date" />
<height xsi:type="xsd:float" />
<weight xsi:type="xsd:decimal" />
<immunizaton xsi:type="xsd:boolean" />
</user>
</xforms:instance>
</xforms:model>
5or starters, * have t!o ne! namespaces, one for 4M7 chema and the second for the 4M7 chema
instance. Both these are re2uired for the ne! features that *8m going to introduce in this e6ample.
"e6t, take a closer look at the definition of the 45orms model. &ou8ll see that each element contains
a ne! >6si-type> attribute. This attribute, !hich references datatypes from the 4M7 chema
namespace ?hence the >6sd-> namespace identifier@ makes it possible to easily use those datatypes
!ithin 45orms. #nce datatypes have been defined in this manner, and links to the form controls
have been set up via >ref> attributes, the 45orms processor !ill generate an error if the data
entered into a field does not match the datatype associated !ith it in the form model.
'o! is this error handled/ imple 3 !ith the ne! ;6forms-alert< element, !hich can be used to
display control3specific errors or alerts. Take a look at this snippet, !hich illustrates-
<xforms:input id="txtage" model="enter" ref="/user/age">
<xforms:label>Age</xforms:label>
<xforms:hint>Enter your age in years</xforms:hint>
<xforms:alert>Can't you read? Tell me your age!</xforms:alert>
</xforms:input>
'ere, if the user does not enter data consistent !ith the definition for the control, the message
specified in the ;6forms-alert< field !ill be displayed.
The *umber ,ame
*f you have special needs, you can even create your o!n datatypes using 4M7 chema, instead of
restricting yourself to the pre3defined datatypes. +onsider the follo!ing e6ample, !hich illustrates-
<html xmlns="http://www.w3.org/1999/xhtml"; xmlns:xforms="http://www.w3.org
/2002/xforms/cr">;
<head>
<!-- form model -->
<xforms:model id="information" schema="users.xsd">
<xforms:instance>
<user>
<name xsi:type="xsd:string" />
<email xsi:type="xsd:string" />
<age xsi:type="adultsOnly" />
</user>
</xforms:instance>
<xforms:submission id="submit" ref="/user/name" action="/scripts/save.cgi"
method="post" indent="yes" omit-xml-declaration="no" />
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=226
10 of 12 4/22/2014 8:13 AM
</xforms:model>
<basefont face="Arial">
</head>
<body>
<!-- define interface controls -->
<table cellspacing="5" cellpadding="5" border="0">
<tr>
<td>
<xforms:input id="txtname" model="information" ref="/user/name">
<xforms:label>Name</xforms:label>
<xforms:hint>Enter your name here</xforms:hint>
</xforms:input>
</td>
</tr>
<tr>
<td>
<xforms:input id="txtemail" model="information" ref="/user/email">
<xforms:label>Email address</xforms:label>
<xforms:hint>Enter your email address here</xforms:hint>
</xforms:input>
</td>
<td>
<xforms:input id="intage" model="information" ref="/user/age">
<xforms:label>Age</xforms:label>
<xforms:hint>Enter your age here</xforms:hint>
</xforms:input>
</td>
</table>
<xforms:submit submission="submit">
<xforms:label>Save</xforms:label>
</xforms:submit>
</body>
</html>
&ou8ll notice that *8ve defined a custom type in the form model 3 something called >adults#nly>. The
definition for this type is stored in an 4M7 chema, and it only allo!s you to enter values e2ual to
or over 1H into the corresponding field. Take a look-
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">;
<xsd:simpleType name="adultsOnly">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="18" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
And that8s about it for today. *n this article, * began by discussing the 45orms submission process,
and e6plained ho! to use the ;6forms-submission< element to save form input to a local file !ith
the ,=T method, and ho! to pass it to a server3side script for storage in a MyD7 database. * also
sho!ed you a real3!orld e6ample of the latter, by using the ,', A4 parser to parse the instance
document generated by an 45orms submission and convert it into an D7 2uery string.
"e6t, * taught you ho! 45orms significantly simplifies the task of input validation, by integrating
!ith 4M7 chema datatypes and allo!ing you to validate user input against those datatypes. 'ere
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=226
11 of 12 4/22/2014 8:13 AM
too, * sho!ed you a couple of different e6amples, one using 4M7 chema built3in datatypes and the
other using my o!n custom types.
"e6t !eek, *8ll be delving a little deeper into the 45orms specification, e6plaining binding, form
events, and built3in functions. =ntil then...stay healthyI
"ote- (6amples are illustrative only, and are not meant for a production environment. Melonfire
provides no !arranties or support for the source code described in this article. &MM)I
Copyright notice:
This article is copyright Melonfire, 2014. All rights reserved.
All source code, brand names, trademarks and other content contained herein and proprietary to
Melonfire, 2014. All rights reserved.
ource code !ithin this article is provided !ith "# $A%%A"T& $'AT#()(%. *t is meant for
illustrative purposes only, and is "#T recommended for use in production environments.
+opyright infringement is a violation of la!.
,rinted from http-..!!!.melonfire.com.community.columns.trog.article.php/id0221
Copyright 1998-2014 Melonfire. All rights reserved
Terms and Conditions | Feedback
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=226
12 of 12 4/22/2014 8:13 AM


Community

Trog
Copyright notice:
This article is copyright Melonfire, 2014. All rights reserved.
All source code, brand names, trademarks and other content contained herein is proprietary to
Melonfire, 2014. All rights reserved.
ource code !ithin this article is provided !ith "# $A%%A"T& $'AT#()(%. *t is meant for
illustrative purposes only, and is "#T recommended for use in production environments.
+opyright infringement is a violation of la!.
,rinted from http-..!!!.melonfire.com.community.columns.trog.article.php/id0221
XForms Basics (part 3)
Perform calculations on form input values and get a crash course in the XForms event
model.
ndgame
*n the previous article, * sho!ed you ho! to manage user input in the 23orms model. * discussed
the process of submitting an 23orm and 4 more importantly 4 validating user input prior to
submission using built4in 2M5 chema support.
*n this concluding segment, *6ll introduce you to some of 23orms6 more arcane features. 3irst, the
concept of binding, !hich allo!s developers to implement a number of useful features 7uickly 4
calculating values instantly, enforcing basic validation rules, taking decisions on the fly or rendering
a particular node non4!ritable.
"e8t, *6ll briefly sho! you ho! you can use 2,ath functions !ithin an 23orms model definition, and
illustrate ho! functions like sum9: and avg9: allo! you to perform comple8 calculations in a simple
and smooth manner. *6ll also take a 7uick look at the 23orms event processing model, e8plaining the
important phases and sho!ing you a basic e8ample of ho! triggers and actions !ork.
5et6s get started, shall !e/
!perating "ith #treme Caution
&ou6ve already seen ho! various 2M5 technologies integrate seamlessly !ith each other !hen it
comes to 23orms. *n fact, in the last part of this tutorial, * sho!ed you ho! to re4use an 2M5
chema datatype definition in an 23orms model, and ho! to use 2,ath e8pressions to reference and
bind instance data !ith the 23orms user interface. ;ut !hy stop there/ &ou can also use logical,
comparison and arithmetic operators and functions !ith 2,ath e8pressions, in order to perform
calculations using the instance data in an 23orms model.
*n order to do this, you need to first understand the <8forms-bind= element, !hich makes it
possible to bind instance data elements to specific properties and constraints. The <8forms-bind=
element comes !ith a number of additional attributes, !hich can be used to specify !hether a
particular element of the instance data is re7uired, read4only, constrained to specific values or
compliant !ith a specific type.
+onsider the follo!ing e8ample, !hich demonstrates-
<!-- form model -->
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=228
1 of 7 4/22/2014 8:14 AM
<xforms:model id="account">
<xforms:instance>
<account>
<name />
<number />
</account>
</xforms:instance>
<xforms:bind id="accountNumberRequired" nodeset="/account/number" required="true()"
/>
</xforms:model>
*n this case, the bind definition states that the account number is re7uired in order for the form to
be submitted. This is a very fundamental e8ample of input validation. $ith normal 'TM5 forms,
you6d need to !rite client4side and server4side code to manage this re7uirement> !ith 23orms, it
comes built4in?
*n case you !ere !ondering !here this bind definition gets used, the 23orms specification states
that user interface elements can then be linked to the definition, simply by adding a @bind@ attribute
to the interface control 9instead of the traditional @ref@ attribute:. 'ere6s an e8ample-
<!-- define the form interface -->
<xforms:input bind="accountNumberRequired">
<xforms:label>Account number</xforms:label>
</xforms:input>
$oney% $oney% $oney
#f course, the @re7uired@ attribute is Aust one e8ample of !hat 23orms calls @model item
properties@. Another one is the @relevant@ attribute, !hich specifies !hen a particular element of the
instance data is enabled or disabled. +onsider the follo!ing e8ample, !hich illustrates-
<!-- form model -->
<xforms:model id="tran">
<xforms:instance>
<transaction>
<type />
<amount />
<checkNumber />
</transaction>
</xforms:instance>
<xforms:bind nodeset="/transaction/checkNumber" relevant="/transaction/type='check'"
/>
</xforms:model>
;asically, this says that !hen performing a transaction 9in this case, a bank account transaction
!hich is either a deposit or a !ithdra!al: the check number is only relevant !hen the transaction
involves a check.
#f course, it6s up to the implementation to decide ho! to handle this particular property. ome
implementations might disable the field for data entry during cash transactions, others might hide
it, and still others might pop up a !arning.
&ou6ll notice, also, that the @relevant@ property contains an e7uality test. Model item properties can
contain comparison tests, so long as these conform to the rules laid do!n for 2,ath e8pressions.
'ere6s another e8ample, this one illustrating the use of a comparison test !ith the previously4
e8plained @re7uired@ property by re7uiring the entry of a ta8 identification number for transactions
greater than BC0,000-
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=228
2 of 7 4/22/2014 8:14 AM
<!-- form model -->
<xforms:model id="taxes">
<xforms:instance>
<transaction>
<name />
<amount />
<taxID />
</transaction>
</xforms:instance>
<xforms:bind id="taxIDRequired" nodeset="/transaction/taxID" required="/transaction
/amount &gt; 50000" />
</xforms:model>
&hop Till 'ou (rop
*t6s also possible to specify that a particular element of the instance data be read4only via the
@readonly@ property. +onsider the follo!ing e8ample-
<!-- form model -->
<xforms:model id="shop">
<xforms:instance>
<item>
<code />
<price />
<discount>2.00</discount>
<quantity />
<grossTotal />
<netTotal />
</item>
</xforms:instance>
<xforms:bind nodeset="/item/discount" readonly="true()" />
</xforms:model>
*n this case, since you don6t !ant users messing !ith the discount rate, you can use the @readonly@
property to make it non4modifiable. As before, you can combine this !ith comparison tests to make
the property6s relevance conditional.
#ne e8tremely useful property in this conte8t 4 and one you6ll probably be using a lot 4 is the
@calculate@ property, !hich lets you calculate some of the form data on the fly. +onsider the
follo!ing e8tension of the e8ample above, !hich illustrates-
<!-- form model -->
<xforms:model id="shop">
<xforms:instance>
<item>
<code />
<price />
<discount>2.00</discount>
<quantity />
<grossTotal />
<netTotal />
</item>
</xforms:instance>
<xforms:bind nodeset="/item/discount" readonly="true()" />
<xforms:bind nodeset="/item/grossTotal" calculate="/item/price * /item/quantity" />
<xforms:bind nodeset="/item/netTotal" calculate="/item/grossTotal - ((item/grossTotal
* /item/discount)/100)" />
</xforms:model>
*n this case, the @calculate@ property has been used to dynamically calculate the value of the
<grossTotal= element from the values of the <price= and <7uantity= elements. The <netTotal= is
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=228
3 of 7 4/22/2014 8:14 AM
then again calculated from the <grossTotal= by accounting for the <discount=.
*n case you !ere !ondering !hy * haven6t used a @readonly@ property for the t!o dynamically4
calculated values 4 * don6t need to, since these values are automatically made read4only !hen a
@calculate@ property is used on them.
The Boo)*orm Turns
*n addition to simple comparison tests, you can also use 2,ath arithmetic and non4arithmetic
functions in an 23orms model. +onsider the follo!ing e8ample, !hich illustrates-
<html xmlns="http://www.w3.org/1999/xhtml"; xmlns:xforms="http://www.w3.org
/2002/xforms/cr"; xmlns:xsd="http://www.w3.org/2001/XMLSchema">;
<head>
<!-- define the form model -->
<xforms:model id="bookstore">
<xforms:instance>
<inventory>
<books>

<title>Be Cool</title>
<author>Elmore Leonard</author>
<price>7.97</price>
<quantity>150</quantity>
<title>Mystic River</title>
<author>Dennis Lehane</author>
<price>25.00</price>
<quantity>86</quantity>
<title>Hit List</title>
<author>Lawrence Block</author>
<price>23.76</price>
<quantity>26</quantity>
<title>Silent Joe</title>
<author>T. Jefferson Parker</author>
<price>24.99</price>
<quantity>268</quantity>
<title>The Travel Detective</title>
<author>Peter Greenberg</author>
<price>34.87</price>
<quantity>9</quantity>

</books>
<totalInventory />
<mostExpensive />
<leastExpensive />
<averageCost />
</inventory>
</xforms:instance>

<xforms:bind nodeset="/inventory/books/totalInventory" calculate="sum(/inventory
/books/quantity)" />
<xforms:bind nodeset="/inventory/books/mostExpensive" calculate="max(/inventory
/books/price)" />
<xforms:bind nodeset="/inventory/books/leastExpensive" calculate="min(/inventory
/books/price)" />
<xforms:bind nodeset="/inventory/books/averagePrice" calculate="avg(/inventory
/books/price)" />

The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=228
4 of 7 4/22/2014 8:14 AM
</xforms:model>
</head>
<body>
<!-- define the form interface -->
<!-- loop over the instance data -->
<xforms:repeat nodeset="/inventory/books">
<xforms:input id="txttitle" ref="title">
<xforms:label>Title</xforms:label>
</xforms:input>
<xforms:input id="txtauthor" ref="author">
<xforms:label>Author</xforms:label>
</xforms:input>
<xforms:input id="txtprice" ref="price">
<xforms:label>Price</xforms:label>
</xforms:input>
<xforms:input id="txtquantity" ref="quantity">
<xforms:label>Quantity</xforms:label>
</xforms:input>
</xforms:repeat>
<!-- print calculated values -->
Total inventory: <xforms:output ref="/inventory/books/totalInventory" /> <br />
Price of most expensive book: <xforms:output ref="/inventory/books/mostExpensive" />
<br />
Price of least expensive book: <xforms:output ref="/inventory/books/leastExpensive"
/> <br />
Average price: <xforms:output ref="/inventory/books/averagePrice" />
</body>
</html>
As usual, all the action is centered around the definition of the 23orms model. This time around, the
instance data has been populated !ith the inventory of the neighbourhood bookstore, and 2,ath
functions like sum9:, min9:, ma89: and avg9: have been used to perform calculations on that data,
and assign the results of those calculations to specific summary elements in the instance data. This
data is then displayed in the form using the <8forms-output= element.
&ou6ll also notice a ne! element in the form above 4 the <8forms-repeat= element. This element
gives 23orms authors the ability to loop over a collection of nodes !ithout having to resort to
comple8 @!hile@ or @for@ loops. *n this e8ample, the <8forms-repeat= element causes the 23orms
processor to iterate over the <books= collection from the instance data, and display the values of
the title, author, price and 7uantity. The @nodeset@ attribute specifies the node over !hich iteration
should take place, !hile the loop counter is handled internally by the processor. 5ooping !ill stop
once no further match is found for the @nodeset@ criteria.
$hy stop Aust at numeric functions, though/ This ne8t e8ample uses the days4from4date9: function
to calculate the number of days bet!een an entered date and Danuary 01 1EF0.
The 23orms model !ill look something like this-
<!-- form model -->
<xforms:model id="dateCalculator">
<xforms:instance>
<calc>
<dt />
<numDays />
</calc>
</xforms:instance>
<xforms:bind nodeset="/calc/numDays" calculate="days-from-date(/calc/dt)" />
</xforms:model>
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=228
5 of 7 4/22/2014 8:14 AM
,retty straightfor!ard, isn6t it/
+n vent To ,emem-er
*t !as the introduction of events in client4side scripting languages like Davacript and );cript that
brought about the rise of the dynamic $eb site. 'o!ever, inconsistencies in implementation across
bro!sers meant that developers had to grapple !ith multiple lines of code to make $eb sites cross4
bro!ser compatible. 23orms has put an end to this misery, at least so far as form events are
concerned.
The 23orms 1.0 specification divides the process of event handling into four phases-
*nitialiGation- This is the very first stage, !herein the 23orms processor @!akes up@ and begins
construction of the data model using the instance data provided. This is also the stage !here all
relevant 2M5 chemas are loaded, and all form controls 9!ith their associated bindings: are
initialiGed.
*nteraction- *nteraction events are fired as a result of action from the user 4 for e8ample, keyboard
navigation to a ne! input control, mouse clicks, data entry or item selection. A number of different
events can occur in this phase, and each one has a default action associated !ith it.
"otification- "otification events don6t usually have a default action associated !ith them> rather,
they6re triggered as a result of a change in the form state, such as a form control receiving focus or
a button being clicked.
(rror handling- These events occur due to errors in 23orm processing, such as illegal binding
e8pressions or illegal 2,ath references. (rrors may be either fatal or non4fatal, depending on their
severity.
#H, no! enough of the theory. 5et6s look at a simple e8ample-
<!-- define the form model -->
<xforms:model id="bankAccount">
<xforms:instance>
<account>
<openingBalance>10000</openingBalance>
<withdrawal />
<closingBalance />
</account>
</xforms:instance>
<xforms:bind id="nodeClosingBalance" nodeset="/account/closingBalance" />
</xforms:model>
<!-- define the form interface -->
<xforms:input id="txtwithdraw" ref="/account/withdrawal">
<xforms:label>Amount to withdraw</xforms:label>
<xforms:hint>Please enter the amount you wish to withdraw</xforms:hint>
</xforms:input>
<xforms:trigger>
<xforms:label>Calculate Closing Balance</xforms:label>
<xforms:setvalue ev:event="DOMActivate" bind="nodeClosingBalance" value="/account
/openingBalance - /account/withdrawal" />
</xforms:trigger>
;y definition, the <8forms-trigger= element is the 23orms counterpart of the regular 'TM5 form
button. $hen clicked, it generates a I#MActivate event, !hich is a catch4all event type fired
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=228
6 of 7 4/22/2014 8:14 AM
!henever any event 9pressing a button, selecting an option: occurs. The <8forms-setvalue=
element, !hich is used to set the value for a particular node after computing it from an 2,ath
e8pression, listens for this event and acts !hen it receives it. *n this case, the action involves
subtracting the !ithdra!al amount from the opening balance to obtain a ne! closing balance.
A number of other event types are available in the 23orms model 4 you6ve already seen one of the
other important ones, the 8forms4submit event, in the previous segment of this tutorial. There are
too many to list here, so you should take a look at the specification 9and the e8cellent e8amples
included !ithin it:, to better understand this topic.
.in) !ut
And that6s about all * have for you. #ver the course of this three4part tutorial, * introduced you to
the ne! 23orms 1.0 specification, and sho!ed you ho! to create a data model and bind its elements
to form input controls. * also e8plained the various 23orms input controls, and sho!ed you ho! they
map into the standard 'TM5 form controls.
"e8t, * discussed the process of submitting an 23orm, !ith a look at the <8forms-submission=
element and the @submit@ input control. * also sho!ed you ho! to perform primitive datatype
validation in an 23orm using built4in 2M5 chema datatypes, and ho! to e8tend this to perform
more comple8 validation by integrating your o!n custom datatypes into the 23orms model.
3inally, in this concluding part, * introducing the concept of binding using the <8forms-bind=
element, !hich allo!s you to disable or enable input controls, mark them as read4only, enforce
special constraints on your input controls, and even calculate values on the fly 4 tasks !hich earlier
re7uired comple8 Davacript, but are no! as simple as combining 2,ath e8pressions. * also looked at
some 2,ath functions, and sho!ed you ho! you can use them !ithin your binding e8pressions for
greater fle8ibility in calculations. * !rapped things up !ith a brief introduction to the 23orms event
model 4 this is a fairly comple8 topic, and one !hich re7uires in4depth understanding of the 2M5
(vents specification as !ell, so if you6d like to learn more about it, be prepared to spend some time
on research 9!ith the specification in hand:.
* hope you enAoyed this article, and that it gave you sufficient grounding to get you started !ith
23orms. 23orms is one of the more interesting emerging 2M5 technologies, and you can e8pect to
see it gro! more po!erful in subse7uent iterations. o go on 4 it6s time to practice?
"ote- (8amples are illustrative only, and are not meant for a production environment. Melonfire
provides no !arranties or support for the source code described in this article. &MM)?
Copyright notice:
This article is copyright Melonfire, 2014. All rights reserved.
All source code, brand names, trademarks and other content contained herein and proprietary to
Melonfire, 2014. All rights reserved.
ource code !ithin this article is provided !ith "# $A%%A"T& $'AT#()(%. *t is meant for
illustrative purposes only, and is "#T recommended for use in production environments.
+opyright infringement is a violation of la!.
,rinted from http-..!!!.melonfire.com.community.columns.trog.article.php/id0221
Copyright 1998-2014 Melonfire. All rights reserved
Terms and Conditions | Feedback
The Melonfire Community - Trog http://www.melonfire.com/community/columns/trog/print.php?id=228
7 of 7 4/22/2014 8:14 AM

S-ar putea să vă placă și