Rey asks:

Hi, I'm trying to do some arithmetic with Spry the data is coming from a dataset. Now how can I loop through the dataset and then add to get a total. For example in ColdFusion I can do this:

<cfset totalA = 0>
<cfset totalB = 0>
<cfloop query="test">
<cfset totalA = totalA + amountA>
<cfset totalB = totalB + amountB>
</cfloop>

and this will give me the totals, but in Spry I can't seem to find a way to do this. Any help you can give me will be appreciated. Thanks!

This can be done by using an observer on the dataset. An observer is basically a way to monitor the life cycle of a dataset. One thing you can monitor is when the data is done loading. Once the data is done, we can then look at it and make our own totals. First let's look at a simple example without the observer: <html>

<head> <title>Spry Test</title> <script type="text/javascript" src="/spryjs/xpath.js"></script> <script type="text/javascript" src="/spryjs/SpryData.js"></script>

<script type="text/javascript"> var mydata = new Spry.Data.XMLDataSet("people.cfm","/people/person"); mydata.setColumnType("age","numeric"); </script> </head>

<body>

<div spry:region="mydata">

<p> <table width="500" border="1"> <tr> <th onclick="mydata.sort('name','toggle');" style="cursor: pointer;">Name</th> <th onclick="mydata.sort('age','toggle');" style="cursor: pointer;">Age</th> <th onclick="mydata.sort('gender','toggle');" style="cursor: pointer;">Gender</th> </tr> <tr spry:repeat="mydata"> <td style="cursor: pointer;">{name}</td> <td style="cursor: pointer;">{age}</td> <td style="cursor: pointer;">{gender}</td> </tr> </table> </p>

</div>

</body> </html>

This file loads a simple XML file (which I won't bother showing, it just has a name, gender, and an age value) and displays the result in a table. Now let's add our observer:

var myObserver = new Object; myObserver.onPostLoad = function(dataSet, data) { var data = dataSet.getData(); var totalAge = 0; for(var i=0; i< data.length;i++) { totalAge += parseInt(data[i].age); } Spry.$("totalDiv").innerHTML = "Total age of my kids: " + totalAge; }; mydata.addObserver(myObserver);

The observer is an object with the particular method (onPostLoad) as a property. Skip over the function code and notice how it is added to my dataset. So basically I've said: "When you are done loading, run this function and pass in the dataset." The meat of the function is just a simple loop. I get the raw data. Loop over it. (Note the parseInt to treat the age as a number.) Finally I update a div with the result. The complete code is below.

<html>

<head> <title>Spry Test</title> <script type="text/javascript" src="/spryjs/xpath.js"></script> <script type="text/javascript" src="/spryjs/SpryData.js"></script>

<script type="text/javascript"> var mydata = new Spry.Data.XMLDataSet("people.cfm","/people/person"); mydata.setColumnType("age","numeric");

var myObserver = new Object; myObserver.onPostLoad = function(dataSet, data) { var data = dataSet.getData(); var totalAge = 0; for(var i=0; i< data.length;i++) { totalAge += parseInt(data[i].age); } Spry.$("totalDiv").innerHTML = "Total age of my kids: " + totalAge; }; mydata.addObserver(myObserver); </script> </head>

<body>

<div spry:region="mydata">

<p> <table width="500" border="1"> <tr> <th onclick="mydata.sort('name','toggle');" style="cursor: pointer;">Name</th> <th onclick="mydata.sort('age','toggle');" style="cursor: pointer;">Age</th> <th onclick="mydata.sort('gender','toggle');" style="cursor: pointer;">Gender</th> </tr> <tr spry:repeat="mydata"> <td style="cursor: pointer;">{name}</td> <td style="cursor: pointer;">{age}</td> <td style="cursor: pointer;">{gender}</td> </tr> </table> </p>

</div>

<div id="totalDiv"></div>

</body> </html>