A reader wrote in asking an interesting question. He was using a Spry PagedView (a nice way to present a 'paged' interface to data loaded in via Ajax) and ran into an issue when trying to display the row number. When he used {ds_RowNumberPlus1}, the row was relative to the page. So on page 2, he saw 1 instead of 11. I read over the docs a bit and nothing seemed like it would work. I then created the following demo to help me test this.


<head> <script src="http://localhost/Spry_1_6_1/includes/xpath.js"></script> <script src="http://localhost/Spry_1_6_1/includes/SpryData.js"></script> <script src="http://localhost/Spry_1_6_1/includes/SpryPagedView.js"></script> <script> var mydata = new Spry.Data.XMLDataSet("data.cfm","/people/person"); var pvdata = new Spry.Data.PagedView(mydata, { pageSize: 10 });

var myFilterFunc = function(dataSet, row, rowNumber) {

if(Spry.$("keyword_filter") == null) return row; var regExpStr = Spry.$("keyword_filter").value;

if(regExpStr == '') return row; var regExp = new RegExp(regExpStr, "i");

if(row["name"].search(regExp) != -1) return row; return null; } mydata.filter(myFilterFunc);

</script> </head>


<form name="filterForm"><input type="text" name="keyword_filter" id="keyword_filter" onkeyup="mydata.filter(myFilterFunc);"></form>

<div spry:region="pvdata">

<div spry:state="loading">Loading - Please stand by...</div> <div spry:state="error">Oh crap, something went wrong!</div> <div spry:state="ready">


<table width="500" border="1"> <tr> <th onclick="pvdata.sort('name','toggle');" style="cursor: pointer;">Name</th> </tr> <tr spry:repeat="pvdata"> <td style="cursor: pointer;"> ds_RowID={ds_RowID} ds_RowNumber={ds_RowNumber} ds_RowNumberPlus1={ds_RowNumberPlus1}<br/> ds_PageFirstItemNumber={ds_PageFirstItemNumber} ds_CurrentRowNumber={ds_CurrentRowNumber}<br/> <b>{name}</b></td> </tr> </table> </p> </div>

<div id="pagination"> <div id="pagination" class="pageNumbers"> <span spry:if="{ds_UnfilteredRowCount} == 0">No matching data found!</span> <span spry:if="{ds_UnfilteredRowCount} != 0" spry:content="[Page {ds_PageNumber} of {ds_PageCount}]"></span> </div> <div id = "pagination" class = "nextPrevious"> <span spry:if="{ds_UnfilteredRowCount} != 0"> <a href="javaScript:pvdata.previousPage()"><< Previous</a> | <a href="javaScript:pvdata.nextPage()">Next >></a> </span> </div> </div>


</body> </html>

The code behind the XML was rather simple:

<cfsavecontent variable="str"> <people> <cfloop index="x" from="1" to="100"> <cfif randRange(1,10) lt 3> <cfoutput><person><name>Sam #x#</name></person></cfoutput> <cfelse> <cfoutput><person><name>Person #x#</name></person></cfoutput> </cfif> </cfloop> </people> </cfsavecontent> <cfcontent type="text/xml" reset="true"><cfoutput>#str#</cfoutput>

Once this was done, I quickly ran the demo and saw that there seemed to be no built in variable that would work. The closest thing I saw was that {ds_PageFirstItemNumber} represented the first row of the current page, and if I added ds_RowNumber, together I got a proper value.

Ok, so long story short, I whipped up a quick function to handle the addition:

function FormattedRowNum(region, lookupFunc) { return parseInt(lookupFunc("{ds_PageFirstItemNumber}")) + parseInt(lookupFunc("{ds_RowNumber}")); }

And then added this to my display: {function::FormattedRowNum}

This worked fine, both before and after I applied a filter. However, I figured I was missing something and I pinged the Spry team. Kin wrote me back and suggested I use {ds_PageItemNumber} instead. That worked perfectly! The reason I had not tried was due to the description:

The unfiltered item number for the current row being processed. This is the unfiltered row index of the row plus one.

I guess when I saw "unfiltered", I figured it wouldn't work with a filtered dataset.