cfdirectory loop limit the results - coldfusion

I' am finding it difficult to understand this. How can I limit the results to 50 only. Let say if in the directory I have 1000 files, how can I limit it so that only 50 files are looped over.
<cfdirectory action="list" directory="#ExpandPath('/downloaded/')#" name="listRoot" filter="*.xml" recurse="false" sort="datelastmodified asc">
<cfoutput>
<cfloop query="listRoot" from="1" to="50" index="i">
....
</cfloop>
</cfoutput>
When I run the above code I get the following error message
Attribute validation error for tag CFLOOP.

If you review the complete error message, it contains the answer (emphasis mine):
It has an invalid attribute combination: from,index,query,to. Possible combinations are:
Required attributes: 'query'. Optional attributes: 'endrow,startrow'.
...
Required attributes: 'from,index,to'. Optional attributes: 'step'.
The code is attempting to mix two different types of loops: query loop and from/to loop. That is not a valid combination. You can either use a query loop OR a from/to loop, but not both.
Having said that, since the goal is to display the output, there is really no need for the cfloop. Just use cfoutput with the "startRow" and "maxRows" attributes:
<cfoutput query="listRoot" startRow="1" maxRows="50">
#name#<br>
</cfoutput>
As mentioned in the other answer, recent versions of CF also support for ...in loops:
<cfscript>
for (row in listRoot) {
writeOutput("<br>Debug: name value = "& row.name );
}
</cfscript>

You can access specific rows in a query with:
query[columnName][rowIndex]
In order to do a from to loop instead of an each loop, go:
<cfoutput>
<cfloop from="1" to="50" index="i">
#listRoot["name"][i]#<br>
</cfloop>
</cfoutput>

Related

Output list in cfloop with two variables

I have following code:
<cfloop from="1" to="3" index="i">
<cfloop list="#FORM.cboStructureLevel_#i##" index="ii" delimiters=",">
#ii#
</cfloop>
</cfloop>
The problem is that I want to output the list but I am getting the error "Element CBOSTRUCTURELEVEL_ is undefined in FORM.". It does not recognize the output of #i# in the list in the second cfloop.
How can I output the whole list as declared above?
Thank you for your help.
Try this for your inner loop:
<cfloop list="#form['cboStructureLevel_' & i]#" index="ii">
try to use evaluate function:
#Evaluate('FORM.cboStructureLevel_#i#')#

Checking the structure is existing or not

Here is my array loop which has structures inside that
I am looping over it and i need to skip those fields where the struct is not defined, howver i am getting everytime
Here is my code:
<cfloop index="apos" from=1 to="#arrayLen(myarray)#">
<cfdump var="#myarray[apos].company#">
<cfdump var="#StructKeyExists(myarray[apos].company,'#myarray[apos].company.size#')#">
<cfdump var="#StructFindKey(myarray[apos].company,'myarray[apos].company.size','ALL')#">
</cfloop>
The error is throwing on line 3, where i am getting error: Element COMPANY.SIZE is undefined in a CFML structure referenced as part of an expression.
Although i had tried the structFindvalue, but that does not work, perhaps that is expecting some simple values, so what could be the best possible alternative here
With structKeyExists you want to give that function the struture to look and the key you're looking for, so in myarray[apos].company you want to see if 'size' exists, not the entire structure.
<cfloop index="apos" from=1 to="#arrayLen(myarray)#">
<cfdump var="#myarray[apos].company#">
<cfdump var="#StructKeyExists(myarray[apos].company,'size')#">
</cfloop>

Creating an Insert Statement for mysql table

