Ask a Jedi: Mixing ColdFusion Ajax and CFCALENDAR

This post is more than 2 years old.

Michael asks:

Ray, huge fan, long time...I have a ? for you. I am diving into CFCALENDAR and want to know how to use the SelectedDate attribute to query and display results from a DB. Right now i have a very simple calendar setup with a cfinput to BIND to cal.SelectedDate. Upon clicking on new dates, the bind works and displays the correct date. How can i use this information to populate a query and/or display data relevant to the date chosen?

Interestingly enough - I was never able to get a bind to work correctly with the cfcalendar tag. I did get onChange to work. You can use onChange with cfcalendar to fire ActionScript code when a user selects a date. Since ActionScript can call JavaScript, that is the route I took. I blogged about this last year, and for this blog entry I'm going to use some of the code Todd Sharp suggested in the comments.

Here is the calendar code I used:

<cfform name="myform" form="html"> <cfcalendar name="cal" onChange="if(cal.selectedDate) getURL('javascript:loadit(\''+cal.selectedDate.getFullYear()+'\',\''+cal.selectedDate.getMonth()+'\',\''+cal.selectedDate.getDate()+'\')')"> </cfform>

Note the onChange. It's way complex, but mainly because of all the single quotes. Basically though it says - if a date is selected (onChange fires when you deselect as well), then call a JavaScript function, loadit, and pass in the year, month, and and date. If you just use selectedDate you get an uglier date string. This is easier to work with. My loadit function looks like so:

<script> function loadit(y,m,d) { ColdFusion.navigate('showdata.cfm?year='+y+'&m='+m+'&d='+d,'dataarea'); } </script>

This uses the ColdFusion.navigate function to tell showdata.cfm to load with the right values. The dataarea area is defined like so:

<cfdiv id="dataarea" />

All showdate.cfm would then is run a SQL command (hopefully via a CFC) to load records based on the URL parameters you send in.

Don't forget to validate the URL parameters. Don't assume it's a valid date. You probably also want to add some 'common sense' validation and prevent dates that are outside the range of your data. If you are doing a movie site, it makes no sense to use dates in the 1800s, or dates in the 23rd century.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Raymond Camden posted on 6/23/2008 at 6:19 PM

Ugh - so the cold medicine may be slowing me down - the third comment in the older post, by Mikkel Johansen, has the same solution.

Sorry all for the waste of space. :)

Comment 2 by todd sharp posted on 6/23/2008 at 6:29 PM

Never hurts to repeat yourself.

Comment 3 by Joerg Zimmer posted on 6/23/2008 at 7:15 PM

Hi,
just did something similar... I also tried cfcalendar first, but as the flash stuff slowed the hole process down, I used Spry together with jscalender... This is pretty cool!

Joerg

Comment 4 by Scott Stroz posted on 6/23/2008 at 8:09 PM

Wait...do you mean to tell me that in the 23rd century there will be no movies? What a travety!

BTW - how do you know this? ;)

Comment 5 by Raymond Camden posted on 6/23/2008 at 8:14 PM

@Scott - I hopped in my TARDIS and confirmed it.

Comment 6 by Michael posted on 6/23/2008 at 10:40 PM

This worked like a charm. I had to reformat the month value because it runs on a 0-11 so march would be 02 and april would be 03... +1 worked and I now have the groundwork to build off of...THANKS!!!

Comment 7 by Michael posted on 6/24/2008 at 12:36 AM

I've researched this until i was blue but is there a way to have multiple dates highlighted in a cfcalendar? Say there is an event on 6/24 and 6/25 to have those dates highlighted?

My research tells me its not possible but is there a way to have multiple startdates/endates and have dates where no events exists to be disabled and those with events to have a normal enabled status? I hope im being clear...;)

Comment 8 by Andy Sandefer posted on 10/15/2008 at 5:18 PM

@Ray and others
This was helpful but do you any of you know how to trigger this to fire after the cfcalendar initially loads? The onChange is working fine but I have to click on a date to make this work and I wish I could make the cfgrid initially load based on the default date in the cfcalendar.

Comment 9 by Raymond Camden posted on 10/15/2008 at 5:22 PM

You could hard code it. cfcalendar takes a selectedDate attribute. If you defaulted to date X, you could make your grid do the same for it's initial data.

Comment 10 by Andy Sandefer posted on 10/15/2008 at 5:44 PM

Thanks for the help @Ray
If anyone else needs to do this then you can simply make a javascript function like this...

initPage = function() {
var todaysDate = new Date();
var year = todaysDate.getFullYear();
var month = todaysDate.getMonth();
var date = todaysDate.getDate();
loadReminderGrid(year, month, date);
}

and then call it using AjaxOnLoad...

<cfset AjaxOnLoad("initPage")>

