## SPRY Data API

### addObserver

#### Description

Adds a function or object as an observer of a region.

Object observers must define a function property for every notification they are interested in receiving. Each notification function will be called with two arguments, the first is the object dispatching the notification, and the 2nd argument is data that may contain more information about the notification. The data argument is optional, so its value may be undefined/null for some notifications.

Function observers get called for *all* notifications. Function observers will be called with 3 arguments. The first argument is the notification type, which is a string that is the name of the notification. For example "onPostUpdate". The 2nd argument is the object dispatching the notification. The 3rd argument is the optional data for the notfication.

#### Format

Spry.Data.Region.addObserver("id", obj);

-- or --

Spry.Data.Region.addObserver("id", function);

#### Arguments

- id- The id of the region being observed.
- function or object to be notified.

#### Returns

N/A

#### Example

    /* Adding an object as an observer. */

    var observer = { onPostUpdate: function(notifier, data) { var acc = new Spry.Widget.Accordion("Acc1"); } };

    Spry.Data.Region.addObserver("Acc1", observer);

    /* Adding a funtion as an observer. */

    function MyObserverFunc(notificationType, notifier, data)
    {
    	if (notificationType != "onPostUpdate")
    		return;
    	var acc = new Spry.Widget.Accordion("Acc1");
    }

    Spry.Data.Region.addObserver("Acc1", myObserverFunc);

#### Sample

Region Observer Sample

### cancelLoadData

ds1.cancelLoadData()

#### Description

This function cancels the loading of the data set data. This is will interrupt any requests made by the loadData() function.

#### Format

datasetname.cancelLoadData();

#### Example

    <a onclick="ds1.cancelLoadData();">

### distinct

datasetname.distinct(column)

#### Description

This function is used to remove duplicate rows from the data set. Spry will evaluate all the columns and if it finds 2 or more rows where every value is the same, it will throw away the duplicate rows and keep only one. This function can only be called *after* the data is already loaded into the data set.

Distinct can also be run automatically whenever new data is loaded into the data set. This is done by specifying the distinctOnLoad constructor option. In case the distinct functionality is need only for specific column(s) they may be defined through the additional parameter distinctFieldsOnLoad

#### Arguments

column - the column(s) of the data set to filter distinct. This parameter is optional.

#### Format

datasetname.distinct(["field1", "field2"]);

#### Example

    /* After a data set is defined and loaded with data, you can call
     * distinct on it.
     */

    var ds1 = Spry.Data.XMLDataSet("xml.xml","xpath");
    ...
    ds1.distinct();

    /* Run distinct automatically whenever data is loaded. */
    var ds2 = Spry.Data.XMLDataSet("xml.xml","xpath", {distinctOnLoad: true, distinctFieldsOnLoad:['fld1', 'fld2']});

### filter

datasetname.filter()

#### Description

This function is used to filter the data set based on a filter function. Filter is a non-destructive method, meaning that Spry creates a filtered array of data and uses that as the outputted data set, as long as the filter function does not change the actual data.

The filter can be removed by passing 'null' to the function.

FilterData is the destructive filter, which actually throws out the filtered data from memory.

#### Format

datasetname.filter(filterFunction);

#### Example

    var myFilterFunc = function(dataSet, row, rowNumber)
    {
    	if (row["@path"].search(/^s/) != -1)
    		return row;                     // Return the row to keep it in the data set.
    	return null;                        // Return null to remove the row from the data set.
    }

    dsPhotos.filter(myFilterFunc);
    //Remove the filter
    dsPhotos.filter(null);

#### Sample

Non Destructive Filtering

### filterData

datasetname.filterData()

#### Description

This function is used to filter the data set based on a filter function. FilterData is a destructive method, meaning that Spry gets rid of the data from memory. The data can only be retrieved again by loading the data set again: loadData()

Filter is the non-destructive filter option.

#### Format

datasetname.filterData(filterFunction);

#### Example

    var myFilterFunc = function(dataSet, row, rowNumber)
    {
    	if (row["@path"].search(/^s/) != -1)
    		return row;                     // Return the row to keep it in the data set.
    	return null;                        // Return null to remove the row from the data set.
    }
    dsPhotos.filterData(myFilterFunc);
    //Remove the filter
    dsPhotos.filter(null);

#### Samples

XPath Filtering Sample

### getColumnType

datasetname.getColumnType(column);

#### Description

This function returns the column type of the specified column.

#### Returns

The column type of the specified column, as a string:

- "string"
- "number"
- "date"

