cfloop empty query condition? - coldfusion

I have the following ColdFusion code that is getting information from a database and displaying the results on the homepage. Here's the cfquery code:
<cfquery name="getSchedule" datasource="#APPLICATION.datasource#" dbtype="odbc">
SELECT * FROM SCHEDULE_Days SD
LEFT JOIN SCHEDULE_ScheduledClasses SSC ON SD.day_id = SSC.day_id
LEFT JOIN SCHEDULE_Classes SC ON SSC.class_id = SC.class_id
WHERE SD.day_date = #createODBCDate(now())# AND SSC.schedule_cancelled = 0
ORDER BY SSC.start_time
</cfquery>
and the output code:
<cfoutput>
<cfloop query="getSchedule">
<tr>
<td width="40"> </td>
<td width="74">#lcase(timeFormat(start_time,"h:mm tt"))#</td>
<td width="158">#class_name#</td>
</tr>
</cfloop>
</cfoutput>
The issue is, if there is no data contained within getSchedule (i.e., there are no ScheduledClasses), it displays nothing.
I'm looking for a way to change this so that, in the event that there is no data to display, I can specify a message and code to be shown in its absence.

First just a quick CF tip you can make you code better by doing it this way:
<cfif getSchedule.recordcount GT 0>
<cfoutput query="getSchedule">
<tr>
<td width="40"> </td>
<td width="74">#lcase(timeFormat(getSchedule.start_time,"h:mm tt"))#</td>
<td width="158">#getSchedule.class_name#</td>
</tr>
</cfoutput>
<cfelse>
<p>Empty record message here</p>
</cfif>
The reason I put the query output first is most likely this will happen more than with your empty set message.

<cfif getSchedule.recordcount>
.... do something
</cfif>
Will work just aswell there is no need for gt 0

Use the recordCount to detect whether the query has any record
<cfif getSchedule.recordcount gt 0>
.... do something
</cfif>

<cfif getSchedule.RecordCount>
<table>
<cfoutput query="getSchedule">
<tr>
<td width="40"> </td>
<td width="74">#lcase(timeFormat(start_time,"h:mm tt"))#</td>
<td width="158">#class_name#</td>
</tr>
</cfoutput>
</table>
<cfelse>
<p>There are currently no records</p>
</cfif>

Related

How to insert a pagebreak in cfdocument after every 4 records

I have the following cfdocument code:
<cfdocument format="pdf" orientation = "landscape" bookmark="Yes" marginleft=".25" marginright=".25" marginTop = ".75" marginbottom=".75" scale="90" localUrl="yes">
<cfoutput>
<cfdocumentsection name="Summary Page" marginleft=".25" marginright=".25" marginTop = "1.65" marginbottom="1" >
<cfdocumentitem type="header">
<center>
<table width="1000" height="200" cellpadding="3" cellspacing="0">
<tr><td>Header Page</td></tr>
</table>
</center>
</cfdocumentitem>
<cfloop query="first_query">
<cfquery name="getDetails" dbtype="query">
select * from first_query
where type= <cfqueryparam cfsqltype="cf_sql_varchar" value="#Type#">
</cfquery>
<cfsavecontent variable="trhead">
<tr class="bigbluecolor" style="text-align:center;">
<td width="6%">Term</td<
</tr>
</cfsavecontent>
#trhead#
<cfloop query="getDetails">
<tr align="center">
<td width="6%">#Listfirst(TermYears,'.')# Years</td>
</tr>
<cfif getDetails.recordcount GT 6 AND getDetails.currentRow EQ 6>
<cfdocumentitem type="pagebreak"/>
#trhead#
</cfif>
</cfloop>
</table>
</td></tr></table>
</cfloop>
</cfoutput>
</cfdocumentsection>
</cfdocument>
However, it does not do the page break. It shows empty pages at the top and then it starts breaking anywhere it wants. I want my inner loop to break after 4 records and the <TH> header to repeat itself again on the start of the second page.
The trhead variable contains the code which I have wrapped with the savecontent to show it.
Can anyone explain what I am missing?
The unpredictability of the page breaks is because of this:
<cfif getDetails.recordcount GT 6 AND getDetails.currentRow EQ 6>
If getDetails has less than 6 records, that condition will never return true. Plus, if you have 12 or more records, it won't return true. I suggest this approach. First, add this to first_query:
order by type
Then build your content like this:
<cfsavecontent variable="trhead">
<tr class="bigbluecolor" style="text-align:center;">
<td width="6%">Term</td>
</tr>
</cfsavecontent>
<cfoutput query="first_query">
other content goes here
<cfif currentRow mod 6 is 0>
<cfdocumentitem type="pagebreak"/>
#trhead#
</cfif>
</cfoutput>

