Spry Tip - Paged Datasets, Filters, and Row Numbering

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> </code>

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.

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate looking for his next gig. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support.

Lafayette, LA https://www.raymondcamden.com

Comments