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.
<html>
<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>
<body>
<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">
<p>
<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>
</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.