How can I leave the loop if no records are part of the if statement?

Below code works, but I would like to show 'no records' message if
<cfif GetResults2.csedept_id eq aFieldValue> has no records for that value. I have tried to put a counter on, but I just can't get it to show 'no records' and not show the
<thead> <th>Name</th> <th>Positive Comment</th> <th>Negative Comment</th></thead> heading of the table if there are no records.
How can I show "No Records" and hide the table head if the results come back empty
Right now if the result comes back empty it will say "no results"(correct) and display the header(incorrect).
<cfset counter3= 0>
<table cellpadding="0" cellspacing="0" class="tablecolors">
<h2> Comments </h2>
<thead> <th>Name</th> <th>Positive Comment</th> <th>Negative Comment</th></thead>
<cfloop query="GetResults2">
<cfif GetResults2.csedept_id eq aFieldValue>
<tr>
<td nowrap="nowrap">#emp_namefirst# #Left(emp_namelast, 1)# </td>
<td>#Replace(commentpositive, emp_namefirst, "<B>" & emp_namefirst & "</B>")#</td>
<td>#Replace(commentnegative, emp_namefirst, "<B>" & emp_namefirst & "</B>")#</td>
</tr>
<cfelse><p>no records</p>
</cfif>
</cfloop>
</table>
UPDATE: Just to add I do have another query above like #FRANK said that does pretty much the same things for example:
'<cfloop query="GetEmployeeTotals3">
<cfif GetEmployeeTotals3.csedept_id eq aFieldValue> '
here is the query:
select GetResults.* , GetEmployees.emp_namefirst, GetEmployees.emp_namelast
from GetResults, GetEmployees
where employee = emp_id
order by csedept_id
so all the solutions above that I tried won't work.
I would recommend using a query of queries to whittle the result set down to just the values you care about first. Then you can easily check, the recordcount before outputting the table at all.
Alternatively, loop first and build up the results with cfsavecontent, then check to see if you found any prior to getting to the table bits.
Something like this should work. You'll have to set a flag of showRecords that will determine if you should show the headers.
<cfset showRecords = false>
<cfloop query="GetResults2">
<cfif GetResults2.csedept_id eq aFieldValue>
<cfset showRecords = true>
<cfbreak>
</cfif>
</cfloop>
<h2> Comments </h2>
<cfif showRecords>
<table cellpadding="0" cellspacing="0" class="tablecolors">
<thead> <th>Name</th> <th>Positive Comment</th> <th>Negative Comment</th></thead>
<cfloop query="GetResults2">
<cfif GetResults2.csedept_id eq aFieldValue>
<tr>
<td nowrap="nowrap">#emp_namefirst# #Left(emp_namelast, 1)# </td>
<td>#Replace(commentpositive, emp_namefirst, "<B>" & emp_namefirst & "</B>")# </td>
<td>#Replace(commentnegative, emp_namefirst, "<B>" & emp_namefirst & "</B>")#</td>
</tr>
</cfif>
</cfloop>
</table>
<cfelse>
<p>no records</p>
</cfif>
EDIT: Updated answer after question was clarified
You'll need to move your cfif to include your table head when checking for records. If the check comes back with a record count, then output the table head as well as the results, otherwise output "no results". I've written two versions below, one is utilizing the cfoutput instead of a loop (just personal preference) and one with your loop if you wish to keep it.
I added Dan's listfind() valuelist() combo...so give him credit for that.
Edit Edit so this is the super-strength/ultra-correct awesome solution with the 'I-am-tired-of-editing-this-answer-50-times-to-get-OP-an-answer', with bonus shameless theft from Dan's answer above/below. Or where ever we ending up order-wise.
<table>
<cfif getresults2.recordcount AND ListFind(ValueList(GetResults2.csedept_id), aFieldValue)>
<tr>
<th>name</th>
<th>positive comment</th>
<th>negative comment</th>
</tr>
<cfoutput query="getresults2">
<tr>
<td nowrap="nowrap">#emp_namefirst# #left(emp_namelast, 1)# </td>
<td>#replace(commentpositive, emp_namefirst, "<b>" & emp_namefirst & "</b>")#</td>
<td>#replace(commentnegative, emp_namefirst, "<b>" & emp_namefirst & "</b>")#</td>
</tr>
</cfoutput>
<cfelse>
<tr colspan="3">
<td><p>no records</p></td>
</tr>
</cfif>
</table>
If you have your cfoutput somewhere in your code (where we cannot see), then here is your cfloop back, simply replace this where I have the cfoutput in the snippet above.
<cfloop query="getresults2">
<tr>
<td nowrap="nowrap">#emp_namefirst# #left(emp_namelast, 1)# </td>
<td>#replace(commentpositive, emp_namefirst, "<b>" & emp_namefirst & "</b>")#</td>
<td>#replace(commentnegative, emp_namefirst, "<b>" & emp_namefirst & "</b>")#</td>
</tr>
</cfloop>
While your question is still unclear, this might be what you want.
<cfif ListFind(ValueList(GetResults2.csedept_id), aFieldValue)>
your existing code to display results in a table
<cfelse>
<p>No Records Found</p>
Note that this:
ListFind(ValueList(GetResults2.csedept_id), aFieldValue)
will execute and return false even if GetResults2 has no records at all.
Edit starts here
Based on this comment, "well if it only appears on some then display does but to those who do not match then ignore" change your existing code to something like:
<cfquery name = "q3" dbtype = "query">
select * from GetResults2
where csedept_id = #aFieldValue#
<cfquery>
<table>
column header row
<cfoutput query="q3">
data rows
</cfoutput>
<table>
The initial construct at the start of this answer still applies.

