Spry Help
Spry Help
Trademarks 1 Step RoboPDF, ActiveEdit, ActiveTest, Authorware, Blue Sky Software, Blue Sky, Breeze, Breezo, Captivate, Central, ColdFusion, Contribute, Database Explorer, Director, Dreamweaver, Fireworks, Flash, FlashCast, FlashHelp, Flash Lite, FlashPaper, Flash Video Encoder, Flex, Flex Builder, Fontographer, FreeHand, Generator, HomeSite, JRun, MacRecorder, Macromedia, MXML, RoboEngine, RoboHelp, RoboInfo, RoboPDF, Roundtrip, Roundtrip HTML, Shockwave, SoundEdit, Studio MX, UltraDev, and WebHelp are either registered trademarks or trademarks of Adobe Systems Incorporated and may be registered in the United States or in other jurisdictions including internationally. Other product names, logos, designs, titles, words, or phrases mentioned within this publication may be trademarks, service marks, or trade names of Adobe Systems Incorporated or other entities and may be registered in certain jurisdictions including internationally. Third-Party Information This guide contains links to third-party websites that are not under the control of Adobe Systems Incorporated, and Adobe Systems Incorporated is not responsible for the content on any linked site. If you access a third-party website mentioned in this guide, then you do so at your own risk. Adobe Systems Incorporated provides these links only as a convenience, and the inclusion of the link does not imply that Adobe Systems Incorporated endorses or accepts any responsibility for the content on those thirdparty sites. 2006 Adobe Systems Incorporated. All rights reserved. This manual may not be copied, photocopied, reproduced, translated, or converted to any electronic or machine-readable form in whole or in part without written approval from Adobe Systems Incorporated. Notwithstanding the foregoing, the owner or authorized user of a valid copy of the software with which this manual was provided may print out one copy of this manual from an electronic version of this manual for the sole purpose of such owner or authorized user learning to use such software, provided that no part of this manual may be printed out, reproduced, distributed, resold, or transmitted for any other purposes, including, without limitation, commercial purposes, such as selling copies of this documentation or providing paid-for support services. Acknowledgments Project Management: Charles Nadeau Writing: Jon Michael Varese Production Management: Adam Barnett Media Design and Production: Adam Barnett, Masayo Noda
First Edition: January 2006 Adobe Systems Incorporated 601 Townsend St. San Francisco, CA 94103
Contents
Using the Spry framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 About AJAX and the Spry framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 About AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 About the Spry framework. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 How Spry pages work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Anatomy of the Spry data set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Anatomy of the Spry dynamic region . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Anatomy of the Spry basic master/detail dynamic region . . . . . . . . .11 Anatomy of master/detail dynamic regions that depend on more than one data set. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Building Spry pages. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 To prepare your files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 To create a Spry data set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 To display data from a Spry data set . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Sample code: Spry data set and dynamic region . . . . . . . . . . . . . . . 23 To sort a Spry data set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Numerical sorting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 To create basic master/detail dynamic regions. . . . . . . . . . . . . . . . . 25 To create master/detail dynamic regions that rely on more than one data set. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Contents
About AJAX
Asynchronous JavaScript and XML, or AJAX, is a concept for how Web developers can use various techniques to update web pages without requiring visible refreshes and without the need for browser add-on technologies like Flash, Java, or ActiveX. AJAX is not a product, company, or trademark. Implementing AJAX features often requires knowledge of JavaScript, XML, and the Document Object Model (DOM). Spry provides a light-weight, HTML-centric framework that makes the task simpler. For more information about AJAX, see http://en.wikipedia.org/wiki/AJAX.
Anatomy of the Spry data set on page 6 Anatomy of the Spry dynamic region on page 9 Anatomy of the Spry basic master/detail dynamic region on page 11 Anatomy of master/detail dynamic regions that depend on more than one data set on page 13
</menu_item> <menu_item id="2"> <item>Thai Noodle Salad</item> <description>lightly sauteed in sesame oil with baby bok choi, portobello mushrooms, and scallions.</description> <price>8</price> </menu_item> <menu_item id="3"> <item>Grilled Pacific Salmon</item> <description>served with new potatoes, diced beets, Italian parlsey, and lemon zest.</description> <price>16</price> </menu_item> </specials>
The data set flattens the XML data into an array of objects (rows) and properties (columns) that can be visualized as the following table:
@id
1
item
Summer salad
description
organic butter lettuce with apples, blood oranges, gorgonzola, and raspberry vinaigrette. lightly sauteed in sesame oil with baby bok choi, portobello mushrooms, and scallions.
price
7
2 3
served with new potatoes, diced beets, Italian 16 parlsey, and lemon zest.
The data set contains a row for each menu item and the following columns: @id, item, description, and price. The columns represent the child nodes of the specials/menu_item node in the XML, plus any attributes contained in the menu_item tag, or in any of the child tags of the menu_item tag. The data set also contains a built-in data reference called ds_RowID (not shown) that can be useful later when you display your data. You create a Spry data set object by using the Spry.Data.XMLDataSet constructor. The default structure (or schema) of the data set is defined by the XML data source. For example, if the data source is a repeating XML node that contains three child nodes, the data set will have a row for each repeating node, and a column for each of the three child nodes. (If any of the repeating nodes or child nodes contain attributes, the data set also creates a column for each attribute.) Once created, the data set object lets you easily display and manage the data. For example, you can create a simple table that displays the XML data, and then use simple methods and properties to reload data, sort and filter data, or page through data.
The following example illustrates how you would create a Spry data set called dsSpecials, and load data from an XML file called cafetownsend.xml:
<head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" / > <title>Spry Example</title> <!--Link the Spry libraries--> <script type="text/javascript" src="includes/xpath.js"></script> <script type="text/javascript" src="includes/SpryData.js"></script> <!--Create a data set object--> <script type="text/javascript"> var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item"); </script> </head> <body> </body> The examples in this document are for reading purposes only and not intended for execution. For working samples, see the demos folder in the Spry_P1_1_06-08 folder. For more information, see To prepare your files on page 18.
N OT E 8
In the example, the first <script> tag links an open-source XPath library to the page where youll eventually display XML data. The XPath library allows for the specification of more complex XPath when you create a data set:
<script type="text/javascript" src="includes/xpath.js"></script>
The second <script> block links the Spry data library, SpryData.js, which is stored in a folder called includes on the server:
<script type="text/javascript" src="includes/SpryData.js"></script>
The Spry data library is dependent on the XPath library, so its important that you always link the XPath library first. The third <script> block contains the statement that creates the data set called dsSpecials. The XML source file, cafetownsend.xml, is stored in a folder called data on the server:
var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item");
In JavaScript the operator new is used to create objects. The Spry.Data.XMLDataSet method is a constructor in the Spry data library that creates new Spry data set objects. The constructor takes two parameters: the source of the data ("data/cafetownsend.xml") and an XPath expression that specifies the node or nodes in the XML to supply the data ("specials/ menu_item").
You can also specify a URL as the source of the XML data, as follows:
var dsSpecials = new Spry.Data.XMLDataSet("http://www.somesite.com/ somefolder/cafetownsend.xml", "specials/menu_item"); The URL you decide to use (whether absolute or relative) is subject to the browsers security model, which means that you can only load data from an XML source that is on the same server domain as the HTML page youre linking from. You can get around this limitation by providing a cross-domain service script. For more information, consult your server administrator.
NO T E
In the example, the constructor creates a new Spry data set object called dsSpecials. The data set obtains data from the specified specials/menu_item node in the XML file cafetownsend.xml and converts the data to a flattened array of objects and properties, similar to the rows and columns of a table. (See the beginning of this section for a visualization of the table.) Each data set maintains the notion of a "current row." By default, the current row is set to the first row in the data set. Later, you can change the current row programatically by calling the setCurrentRow() method on the data set object. For more information, see Anatomy of the Spry basic master/detail dynamic region on page 11.
title tr
While you cannot use any of the above HTML elements as Spry dynamic region containers, you are allowed to use them inside Spry dynamic region containers.
Dynamic regions are limited to regions within the body tag. You can't add the spry:region attribute to any tag that is outside the body tag.
NO TE 10
In the following example, weve created a container for a dynamic region called Specials_DIV using a div tag that includes a standard HTML table. Tables are typical HTML elements used for dynamic regions because the first row of the table can contain headings, and the second row can contain repeated XML data.
<!--Create the Spry dynamic region--> <div id="Specials_DIV" spry:region="dsSpecials"> <!--Display the data in a table--> <table id="Specials_Table"> <tr> <th>Item</th> <th>Description</th> <th>Price</th> </tr> <tr spry:repeat="dsSpecials"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr> </table> </div>
In the example, the div tag that creates the container for the dynamic region needs only two attributes: a spry:region attribute that declares the dynamic region and specifies the data set to use in it, and an id attribute that names the region:
<div id="Specials_DIV" spry:region="dsSpecials">
The new region is an observer or listener of the dsSpecials data set. Any time the dsSpecials data set changes, the new dynamic region regenerates itself with the updated data. An HTML table displays the data:
<table id="Specials_Table"> <tr> <th>Item</th> <th>Description</th> <th>Price</th> </tr> <tr spry:repeat="dsSpecials"> <td>{item}</td>
The values in curly braces in the second row of the table specify the columns in the data set. The curly braces bind the table cells to the data in specific columns of the data set. Because XML data often includes repeating nodes, the example also declares a spry:repeat attribute in the second table row tag. This causes all of the rows in the data set to appear when the user loads the page (instead of just the data sets current row).
11
<th>Description</th> <th>Price</th> </tr> <!--User clicks to reset the current row in the data set--> <tr spry:repeat="dsSpecials" onclick="dsSpecials.setCurrentRow('{ds_RowID}')"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr> </table> </div> <!--Create the detail dynamic region--> <div id="Specials_Detail_DIV" spry:detailregion="dsSpecials"> <table id="Specials_Detail_Table"> <tr> <th>Ingredients</th> <th>Calories</th> </tr> <tr> <td>{ingredients}</td> <td>{calories}</td> </tr> </table> </div> . . . </body> The example XML file in Anatomy of the Spry data set on page 6 does not contain nodes for ingredients or calories. Weve added these nodes to the data set for purposes of this example.
N OT E 12
In the example, the first div tag contains the id and spry:region attributes that create a container for the master dynamic region:
<div id="Specials_DIV" spry:region="dsSpecials">
The first table row tag of the master region contains an onclick event handler that resets the value of the current row in the data set.
<tr spry:repeat="dsSpecials" onclick="dsSpecials.setCurrentRow('{ds_RowID}')">
The second div tag contains the attributes that create a container for the detail dynamic region:
<div id="Specials_Detail_DIV" spry:detailregion="dsSpecials">
Every Spry data set maintains the notion of a current row. By default, the current row is set to the first row in the data set.
The binding expressions in the detail region ({ingredients} and {calories}) display data from the data sets current row when the page loads in a browser. When a user clicks a row in the master region table, however, the onclick handler changes the current row in the data set to the row the user selected. The {ds_RowID} data reference is a built-in part of the Spry framework that points to an automatically-generated unique ID for each row in the data set. (See Anatomy of the Spry data set on page 6.) When the user selects a row in the master region table, the onclick event handler supplies the unique ID to the setCurrentRow method, which causes the resetting of the current row in the data set. Whenever the data set is modified, all dynamic regions bound to that data set regenerate themselves and display the updated data. Since the detail region, like the master region, is an observer of the dsSpecials data set, it also changes as a result of the modification, and displays data related to the row the user selected (the new current row). The difference between a spry:region and a spry:detailregion is that the specifically listens for CurrentRowChange notifications (in addition to DataChanged notifications) from the data set, and updates itself when it receives one. Normal spry:regions, on the other hand, ignore the CurrentRowChange notification, and only update when they receive a DataChanged notification from the data set.
spry:detailregion
Anatomy of master/detail dynamic regions that depend on more than one data set
In some cases, you might want to create master/detail relationships that involve more than one data set. For example, you might have a list of menu items that has a great deal of detail information associated with it. (This section uses a list of ingredients to illustrate the point.) Fetching all of the information associated with every menu item in a single query might be an inefficient use of bandwidth not to mention unnecessary, given that many users might not even be interested in the details of everything on the menu. Instead, it would be more efficient to download only the detail data that the user is interested in when the user requests it, thus improving performance and reducing bandwidth. Limiting the amount of data exchange in this way is a common technique used to improve performance in AJAX applications. Following is the XML source code for a sample file called cafetownsend.xml:
<?xml version="1.0" encoding="UTF-8"?> <specials> <menu_item id="1"> <item>Summer Salad</item> <description>organic butter lettuce with apples, blood oranges, gorgonzola, and raspberry vinaigrette.</description> <price>7</price>
13
<url>summersalad.xml</url> </menu_item> <menu_item id="2"> <item>Thai Noodle Salad</item> <description>lightly sauteed in sesame oil with baby bok choi, portobello mushrooms, and scallions.</description> <price>8</price> <url>thainoodles.xml</url> </menu_item> <menu_item id="3"> <item>Grilled Pacific Salmon</item> <description>served with new potatoes, diced beets, Italian parlsey, and lemon zest.</description> <price>16</price> <url>salmon.xml</url> </menu_item> </specials> This XML sample code is different from the code used in Anatomy of the Spry data set on page 6.
N OT E 14
The cafetownsend.xml file supplies the data for the master data set. The url node of the cafetownsend.xml file points to a unique XML file (or URL) for each menu item. These unique XML files contain a list of ingredients for the corresponding menu items. The summersalad.xml file, for example, might look as follows:
<?xml version="1.0" encoding="iso-8859-1" ?> <item> <item_name>Summer salad</item_name> <ingredients> <ingredient> <name>butter lettuce</name> </ingredient> <ingredient> <name>Macintosh apples</name> </ingredient> <ingredient> <name>Blood oranges</name> </ingredient> <ingredient> <name>Gorgonzola cheese</name> </ingredient> <ingredient> <name>raspberries</name> </ingredient> <ingredient> <name>Extra virgin olive oil</name> </ingredient> <ingredient>
<name>balsamic vinegar</name> </ingredient> <ingredient> <name>sugar</name> </ingredient> <ingredient> <name>salt</name> </ingredient> <ingredient> <name>pepper</name> </ingredient> <ingredient> <name>parsley</name> </ingredient> <ingredient> <name>basil</name> </ingredient> </ingredients> </item>
Once you are familiar with the structure of your XML, you can create two data sets that youll use to display data in master/detail dynamic regions. In the following example, a master dynamic region displays data from the data set dsSpecials, and a detail dynamic region displays data from the data set dsIngredients:
<head> . . . <script type="text/javascript" src="../includes/xpath.js"></script> <script type="text/javascript" src="../includes/SpryData.js"></script> <script type="text/javascript"> <!--Create two separate data sets--> var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item"); var dsIngredients = new Spry.Data.XMLDataSet("data/{dsSpecials::url}", "item/ingredients/ingredient"); </script> </head> . . . <body> <!--Create a master dynamic region--> <div id="Specials_DIV" spry:region="dsSpecials"> <table id="Specials_Table"> <tr> <th>Item</th> <th>Description</th> <th>Price</th> </tr> <!--User clicks to reset the current row in the data set--> <tr spry:repeat="dsSpecials" onclick="dsSpecials.setCurrentRow('{ds_RowID}')">
15
<td>{item}</td> <td>{description}</td> <td>{price}</td> </tr> </table> </div> <!--Create the detail dynamic region--> <div id="Specials_Detail_DIV" spry:region="dsIngredients"> <table id="Specials_Detail_Table"> <tr> <th>Ingredients</th> </tr> <tr spry:repeat=dsIngredients> <td>{name}</td> </tr> </table> </div> . . . </body>
In the example, the third <script> block contains the statement that creates two data sets, one called dsSpecials and one called dsIngredients:
var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item"); var dsIngredients = new Spry.Data.XMLDataSet("data/{dsSpecials::url}", "item/ingredients/ingredient");
The url for the second data set, dsIngredients, contains a data reference ({dsSpecials::url}) to the first data set, dsSpecials. More specifically, it contains a data reference to the url column in the dsSpecials data set. When the url or XPath argument in the constructor that creates a data set contains a reference to another data set, that data set (the data set being created) automatically becomes an observer of the data set its referencing. As such, the new data set is dependent on the original data set, and reloads its data or reapplies its XPath whenever the data or current row changes in the original data set. In the example, the act of changing the current row in the dsSpecials data set sends a notification to the dsIngredients data set that it also needs to change. Because each row of the dsSpecials data set contains a distinct URL in the url column, the dsIngredients data set must update to include the correct URL for the selected row.
16
By default, the dsIngredients data set (whose data is displayed in the detail region) is created using the data it obtains from the URL specified in the constructorin this case a reference to the data in the url column of the dsSpecials data set. The default current row in the dsSpecials data set (the first row) contains a unique path to the summersalad.xml file, and thus the detail region displays the information from that file when the page loads in a browser. When the current row of the dsSpecials data set changes, however, the URL also changesto salmon.xml for exampleand the dsIngredients data set (and by association, the detail dynamic region) updates accordingly. This process is functionally equivalent to the one illustrated in Anatomy of the Spry basic master/detail dynamic region on page 11, the technical difference being that in this case the second (or detail) data set is listening for data and row changes in the master data set, whereas in the basic example, the detail region is listening for data and row changes in the master data set. It should also be noted that in the example code, spry:region is used for the detail region instead of spry:detailregion. As outlined in the previous section, the difference between a spry:region and a spry:detailregion is that the spry:detailregion specifically listens for CurrentRowChange notifications (in addition to DataChanged notifications) from the data set, and updates itself when it receives one. Because the current row of the dsIngredients data set never changes (its the current row of the dsSpecials data set that changes), there is no need to use a spry:detailregion attribute. In this case, the spry:region attribute, which defines a region that only listens for DataChanged notifications, suffices.
To prepare your files on page 18 To create a Spry data set on page 19 To display data from a Spry data set on page 21 Sample code: Spry data set and dynamic region on page 23 To sort a Spry data set on page 24 To create basic master/detail dynamic regions on page 26 To create master/detail dynamic regions that rely on more than one data set on page 28
17
Locate the Spry_P1_1_06-08.zip file on the Labs website. Download and unzip the Spry_P1_1_06-08.zip file to your hard drive. Open the unzipped Spry_P1_1_06-08 folder and locate the includes folder. This folder contains the xpath.js and SpryData.js files necessary for running the Spry framework. Copy the includes folder and either paste or drag a copy of it to the root directory of your web site.
If you drag the original includes folder out of the unzipped Spry_P1_1_06-08 folder, the demos in the Spry_P1_1_06-08 folder wont work properly.
N OT E
5.
In Code view (View > Code) link the Spry data library files to your web page by inserting the following script tags within the pages head tag:
<script type="text/javascript" src="includes/xpath.js"></script> <script type="text/javascript" src="includes/SpryData.js"></script>
The SpryData.js file is dependent on the xpath.js file, so its important that the xpath.js file come first in your code. Once youve linked the Spry data library, you are ready to create a Spry data set. For instructions, see To create a Spry data set on page 19.
6.
Add the Spry name space declaration to the HTML tag so that the HTML tag looks as follows:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:spry="http:// ns.adobe.com/spry/">
The Spry name space declaration is necessary if you want to validate your code.
Spry features will work locally as long as the Spry data library files are linked to your HTML page. When you want to publish the HTML page to a live server, however, youll need to upload the xpath.js and SpryData.js files as dependent files.
N OT E 18
Open a new or existing HTML page. Make sure that youve linked the Spry data library files to the page. For more information, see To prepare your files on page 18. Locate the XML source for the data set. For example, you might want to use an XML file called cafetownsend.xml located in a folder called data in the sites root folder: data/cafetownsend.xml You could also specify a URL to an XML file, as follows: http://www.somesite.com/somefolder/cafetownsend.xml
The URL you decide to use (whether absolute or relative) is subject to the browsers security model, which means that you can only load data from an XML source that is on the same server domain as the HTML page youre linking from. You can get around this limitation by providing a cross-domain service script. For more information, consult your server administrator.
NO T E
4.
Because youll need to specify the repeating XML node that supplies data to the data set, make sure you understand the structure of the XML before you create the data set. In the following example, the cafetownsend.xml file consists of a parent node called specials that contains a repeating child node called menu_item.
<?xml version="1.0" encoding="UTF-8"?> <specials> <menu_item id="1"> <item>Summer Salad</item> <description>organic butter lettuce with apples, blood oranges, gorgonzola, and raspberry vinaigrette.</description> <price>7</price> </menu_item> <menu_item id="2"> <item>Thai Noodle Salad</item> <description>lightly sauteed in sesame oil with baby bok choi, portobello mushrooms, and scallions.</description> <price>8</price> </menu_item> <menu_item id="3"> <item>Grilled Pacific Salmon</item> <description>served with new potatoes, diced beets, Italian parlsey, and lemon zest.</description> <price>16</price> </menu_item> </specials>
19
5.
Create the data set by inserting the following script block after the script tags importing the library:
<script type="text/javascript"> var datasetName = new Spry.Data.XMLDataSet("XMLsource", "XPathToRepeatingChildNode"); </script>
In the Cafe Townsend example, you would create a data set with the following statement:
var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item");
The statement creates a new data set called dsSpecials that retrieves data from the specials/ menu_item node in the specified XML file. The data set will have a row for each menu item and the following columns: @id, item, description, and price. The table can be visualized as follows:
@id
1
item
Summer salad
description
organic butter lettuce with apples, blood oranges, gorgonzola, and raspberry vinaigrette. lightly sauteed in sesame oil with baby bok choi, portobello mushrooms, and scallions. served with new potatoes, diced beets, Italian parlsey, and lemon zest.
price
7
16
You can also specify a URL as the source of the XML data, as follows:
var dsSpecials = new Spry.Data.XMLDataSet("http://www.somesite.com/ somefolder/cafetownsend.xml", "specials/menu_item"); The URL you decide to use (whether absolute or relative) is subject to the browsers security model, which means that you can only load data from an XML source that is on the same server domain as the HTML page youre linking from. You can get around this limitation by providing a cross-domain service script. For more information, consult your server administrator.
N OT E 20
... </head> 6.
(Optional) If the values in your data set include numbers (as in this example) youll want to reset the column types for the columns that contain those numerical values. This becomes important later if you want to sort data. You set column types by adding a data set method called setColumnType to the head tag of your document, after youve created the data set, as follows (in bold):
<script type="text/javascript"> var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item"); dsSpecials.setColumnType("price", "number"); </script>
In the example, the expression calls the setColumnType method on the data set object called dsSpecials, which youve already defined. The setColumnType method takes two parameters: the name of the data set column to re-type ("price") and the desired data type ("number"). For more information, see To sort a Spry data set on page 24. Once youve created the data set, your next step is to create a dynamic region so that you can display the data. For instructions, see To display data from a Spry data set on page 21. Related topics Sample code: Spry data set and dynamic region on page 23
In Code view, create a Spry dynamic region by adding the spry:region attribute to the tag that will contain the region. The attribute uses the syntax
spry:region="datasetName". Most, but not all, HTML elements can act as containers for dynamic regions. For more information, see Anatomy of the Spry dynamic region on page 9.
N O TE
For example, if you are going to use a div tag as the container for the dynamic region displaying data from the dsSpecials data set, you would add the spry:region attribute to the tag as follows:
21
<div id="Specials_DIV" spry:region="dsSpecials"> </div> Dynamic regions can depend on more than one data set. You can add more data sets to the region by listing them as additional values of the spry:region attribute, separated by a space. For example, you could create a dynamic region using spry:region="dsSpecials dsSpecials2 dsSpecials3".
N OT E
2.
Within the tag containing the dynamic region (this example uses a div tag), insert an HTML element to display the first row of the data set. You can use any HTML element to display data. One of the most typical elements used for this purpose, however, is a two-row HTML table, where the first row contains static column headings and the second row contains the data:
<table id="Specials_Table"> <tr> <th>Item</th> <th>Description</th> <th>Price</th> </tr> <tr spry:repeat="dsSpecials"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr> </table>
The values in curly braces in the second row specify columns in the data set. The curly braces bind the table cells to data in specific columns of the data set.
If the Spry region depends on more than one data set, you must specify the data set to which youre binding the dynamic region. The full syntax takes the form of {datasetName::columnName}. For example, if you wanted to bind the dynamic region to two or three different data sets, you would need to enter the data in the above example as follows: {dsSpecials::item}, {dsSpecials::description}, and so forth.
N OT E
3.
Make the HTML element repeat automatically to display all the rows of the data set by adding the spry:repeat attribute and value to the HTML element tag in the form of:
spry:repeat="datasetName"
In the example, you would add the spry:repeat attribute to the table row tag as follows (in bold):
<tr spry:repeat="dsSpecials"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr>
22
In the example, the completed code binding the dynamic region to the data set would look as follows:
<div id="Specials_DIV" spry:region="dsSpecials"> <table id="Specials_Table"> <tr> <th>Item</th> <th>Description</th> <th>Price</th> </tr> <tr spry:repeat="dsSpecials"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr> </table> </div> 4.
If you want, you can make the dynamic region more interactive by defining click events that allow users to sort data. For instructions, see To sort a Spry data set on page 24.
Related topics Sample code: Spry data set and dynamic region on page 23
23
<tr spry:repeat="dsSpecials"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr> </table> </div> ... </body>
Locate the place in the code where you want to add the onclick handlers. In this example, well be adding the onclick handlers to two column headers in a table that displays the XML data. Add an onclick handler with a sort method to the appropriate column header tags in the form of
onclick="datasetName.sort(columnName);"
2.
The value defined in the sort method tells the data set which column to use when sorting the data. For example, adding the following onclick handlers (in bold) to column header tags causes the dynamic region to sort the data according to the specified value whenever the user clicks a column header on the page.
<div id="Specials_DIV" spry:region="dsSpecials"> <table id="Specials_Table" class="main"> <tr> <th onclick="dsSpecials.sort(item);">Item</th> <th onclick="dsSpecials.sort(description);">Description</th> <th>Price</th> </tr> <tr spry:repeat="dsSpecials"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr>
24
</table> </div>
Clicking Item on the page sorts the data alphabetically according to the menu item name, and clicking Description on the page sorts the data alphabetically according to the menu items description.
Numerical sorting
By default all data in the data set (including numbers) is considered text, and sorts alphabetically. To sort numerically (for example, to sort by price of menu item), you can use the data set method called setColumnType to change the data type of the price column from text to numbers. The method takes the form:
datasetName.setColumnType("columnName", "number");
Using the above example, you would add the setColumnType method to the head tag of your document, after youve created the data set (in bold):
<script type="text/javascript"> var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item"); dsSpecials.setColumnType("price", "number"); </script>
The expression calls the setColumnType method on the data set object called dsSpecials, which youve already defined. The setColumnType method takes two parameters: the name of the data set column to re-type ("price") and the desired data type ("number"). You can now add the onclick handler to the price column so that all three columns in the HTML table are sortable when the user clicks any of the table headers:
<div id="Specials_DIV" spry:region="dsSpecials"> <table id="Specials_Table" class="main"> <tr> <th onclick="dsSpecials.sort(item);">Item</th> <th onclick="dsSpecials.sort(description);">Description</th> <th onclick="dsSpecials.sort(price);">Price</th> </tr> <tr spry:repeat="dsSpecials"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr> </table> </div>
25
Create a data set. See To create a Spry data set on page 19. Create the master region by adding the spry:region attribute to the HTML element that will act as the container tag for the region. See To display data from a Spry data set on page 21. In the following example, a master dynamic region displays repeated data from the data set dsSpecials:
<head> . . . <script type="text/javascript" src="../includes/xpath.js"></script> <script type="text/javascript" src="../includes/SpryData.js"></script> <script type="text/javascript"> var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item");</script> </head> . . . <body> <div id="Specials_DIV" spry:region="dsSpecials"> <table id="Specials_Table"> <tr> <th>Item</th> <th>Description</th> <th>Price</th> </tr> <tr spry:repeat="dsSpecials"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr> </table> </div> </body>
3.
Add event handlers that will allow users to change the current row in the data set. In the following example, an onclick event handler (in bold) changes the current row in the data set whenever a user clicks a row in the master region table:
<tr spry:repeat="dsSpecials" onclick="dsSpecials.setCurrentRow('{ds_RowID}')"> <td>{item}</td>
26
The {ds_RowID} data reference used in the example is a built-in part of the Spry framework that points to an automatically-generated unique ID for each row in the data set. (See Anatomy of the Spry data set on page 6.) When the user selects a row in the master region table, the onclick event handler supplies the unique ID to the setCurrentRow method, which causes the resetting of the current row in the data set.
4.
Create the detail dynamic region on the page by adding the spry:detailregion attribute to the tag that will contain the region. The attribute uses the syntax
spry:detailregion="datasetName".
In the following example, a div tag contains the detail dynamic region:
<div id="Specials_Detail_DIV" spry:detailregion="dsSpecials"> </div> 5.
Within the tag containing the detail dynamic region, insert an HTML element to display the detail data from the current row of the data set. In the example, an HTML table displays detail data from the {ingredients} column and {calories} column in the dsSpecials data set.
<div id="Specials_Detail_DIV" spry:detailregion="dsSpecials"> <table id="Specials_Detail_Table"> <tr> <th>Ingredients</th> <th>Calories</th> </tr> <tr> <td>{ingredients}</td> <td>{calories}</td> </tr> </table> </div>
The completed example code binding both the master and detail dynamic regions to the dsSpecials data set would look as follows:
<div id="Specials_DIV" spry:region="dsSpecials"> <table id="Specials_Table"> <tr> <th>Item</th> <th>Description</th> <th>Price</th> </tr> <tr spry:repeat="dsSpecials" onclick="dsSpecials.setCurrentRow('{ds_RowID}')"> <td>{item}</td> <td>{description}</td>
27
<td>{price}</td> </tr> </table> </div> <div id="Specials_Detail_DIV" spry:detailregion="dsSpecials"> <table id="Specials_Detail_Table"> <tr> <th>Ingredients</th> <th>Calories</th> </tr> <tr> <td>{ingredients}</td> <td>{calories}</td> </tr> </table> </div>
To create master/detail dynamic regions that rely on more than one data set
You can create master/detail relationships that involve more than one data set. For an overview of how such relationships work, see Anatomy of master/detail dynamic regions that depend on more than one data set on page 13.
1. 2. 3.
Familiarize yourself with the structure of the XML files used in creating the data set. Youll need to understand the structure in order to make one data set depend on another. Create a data set by adding the appropriate code to the head of your document. (See To create a Spry data set on page 19.) This will be the master data set. Create a second data set (the detail data set) immediately following the master data set you just created. The URL or XPath in the constructor of the detail data set contains a data reference to one or more of the columns in the master data set. The data reference is in the form {MasterDatasetName::columnName}. In the following example, the third <script> block contains the statement that creates two data sets, one called dsSpecials (the master) and one called dsIngredients (the detail):
<head> . . . <script type="text/javascript" src="../includes/xpath.js"></script> <script type="text/javascript" src="../includes/SpryData.js"></script> <script type="text/javascript"> var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item"); var dsIngredients = new Spry.Data.XMLDataSet("data/ {dsSpecials::url}", "item/ingredients/ingredient");
28
</script> </head>
The path to the XML file for the detail data set, dsIngredients, contains a data reference ({dsSpecials::url}) to the master data set, dsSpecials. More specifically, it contains a data reference to the url column in the dsSpecials data set. When the url or XPath argument in the constructor that creates a data set contains a reference to another data set, that data set (the data set being created) automatically becomes an observer of the data set its referencing.
4.
Create the master region by adding the spry:region attribute to the HTML element that will act as the container tag for the region. See To display data from a Spry data set on page 21. In the following example, a master dynamic region displays repeated data from the data set dsSpecials:
<body> <div id="Specials_DIV" spry:region="dsSpecials"> <table id="Specials_Table"> <tr> <th>Item</th> <th>Description</th> <th>Price</th> </tr> <tr spry:repeat="dsSpecials"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr> </table> </div> </body>
5.
Add event handlers that will allow users to change the current row in the master data set. In the following example, an onclick event handler (in bold) changes the current row in the dsSpecials data set whenever a user clicks a row in the master region table:
<tr spry:repeat="dsSpecials" onclick="dsSpecials.setCurrentRow('{ds_RowID}')"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr>
29
The {ds_RowID} data reference used in the example is a built-in part of the Spry framework that points to an automatically-generated unique ID for each row in the data set. (See Anatomy of the Spry data set on page 6.) When the user selects a row in the master region table, the onclick event handler supplies the unique ID to the setCurrentRow method, which causes the resetting of the current row in the data set.
6.
Create the detail dynamic region on the page by adding the spry:region attribute to the tag that will contain the region. The attribute uses the syntax
spry:region="datasetName". When creating master/detail relationships using two or more data sets, it is not necessary to use the spry:detailregion attribute as is outlined in To create basic master/detail dynamic regions on page 26. Because the current row of the detail data set never changes (its the current row of the master data set that changes), the spry:region attribute suffices. For more information, see Anatomy of master/ detail dynamic regions that depend on more than one data set on page 13.
N OT E
In the following example, a div tag contains the detail dynamic region:
<div id="Specials_Detail_DIV" spry:region="dsSpecials"> </div> 7.
Within the tag containing the detail dynamic region, insert an HTML element to display the detail data from the current row of the master data set. In the example, an HTML table displays detail data from the {name} column in the dsIngredients data set. The dsIngredients data set creates the {name} column based on the information it receives from the dsSpecials data set.
<div id="Specials_Detail_DIV" spry:region="dsIngredients"> <table id="Specials_Detail_Table"> <tr> <th>Ingredients</th> </tr> <tr spry:repeat=dsIngredients> <td>{name}</td> </tr> </table> </div>
The completed example code binding the master region to the dsSpecials data set, and detail region to the dsIngredients data set, would look as follows:
<head> . . . <script type="text/javascript" src="../includes/xpath.js"></script> <script type="text/javascript" src="../includes/SpryData.js"></script> <script type="text/javascript"> var dsSpecials = new Spry.Data.XMLDataSet("data/cafetownsend.xml", "specials/menu_item");
30
var dsIngredients = new Spry.Data.XMLDataSet("data/{dsSpecials::url}", "item/ingredients/ingredient"); </script> </head> . . . <body> <div id="Specials_DIV" spry:region="dsSpecials"> <table id="Specials_Table"> <tr> <th>Item</th> <th>Description</th> <th>Price</th> </tr> <tr spry:repeat="dsSpecials" onclick="dsSpecials.setCurrentRow('{ds_RowID}')"> <td>{item}</td> <td>{description}</td> <td>{price}</td> </tr> </table> </div> <div id="Specials_Detail_DIV" spry:region="dsIngredients"> <table id="Specials_Detail_Table"> <tr> <th>Ingredients</th> </tr> <tr spry:repeat=dsIngredients> <td>{name}</td> </tr> </table> </div> . . . </body>
31
32