#### Example

    var colType = ds1.getColumnType("names");

### getCurrentRow

datasetname.getCurrentRow();

#### Description

This function returns the object that is the 'currentRow' in the data set. By default, the current row is the first row of the data set, but this can be changed by calling the function setCurrentRow() and passing it the ds_RowID of the row.

#### Arguments

N/A

#### Returns

The row object or null.

#### Example

    var row = ds1.getCurrentRow();

    if (row["@title"] == "Me, Myself and I")
    ...

### getData

datasetname.getData();

#### Description

This function returns an array of the internal row objects that store the data in the data set. Modifying any property of a row object results in a modification of the data in the data set. Users should keep in mind that some data sets load their data asynchronously, so they should check if it is ok to access the data, with a call to getDataWasLoaded(), before attempting to call getData().

#### Arguments

unfiltered - Optional argument. If true, getData() returns all of its data. If false, it returns the rows that are not filtered.

#### Returns

The data in the data set.

#### Example

    var rows = ds1.getData();
    for (var i = 0; i < rows.length; i++)
    {
    	if (rows[i]["name"] == "Spry")
    		return rows[i]["ds_RowID"];
    }

### getDataWasLoaded

datasetname.getDataWasLoaded();

#### Description

This function returns 'true' if a data set successfully loaded its data. If this function returns true, it is safe to access and manipulate the data set. This function will return false if a load request is pending, or an error ocurred while trying to load the data.

#### Arguments

N/A

#### Returns

true/false

#### Example

    if (ds1.getDataWasLoaded())
    {
    	var rows = ds1.getData();
    	for (var i = 0; i < rows.length; i++)
    	{
    		if (rows[i]["name"] == "Spry")
    			return rows[i]["ds_RowID"];
    	}
    }

### getDocument

getDocument();

#### Description

This function returns the XML DOM representation of the document that was used to extract the data for the data set.

#### Arguments

N/A

#### Returns

The XML DOM document node.

### getLoadDataRequestIsPending

datasetname.getLoadDataRequestisPending();

#### Description

This method will return true if a request for data has been made and has not yet completed. Otherwise, it will return false.

#### Returns

true/false

### getRowCount

datasetname.getRowCount();

#### Description

This function returns the number of rows in the data set. If the data set has a non-destructive filter, this function returns the number of filtered rows. Users can pass an optional boolean argument to this function. If true, it will return the number of unfiltered rows. If false it will return the number of filtered rows.

#### Arguments

unfiltered - Optional argument. If true, getData() returns all of its data. If false, it returns the rows that are not filtered.

#### Returns

An integer that is the number of rows in the data set.

#### Example

    var filteredRowCount = ds1.getRowCount();
    var unfilteredRowCount = ds1.getRowCount(true);

### getRowNumber

datasetname.getRowNumber(rowObject);

#### Description

This function returns the row number for the specified row object in the data set.

#### Argument

A row object

#### Returns

An integer that is the number of the specified row in the data set.

### getSortColumn

datasetname.getSortColumn();

#### Description

This function returns the name of the column that was used when the data set was last sorted. This function will return an empty string if the data set was never sorted.

#### Returns

Data set column name that is currently being sorted, or an empty string.

#### Example

    var columnName = ds1.getSortColumn();

### getSortOrder

datasetname.getSortOrder();

#### Description

This function returns the name of the sort order that was used when the data set was last sorted. This function will return an empty string if the data set was never sorted.

#### Returns

The current sort order of the data set:

- "ascending"
- "descending "
- ""

#### Example

    var sortOrderName = ds1.getSortOrder();

#### Sample

Sort Sample

### getUnfilteredData

datasetname.getUnfilteredData();

#### Description

This function is *DEPRECATED*. Use getData(true) instead.

### getURL

datasetname.getURL();

#### Description

This function returns the URL that will be used to load the data for the data set. The URL can be set programmatically with setURL().

#### Returns

A string that is the current URL of the data set.

#### Example

    var url = ds1.getURL();

### getXPath

datasetname.getXPath();

#### Description

This function returns the XPath that will be used to select the data nodes within the XML document to be flattened for the data set.. The XPath can be set programmatically with setXPath().

#### Returns

A string that is the current XPath of the data set.

#### Example

    var x = ds1.getXPath();

### loadData

datasetname.loadData();

#### Description

This function fires off an asynchronous load request for the data for the data set. This function is commonly used after calling setURL() or setXPath().

#### Arguments

N/A

#### Returns

NA

