Posted At : January 27, 2006 9:07 AM
| Posted By : Joe Danziger
Related Categories:
Prototype, AJAX, ColdFusion
In this series of posts, I'm going to demonstrate how to get some basic AJAX going using Prototype along with ColdFusion - it's easier than you think. Prototype is all you need to get some serious AJAX going. You can do it yourself and interact with the XmlHttpRequest object directly if you'd like, but Prototype abstracts all the hard stuff - like worrying about how each specific browser gets its AJAX magic going.
For this first example, we're going to keep it simple. We'll just output the current time and date. So here's what you need to do...
First, include the following snippet in the <head> section of your page to include the Prototype library:
The next step is to create a button which will run our JavaScript function when we click it. We'll also add a div to display the results of our AJAX call:
Next, we'll add the javascript function which handles the actual AJAX call:
<script type="text/javascript"> function run_ajax() { var url = '/ajax/easy1.cfm'; var target = 'ajax_div'; var myAjax = new Ajax.Updater(target, url); } </script>
And finally, we'll add a file to handle the ajax output. We reference it as /ajax/easy1.cfm, so we'll create that file and add the following code to it:
<cfsetting showdebugoutput="no"> <cfoutput> It's #TimeFormat(Now(),"h:mmtt")# EST on #DateFormat(Now(),"mmmm dd, yyyy")#. </cfoutput>
That's it! Click the button above and the current time and date should pop in right next to it. The seconds are output as well so you can click a few times to see some AJAX in action.
One final note: you'll want to make sure that your debugging info is turned off at least for the page that get called through AJAX. Otherwise all of that debugging info will be returned into the calling page.
In part 2 of this series, we'll look at how to pass parameters in to our AJAX call...
This is exactly what ColdFusion developers needed who wanted to learn more about AJAX. The Wikipedia link for XmlHttpRequest refers to an issue with caching.
How often is this an issue with HttpRequests with CF templates?
Wikipedia offered a random hash string added to query string of the HttpRequest call to avoid this problem.
I hope I am not getting to deep for the newbie AJAX CF integration. :)
Hmm.. I haven't run into issues with caching, but I am doing a post and not get in this example. I also don't use Internet Explorer too much :).
It seems like the workaround should be easy enough to implement. You can make the URL always be unique by tacking a random number onto the end. In part 2, when we look at passing in variables, I'll give an example of how this can be done.
I agree with the usage of IE. Will Prototype be the library du jour for most of your examples or will you consider creating a publically licensed library?
I have heard from some AJAX users that the size of the libraries is a give and take situation. You get great functionality at the expense of the download time of the libraries linked.
Joe, nice job with all this. I have a couple of comments on this particular example that may help others who may experience problems running it.
Before I do, I want to test to see if your commenting system automatically handles and renders HTML/CFML tags for display or if I need to do it myself.
ok, it does render (at least CFML) tags for display, so here goes:
First, some may be surprised that their running of your example doesn't show the time message showing up to the right of the "get time" button (in IE at least).
It's just that there's a slight difference between your running code and the code show us. For those who didn't catch it, his running code uses <SPAN class="s14 b i" id="ajax_div"></SPAN>, while the sample shown uses just <div id="ajax_div"></div>. If anyone is interested to add that, be sure to also download the /includes/style.css on his site that his page uses. Of course we'd need to add <link rel="stylesheet" href="style.css" type="text/css" /> to our page to point to it.
Second, you mention that folks should be sure to turn off debugging in pages that they call from ajax clients, and that's very good advice. It seems worth going ahead and showing in the example that the easy1.cfm page could have <cfsetting showdebugoutput="No"> in it to solve that problem. (Another problem of a similar ilk is that if a CFM page has an error it will return a bug ugly HTML page, which again your code may not be anticipating, so use error handling carefully when calling CFML pages from clients using ajax, flash, wml, etc.)
Finally, where you have hardcoded the pointer back to the CFM page to be executed, that could be troublesome if either someone isn't noticing that that must be changed, or if indeed they ever change where these pages are located. I'll share a tip that would help when the HTML client page is a CFM page and it's running from the same directory as the CFM page being called. One could change the var url line to be:
<cfoutput> var url = '#getdirectoryfrompath(cgi.script_name)#easy1.cfm'; </cfoutput>
Charlie, thanks very much for the positive feedback and for the suggestions. I never fail to learn something in the process :).
You are correct in that I am actually using a SPAN in my example. I was trying to keep the code samples clean, but I guess accuracy is the better choice in case users run into problems. The differences are actually hardcoded into the element and are not in the stylesheet, so that won't do much good. Will take note for future examples to try and keep things more exact.
I updated the AJAX code samples to include the <cfsetting showdebugoutput="No">, that should have been in there.
One thing to be aware of (that I ran into with another AJAX project I was working on). If there's extra line breaks at the top of the PARSED page, your return var might break. I found out that my Application.cfm file was adding about 20 line breaks before the output which broke my javascript.
My solution was to wrap the entire contents of the app.cfm file in a cfsilent tag. Works perfectly now.
Choosing A Slice And A CF Server
Joe Danziger said: @Jordan - thanks for providing the installer. That is a really great thing for the community and wi...
[More]
Blue Dragon To The Rescue
Joe Danziger said: @Todd: The thing is, I really blame the issues on the application and the fact that so many robots a...
[More]
Blue Dragon To The Rescue
Matt Woodward said: Nice Joe! Glad you found it so easy to get up and running. If you need any assistance just say the w...
[More]
Blue Dragon To The Rescue
Jordan Michaels said: Just a quick correction to the above post, OpenBD is licensed under the GPLv3, instead of 2. It's no...
[More]
How often is this an issue with HttpRequests with CF templates?
Wikipedia offered a random hash string added to query string of the HttpRequest call to avoid this problem.
I hope I am not getting to deep for the newbie AJAX CF integration. :)
It seems like the workaround should be easy enough to implement. You can make the URL always be unique by tacking a random number onto the end. In part 2, when we look at passing in variables, I'll give an example of how this can be done.
I have heard from some AJAX users that the size of the libraries is a give and take situation. You get great functionality at the expense of the download time of the libraries linked.
Before I do, I want to test to see if your commenting system automatically handles and renders HTML/CFML tags for display or if I need to do it myself.
<cftag>this is inside a cf tag</cftag>
First, some may be surprised that their running of your example doesn't show the time message showing up to the right of the "get time" button (in IE at least).
It's just that there's a slight difference between your running code and the code show us. For those who didn't catch it, his running code uses <SPAN class="s14 b i" id="ajax_div"></SPAN>, while the sample shown uses just <div id="ajax_div"></div>. If anyone is interested to add that, be sure to also download the /includes/style.css on his site that his page uses. Of course we'd need to add <link rel="stylesheet" href="style.css" type="text/css" /> to our page to point to it.
Second, you mention that folks should be sure to turn off debugging in pages that they call from ajax clients, and that's very good advice. It seems worth going ahead and showing in the example that the easy1.cfm page could have <cfsetting showdebugoutput="No"> in it to solve that problem. (Another problem of a similar ilk is that if a CFM page has an error it will return a bug ugly HTML page, which again your code may not be anticipating, so use error handling carefully when calling CFML pages from clients using ajax, flash, wml, etc.)
Finally, where you have hardcoded the pointer back to the CFM page to be executed, that could be troublesome if either someone isn't noticing that that must be changed, or if indeed they ever change where these pages are located. I'll share a tip that would help when the HTML client page is a CFM page and it's running from the same directory as the CFM page being called. One could change the var url line to be:
<cfoutput>
var url = '#getdirectoryfrompath(cgi.script_name)#easy1.cfm';
</cfoutput>
You are correct in that I am actually using a SPAN in my example. I was trying to keep the code samples clean, but I guess accuracy is the better choice in case users run into problems. The differences are actually hardcoded into the element and are not in the stylesheet, so that won't do much good. Will take note for future examples to try and keep things more exact.
I updated the AJAX code samples to include the <cfsetting showdebugoutput="No">, that should have been in there.
My solution was to wrap the entire contents of the app.cfm file in a cfsilent tag. Works perfectly now.