Coldfusion limit cfloop to 10 - coldfusion

I'm working with quite a large array of items in a cfloop. I would like to pare this down and add pagination. Is there anyway in my cfloop to limit the array to the first 10?
I have
<cfloop array="#qryItems#" index="index">
I have tried turning it into a condition loop with no luck and a few other things. I haven't touched coldfusion in a while and am a little rusty. Google is not helping haha
I have tried
<cfloop from="1" to="10" array="#qryItems#" index="index">
and have also tried max_rows
<cfloop maxrows="10" array="#qryItems#" index="index">
each time I get the error message
"Attribute validation error for tag CFLOOP."

<cfloop from="1" to="10" index="index">
<!--- Then do your business with array elements qryItems[index], that is, with qryItems[1], qryItems[2],..., qryItems[10] --->
</cfloop>

There is no combination of attributes for cfloop to accomplish what your expecting. As BKBK suggested, you'll need to use a from/to loop to output a select group of records. If I understand your requirements correctly, I would update your cfloop with a new index variable as well, and then set the old variable by referencing the array element.
The two cfloops below output the same data, with the second displaying only the records in the pagination range.
<cfset qryItems = [1,2,3,4,5,6,7,8,9,10,'a','b','c','d'] />
<cfoutput>
<!--- Current loop: Outputs all records --->
<cfloop array="#qryItems#" index="index">
#index#
</cfloop>
<cfset paginationStart = 1 />
<cfset paginationEnd = 10 />
<!--- Only the range of of records requested --->
<cfloop from="#paginationStart#" to="#paginationEnd#" index="indexNumber">
<cfset index = qryItems[indexNumber] />
<!--- code remain the same --->
#index#
</cfloop>
</cfoutput>

Related

ColdFusion cfloop issue

I'm running ColdFusion 2016. I have a cfloop which pulls in data from a query, all other ColdFusion queries work fine on the page and if I pull in the same variable in an output outside the loop, it works fine, except the loop is giving me an error. The error output says:
Variable GPS_LATITUDE is undefined.
Which is correct, as in the database there is no GPS_LATITUDE but there is a GPS_LATITUDE1.
I need to add the loop number on the end of the variable so as it loops pulls in the data gps_latitude1, gps_latitude2, gps_latitude3 not just gps_latitude.
My loop code is...
<cfoutput>
<cfloop index="i" from="1" to="3">
<td><p>#gps_latitude[i]#</p></td>
<td><p>#gps_longitude[i]#</p></td>
</cfloop>
</cfoutput>
Any guidance much appreciated.
#elixieru, You can't directly give gps_latitude[i]. which is not check your query which is consider it as Array. I can imagine your scenario and give my sample code about how to get an same columnName with
<cfquery name='test' datasource="mytest">
select * from test
</cfquery>
This is my sample query. It's having column name as address1, address2 etc... I'm going to get the data about address1 & address2 like your scenario.
<cfloop query="test">
<cfloop from="1" to="2" index="i">
<cfset a = test["address#i#"]>
<cfoutput> #a# </cfoutput> <br/>
</cfloop>
</cfloop>
Here I'm looping over the query and so some simple / index loop based on my count ( Address1,2,3,4,5 etc ). For now I'm just use 2 like from 1 to 2.
Here I've store the test['address#i#'] in variable a and print that variable. Now test['address#i#'] it will consider as test.address1
I hope my sample help you more.

Need to insert the Upload count in the database and in table

I am getting the following details in my form. I need to loop through the fields which have "attachment" in the name and add the count to the table, and also the values in the new table.
ATTACHMENT C:\ColdFusion10\cfusion\runtime\work\Catalina\localhost\tmp\neotmp3230094756217875313.tmp
ATTACHMENT2 C:\ColdFusion10\cfusion\runtime\work\Catalina\localhost\tmp\neotmp4341408903737742616.tmp
ATTACHMENT3 C:\ColdFusion10\cfusion\runtime\work\Catalina\localhost\tmp\neotmp2809169853442728277.tmp
I am trying to do a loop over the form fields, but I am lost in between, and am unsure where to proceed.
<CFLOOP collection="#structform#" item="whichField">
<cfif FindNoCase('attachment',whichField)>
<cfset total = len(whichField)>
<cfoutput>#total#</cfoutput><br><br>
</cfif>
<CFOUTPUT>#whichField# = #structform[whichField]#</CFOUTPUT><br>
</CFLOOP>
I'm still not certain I've understood what's going on, so this might need tweaking/changing to make it work as needed, but this is without doubt a better approach:
<cfset Total = 0 />
<cfloop collection=#StructForm# item="FieldName" >
<cfif findNoCase('attachment',FieldName) AND len(StructForm[FieldName]) >
<cfset ++Total />
</cfif>
</cfloop>
<CFLOOP collection="#structform#" item="whichField">
<cfif FindNoCase('attachment',whichField)>
<cfset lstvalue = ListAppend(lstvalue,whichField)>
</cfif>
</CFLOOP>
<cfset total = ListLen(lstvalue)>
<cfif (len(total) AND total EQ 1) AND (Evaluate(lstvalue) EQ '')>
<cfset total = 0>
</cfif>

