### Spry Primer

Spry is an easy-to-use Ajax toolkit, made for designers and developers both. While it is simple to get started, there are a few concepts that, once familiar with, will make building Spry page easy.

This document will outline the high level concepts of Spry and link to more detailed information and samples.

#### Goals of Spry

Spry was started because most other Ajax frameworks out there can be quite complex; hard to get started, many dependent files and markup injection, making it hard to style and edit. We thought there was an easier way.

Spry leverages what you already know: HTML and CSS and some javascript, and uses custom attributes or small constructor scripts, to activate the functionality. The framework does most of the heavy lifting.

We try make sure that it is easy to customize. We provide simple CSS with clear class name as hooks for customization. If you want to set the size of the accordion, just set the width on the class, as you would normally set the width, or any other property, of an element.

An important idea for Spry is to not inject markup. This means that all the HTML code that is needed is actually on the page, not buried within a <script> tag. This makes it easy to figure out the generated code and it makes the HTML easy to edit and style.

#### The 3 Parts of Spry

Spry consists of 3 main parts:

- Data - Using XML, JSON or HTML data to populate the page.
- Widgets - Advanced page functionality using simple markup. Accordion and Sliding Panels are examples of widgets.
- Effects - Add polish to the page by moving, showing and hiding elements on the page. Slide and Fade are examples of Effects.

### Data

Spry Data was the first piece of Spry to be released and it is probably the most powerful part of the framework. It has two main concepts:

1. Retreiving the data.
2. Using the data on the page.

#### Pulling in the Data

First, to use Spry Data, you need to attach the core Spry javascript files to your page. The exact files you will need depend on the data source type, but all data sets use SpryData.js. These files are in the 'includes' folder in the Spry zip.

Spry has the concept of a 'data set'. This is data pulled in from XML, JSON or HTML files and converted into a table (a javascript object), with rows and columns, like a database table. The end result of the data set is the same, no matter what the data type is.

To this data set, you can specify some attributes or behaviors. By default, Spry downloads the data file, XML for instance, once and uses that to build the data set. We cache that data: If you want to get new data from the server directly, you can turn off the cache and tell Spry to get new data every 5 seconds, for example. These can be set as options in the constructor. The constructor is the script where the data set is defined.

A basic data set constructor looks like

    <script>
       var ds1 = new Spry.Data.XMLDataSet("folder/products.xml","products/product");
    </script>

where the first value is simply the path to the XML source. The second value is the XPath into the XML file. This defines where you want to start pulling in data. XPath is explained well here.

The var name 'ds1' is the data set name and it is used in many places within a standard Spry page.

Any of our Data samples will have a data set defined.

You can have multiple data sets on a page. These data sets can depend on other data sets. Data set types can be mixed: you can have one XML data set and one JSON data set, for example.

If your are using XML as your data source, this can come from a XML file, or any file that generates XML. This can be Coldfusion, PHP or anything else that generates valid XML; Spry doesn't care where the data comes from.

Once the data set is created, it can be used on the page.

#### Spry Regions

The second half of the Spry data concept are Spry regions. Spry regions are elements on the page where Spry processing happens. These elements are denoted by custom attributes applied to elements on the page.

A basic Spry region looks like <div spry:region="datasetname"></div>. Spry regions can be used with most HTML tags.

This custom attribute tells Spry to look within this <div> for things to process. There are 2 things to process:

1. Other spry attributes
2. Data references.

There are Spry attributes for logical processing, things like 'spry:if' and 'spry:when'. There are also Spry attributes for behavioral things like 'spry:hover' which applies a CSS class to the element when the user mouses over the element.

Data references are used to add the data set data to the page. These are placeholders for the real data. A data reference is the data node name, wrapped in curly braces {}. For example, with this XML as a data set:

    <products>
        <product id="1">
           <name>Photoshop</name>
           <category>Digital Imaging</category>
        </product>
    </products>

Our data references are the node names wrapped in curly braces, therefore, we would have Spry code that looks like:

There is a spry:region because all Spry processing happens within a spry:region. Then we have the data references within the region. When the page is loaded in the browser, the output would be the first values in the XML file:

    Photoshop
    1
    Digital Imaging

So the most basic Spry data page would look like:

    <html xmlns="http://www.w3.org/1999/xhtml">
       <head>
       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
       <title>Spry Page</title>
       <script src="SpryAssets/xpath.js" type="text/javascript"></script>
       <script src="SpryAssets/SpryData.js" type="text/javascript"></script>
       <script type="text/javascript">
       var ds1 = new Spry.Data.XMLDataSet("data/adobe_products.xml", "products/product");
       </script>
       </head>
       <body>
       <div spry:region="ds1"> {ds1::name}</div>
       </body>
     </html>

A note here about data references. Notice in the example above, it is written {ds1::name}. This is the formal way of writing data references. In a scenario where you have multiple data sets, there might be more than one {name} column. Prepending the node name with the data set name and 2 colons is used to specify the data set it comes from.

If you want to use multiple data sets in one region, simply add the data set names to the spry:region attribute, separated by a space. The Master Detail sample uses 2 data sets.

    <div spry:region="ds1 ds2">
    {name}{ds2::name}
    </div>

In this case, 'ds1' is listed first. That means you can use either the short or the formal data references for that data set. Any other data sets listed in the region must use the formal data reference form.

We mentioned above that you can have data sets from XML, JSON or HTML. The region part of the page does not care where that data comes from. The data references are all written the same way, regardless of the data source. All the spry:attributes work the same way, no matter what the data set is.

There are other Spry attribute for controlling the look and the flow of the page. For instance, a common Spry attribute is 'spry:if'. This is used to determine whether to show a part of the page, depending on a condition. A sample:

    <div spry:region="ds1 ds2">
       <span spry:if="{name} == 'Photoshop'">{name}{ds2::name}</span>
     </div>