checking the existence while printing value in a table

I am displaying results in a table after looping through a query. For TestNumber, there are some results in my query where the number is not present and
hence I want to display N/A instead of just blank in the table. So, I am checking the existence
using IsDefined, but for some reason it keeps on printing N/A everytime.
<cfloop query="GetMyList1">
<tr>
<td align="center">#TestName#</td>
<cfif IsDefined(TestNumber) >
<td align="center">#TestNumber#</td>
<cfelse>
<td align="center">N/A</td>
</cfif>
<td align="center">#Date#</td>
</tr>
</cfloop>
You would want to check if there is a length of the item. The field exists, so isDefined will always return true
<cfloop query="GetMyList1">
<tr>
<td align="center">#GetMyList1.TestName#</td>
<td align="center"><cfif len(trim(GetMyList1.TestNumber))>#GetMyList1.TestNumber#<cfelse>N/A</cfif></td>
<td align="center">#GetMyList1.Date#</td>
</tr>
</cfloop>

creating a custom td tr table for Displaying the Data

I have the following string and i want to split that string to display data in table format but the way i want to display is not working, Here is the data and here is how it should look like
vendorname- #name#: city-#city#: state-#state#:zip-#zip#:in network-#innetwork#
i want to create the above as the following table:
<table>
<tr>
<td>vendorname</td><td>#vendorname#</td>
<td>city</td><td>#city#</td>
<td>state</td><td>#state#</td>
</tr>
<tr><td>zip</td><td>#zip#</td>
<td> </td><td> </td>
<td> </td><td> </td>
</tr>
</table>
trying to create 6 columns in one TR
Here is try so far
<table align="center" width="100%" border="0" cellpadding="4" cellspacing="6" bordercolor="#CCCCCC;">
<tr>
<cfloop index="aPair" list="#Demo_Details#" delimiters=":">
<cfset Key= listFirst(aPair,"-")>
<cfif listLen(apair,"-") gt 1>
<cfset value= listLast(aPair,"-")>
<cfelse>
<cfset value = "">
</cfif>
<cfoutput>
<td><strong>#key#</strong></td>
<td>#value#</td>
</cfoutput>
</cfloop>
</tr>
</table>
It is not generating the columns as expected, it is showing everything in single line
How about something like this
<cfset Vendor = "">
<cfset City = "">
<cfset State = "">
<cfset ZIP = "">
<cfloop index="aPair" list="#Demo_Details#" delimiters=":">
<cfset Key= listFirst(aPair,"-")>
<cfif listLen(apair,"-") gt 1>
<cfset SetVariable(key, listLast(aPair,"-")>
</cfif>
</cfloop>
<cfoutput>
<table align="center" width="100%" border="0" cellpadding="4" cellspacing="6" bordercolor="#CCCCCC;">
<tr>
<td>vendorname</td><td>#vendorname#</td>
<td>city</td><td>#city#</td>
<td>state</td><td>#state#</td>
</tr>
<tr>
<td>zip</td><td>#zip#</td>
<td> </td><td> </td>
<td> </td><td> </td>
</tr>
</table>
</cfoutput>

report is not paging correctly

I have a report which is doing a page-break on a tfoot tag.
<style type="text/css">
#media print
{
tfoot{page-break-after:always}
}
</style>
The output comes from a query (here called "test"), ordered by state. The report is in a table and I want to break after each state. It's PAGING correctly. But the problem is that the first header (for the first state) precedes and the first footer (for the first state) follows each subsequent header and footer. In my test program I worked around it by inventing a blank state and setting its header and footer to blank. However, in my real program things are too complicated to do that; and I don't like kluges anyway. Can anyone tell me how to get that first header and footer to appear just once where they are supposed to be? Here is the test program:
<cfset statels = (" ,DE,NC,MD")> <!--- the blank state is the kluge --->
<cfset i = 0>
<table style = "margin-left: 50px">
<cfloop list = #statels# index = "state">
<cfset i = i + 1>
<cfoutput>
<thead>
<cfif i EQ 1>
<tr><td>&nbsp </td></tr>
<cfelse>
<tr>
<td style = "border:1px solid green">This is a Header #state#</td>
<td> <img src="http://localhost/reports/XYZinc.jpg" alt="picture"> </td>
</tr>
<!--- column headings to be on each page --->
<tr>
<cfloop array = #test.GetColumnList()# index = "col">
<td class = "repsort">#col# </td>
</cfloop>
</tr>
</cfif>
</thead>
</cfoutput>
<cfoutput query = "test">
<cfif test["PersonState"][currentrow] EQ state>
<tr>
<cfloop array = #test.GetColumnList()# index = "col">
<td>#test[col]currentrow]# </td>
</cfloop>
</tr>
</cfif><!--- personstate is state --->
</cfoutput>
<cfoutput>
<tfoot>
<cfif i EQ 1>
<tr><td>&nbsp </td></tr>
<cfelse>
<tr>
<td>This is a footer<br> i is #i# state is #state#
</td>
</tr>
</cfif>
</tfoot>
</cfoutput> <!---query = test --->
</cfloop> <!--- i loop --->
</table>