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.