#### Example

    ds1.setURL("newXML.xml");
    ds1.loadData();"

#### Sample

Region States Sample

### removeObserver

datasetname.removeObserver(observername);

#### Description

This function will delete the observer from the list of objects that receive notifications.

#### Arguments

observername - the name of the observer that should be removed from the notification list.

#### Returns

N/A

#### Example

    dsPhotos.removeObserver(myObserver);

### setColumnType

datasetname.setColumnType(column,type);

#### Description

This function is used to set a column type for a data column. This is used to tell Spry the type of data it is dealing with. A common application is for setting numeric data as 'number'. This ensures that the column will sort numerically, and not alpha-numerically.

The 'column' value can take a column name as a string or an array of column name strings for setting multiple columns to a common type.

#### Returns

column - The data set column name(s) to be set.

type - The type of data of the column.

- "date"
- "html"
- "image"
- "number"
- "string"

The 'html' Column Type will result in the automatic entity decoding of values stored in a column of that type

#### Example

    var ds1 = new Spry.Data.XMLDataSet("myxml.xml","races/standings");
    ds1.setColumnType(["rank","place"],"number");

### setCurrentRow

datasetname.setCurrentRow(newNumber);

#### Description

This function sets the number of the 'currentRow' of the data set. Setting the currentRow causes spry:detailregions to update.

#### Arguments

newNumber - the number to update the currentRow to.

#### Example

    onClick = "ds1.setCurrentRow(3);"
    onChange = "ds1.setCurrentRow('{dsRowID}');

Note that single quotes are used when using data references in the function. This is to deal with how IE handles javascript.

#### Sample

Set Current Row sample

### setCurrentRowNumber

datasetname.setCurrentRowNumber(index);

#### Description

This function makes the row at the specified index the CurrentRow of the data set. Spry uses a zero based counting system for row numbers.

CurrentRowNumber is different than RowID. RowID is a unique, non-changing number of a specific row in the data set. RowNumber refers to the number of the row being processed. For example, in a looping construct repeating <tr>, the 3rd row written out is RowNumber 2 (zero based counting system), but the RowID of the data in RowNumber 2 may be anything.

#### Arguments

index - the number to update the CurrentRowNumber to.

#### Example

    onClick = "ds1.setCurrentRowNumber(3);"
    onChange = "ds1.setCurrentRowNumber('{dsRowID}');

Note that single quotes are used when using data references in the function. This is to deal with how IE handles javascript.

#### Sample

DataSet Master Detail Sample

### setDataFromDoc

datasetname.setDataFromDoc(docsource);

#### Description

setDataFromDoc will set a variable or a string as the source for the specified data set. For instance, with this function, a XML string can converted to a DOM object and then used for the source of the data.

#### Argument

docsource

- The XML object

#### Example

    var xmlStr = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?> \
    <employees xmlns=\"http://www.foo.com/employees\"> \
    	<employee id=\"123456\"> \
    		<lastname>Smith</lastname> \
    		<firstname>Edward</firstname> \
    		<phone>(415) 333-0235 </phone> \
    		<username>esmith</username> \
    	</employee> \
    	<employee id=\"127937\"> \
    		<lastname>Johnson</lastname> \
    		<firstname>Neil</firstname> \
    		<phone>(415) 333-9475 </phone> \
    		<username>njohnson</username> \
    	</employee> \
    </employees>";

    var dsEmployees = new Spry.Data.XMLDataSet(null, "/employees/employee");

    var xmlDOMDocument = Spry.Utils.stringToXMLDoc(xmlStr);

    dsEmployees.setDataFromDoc(xmlDOMDocument);

### setState

Spry.Data.getRegion(regionName).setState(state);

#### Description

This method allows developers to programmatically set the state of the data set. This also allows developers to get into custom states.

#### Arguments

regionName

- This ID of the region that is getting the updated state.

state

- The string that is the state to set the region to.
  - loading
  - ready
  - error

#### Returns

NA

#### Example

    function SetState(rgnState)
    {
    	for (var i = 1; i <= numRegions; i++)
    		Spry.Data.getRegion("regionID").setState(rgnState);
    }

      <input type="button" value="Ready" onclick="SetState('ready');" />

#### Sample

Region State Sample

### setURL

datasetname.setURL(url);

#### Description

This function sets the path to the XML sources used in the data set. This can be used to programmatically changing the data source of the XML data set. Setting the URL does not automatically reload the data. Use the loadData function to load the data.

#### Arguments

url

- The url argument is the new path to the XML source. This can be a hard coded path or a spry data reference.

