Adobe Spry is an Ajax framework developed for Web designers, making it possible to create a richer experience on an HTML page. Spry is intended to be a way of easily implementing Ajax — designers with entry level HTML, CSS and JavaScript experience should find Spry an easy way to integrate content.
Spry differs from other Ajax frameworks because it has been created for designers rather than developers. It is less reliant on server-side technology compared to some other Ajax frameworks; instead it relies on XML, which is easily consumed by Spry’s components with a minimum of fuss.
In its attempt to make the implementation of Spry simple, Adobe has drawn some fire from Web standards adherents with criticism that it makes use of custom HTML attributes.
Adobe released an updated version, Spry 1.5, recently on its Adobe Labs site; this is the sixth release since the original beta last year with new features added for interacting with different kinds of data including:
- Nested Data Sets
- JSON Data Sets
- HTML Data Sets
- Session Handling
- Form Submission
- Paged Data View
- Rewrite of existing Effects
- Radio Button Validation Widget
- Auto Suggest Widget
- Spry API
The Spry framework contains the following components:
- Spry Data and Dynamic Region
- Data Utilities
- Server Side Utilities
- Widgets
- Effects
Spry is a free download from Adobe, included in the download is a multitude of demos, samples, articles and documentation. Documentation is also available online via Adobe’s LiveDocs, there is also a developer centre for Spry where you can find numerous articles already available.
Working With Data
XML Data
Enough talk; let’s put the framework to the test. The first thing that we evaluated was Spry’s ability to handle XML data. We created some sample data in the form of an XML file with the details for the employees of a fictitious municipality. A sample below:
<?xml version="1.0" encoding="UTF-8"?> <employees> <employee id="1"> <fname>Frank</fname> <lname>Bacon</lname> <email>fbacon@municipality.gov</email> <mobilePhone>2201-09-0426</mobilePhone> <department>Board of Education</department> </employee> <employee id="2"> <fname>Bob</fname> <lname>Boyle</lname> <email>bboyle@municipality.gov</email> <mobilePhone>2501-301-291</mobilePhone> <department>Animal Services</department> </employee> </employees>
You can see that the data has multiple rows each with the same properties, there’s no DTD (Data Type Definition) required by Spry to interact with XML, which is typically a problem of consuming XML — no standardisation. The goal here is to have Spry handle data for us and output that in an HTML page, you nominate the attributes and properties from the data and tell Spry where on the page to display them.
Using a text editor we’ll work on the HTML content. Below is a snippet from between the tags. I’ve imported two .js files, the first uses Google’s open source code to utilize XPath so that we can filter data later on, the second is the Spry data library — it’s dependant on the XPath library which is why the other is declared first.
Next an instance of the Spry XMLDataSet is declared; here we’ve called it dsEmployees. The instantiation requires two parameters: the location of the XML file and an XPath expression that identifies the XML node or nodes that the data is contained within. The XML can also be loaded from a URL. Note that the XPath expression identifies the XML root node then the name of the child node that represents each row of data.
<title>Spry Simple Data Example</title> <script type="text/javascript" src="includes/xpath.js"></script> <script type="text/javascript" src="includes/SpryData.js"></script> <script type="text/javascript"> var dsEmployees = new Spry.Data.XMLDataSet("assets/employee_data.xml", "employees/employee"); </script> </head>
Outputting the Spry data set within the body of the page is simple. Spry dynamic regions are used to display XML data on the page; they update themselves when the data set changes. A dynamic region is declared within a div tag using spry:region, HTML tags then are used as dynamic region containers. The region is an “observer” of the Spry data set, curly braces are used to identify columns from the data set, the spry:repeat tag iterates through the data set displaying all the rows.
<div id="Employees_DIV" spry:region="dsEmployees"> <table id="Employees Table"> <tr> <th>Name</th> <th>Department</th> <th>Email</th> </tr> <tr spry:repeat="dsEmployees"> <td>{fname} {lname}</td> <td>{department}</td> <td><a href="mailto:{email}">{email}</a></td> </tr> </table> </div>
Spry has provisions to do master/detail dynamic regions from one or more sets of data. The sample code below uses the same logic within the head tag to declare a Spry data set as above. An onclick event has been added to the repeated table row that links to a Spry XMLDataSet method called setCurrentRow passing the id of the current row as parameter. The second table is surrounded with a div that uses the spry:detailregion to populate the detail portion of the code. Sorting table data by column headings is just as easy.
<div id="Employees_DIV" spry:region="dsEmployees"> <table id="Employees Table"> <tr> <th>Name</th> </tr> <tr spry:repeat="dsEmployees" onclick="dsEmployees.setCurrentRow('{ds_RowID}')"> <td>{fname} {lname}</td> </tr> </table> </div> <div id="Employee_Detail_DIV" spry:detailregion="dsEmployees"> <table id="Employee Detail Table" border="1"> <tr> <th>Name</th> <th>Department</th> <th>Email</th> <th>Mobile Phone</th> </tr> <tr> <td>{fname} {lname}</td> <td>{department}</td> <td><a href="mailto:{email}">{email}</a></td> <td>{mobilePhone}</td> </tr> </table> </div>
JSON
Spry handles data from JSON in the same way, the differences are naturally the way that the data file has been formatted and the Spry data library used to handle the JSON. Below is a sample of the data file where the same information as before is now an array of objects – this is the advantage of JSON, having a formal way of describing data in it’s type rather than needing to use a custom description of the data’s contents like the DTD used for the XML example.
[ { id: "1", fname: "Frank", lname: "Bacon", email: "fbacon@municipality.gov", mobilePhone: "2201-09-0426", department: "Board of Education" }, { id: "2", fname: "Bob", lname: "Boyle", email: "bboyle@municipality.gov", mobilePhone: "2501-301-291", department: "Animal Services" } ]
Here is the same snippet from the <head> tags of the page, the .js for the SpryJSONDataSet library has also been imported.
<script language="JavaScript" type="text/javascript" src="includes/xpath.js"> </script> <script language="JavaScript" type="text/javascript" src="includes/SpryData.js"></script> <script language="JavaScript" type="text/javascript" src="includes/SpryJSONDataSet.js"></script> <script type="text/javascript"> var dsEmployees = new Spry.Data.JSONDataSet("assets/employee_data.js"); </script> </head>
The same output code as the XML data is used on the page to display the JSON data, this example works well with only a minimal change to the page required to display the JSON data instead — however this time it failed to work for us on Safari. Firefox on the Mac was fine — this is beta code and the first version to be able to consume JSON so perhaps there’s some unknown conflict between Safari and the imported JavaScript libraries. Our expectation was that it should have worked.
Spry Widgets
Another part of Spry is the widgets — visual elements to add to the page that combine HTML, CSS and JavaScript. These are part of the Spry framework and add user interactions to the page to provide a richer experience. The majority of the widgets are enhanced versions of HTML form elements — there are also additional visual elements that offer menus and other alternate ways to display content.
Each Spry widget consists of HTML code for layout, JavaScript to deliver behaviours and CSS styling. Adobe advise that care has been taken in the coding of these widgets to take accessibility into account; this includes keyboard access and the availability of widget content should JavaScript be turned off in the browser or be unsupported. A set of development guidelines is available from Adobe to ensure that developers building their widgets with the Spry 1.5 API include accessibility.
The Spry widgets that extend existing HTML form elements are:
- Checkbox widget
- Radio Button widget
- Select widget
- Text Area widget
- Text Field widget
These widgets extend the normal form functionality by adding validation combined with feedback to the user that includes entry prompts and error messages. Feedback is indicated by either using CSS to change the background colour of a form element, or the display of an error message. Most of these widgets provide a number of events so that the validation can occur at different moments during user interaction; for example typing a value, choosing another form element or submitting the form.
Below is a simple example of the Validation Textfield widget being used for form validation, the field is both required and typed as an integer value with separate error messages for each validation type. Like previous examples we’ve taken an excerpt from the page. Notice that within the <head> tags we’ve imported both the JavaScript and CSS files for this widget — while part of the Spry download, these files are not found in the same folder as the data libraries, instead they can be found within the widgets folder.
<title>Spry Text Field Widget Example</title> <script src="includes/SpryValidationTextField.js" type="text/javascript"></script> <link href="includes/SpryValidationTextField.css" rel="stylesheet" type="text/css" /> </head> <body> <form id="form1" name="form1" method="post" action=""> <span id="sprytextfield1"> <input type="text" name="textfield" id="textfield" /> <span class="textfieldRequiredMsg">The value is required.</span> <span class="textfieldInvalidFormatMsg">Invalid format.</span> </span> </form> <script type="text/javascript"> <!-- var sprytextfield1 = new Spry.Widget.ValidationTextField("sprytextfield1", "integer", {validateOn:["blur"]}); //--> </script> </body>
Within the <form> tags in the code above you will see that we’ve used a <span> to identify the textfield to be validated. Nested within that <span> we’ve nested <span> tags for each validation message, classes set to the specific types of validation. Below the form is a JavaScript block that inserts the logic for the browser to trigger the validation.
The Spry.Widget.ValidationTextField method has a required parameter for the textfield to be validated, and two more optional parameters to identify data type validation and a specific event to trigger the validation — in this case when the textfield loses focus.
The Auto Suggest widget is a new addition to Spry 1.5, it’s a textfield form element designed for search interfaces that responds as the user types by displaying a list of possible matches for criteria entered. It’s different to the other widgets because it is reliant on a data set for the suggestions displayed. The way that matches can be displayed is only limited to the imagination — the sample files included with Spry have combinations of text and images.
There are a number of additional widgets not specific to form elements:
- Accordion
- Collapsible Panel
- Menu Bar
- Sliding Panels
- Tabbed Panel
We can put the Menu Bar widget to one side as it’s a straight forward multi-node navigation object; the other widgets offer various ways of showing additional data on screen without the need for a page reload. They are typical of other Ajax frameworks in the way they operate; they behave more like desktop application user controls than the normal interface controls that HTML has to offer.
There are good examples of how each of these widgets work included with the Spry download from the Adobe Labs site.
Spry Effects
While Spry Effects have been part of the framework for some time there has been a rewrite of the Effects library for version 1.5 — notably changes have been made to the names of the methods themselves to make them more consistent with other languages.
The purpose of the Spry Effects is to add visual effects to visual elements on an HTML page. These effects can include animated transitions and content highlighting. I’m a big believer in the judicial use of animation, keeping its use to a minimum, but there are times where it can be used to do things like indicate application state. A transition from one state to another can be subtly animated to give the user better feedback.
The Spry Effects are:
- Blind
- Fade
- Glow
- Highlight
- Shake
- Slide
- Squish
Observers can be used to combine effects together so that, for example, as one panel is reduced in width another is proportionally increased in width by the same amount giving the switch between the two panels a sliding effect.
Clustering allows effects to be run one after another so that a panel could first increase in width then increase in height instead of simultaneously which is what an observer could do.
Below is an excerpt from an HTML page where the Blind Effect has been used. In this example the effect is triggered by clicking on a hyperlink; the Blind Effect will make the div containing the text reduce in height gradually until it’s disappeared and will work from the hyperlink in both directions. The Spry Effects library is part of the standard includes directory from within the Spry download.
<title>Spry Effect Example</title> <script src="includes/SpryEffects.js" type="text/javascript"></script> <style type="text/css"> .animationContainer{ height: 220px; } .demoDiv{ height: 200px; width: 400px; overflow: hidden; background-color: #CCCCCC; } </style> </head> <body> <a href="#" onclick="blind_toggle.start(); return false;">Blind Example</a> <br /> <div class="animationContainer"> <div class="demoDiv" id="slideItUp2"> <h4>Spry Blind Effect Example</h4> <p class="sampleText"> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. </p> </div> </div> <script type="text/javascript"> <!-- var blind_toggle = new Spry.Effect.Blind('slideItUp2', {toggle:true}); //--> </script>
Spry and Dreamweaver CS3
An enhanced version of Spry 1.4 is integrated into Dreamweaver CS3, with tag editors making the job easy. Spry Data, for example, is easier to implement through the dialogs in Dreamweaver CS3 because you can do things like import the XML schema and preview data. Dreamweaver CS3 will also include the necessary JavaScript and CSS files in the current site.
Included in the Spry toolbar are three sets of objects discussed previously; for displaying XML data, form validation elements, and menus and panel sets.
Dreamweaver CS3 can introspect the XML data used by the Spry XmlDataSet library, displaying the individual properties of a row within the Bindings panel — these properties can be dragged from the Bindings panel into the page and provided they’re within a Spry Region or Spry Repeat will be dynamically rendered within the browser.
Conclusion
The Spry framework is an easy to implement Ajax framework, especially for designers, who are the intended user group. Web standards adherents have made criticism that the implementation of Spry makes use of custom HTML attributes, for the uninitiated this may not be an issue as the Spry components work as promised.
While Spry is integrated in Dreamweaver CS3 it is easy to deploy from within a text editor — Adobe supply a multitude of examples with the Spry download. The current release has an API that allows developers to create their own widgets to use within the Spry framework.