XForms is the "new" standard way to create forms. The specification actually isn't that new, but it's definitely new to almost all developers, few of whom have ever used it. Understanding XFormsUnderstanding XForms requires us to take a little detour into the worlds of XML and XSL. Here goes: XML is simply a way to share structured data. XML documents are each of a specific type that defines what fields and information need to be in XML documents of that type. XForms is an XML type used to define what forms contain. It's important to understand that. Unlike HTML forms, which contain form controls and presentation, XForms forms contain only form controls. Or put differently, when we first looked at forms (back in Chapter 12, "ColdFusion Forms"), the forms we created contained controls (the form fields themselves) as well as presentation information (where the label should be displayed, HTML tables, and so on). An XForms form only contains controls, a list of controls and what their attributes are. Attributes include things like:
There is no presentation at all in the XForms, just lots of information that could be used by whoever (or whatever) needs to provide the presentation. XSL stands for Extensible Stylesheet Language, a language used to provide processing rules for XML. Let's say you had an XML file containing raw movie information and you wanted to convert that data into the format your database needed. You would write an XSL file that provided the translation rules, defining how XML data is to be processed and what any generated output should look like. The XSL file is then applied, and the output you need is generated. When working with Xforms, you need two documents:
The big idea is to explicitly divorce form contents from form presentation. Why is this a good thing? Consider the following scenarios:
Barriers to XForms AdoptionThere have been three primary barriers to XForms adoption:
All things considered, it's easy to see why XForms adoption has been slow. Yet XForms does indeed have value, as already explained. ColdFusion and XFormsAs you've seen, ColdFusion is all about reducing complexity and making development tasks simpler. While ColdFusion can't solve all of the above problems, this is what it can do for you:
With that, let's look at an example. Listing 15.11 is a simple form: two inputs and no formatting. Figure 15.13 shows the output it generates. Listing 15.11. xforms1.cfmBasic XForms Example<!--- Name: xforms.cfm Author: Ben Forta (ben@forta.com) Description: Basic XForms example Created: 12/22/04 ---> <cfform format="xml" action="formdump.cfm"> <cfinput name="MovieTitle" label="Title:" type="text"> <cfinput name="PitchText" label="Tag Line:" type="text"> </cfform> Figure 15.13. If no XSL skin is specified, a default skin is used.There is no formatting in Listing 15.11, and yet the fields were laid out in an HTML table. As no skin was specified, the default skin was used. If you look at the generated source (do a View Source in the browser) you will see that an HTML table was generated automatically by the XSL transformation. Try modifying the <cfform> line so that it reads: <cfform format="xml" skin="silver" action="formdump.cfm"> This will generate an output like the one seen in Figure 15.14. By simply specifying an alternate skin, a different output could be generated. Figure 15.14. A series of basic colored skins are provided with ColdFusion.Let's look at a more complete example, an XForms version of the movie edit screen, but with a twist. Listing 15.12 contains the new form code. Its output is shown in Figure 15.15. Listing 15.12. xforms2.cfmComplete XForms Example<!--- Name: xforms2.cfm Author: Ben Forta (ben@forta.com) Description: XForms example (based on 14/movie_edit.cfm Created: 12/22/04 ---> <!--- Default skin ---> <cfparam name="skin" default="basic"> <!--- Check that FilmID was provided ---> <!--- If yes, edit, else add ---> <cfset EditMode=IsDefined("URL.FilmID")> <!--- If edit mode then get row to edit ---> <cfif EditMode> <!--- Get the film record ---> <cfinvoke component="ows.14.movies" method="get" film returnvariable="film"> <!--- Save to variables ---> <cfset MovieTitle=Trim(film.MovieTitle)> <cfset PitchText=Trim(film.PitchText)> <cfset AmountBudgeted=Int(film.AmountBudgeted)> <cfset RatingID=film.RatingID> <cfset Summary=Trim(film.Summary)> <cfset ImageName=Trim(film.ImageName)> <cfset DateInTheaters=DateFormat(film.DateInTheaters, "MM/DD/YYYY")> <!--- Form text ---> <cfset FormTitle="Update a Movie"> <cfset ButtonText="Update"> <cfelse> <!--- Save to variables ---> <cfset MovieTitle=""> <cfset PitchText=""> <cfset AmountBudgeted=""> <cfset RatingID=""> <cfset Summary=""> <cfset ImageName=""> <cfset DateInTheaters=""> <!--- Form text ---> <cfset FormTitle="Add a Movie"> <cfset ButtonText="Insert"> </cfif> <!--- Get ratings ---> <cfinvoke component="ows.14.movies" method="getRatings" returnvariable="ratings"> <!--- Page header ---> <cfinclude template="../14/header.cfm"> <!--- Available skins ---> <cfset skins="basic,basiccss,beige,blue,bluegray,lightgray,red,silver"> <!--- Skin selection form ---> <p align="right"> <form action="xforms2.cfm" method="post"> Skin: <select name="skin" onChange="submit()"> <cfloop list="#skins#" index="s"> <cfoutput> <option value="#s#" <cfif s IS skin>selected</cfif>>#s#</option> </cfoutput> </cfloop> </select> </form> </p> <!--- Add/update movie form ---> <cfform format="xml" action="formdump.cfm" skin="#skin#"> <cfif EditMode> <!--- Embed primary key as a hidden field ---> <cfinput type="hidden" name="FilmID" value="#Film.FilmID#"> </cfif> <cfinput type="Text" label="Movie:" name="MovieTitle" value="#MovieTitle#" message="MOVIE TITLE is required!" required="Yes" validateAt="onSubmit,onServer" size="50" maxlength="100"> <cfinput type="Text" label="Tag Line:" name="PitchText" value="#PitchText#" message="TAG LINE is required!" required="Yes" validateAt="onSubmit,onServer" size="50" maxlength="100"> <cfselect name="RatingID" label="Rating:" query="ratings" value="RatingID" display="Rating" selected="#VARIABLES.RatingID#" /> <cftextarea label="Summary:" name="summary" cols="40" rows="5" wrap="virtual"><cfoutput>#Summary#</cfoutput></cftextarea> <cfinput type="Text" label="Budget:" name="AmountBudgeted" value="#AmountBudgeted#" message="BUDGET must be a valid numeric amount!" required="NO" validate="integer" validateAt="onSubmit,onServer" size="10" maxlength="10"> <cfinput type="text" label="Release Date:" name="DateInTheaters" value="#DateInTheaters#" message="RELEASE DATE must be a valid date!" required="NO" validate="date" validateAt="onSubmit,onServer" size="10" maxlength="10"> <cfinput type="Text" label="Image File:" name="ImageName" value="#ImageName#" required="NO" size="20" maxlength="50"> <cfinput type="submit" name="BtnSubmit" value="#ButtonText#"> </cfform> <!--- Page footer ---> <cfinclude template="../14/footer.cfm"> Figure 15.15. Skins can be changed on the fly, allowing for user-selectable presentation options.Figure 15.14. A series of basic colored skins are provided with ColdFusion.So what changed in Listing 15.12? At the top of the page is a <cfparam> tag that checks to see if a skin name was passed as a parameter, defaulting to "basic" if none was specified. A new form was added to the top right of the page. The following code creates a simple drop-down list of available skins. A variable is defined with a list of skins, then a <cfloop> loops through that list to populate the drop-down list (making sure to pre-select the current skin). An onChange JavaScript event submits the form if a selection is made, allowing you to switch skins by a simple selection: <!--- Available skins ---> <cfset skins="basic,basiccss,beige,blue,bluegray,lightgray,red,silver"> <!--- Skin selection form ---> <p align="right"> <form action="xforms2.cfm" method="post"> Skin: <select name="skin" onChange="submit()"> <cfloop list="#skins#" index="s"> <cfoutput> <option value="#s#" <cfif s IS skin>selected</cfif>>#s#</option> </cfoutput> </cfloop> </select> </form> </p> The next change is the <cfform> tag, which now reads: <cfform format="xml" action="formdump.cfm" skin="#skin#"> The format has been changed to "xml", and a skin is being specified using variable skin. The only other change is that the datefield has been changed to a text field as type="datefield" is only supported by Flash. This just scratches the surface of what can be done with XForms and XSL. Beyond simple presentation abstraction, XForms and XSL become particularly useful in abstracting form logic and intelligent form controls. Where Do XSL Files Go?The skins used in the examples here are XSL files, skin="red" refers to a file named red.xls. So where are these files? Actually, they can be just about anywhere on your server, or in a specially designated folder. Here is how it works:
NOTE If you intend to use XForms extensively, you'll want to pick up a book on XSL. Between Flash Forms and XForms support, ColdFusion provides developers with additional options that will help create better and more usable applications. NOTE If you're looking for additional examples of Flash Forms use and XSL skins, visit http://www.cfform.com/. |