Comment 11 by Chris Luksha posted on 2/5/2009 at 10:12 PM

I just tried this method and all works great - until I hit the calendar a second time. I did a little formatting of the date so I could verify the end user put in a good date and didn't try typing in some bogus code.

I started with
<cfif isDefined('URL.date')>
<cfset FORM.activityDate = URL.date>
<cfelse>
<cfparam name="FORM.activityDate" default="#dateformat(now(),'mm/dd/yyyy')#">
</cfif>

Then I added your js in the head (a little manipulated)
<cfoutput>
function loadit(y,m,d) {
var datefield = m+'/'+d+'/'+y;
alert(m+'/'+d+'/'+y);//Just for testing before the page is submitted window.location.href='#request.ThisPage#?date='+escape(datefield);
}</cfoutput>

Then I called the calendar like this...
<cfcalendar name="cal" selecteddate="#FORM.activityDate#" onChange="if(cal.selectedDate) getURL('javascript:loadit(\''+cal.selectedDate.getFullYear()+'\',\''+cal.selectedDate.getMonth()+'\',\''+cal.selectedDate.getDate()+'\')')"></cfform>

This worked great when I loaded the page and then changed the date - the form submitted and hte page reloaded and the calendar had the appropriate date selected. But then if I clicked on the calendar a second time - the alert popped up telling me that the date I was submitting was 0/14/2009 and when the form submitted the cfcalendar threw me the error "0/14/2009 is an invalid date or time string"

So - my question is can you see anything that I did that may have changed dates stored in the calendar? Or is this some kind of fluke in the cfcalendar tag when you set it based on an escaped url date?

Thanks,
Chris

Comment 12 by Andy Sandefer posted on 2/5/2009 at 10:15 PM

@Chris
The months start at 0. Add 1 to them.

Comment 13 by Chris Luksha posted on 2/5/2009 at 10:22 PM

Interesting conundrum - It would seem that the calendar is returning the previous month when clicking.

So when I first load the page - the calendar says Feb 5, 2009, but when I click on a date I noticed (and missed completely before) that the date it was returning was Jan 9, 2009 (I clicked on the 9th of course) so that click worked but I was then in a January calendar.

Then when I click on another date - say Jan 14 - I am returned 0/14/09 Or (Jan[1] - 1) / 14/09

Really odd behavior.
I'm stumped.

Comment 14 by Chris Luksha posted on 2/5/2009 at 10:24 PM

@Andy - I hadn't seen your post when I typed my last one - thanks for that. It makes sense so now I jsut need to correct for it via my JS.

thanks
Chris

Comment 15 by Chris Luksha posted on 2/5/2009 at 10:42 PM

You know I am actually still confused.

Why - if I load the page via activityForm.cfm?date=12/09/1970 - why does the calendar say it is december - but clicking on a date in December - returns that date in November.

It shouldn't do that. I tried uploading the file to my server for all to see - but it would seem that for some reason cfcalendar is not functioning on my nice pretty little cf8 shared hosting box :(

Comment 16 by Chris Luksha posted on 2/6/2009 at 12:08 AM

Never mind - my brain - yes - was in the dirt. It took me some playing around to get the sense of it but it still freaks me out. Who thought of this anyway? Can I shoot him/her? Maybe dock their pay? What is the reasoning behind January being 0 and not 1 like we all think, write an say? Why does programming have to be different just to have fun with us.

Oh well off the soap box - I get it. Now I just have to get my host to actually support it in some way. They say that they do but that flash elements are inherently quirky in cf8 - that part I'm not so sure I'm down with. Anyone know why cfcalendar wouldn't work on my live cf8 server and it would on my local cf8 server? The developer edition got some extra cheerios in the box that the production version ain't got? Maybe some help I could point my isp to? I haven't found anything stating as much.

Comment 17 by Jc posted on 2/6/2009 at 2:19 AM

Ok do you have a live example of this somewhere? I am doing something quite similar, and would like to take a peek. Thx

Comment 18 by Chris Luksha posted on 2/6/2009 at 3:10 AM

I would except it only functions on my local server. My isp says
"This is a flash based component. And unfortunately, the ColdFusion flash based components are not terribly stable in ColdFusion 8. I sure do wish I had a better answer for you. We have actually spent a significant amount of time trying to stabilize flash based components on ColdFusion 8 without any success...."

They are looking into it more which I am grateful of - but for now I don't have a live example b/c I can't get it to work on any of my sites on their servers. I have tried 6 sites with no joy.

In the end I had to do a little jQuerying and get teh calendar running using http://keith-wood.name/date...

I hope this helps some
Chris

Comment 19 by Jc posted on 2/6/2009 at 11:38 PM

Well to explain I was attempting to take the basic cfcalendar form and add some functionality so as with a script on the back end I would be able to highlight a date, and possibly add some text for appt's etc. any input?