#### Returns

NA

#### Example

    dsPhotos.setURL('galleries/{@base}{@file}');
    dsPhotos.setURL('xmlsource.xml');

### setXPath

datasetname.setXPath(xpath);

#### Description

This function sets the xpath for the XML file used in the data set. Changing the XPath doesn't automatically load the data. Use the loadData function to load the new data.

#### Arguments

xpath

- The xpath used in the XML data source file. This can be a hard coded path or a spry data reference.

#### Returns

NA

#### Example

    dsPhotos.setXPath('galleries/{@id}');
    dsPhotos.setXPath('photos/photo');

    dsPhotos.setXPath("/states/state[position() >= 30 and position() < 40]");

### sort

datasetname.sort(column,order);

#### Description

This function sets the sort order applied to the dataset. Secondary and Tertiary sorts can be applied by listing the appropriate column names.

#### Arguments

column - the column(s) of the data set to be sorted.

order - The order used on the data set.

- "ascending"
- "descending"
- "toggle"

#### Example

    var ds1 = new Spry.Data.XMLDataSet("names.xml","employees/names");
    ds1.sort("names","ascending");

    onClick="ds1.sort(["firstname", "lastname", "@id"], "toggle");" //sort by firstname, then lastname, then @id.

### Spry XML Data Set

#### Description

Data Sets are the core of the Spry Data Framework. A Spry XML data set pulls in XML data from a source and adds this data to the page via spry regions, data references and the other functions described in this document.

The Data Sets point to an XML data source. This can be an external XML file or any other file that generates valid XML. XPath is used to drill down in the XML and retrieve the desired data.

#### Basic Format

    <script type="text/javascript">
    var dsData = new Spry.Data.XMLDataSet("XML source URL", "XPath");
    </script>

#### Arguments

The basic data set requires a minimum of 2 arguments: The XML source URL and the XPath.

- XML source URL

The URL argument can be a relative or absolute URL to an XML file, or to a web service/application that returns XML data. Users need to be aware that the loading of XML data is subject to the browser's security model which requires that any data you load must come from the domain from which the HTML page currently running in the browser, came from.

By default, the data set uses the HTTP GET method when retrieving the XML data.

- XPath

This is a valid XPath into the schema of the XML source.

#### Example

    <script type="text/javascript">
    var dsData = new Spry.Data.XMLDataSet("source.xml", "/employees/home_office/finance");
    </script>

    <script type="text/javascript">
    var dsData = new Spry.Data.XMLDataSet("source.php?office=home&dept=finance", "/employees/home_office/@finance/");
    </script>

#### Optional Arguments

useCache- By default, the XML data is cached on the client. This data cache is used when the data set is filtered, sorted or reloaded. Using an optional argument in the data set constructor will force the XML data to be reloaded from the server.

    var dsPhotos = new Spry.Data.XMLDataSet("/photos.php?galleryid=2000", "/gallery/photos/photo",{useCache: false})

distinctOnLoad - Use the distinctOnLoad argument to remove duplicate records from the dataset. This will remove duplicate records where columns are identical with another record.

distinctFieldsOnLoad - Use the distinctFieldsOnLoad argument to specify the list of columns that should have distinct values and remove duplicate records from the dataset. When this parameter is missing and the distinctOnLoad option is used then all the fields of the records should be identicals.

    var dsPhotos = new Spry.Data.XMLDataSet("/photos.php?galleryid=2000", "/gallery/photos/photo",{distinctOnLoad: true});

Distinct can also be called as a separate function:

     var dsPhotos = new Spry.Data.XMLDataSet("/photos.php?galleryid=2000", "/gallery/photos/photo");
     dsPhotos.distinct();

Filtering Data Sets

Data sets support both destructive and non-destructive filtering.

Before using either method of filtering, you must supply a filter function that takes a data set, row object and rowNumber. This function will be invoked by the data sets filtering methods for each row in the data set. Your function must return either the row object passed to your function, or a new row object, meant to replace the row passed into your function. If your function wants to filter out the row, it should return a null value.

The data set's destructive filter method is filterData(). This method will actually replace or discard the rows of the data set. The only way to get the original data back is to reload the XML data of the data set.

    var dsPhotos = new Spry.Data.XMLDataSet("/photos.php?galleryid=2000", "/gallery/photos/photo");
    var myFilterFunc = function(dataSet, row, rowNumber)
    {
    	if (row["@path"].search(/^s/) != -1)
    		return row;                     // Return the row to keep it in the data set.
    	return null;                   //Return null to remove the row from the data set.
    }

    dsPhotos.filterData(myFilterFunc);

