Odd placement of event in schedule - coldfusion

I have a page that shows a schedule of events over a period of time. Thanks to Leigh on this site, I was able to get it working the way I wanted, except for one small issue. One of the events is placed at the bottom of one of the lists that is sorted by the datetime column "eventtime". I'm baffled.
Here's my code:
<cfquery datasource="fairscheduledb" name="getfairevents">
SELECT fd.FairDayDate, fd.daycolor, fd.description, ev.eventname, ev.eventday, t.eventtype, ev.eventtime
FROM fairdays fd
LEFT OUTER JOIN events ev ON ev.eventday = fd.fairdaydate
LEFT OUTER JOIN eventtypes t ON t.eventtype = ev.eventtype
ORDER BY fd.fairDaydate, t.id, ev.eventtime
</cfquery>
<cfoutput query="getfairevents" group="eventday">
<div class="schedulebox">
<!--- display event dates --->
<div class="schedulehead" style="clear: both; color: ###daycolor#;">#dateformat(fairdaydate,"dddd, mmmm dd")#</div>
<div class="schedulesubhead" style="clear: both; color: ##ffffff; background: ###daycolor#;">#description#</div>
<!--- event types for current date --->
<cfoutput group="eventtype">
<div class="scheduleitemtitle" style="clear: both; width: 700px; color: ###daycolor#;">#eventtype#</div>
<!--- individual events --->
<cfoutput>
<div class="scheduleitem" style="float: left; width: 75px; text-align: right;"><strong>#LCase(TimeFormat(eventtime,"h:mmtt"))#</strong></div>
<div class="scheduleitem" style="float: left; width: 550px;"> #eventname#</div><br/>
</cfoutput>
</cfoutput>
</div>
</cfoutput>

You're grouping your output on eventday and eventtype. You need to add those two columns to your ORDER BY, otherwise you can get unpredictably-ordered results.
ORDER BY fd.fairDaydate, t.id, ev.eventday, ev.eventtime, ev.eventtype

Ok. I found the problem, and it was a stupid one for me to miss. When I changed that specific entry yesterday, and typed in the correct time, it "auto inserted" the current date. In other words, I typed "8:45pm", and hit enter, and MSSQL automatically converts it to "2014-01-31 19:45:00.000", because yesterday was 01-31-2014. When the data was originally entered, it was 01-23-2014, so all of the entries reflected that date. Because the data type I used for that column was datetime.
I solved the problem by changing the data type to time(7), and viola, all is well. I feel stupid, now.
Thanks to everyone that tried to help with this.

Related

Why is cfoutput being ignored?

I have a very simple CFML page as follows:
<cfquery name="qry" datasource="#application.db.source#" username="#application.db.user#" password="#application.db.pass#">
SELECT * FROM changemgmt.rfc WHERE rfc_id = <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="0">;
</cfquery>
<cfoutput query="qry">
#qry.RecordCount#
</cfoutput>
My <cfoutput> tag is not working as I would expect. If you were to look at the source code of this page, it would be entirely composed of empty lines. It's as if the <cfoutput> tag is being parsed out by the server. However if I change the code to:
<cfoutput>
#qry.RecordCount#
</cfoutput>
I am using Lucee as my backend CFML engine. Can anyone explain to my why there is a difference?
<cfoutput query="qry"> this is used to loop throw all the rows in the query. If your query result have no rows, the execution will never reach the login with in the <cfoutput query="qry">. But if there are 1+n rows in the result, your code will print the recordcount 1+n times.
In this case if all you want is to print recordcount of the result, then you just need to use <cfoutput>#qry#</cfoutput>
But if you want to print values each row of the query then you can use <cfoutput query="qry">
<cfoutput query="qry">
<div>
<span>#qry.rfc_id#</span>
<span>#qry.name#</span>
...
</div>
</cfoutput>

CFGRID vertical scrollbar and restricted visible records

I am working on coldfusion 10 and i have the following requirement,
How I need to display 100 records in first page with 18 records visible and remaining 82 records visible should be through scroll bar.
Your help is greatly appreciated.
Thank you in advance.
This sounds like an encapsulation thing. You provided no code in your question so I am going to do the best here conceptually.
You will have a query that selects 100 records using <cfquery>
I am not sure your SQL base so you can limit it with <cfquery> and the maxrows parameter like this:
<cfquery name="q"
datasource="#application.dsn#"
maxrows="100">
SELECT * FROM events order by someDate Desc
</cfquery>
or you can use TOP or LIMIT in SQL itself.
Next comes your table.
To keep concepts simple I broke it up into a div and you can adapt it to your table or grid or whatever:
<cfoutput query="q" maxrows="18">
<div>#firstcolumn# - #secondColumn# - etc.</div>
</cfoutput>
The rest spill into a scrollable div.
<div style="width:500px;height:100px;overflow:auto;">
<cfoutput query="q" startrow="19">
#firstcolumn# - #secondColumn# - etc.
</cfoutput>
</div>
So then the main concepts of concern are:
Your SQL query limited and ordered.
Your first div (or table row or grid row) with MAXROWS set to 18
Your scrolling div (or whatever) with STARTROWS set to 19
The rest falls into place.