I am creating a INSERT Starement for my table. Till now all going good and i have been able to create the Insert Statement. Only Issue Left is: It shows a trailing comma after the end of every single record. Can you guys have a look around what mess I am doing here
<cfset listcount = getQueryColumns(insertData)>
<cfset counter = 1>
<cfloop query="insertData">
<cfoutput>
INSERT INTO `mytable` (#listcount#)
VALUES(
<cfloop index="col" list="#listcount#">'#insertData[col][currentRow]#'
<cfif counter LT insertData.recordcount>,</cfif>
</cfloop>);<br><br>
</cfoutput>
<cfset counter++>
</cfloop>
Your error is due to the fact that you are incrementing your counter in the outer loop instead of the inner loop.
I think I've got it. I believe this is what you need:
<cfset listcount = getQueryColumns(insertData)>
<cfloop query="insertData">
<cfset counter = 1>
<cfoutput>
INSERT INTO `mytable` (#listcount#)
VALUES(
<cfloop index="col" list="#listcount#">'#insertData[col][currentRow]#'
<cfif counter LT listcount>,</cfif>
<cfset counter++>
</cfloop>);<br><br>
</cfoutput>
</cfloop>
What I changed is:
As Dan Bracuk pointed out, I moved <cfset counter++> inside the inner loop. I also moved <cfset counter = 1> inside the outer loop, as it will need to be reinitialized through successive INSERT statements.
I changed <cfif counter LT insertData.recordcount> to <cfif counter LT listcount>, as you don't want to iterate over the recordcount (this is why your commas stopped appearing after Priority, which was the 8th field). Instead, you want to iterate over the number of columns.
EDIT: See my more recent answer. I'm leaving this one in place because the comments were useful in the diagnosis.
I think Dan Bracuk is correct about your counter increment. But you might be able to simplify your code and avoid the <cfif > statement entirely if you you use the list attribute in <cfqueryparam >. For example:
<cfqueryparam value="#NAME_OF_LIST#" list="yes" >
By default this will put a comma between your list values before sending them to the database.
Check out the other attributes it takes at http://www.cfquickdocs.com/cf8/#cfqueryparam.

ColdFusion: Can you pull out a unique record from a query using recordCount?

It's a bit of tricky question, however, my page for most rated bands displays the band logos in order of how high they have been rated. My only problem is i want to count through the records by using a cfloop from 1 to 10 and because it is split in to two columns, have one counting 1 through to 9 and the other 2 through to 10, each of them with steps of two.
Can anybody help me with this? If i've confused just mention it and ill try to clarify exactly what i mean.
<DIV class="community_middle">
<cfoutput query="top10MostRated">
<cfloop from="2" to="10" index="i" step="2">
<DIV class="communityContent">
#chr(i)#
<IMG src="logo/#top10MostRated.Logo#" alt="#top10MostRated.Name#" width="100%" height="100%"></IMG>
</DIV>
<BR/>
</cfloop>
</cfoutput>
</DIV>
If you're looking to do odd/even lists separately, then you can use the currentrow property of the query combined with the modulo operator (%) to work out if the row is odd or even:
<cfloop query="topBands>
<cfif topBands.currentRow % 2 = 1>
<!--- do your odd number output here --->
</cfif>
</cfloop>
<cfloop query="topBands>
<cfif topBands.currentRow % 2 = 0>
<!--- do your even number output here --->
</cfif>
</cfloop>
I think these answers address your side-by-side part of your question but does not explain the "same image" issue. Their code is written correctly but does not explain the reason.
Your code:
<IMG src="logo/#top10MostRated.Logo#"
alt="#top10MostRated.Name#"
width="100%" height="100%"></IMG>
... would be fine if you were only inside a <cfloop query = "top10MostRated"> or <cfoutput query = "top10MostRated"> block. The reason is because inside these types of blocks CF is smart enough to know you want the data for the current row. It would be the same as:
<IMG src="logo/#top10MostRated.Logo[top10MostRated.currentRow]#"
alt="#top10MostRated.Name[top10MostRated.currentRow]#"
width="100%" height="100%" />
Because you're nesting the to/from cfloop inside a <cfoutput query = ""> block, you are getting unexpected results. Your existing code is always asking for the record provided by your outer loop. Hence you see the same image 5 times. (using any of the fine examples provided will help you get out of this) but, you can remove the query from your cfoutput and simply ask CF to show you the value for the correct row in your loop using your index (you set your index to "i") so the below would show you the image that corresponds to your loop.
<IMG src="logo/#top10MostRated.Logo[i]#"
alt="#top10MostRated.Name[i]#"
width="100%" height="100%" />
It sounds like what you'd like to get is a collection of even-numbered records and a collection of odd-numbered records. In Coldfusion 10 or Railo 4, you can use groupBy() from Underscore.cfc to split up your query result into manageable sub-sets, like so:
_ = new Underscore();// instantiate the library
groupedBands = _.groupBy(topBands, function (val, index) {
return index % 2 ? "odd" : "even";
});
This returns a struct with two elements odd and even, each containing an array of records which are odd or even. Example result:
{
odd: [{name: "Band one"}, {name: "Band three"}],
even: [{name: "Band two"}, {name: "Band four"}]
}
Splitting your results into logical sub-sets makes the code more readable:
<cfoutput>
<cfloop from="1" to="5" index="i">
<div class="left">#groupedBands.odd[i].name#</div>
<div class="right">#groupedBands.even[i].name#</div>
</cfloop>
</cfoutput>
You'll also be able to use those sub-sets in other places on your page if you need to.
Note: I wrote Underscore.cfc
Ben Nadel has a post exactly for this. Link here
A breakdown for this is
<cfloop query="top10MostRated">
<cfif top10MostRated.CurrentRow MOD 2>
<!--- Add to the "odd list" --->
<cfelse>
<!--- Add the record to the "even list" --->
</cfif>
</cfloop>
Then you'll have 2 lists oddList and evenList. Then it's just a matter of displaying them.
I'd do it a different way. The objective is to have records 1 and 2 side by side and I don't see that in #barnyr's answer.
<cfoutput>
<cfloop from="2" to="topbands.recordcount + 1" index = "i" step="2">
#topbands.fieldname[i-1]#
<cfif i lte topbands.recordcount>
#topbands.fieldname[i]# <br />
</cfif>
</cfloop>
</cfoutput>

ColdFusion loop condition attribute

I have a variable <cfset takeFour = 0 >. I then have a loop that I want to run 4 times.
<cfloop query="getVids" condition="takeFour LTE 4">
<cfset takeFour= takeFour + 1/>...
The CF debugger says that there is a attribute validation error for this tag, however this syntax should be correct. Any ideas?
When using cfloop to loop over a query, the acceptable attributes are, query, startRow, and endRow. Condition is not used when query is, which is why the complier is giving you an attribute validation error.
http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=Tags_j-l_10.html
You can't use the condition attribute on a cfloop with a query attribute, you can, however, break out of a loop when your condition is met. You could do this:
<cfloop query="getVids">
<cfset takeFour = takeFour + 1 />
<cfif takeFour GT 4>
<cfbreak />
</cfif>
</cfloop>
Of course, if you just want to loop over the first four rows, you can do this:
<cfloop query="getVids" startrow="1" endrow="4">
</cfloop>