It is important to note that your filter function will remain active, even when loading XML data from another URL, until you call filterData() with a null.

    dsPhotos.filterData(null);

The data set's non-destructive filter method is filter(). Unlike filterData(), filter() creates a new array of rows which reference the original data, so as long as your filter function does not modify the row object passed into it, you will be able to get the original data back by simply calling filter() and passing a null argument.

    var dsPhotos = new Spry.Data.XMLDataSet("/photos.php?galleryid=2000", "/gallery/photos/photo");
    var myFilterFunc = function(dataSet, row, rowNumber)
    {
    	if (row["@path"].search(/^s/) != -1)
    		return row;                     // Return the row to keep it in the data set.
    	return null;                        // Return null to remove the row from the data set.
    }

    dsPhotos.filter(myFilterFunc); // Filter the rows in the data set.

    dsPhotos.filterData(null); // Turn off non-destructive filtering.

Automatic Data Refresh

This function will refresh the data from the server every period set in the constructor. Time is set in milliseconds. Turn off the cache to force the new data from the server, otherwise, the data will load from the cached XML file.

    var dsPhotos = new  Spry.Data.XMLDataSet("/photos.xml", "/gallery/photos/photo", { useCache:  false, loadInterval: 10000 });

You can also turn on this interval loading programmatically with the startLoadInterval() method, and stop it with the stopLoadInterval() method.

    dsPhotos.startLoadInterval(10000); // Start loading data every 10 seconds.
    dsPhotos.stopLoadInterval(); // Turn off interval loading.

Sorting onLoad

You can sort a data set by a column when the data loads. This can be done by setting an option in the data set constructor. It can also be set programmatically if needed.

'sortOnLoad:' takes the column to be sorting. 'sortOrderOnLoad:' takes the type of sorting, either 'ascending' or 'descending'.

    var dsPhotos = new Spry.Data.XMLDataSet("/photos.php?galleryid=2000", "/gallery/photos/photo", { sortOnLoad: "@path", sortOrderOnLoad: "descending" });

Data Set data points

- ds_RowID - This is the id of a row in the data set. This id can be used to refer to a specific record in the data set. It does not change even when the data is sorted.
- ds_RowNumber - This is the row number of the "current row" of the data set. Within a loop construct, this number reflects the position of the row currently being evaluated.
- ds_RowCount - This is the number of rows in the data set.
- ds_CurrentRowID - This is the id of the "current row" of the data set. This value will not change, even when used within a looping construct construct.
- ds_CurrentRowNumber - This is the row number of the "current row" of the data set. This value will not change, even when used within a looping construct.
- ds_SortColumn - This is the name of the column last used for sorting. If the data in the data set has never been sorted, this will output nothing (an empty string).
- ds_SortOrder - This is the current sort order of the data in the data set. This data reference will output the words "ascending", "descending", or nothing (an empty string).

### startLoadInterval

datasetname.startLoadInterval(milliseconds);

#### Description

This function will reload the specified data set in the specified time interval.

#### Arguments

milliseconds - the load interval in milliseconds

#### Returns

N/A

#### Example

    dsPhotos.startLoadInterval(10000);

### stopLoadInterval

    datasetname.stopLoadInterval();

#### Description

This function will stop the periodic reloading of data when the LoadInterval is set.

#### Returns

N/A

#### Example

    dsPhoto.stoptLoadInterval();

### UpdateRegion

Spry.Data.updateRegion("region ID");

#### Description

UpdateRegion allows the developer to trigger a region redraw whenever needed. This can be used, for instance, when a filter function has updated the dataset but only certain regions need to be updated.

#### Parameter

The id of the region container tag to be updated.

#### Example

    <script>
    dsStates1.filter(MyPagingFunc);
    Spry.Data.updateRegion("region1");
    </script>

    <div id="region1" spry:region="ds1">
    	{description}
    </div>

## Data References

#### Description

A data reference is a placeholder for a piece of data from a data set. When loaded in the browser, these data references are replaced with the actual data from the dataset. Data references must be within a spry:region or a spry:detailregion.

If the spry:region or spry:detailregion contains only a single dataset, the dataset name is not required. It is required when multiple data sets are used within a region.

#### Format

{datasetname::columnname}

There are 2 colons between the data set name and the column name.

#### Example

    {dsData::firstname}

    {firstname}

Copyright © 2007. Adobe Systems Incorporated.
All rights reserved.