ColdFusion cfoutput & excluding items - coldfusion

<cfif dir.name IS NOT "Thumbs.db">
This code excludes Thumbs.db from being called in the cfoutput query, but what if I want another file excluded? Not sure how to exclude more than one item though.
Right now have
<cfset counter = 1 />
<cfoutput query="dir1">
<cfif !listfindNoCase( 'Thumbs.db,2. Electric Accounts Tracking Report.xls,1. Electric Accounts Performance Analytics.xls', dir1.name) >
<a href="/091_AU20100226/020_Cost_Analyses/010_Electric/Flatten_Files/#dir1.name#" target="_blank">
#dir1.name#</a><br />
<cfset counter++ /> </cfif> </cfoutput>

You can use listFind() or listFindNoCase().
<cfif !listfindNoCase( 'Thumbs.db,otherFile.txt', dir.name) >
...do stuff...
</cfif>

Related

coldfusion 9 audit trail

I want to audit how many times a certain page is executed. I was hoping to add <cfinclude template="audit.cfm"> to the end of the page and log simple data, like user, date, script name.
Question: how do I pass a current script name into <cfinclude>?
I am using CF9 and application.cfm. I thought I can add code to onSessionEnd(), but I don't think it will work. Here is my onSessionEnd() and onRequestEnd()
<cffunction name="onSessionEnd">
<cfset SESSION.session_time = TimeFormat(Now() - SessionScope.started, "H:mm:ss")> <=== want to do this!!!
<cfset structClear(SESSION)> <=== currently in place
</cffunction>
<cffunction name="onRequestEnd">
<cfif NOT isDefined("URL.contentonly")>
<p align="right">
<cfoutput>
<font size="2" face="sans-serif" color="black">
<i>©#Year(Now())# Seattle Pacific Industries Inc</i><BR>
</cfoutput>
</p>
</cfif>
</cffunction>
Thanks,

Query created from Query returned from cfspreadsheet not having proper values

Today I came across a very odd case while reading a vlue from a spreadsheet and trying to filter them on a condition and a create a spreadsheet from the filtered data. Here are my steps
Read Excel sheet
<cfspreadsheet action="read" src="#local.sFilePath#" excludeHeaderRow="true" headerrow ="1" query="local.qExcelData" sheet="1" />
Create a holding Query
<cfset local.columnNames = "LoanNumber,Product," />
<cfset local.qSuccessData = queryNew(local.columnNames,"VarChar,VarChar") />
Filter the Excel returned query on a condition and add the valid ones into the new Holding query
<cfloop query="local.qExcelData" >
<cfif ListFind(local.nExceptionRowList,local.qExcelData.currentrow) EQ 0>
<cfset queryAddRow(local.qSuccessData) />
<cfset querySetCell(local.qSuccessData, 'LoanNumber', local.qExcelData['Loan Number']) />
<cfset querySetCell(local.qSuccessData, 'Product', local.qExcelData['Product']) />
</cfif>
</cfloop>
Create the new spreadsheet
<cfspreadsheet action="write" query="local.qSuccessData" filename="#local.sTempSuccessFile#" overwrite="true">
However I am getting the following content in my excel sheet
Loannumber Product
coldfusion.sql.column#87875656we coldfusion.sql.column#89989ER
Please help on this to get it work.
I believe the query loop is not mapping values to the Holding-Query properly.
Please modify your loop as below:
<cfloop query="local.qExcelData" >
<cfif ListFind(local.nExceptionRowList,local.qExcelData.currentrow) EQ 0>
<cfset queryAddRow(local.qSuccessData) />
<cfset querySetCell(local.qSuccessData, 'LoanNumber', local.qExcelData['Loan Number'][currentRow]) />
<cfset querySetCell(local.qSuccessData, 'Product', local.qExcelData['Product'][currentRow]) />
</cfif>
</cfloop>

ColdFusion cfloop skip row or change loop endRow