How can I display each days events?

I have an events page where I need to display the events for each day. I've gotten it to this point, so I'm making progress.
The database has 3 tables: fairdays, eventtypes, events
fairdays: id, fairdaydate (datetime), daycolor, description
eventtypes: id, eventtype <-- This table is for the input select in the "add event form"
events: id, eventname, eventtype, eventday (datetime), eventtime (datetime)
My intent is to display the day with the description, then under that is the event types, then under each of those is the corresponding events.
I haven't worked out how to display the event type sub heading, then the individual events under each of those, but here's my code so far. Any help would be hugely appreciated.
<cfquery datasource="fairscheduledb" name="getfairdays">
select * from fairdays
</cfquery>
<cfquery datasource="fairscheduledb" name="getfairevents">
select * from events ev
inner join fairdays fd on fd.fairdaydate = ev.eventday
where ev.eventday = fd.fairdaydate
</cfquery>
<cfloop query="getfairdays">
<cfoutput>
<div class="schedulebox">
<div class="schedulehead" style="color: ###getfairdays.daycolor#;">#dateformat(getfairdays.fairdaydate,"dddd, mmmm dd")#</div>
<div class="schedulesubhead" style="color: ##ffffff; background: ###getfairdays.daycolor#;">#getfairdays.description#</div>
<cfoutput query="getfairevents">
<div class="scheduleitem" style="float: left; width: 75px; text-align: right;">#LCase(TimeFormat(getfairevents.eventtime,"h:mmtt"))#</div>
<div class="scheduleitem" style="float: left; width: 550px;">#getfairevents.eventname#</div><br/>
</cfoutput>
</div>
</cfoutput>
</cfloop>
Here's what the list of days and events should look like:
<div class="schedulebox">
<div class="schedulehead" style="color: #4CC417;">Friday, February 22</div>
<div class="schedulesubhead" style="color: #ffffff; background: #4CC417;">Opening Ceremony 4:30pm at Gate<br/>5:00 - 6:00pm - Free Admission & Free Rides</div>
<div class="scheduleitemtitle" style="color: #4CC417;">Strolling Acts</div>
<div class="scheduleitem">5:30pm - Scotts Magic Show</div>
<div class="scheduleitem">6:30pm - Rock-It the Robot</div>
<div class="scheduleitem">7:30pm - Scotts Magic Show</div>
<div class="scheduleitem">8:30pm - Rock-It the Robot</div>
<div class="scheduleitemtitle" style="color: #4CC417;">Acts</div>
<div class="scheduleitem">5:30pm - Sea Lion Show</div>
<div class="scheduleitem">6:00pm - Alligator Wrestling</div>
<div class="scheduleitem">6:30pm - Petting Zoo Presentation </div>
<div class="scheduleitem">8:00pm - Alligator Wrestling</div>
<div class="scheduleitem">8:30pm - Petting Zoo Presentation </div>
<div class="scheduleitem">9:00pm - Sea Lion Show</div>
<div class="scheduleitemtitle" style="color: #4CC417;">Stage Acts</div>
<div class="scheduleitem">7:00pm - Youth Royalty</div>
<div class="scheduleitemtitle" style="color: #4CC417;">Livestock Program</div>
<div class="scheduleitem">6:00pm - Beef Breeding Screening</div>
<div class="scheduleitem">7:00pm - Horse Judging Competition</div>
</div>
First, you don't need the first query.
Next, add
order by eventday
to query getfairevents. That will enable you to do this:
<cfoutput query="getfairevents" group = "eventday">
#eventday#
<cfoutput>
output other stuff here (individual events and times)
</cfoutput>
</cfoutput>
(This is too long for comments ...)
To expand on Dan's answer, he is suggesting a more efficient way of producing that output by using JOIN's and cfoutput's group feature (emphasis is mine):
... Eliminates adjacent duplicate rows when data is sorted. Use if you
retrieved a record set ordered on one or more a query columns. For
example, if a record set is ordered on "Customer_ID" in the cfquery
tag, you can group the output on "Customer_ID."
For your JOIN's you will need to include all three tables to grab all of the columns you need. I cannot test it right now, but something along these lines. (Notice the results are sorted the same way you wish to display them ie by event date, type and time)
SELECT ev.eventDay, t.EventType, ev.EventTime
FROM fairdays fd
INNER JOIN events ev ON ev.eventDay = fd.fairdaydate
INNER JOIN eventType t ON t.ID = ev.EventType
ORDER BY ev.eventDay, t.EventType, e.EventTime
Once you have the sorted results, use "group" generate the desired results. Be sure to group by the same columns, in the same order, as the sql query. Otherwise, it will not work correctly.
<cfoutput query="yourQuery" group="EventDay">
<!--- display event dates --->
#EventDay# <hr/>
<!--- event types for current date --->
<cfoutput group="EventType">
#EventType#<br/>
<!--- individual events --->
<cfoutput>
#EventTime# <br/>
</cfoutput>
</cfoutput>
</cfoutput>
Update from comments:
As discussed in the comments, if you want to retrieve all fairdays (even ones without a matching event) use outer joins instead of inner joins.
SELECT fd.fairDayDate, t.ID, ev.EventType, ev.EventTime
FROM fairdays fd
INNER JOIN events ev ON ev.eventDay = fd.fairDayDate
INNER JOIN eventType t ON t.ID = ev.EventType
ORDER BY fd.fairDayDate, t.ID, e.EventTime
Again, since the cfoutput "group" feature requires sorted query data to work properly, if you change the ORDER BY clause, be sure to update the "group" columns to match your ORDER BY clause. ie Group by fairDayDate first, then event ID:
<cfoutput query="yourQuery" group="fairDayDate">
<!--- display event dates --->
#fairDayDate# <hr/>
<!--- event types for current date --->
<cfoutput group="ID">
#EventType#<br/>
<!--- individual events --->
<cfoutput>
#EventTime# <br/>
</cfoutput>
</cfoutput>
</cfoutput>