returning a struct of queries

If a series of queries are created like so:
<cfloop list="#platform_list#" index="x">
<cfquery name="#trim(x)#" dbtype="query">
<!--- stuff to build the query --->
</cfquery>
</cfloop>
and I then return the queries in a struct like so:
<cfset queries_RET = StructNew() />
<cfloop list="#platform_list#" index="x">
<cfif StructKeyExists(args, #trim(x)#)>
<!--- here's where I think things go horribly wrong --->
<cfset queries_RET[x] = #x# />
</cfif>
</cfloop>
<cfreturn queries_RET />
And then when returned to the calling function as "graphData", I try to access it like so:
<cfloop list="#platform_list#" index="x">
<cfif StructKeyExists(url, x) and StructKeyExists(graphData, x)>
<cfloop query="graphData[x]">
I get an error at the last line:
Attribute validation error for tag cfloop.
The value of the attribute query, which is currently graphData[x], is invalid.
The value of the struct at graphData[x] is a string having the same value as the element name... so what do I do to assign the query with that name instead? I'm sure it's ridiculously obvious. :(
EDIT:
I'll give the answer to Shawn, although I finally figured out what my underlying issue(s) are. First, I didn't realize that
<cfset queries_RET[x] = #x# />
doesn't actually assign the query to the element at x, but instead a reference to it. To assign the actual query object, I need to do this:
<cfset queries_RET[x] = #Evaluate(x)# />
Second, when the struct is returned to the calling function, calling
<cfloop list="#Application.platform_list#" index="x">
<cfloop query="#graphData[x]#">
didn't work because the query attribute of cfloop is looking for a reference to a query object --- and the query object it was looking for didn't exist since it hadn't been returned.
Finally, now that I am actually returning a valid query object, that query attribute still doesn't work, because now graphData[x] isn't a reference. To make it work, I have to first assign a reference, and use that as the query attribute in the cfloop:
<cfloop list="#Application.platform_list#" index="x">
<cfset thisQuery = #graphData[x]#>
<cfloop query="thisQuery">
I think that my fundamental problem was not understanding the the query attribute isn't an actual query object, but a reference to one instead. It's been a learning curve!
Try
<cfloop list="#platform_list#" index="x">
<cfif StructKeyExists(url, x) and StructKeyExists(graphData, url[x])>
<cfset q = graphData[x]>
<cfloop query="q">
If this throws
The value of the attribute query, which is currently q, is invalid
Then you should cfdump the q make sure it is a query object.
The <CFLOOP> query attribute takes the name of a query (string), not an actual query object.
When you pass something into that attribute, CF expects it to be a string.
If it's a literal, CF will expect it to be the name of a valid query.
If it's a variable, CF will expect the value of the variable to be equal to the name of the query.
Therefore, the output you ultimately want is:
<cfloop list="#platform_list#" index="x">
<cfloop query="#x#">
Here is a full snippet of code that confirms this, which you may refer to/compare to for your own code:
<cfset query_a = QueryNew('id,name,pass') />
<cfset QueryAddRow(query_a)>
<cfset QuerySetCell(query_a,'id',1)>
<cfset QuerySetCell(query_a,'name','joe')>
<cfset QuerySetCell(query_a,'pass','joe123')>
<cfset query_b = QueryNew('id,name,pass') />
<cfset QueryAddRow(query_b)>
<cfset QuerySetCell(query_b,'id',4)>
<cfset QuerySetCell(query_b,'name','pete')>
<cfset QuerySetCell(query_b,'pass','pete123')>
<cfset query_c = QueryNew('id,name,pass') />
<cfset QueryAddRow(query_c)>
<cfset QuerySetCell(query_c,'id',7)>
<cfset QuerySetCell(query_c,'name','frank')>
<cfset QuerySetCell(query_c,'pass','frank123')>
<cfset platform_list = 'query_a,query_b,query_c' />
<cfloop list="#platform_list#" index="x">
<cfloop query="#x#">
<cfoutput>#id# #name# #pass#</cfoutput><br/>
</cfloop>
</cfloop>
You'll notice in this snippet that if you change the query attribute back to "x" (rather than #x#) you'll produce the exact same error you are encountering now.
Why?
Answer: platform_list is a comma-delimited list of strings (which x becomes via the loop), not a comma-delimited list of Query objects.

How to Break out of Cfoutput

I am looping through the results of a query, and I need to limit the number of rows displayed. I need to use cfoutput because I'm using the group attribute, and I cannot use the maxrows because not all rows will be displayed.
I tried to use <cfbreak> inside the <cfoutput>, but that throws an error.
How can I break out of the <cfoutput> loop?
If your group by is only there to remove duplicates from your results I would suggest using your query to cut them down then you can cfloop (select distinct and reducing your returned column list).
If you are using your group by to "group" your results You could run a counter within your loop and a cfif statement inside your first loop to omit later results.
You could fake the group by option in your cfloop by matching value from previous row if you need cfbreak
<cfloop query="queryname">
<cfif queryname.column[currentrow-1] neq queryname.column[currentrow]>
#queryname.column#
</cfif>
</cfloop>
Random note: you can maxrows on any/all levels of your grouped cfoutput
<cfset tmp = querynew('id,dd')>
<cfloop from="1" to="20" index="i">
<cfset queryaddrow(tmp,1)>
<cfset querysetcell(tmp,'id',rand(),i)>
<cfset querysetcell(tmp,'dd',(i mod 4),i)>
</cfloop>
<cfquery dbtype="query" name="tmp">select * from tmp order by dd</cfquery>
<cfoutput query="tmp" group="dd" maxrows="2">#dd#<br
<ul>
<cfoutput maxrows="2" group="id"><li>#id#</li></cfoutput>
</ul>
</cfoutput>
You could use the cfthrow tag to trigger an exception that will allow you to break out of the loop using cfcatch you can then ignore the exception and continue processing. That will give you what you want.
<cftry>
<cfset i = 0>
<cfoutput query="qMyQuery" group="someGroup">
<cfset i = i + 1>
Parent
<cfoutput>
Child
</cfoutput>
<cfif i GTE 10>
<cfthrow type="break">
</cfif>
</cfoutput>
<cfcatch type="break">
<!--- DO NOTHING - THIS IS A HACK FOR NOT BEING ABLE TO USE CFBREAK inside cfoutput. --->
</cfcatch>
</cftry>

insert anchor if row is current date

We have a schedule that is dynamically generated using, in part, this code:
<cfloop from="0" to="6" index="x">
<cfset thisDate = dateFormat(dateAdd("d",x,theDate),"yyyy-mm-dd")>
<cfoutput><tr><td colspan="4" class="date"><strong>#dateFormat(thisDate,"DDDD, M/D")#</strong></td></tr></cfoutput>
<cfif structKeyExists(dayData,thisDate)>
<cfif arrayLen(dayData[thisDate]) gt 0>
<cfloop from="1" to="#arrayLen(dayData[thisDate])#" index="y">
<cfoutput><tr>#dayData[thisDate][y]#</tr></cfoutput>
</cfloop>
<cfelse>
<cfoutput><tr><td colspan="4">There are no classes scheduled for this day</td></tr></cfoutput>
</cfif>
<cfelse>
<cfoutput><tr><td colspan="4">Schedule not available</td></tr></cfoutput>
</cfif>
</cfloop>
What I'm trying to do is dynamically insert an anchor (e.g., < a name="anchor">) depending on whether the date in the displayed row is the current date. So I want a cfif that will display the anchor on the row of the current day in the schedule. The goal is to link to this using the anchor.
Any suggestions are much appreciated.
So something like this?
<cfif dateFormat(now()),"yyyy-mm-dd") eq thisDate>
<a name="anchor" />
</cfif>
BTW, did you know you can loop over dates in ColdFusion.
<cfloop from="#theDate#" to="#dateAdd("d", 6, theDate)#" index="thisDate" step="#CreateTimeSpan( 1, 0, 0, 0 )#">
</cfloop>
This assumes that the dates are in a format that CF sees as dates, like what now() returns.