The value of the spry:if attribute is a javascript expression that equals 0 or 1 (true or false). Above, we are checking to see if the value of the {name} data rerefence is 'Photoshop'. If it is, that <span> would be printed on the page. If it is not equal, that <span> would not be displayed.

There are also attributes like 'spry:hover'. This applies the specified class name to the element when the mouse is over the element.

    <style>
    .redBG{background-color:red;}
    </style>

    ...

    <div spry:region="ds1 ds2">
       <span spry:hover="redBG">{name}</span>
     </div>

When the mouse is over the <span> tag, the 'redBG' class will be applied and turn the background color to red. When the mouse leaves the <span> the class will be removed.

With a combination of Spry attributes and data references, a high degree of control can be used on the page with a small amount of markup.

#### Learn more about Spry Data

The Data Set Overview describes in detail the flattening/XPath idea, advanced data set options and region concepts. A good read for learning Spry concepts.

The Dynamic Table document goes over building a basic Spry table.

See the Data/Region samples.

Read the XML Primer. This describes the basic concepts of XML.

Read the JSON Primer. The JSON data set overview.

The HTML data set overview. Describes how to use HTML tables as data sets.

The Data API describes all the features of the data capabilities.

### Spry Widgets

Spry widgets are pieces of advanced page functionality encapsulated in regular HTML markup. Many are familiar with Accordions and Tabbed Panels. Spry also has widget like Sliding Panels and Collapsible Panels.

We refer to these as 'disclosure widgets', because content is hidden and 'disclosed' as users click into other panels. We also have form validation widgets like Checkbox and Text Field validation.

#### Widget Philosophy

The idea behind Spry widgets is that the widget structure is defined in HTML on the page. Then a small constructor script is used to convert that markup into the functioning widget.

For instance, the Collapsible Panel markup is the most basic:

    <div id="CollapsiblePanel1" class="CollapsiblePanel">
      <div class="CollapsiblePanelTab" tabindex="0">Tab</div>
      <div class="CollapsiblePanelContent">Content</div>
    </div>
     <script type="text/javascript">
         var CP1 = new Spry.Widget.CollapsiblePanel("CollapsiblePanel1");

     </script>

Widgets have a container tag around them which defines for Spry where the widget begins and ends. These container tags have an ID defined that Spry uses to identify the widget markup.

For the Collapsible Panel, there is a tag for the tab and a tag for the content panel. Within these structure tags, you can put in any HTML you wish. Spry just needs to have that main structure correct.

The constructor script comes after the widget markup. This is because that markup needs to exist before Spry executes the script to create the widget.

The constructor defines a variable for the widget name ("CP1"). We then pass the ID of the widget container to the constructor ("CollapsiblePanel1").

We can set options for the widget (for Data, Widgets and Effects) by adding the options to the constructor. The syntax is ,{option:value, option:value}. For instance, instead of having the Collapsible Panel smoothly open and close, we can turn off the animation by passing an option in the constructor.

     <script type="text/javascript">
       var CP1 = new Spry.Widget.CollapsiblePanel("CollapsiblePanel1",{enableAnimation:false});
     </script>

Most widgets have behaviors defined that allow control of the widget from other parts of the page. For instance, we can create a text link that will open or close a Collapsible Panel.

    <a href="#" onclick="CP1.open();">Open the Panel</a>
    <a href="#" onclick="CP1.close();">Close the Panel</a>

Most widgets will have a number of functions for these sorts of operations, depending on the complexity of the widget.

#### Learn More about Widgets

The Widget Model document describes in more detail the widget ideas presented here.

Each widget has an overview document. See them here.

### Effects

Effects are combinations of javascript and CSS that cause page elements to change appearance, size or position. See the Effects demo for a sample of each Effect.

All the effects are contained within the SpryEffects.js file. This file should be included on your page if you want to use the effects.

Effects work by first defining the effect as a javascript object. Then add functions to your page to start or stop the effect. A simple effect looks like:

    <div id="fadeMe">Fading...</div>
    <a href="#" onclick="myEffect.start();">Fade it</a>

    <script>
    var myEffect = new Spry.Effect.Fade("fadeMe",{from:100, to:0, duration:1000, toggle:true});
    </script>

Note that again, the constructor scripts come after the markup.
Here we define an Effect called 'myEffect'. This is the name we use to control the effect. In the constructor, we specify the ID of the element we will fade: "fadeMe". We then list the options:

- from: the starting opacity
- to: the final opacity
- duration: how long to complete the effect, in milliseconds.
- toggle: Tells the effect to reverse when clicking the link again.

In the <a> we call the 'start' method that starts the effect: onclick="myEffect.start();".

The effects list contains base effects and combination effects. Base effects are simple animators: Move, Size, Opacity or Color. All other effects, like Puff, are combinations of these base effects.

For more advanced effects, there are Cluster effects. Users can take our base effects and combine them into groups. These groups can be run in parallel or in sequence. The demo has 2 examples.

#### Learn More about Effects

The Effects Coding document describes each effect and all their options.

### Advanced Spry

Spry can do more than what is described here.

We have functions for:

- Submitting forms via Ajax
- Session Timeout
- URL Utilities
- HTML Data sets
- Converting database queries to XML

and more...

### Getting started with Spry

Hopefully this document as explained the basics of Spry. To get into the code, check these resources.

- Spry Documentation
- Spry Samples are a great way to see simple Spry code.
- Spry Demos show Spry in more complex situations.
- The Data files are kept in the 'includes' folder.
- The widget files are kept in the 'widgets' folder, along with reference files.
- The 'data' folder has XML and JSON data files.

Copyright Adobe Systems Inc, 2007.