Coldfusion Need Help Parent / Child Dynamic Menu

Basically I want to have each child menu only display on the parent menu ID. But so far, all I can get is all of the child li's connecting to any parent menu I set up.
Here is a diagram to explain how the menu is displaying right now:
Home
About > Employment & Mobile (I only want employment to display)
Services > Employment & Mobile (I only want mobile to display)
Contact
So the queries output the following variables from the database
pg_LinkName
pg_MenuTitle
pg_ParentMenu (the name of the parent menu),
pg_MenuType (a yes/no to say if it is a parent/sub menu),
pg_SubMenu (a yes/no to specify whether the menu is a parent menu or not)
I want to know if there's a way to connect the child to the parent dynamically. eg. If I choose to attach a page to a parent, it only shows on that parent in the drop down.
Here are my queries:
<cfquery name="qry_GetMenu" datasource="#request.dsn#">
SELECT *
FROM tbl_pages
WHERE pg_MenuType = TRUE AND pg_Display = TRUE AND pg_AutoMenu = TRUE AND pg_Horiz_VertMenu = TRUE
ORDER BY pg_sort
</cfquery>
<cfquery name="qry_GetSubMenus" datasource="#request.dsn#">
SELECT *
FROM tbl_pages
WHERE pg_MenuType = FALSE
ORDER BY pg_sort
</cfquery>
<cfquery name="qry_SubMenu" datasource="#request.dsn#">
SELECT *
FROM tbl_pages
WHERE pg_SubMenu = TRUE
ORDER BY pg_sort
</cfquery>
And this is what I have for the menu:
<ul class="menu">
<cfoutput query="qry_GetMenu">
<li <cfif cgi.path_info contains "#pg_LinkName#"> class="current-menu-parent"</cfif>>
#pg_MenuTitle#
<cfif pg_SubMenu gt 0>
<ul class="sub-menu">
<cfloop query="qry_GetSubMenus">
<li>#pg_MenuTitle#</li>
</cfloop>
</ul>
</cfif>
</li>
</cfoutput>
</ul>
If I'm understanding correctly, you only want to display the assigned children under the corresponding parent, and your code is currently displaying the child elements under every parent displayed?
With your current code, you would need to move one of your queries in line
<ul class="menu">
<cfoutput query="qry_GetMenu">
<li <cfif cgi.path_info contains "#pg_LinkName#"> class="current-menu-parent"</cfif>>
#pg_MenuTitle#
<cfif pg_SubMenu gt 0>
<ul class="sub-menu">
<!---moved inline to add additional conditional pg_ParentMenu clause--->
<cfquery name="qry_GetSubMenus" datasource="#request.dsn#">
SELECT * FROM q WHERE pg_MenuType = 0 AND pg_ParentMenu = '#pg_ParentMenu#'
</cfquery>
<cfloop query="qry_GetSubMenus">
<li>#pg_MenuTitle#</li>
</cfloop>
</ul>
</cfif>
</li>
</cfoutput>
This would allow the query to be filtered specifically to the current parent menu as opposed to all parent menus. If it is a huge data set, this will become pretty inefficient.
There are lots of options at that point (perform the loops and assign to another object like an array of structs that has the keys for parent and children, with the children being another array, or re-working the database to make the sub-menus relational, etc.).
Hope that is moving in the right direction.