I am trying to display 2 images, and skip one if it matches the following criteria (<cfif myDir.name eq property_mainimage> which works fine, and then continue onto the next image and display the next image until I have a total of 2 images. But when the criteria image is say in row 5, the loop displays 3 images, when the criteria image is say row 1, it displays 2 images.
There doesn't seem to be a skip row in cfloop?
I have tried <cfif counter gt 3 > <cfabort> which works but it displays the 3 images still of the criteria image is in a row greater than 3. Below is what i'm working with...
<cfdirectory directory="C:\Domains\domain.com\wwwroot\uploads\images\#property_ID#\" filter="*.jpg" name="myDir" type="file" sort="datelastmodified">
<ul>
<cfset counter = 0>
<cfset endrowvalue = 3 >
<cfloop query="myDir" endRow="#endrowvalue#">
<cfset counter = counter +1 >
<li>
<cfif right(myDir.name,4) is ".jpg">
<cfif fileexists("C:\Domains\ domain.com\wwwroot\uploads\ images\#property_ID#\#left(mydir.name,len(myDir.name)-4)#.jpg")>
<cfif myDir.name eq property_mainimage>
DO NOT SHOW THIS IMAGE
<cfelse>
<cfset endrowvalue = 1 >
<cfset myDir.endRow = 1 >
test #endrowvalue#
test #counter# <img src="#request.root#uploads/images/#property_ID#/#myDir.name#" border="0" width="230px" style="margin-bottom:15px;" />
</cfif>
</cfif>
</cfif>
</li>
</cfloop>
</ul>
any help would be most appreciated.
I would use a counter to count when you show the image. Once you get to 2 images displayed break out of the loop.
<cfdirectory directory="C:\Domains\domain.com\wwwroot\uploads\images\#property_ID#\" filter="*.jpg" name="myDir" type="file" sort="datelastmodified">
<ul>
<cfset counter = 1>
<cfloop query="myDir">
<li>
<cfif right(myDir.name,4) is ".jpg">
<cfif fileexists("C:\Domains\ domain.com\wwwroot\uploads\ images\#property_ID#\#left(mydir.name,len(myDir.name)-4)#.jpg")>
<cfif myDir.name eq property_mainimage>
DO NOT SHOW THIS IMAGE
<cfelse>
<!--- image displayed increment coutner --->
<cfset counter++>
<img src="#request.root#uploads/images/#property_ID#/#myDir.name#" border="0" width="230px" style="margin-bottom:15px;" />
</cfif>
</cfif>
</cfif>
<cfif counter EQ 2>
<cfbreak>
</cfif>
</li>
</cfloop>
</ul>
This is a formatted comment. Your code has this:
<cfset endrowvalue = 3 >
<cfloop query="myDir" endRow="#endrowvalue#">
<cfif myDir.name eq property_mainimage>
DO NOT SHOW THIS IMAGE
<cfelse>
<cfset endrowvalue = 1 >
You would have to test it to be sure, but I suspect that the endRow attribute of your cfloop tag will continue to be 3, even if you change the value of the endrowvalue variable to 1.
This might not be the cause of your current problem, but, it my suspicians are correct, you will either have a problem elsewhere or you are running a pointless command.

Delete items unchecked from a form using ColdFusion

When a user deselects an item (by unchecking the checkbox) from the form, I want the corresponding data to be deleted from the database.
Here is what my form looks like:
Category
Item 80 626
1.Item # 1 (87) chk chk
2.Item # 2 (59) chk chk
So basically, the list looks like this:
DB_list = (80|87, 626|87, 80|59, 626|59)
Now if a user deselects one of these items 80|87, I want it to be deleted from the database like so:
DELETE FROM TBL
WHERE Item = 87
AND Category = 80
So on form submit, the list becomes
New_List = (626|87, 80|59, 626|59)
How do we delete 80|87?
This is one way to do it:
<cfoutput>
<cfset DB_list = "80|87,626|87,80|59,626|59" />
<cfset New_List = DB_list />
<cfset myitems="80,626">
<cfset mycategories = "87,59"/>
<cfif structKeyExists(form,"fieldnames")>
<!-- on submit -->
<cfif structKeyExists(form,"listitem")>
<cfset New_List = form.listitem>
</cfif>
<br />RESULT:<br />
DB_list:#DB_list#<br />
New_List:#New_List# <br /><br />
<cfloop from="1" to="#ListLen(DB_list)#" index="ix">
<cfset listitem = ListGetAt(DB_list,ix)>
<cfif ListFindNoCase(New_List,listitem) eq 0>
<!-- hence: split in javascript -->
<cfset listitemarray=ListToArray(listitem,"|")/>
<cfset itemid=listitemarray[1] />
<cfset categoryid=listitemarray[2] />
<cfquery>
DELETE FROM TBL
WHERE Item = <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#itemid#">
AND Category = <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#categoryid#">
</cfquery>
</cfif>
</cfloop>
</cfif>
<form name="tstForm" id="tstForm" method="post" action="">
<table>
<tr>
<td> </td>
<cfloop from="1" to="#ListLen(mycategories)#" index="lstindex1">
<td>Category #ListGetAt(mycategories,lstindex1)#</td>
</cfloop>
</tr>
<cfloop from="1" to="#ListLen(myitems)#" index="lstindex2">
<tr>
<cfset itemid=#ListGetAt(myitems,lstindex2)# />
<td>item #itemid#</td>
<cfloop from="1" to="#ListLen(mycategories)#" index="lstindex3">
<cfset catid=#ListGetAt(mycategories,lstindex3)# />
<td>
<input type="checkbox" id="listitem_#itemid#_#catid#" name="listitem" value="#itemid#|#catid#" <cfif ListFindNoCase(New_List,"#itemid#|#catid#",",") gt 0>checked</cfif>/>
</td>
</cfloop>
</tr>
</cfloop>
</table>
<button type="submit">Submit</button>
</form>
</cfoutput>
Run this code here
My approach would be to have a hidden field in the form that has all the available values for the checkboxes. Then when the form is submitted, compare what's in the hidden form field with what's in the checkbox field. Whatever the hidden field has that the check box field does not can be deleted.
Without the use of JavaScript, Dan Bracuk's solution would work the best for your stated requirements. However, another simpler approach to this problem is to just delete all previous choices then re-insert whatever items are still checked. Then there is no need to compare old and new values to determine what has changed.
How about
DELETE
FROM tbl
WHERE NOT CONVERT(varchar(20), Item) + '|' + CONVERT(varchar(20), Category)
IN <cfqueryparam cfsqltype="CF_SQL_varchar" value="#form.new_list#" list="yes">
My approach using sql server is to delete all the list items from the db, and then add only the ones that have been submitted by the form. All delete and add queries should be put into a single transaction, so if anything fails you can make o rollback.

Nesting queries in CF

I'm using this code to display a list of platforms. If a platformID was specified upon entering the page, I would like to create a list of genres underneath the specified platform.
browse.cfm was accessed via a link that specified a platformID of 1
browse.cfm will list all available platforms
browse.cfm will now list all available genres under platformID of 1.
<ul>
<li>Browse</li>
<cfoutput query="qGetPlatforms">
<li>
#qGetPlatforms.pName#
<cfif URL.platformID EQ qGetPlatforms.platformID>
<ul>
<cfoutput query="qGetGenres">
<li>#qGetGenres.gName#</li>
</cfoutput>
</ul>
</cfif>
</li>
</cfoutput>
</ul>
By using this approach, however, I'm getting an invalid nesting configuration. How do I fix this? Or is there another approach to achieve the same idea?
Thanks
MY queries:
<!---Get platforms--->
<cffunction
name="fGetPlatforms"
access="public"
returntype="query"
output="false"
hint="I get all the platforms">
<!---Local var--->
<cfset qGetPlatforms = "">
<!---Database query--->
<cfquery name="qGetPlatforms" datasource="#REQUEST.datasource#">
SELECT
platforms.platformID,
platforms.platformName AS pName
FROM
platforms
</cfquery>
<cfreturn qGetPlatforms>
</cffunction>
<!---Get genres--->
<cffunction
name="fGetGenres"
access="public"
returntype="query"
output="false"
hint="I get all the genres">
<!---Local var--->
<cfset qGetGenres = "">
<!---Database query--->
<cfquery name="qGetGenres" datasource="#REQUEST.datasource#">
SELECT
genres.genreID,
genres.genreName AS gName
FROM
genres
</cfquery>
<cfreturn qGetGenres>
</cffunction>
You can use <cfloop query="qGetGenres"></cfloop>, they can be nested.
IMO, using cfoutput for looping over the queries is old style and should be avoided. Use cfoutput for output, cfloop for looping and you'll have more readable code.
more food for thought is to use an inner join between the two tables, combine and retrieve everything in one query and then use cfoutput's group attribute to display the results:
<cfset URL.platformID = int(val(URL.platformID))>
<cfquery name="getPlatformsAndGenres" datasource="#REQUEST.datasource#">
SELECT
p.platformID AS platformID
,p.platformName AS pName
,g.genreID AS genreID
,g.genreName AS gName
FROM
platforms p
INNER JOIN genres g
ON p.platformID = g.platformID
WHERE
p.platformID = <cfqueryparam cfsqltype="cf_sql_integer" value="#URL.platformID#">
ORDER BY
pName
,genreName
</cfquery>
Once you have everything in one query, you can use <cfoutput query="getPlatformsAndGenres" group="pName">
to lessen your code:
<ul>
<li>Browse</li>
<cfoutput query="getPlatformsAndGenres" group="pName">
<li>
#pName#
<ul>
<cfoutput>
<li>#gName#</li>
</cfoutput>
</ul>
</cfif>
</li>
</cfoutput>
</ul>