Creating an Alphabetical Indexed List (ColdFusion + Microsoft SQL Server)

I'm currently struggling to find anyone who knows how this can be done? I've tried a few different methods and ended up with halfway results but not quite what i wanted. Basically i'm trying to create a list showing all the bands A-Z, but the band names are being called from a database, so i'm having to use #band_name# within a nested list. If i re-write the code and post it, someone might be able to see where i'm going wrong.
<cfoutput query="bandNameList">
<cfloop from="65" to="90" index="i">
<UL>
<LI> #chr(i)#
<UL>
<LI> #band_name# </LI>
</UL>
</LI>
</UL>
</cfloop>
</cfoutput>
What I think you're after is to only output the Letter for the first band that begins with that letter.
One way to achieve this is to change your query slightly (note I'm using what I think is SQL-92 syntax here, but there's probably a nicer way to get the first letter in your particular database):
select
band_name,
SUBSTRING(band_name from 1 for 1) AS first_letter
from
bands
order by
band_name
Which will get you the first letter in the query.
If you want to group all the bands with numeric first letters together, then you can use SQL's CASE statement to do that (you may need to find the equivalent to ascii() in your DBMS). You could also invert the logic and match against 'normal' letters and lump everything else into a '0-9 and punctuation' category if that's easier. I think that's what a number of music systems do (I'm thinking iTunes on the iPhone, but I'm sure there are others)
select
band_name,
CASE
WHEN ascii(left(band_name, 1)) BETWEEN 48 AND 57 THEN '0-9'
ELSE left(band_name, 1)
END AS first_letter
from
bands
order by
band_name
Now you can use that extra column along with cfoutput's group attribute to help get the output as you want it.
<UL>
<cfoutput query="bandNameList" group="first_letter">
<LI> #first_letter#
<UL>
<cfoutput>
<LI> #band_name# </LI>
</cfoutput>
</UL>
</LI>
</cfoutput>
</UL>
Update your query to have a left(band_name,1) AS BandStart and make sure to order by band_name in your ORDER BY. Then use group to output the list.
<cfoutput query="bandNameList" group="BandStart">
<UL>
<LI>#bandNameList.BandStart#
<cfoutput>
<UL>
<LI> #bandNameList.band_name# </LI>
</UL>
</cfoutput>
</LI>
</UL>
</cfoutput>
If you want to display all letters, even if no bands starting with that letter exist, another option is using a CTE to generate a table of letters A-Z. Then display the results with a "grouped" cfoutput:
<cfquery name="getBandNameList" ...>
;WITH ltrs ( code ) AS (
SELECT ascii('A') AS code
UNION ALL
SELECT code + 1
FROM ltrs
WHERE ascii('Z') > code
)
SELECT char(code) AS letter, t.band_name
FROM ltrs LEFT JOIN #YourTable t ON t.band_name LIKE char(code) +'%'
ORDER BY letter ASC, t.band_name ASC
</cfquery>
<cfoutput query="bandNameList" group="Letter">
<UL>
<LI> #letter#
<UL>
<cfoutput>
<LI> #band_name# </LI>
</cfoutput>
</UL>
</LI>
</UL>
</cfoutput>
Another approach is to write a sql server stored proc that returns everything in a single query object. The code would resemble this:
declare #thisNum as int
declare #lastNum as int
set #thisNum = 65;
set #lastNum = 90;
declare #letters as table(letter char(1))
while (#thisNum <= #lastNum)
begin
insert into #letters values (CHAR(#thisNum))
set #thisNum = #thisNum + 1;
end
select letter, bandname
from #letters left join band on letter = left(bandname, 1)
order by letter, bandname
Then, in ColdFusion, you can use cfoutput with the group attribute.
Try this code ::
<cfquery datasource="orcl" name="list">
select upper(brand) brand from tbl
</cfquery>
<cfoutput query="list">
<cfloop from="65" to="90" index="i">
<UL>
<LI> #chr(i)#
<UL>
<LI><cfif mid(brand,1,1) eq chr(i)> #brand#</cfif></LI>
</UL>
</LI>
</UL>
</cfloop>
</cfoutput>