Today I begin a series of blog posts looking at the new AJAX UI elements in ColdFusion. Let me start off by saying that when I first discovered that ColdFusion would be shipping UI elements I was a bit.... wary. I mean - how many of you are using CFTABLE? The only real success ColdFusion has had in UI elements is Flash Forms... which frankly are dead to me now that I can use Flex 2 for free. So I think I'm being quite honest when I say I didn't have high expectations when I first started to dig into these features. After playing with them though I'm beginning to really like them. Let's start with the simplest of the UI controls - the layouts.
ColdFusion ships with two tags that I will be focusing on tonight - cflayout and cflayoutarea. These tags have multiple uses, but I'll be focusing on the border type. The border type acts a lot like frames. Everyone remember frames? If you are new to the whole web thing then you may have missed out on them. They rose to popularity quickly and then dropped out of usage almost as quickly. A few places still use them. A good example of this is the ColdFusion Administrator. Speaking personally - I haven't used frames for a while. I did use them for SpoolMail. It seemed to make sense for the application. I think the same applies to the border layout controls. While I wouldn't build a blog with them, I could see them being very useful AJAX style applications, or RIAs in general.
So enough pontificating. Let's look at some code. At a base level, you begin your border layout by wrapping your content with cflayout:
<cflayout type="border">
</cflayout>
You now have the option to place 5 different items. These items are all placed in one of the following positions: top, bottom, left, right, center.
So consider a simple example:
<cflayout type="border">
<cflayoutarea position="top" title="Top Layout Area">
This is the top layout area.
</cflayoutarea>
<cflayoutarea position="center">
This is the center layout area.
</cflayoutarea>
</cflayout>
In this example I've added two cflayoutareas. One on top, with a title, and one in the center position. The center position isn't allowed a title. When you do use a title in the cflayoutarea, it adds a graphical header to the section. Want to add another section? Just add it and specify a position:
<cflayout type="border">
<cflayoutarea position="top" title="Top Layout Area">
This is the top layout area.
</cflayoutarea>
<cflayoutarea position="center">
This is the center layout area.
</cflayoutarea>
<cflayoutarea position="bottom" title="Bottom Layout Area">
This is the bottom layout area.
</cflayoutarea>
</cflayout>
Here is a screen shot of how this looks:

Want to get crazy? Add a left and right layoutarea as well:
<cflayout type="border">
<cflayoutarea position="top" title="Top Layout Area">
This is the top layout area.
</cflayoutarea>
<cflayoutarea position="center">
This is the center layout area.
</cflayoutarea>
<cflayoutarea position="bottom" title="Bottom Layout Area">
This is the bottom layout area.
</cflayoutarea>
<cflayoutarea position="left" title="Left Layout Area">
This is the left layout area.
</cflayoutarea>
<cflayoutarea position="right" title="Right Layout Area">
This is the right layout area.
</cflayoutarea>
</cflayout>
Which results in this:

The layoutareas that surround the center have numerous options. You can set an initial size. You can set a max and min size. You can even allow them to be collapsed or even closed. Most of these options require the splitter attribute to be true. This creates a "grippable" handle that lets you change the size of the area. Consider this example:
<cflayout type="border">
<cflayoutarea position="center">
This is the center layout area.
</cflayoutarea>
<cflayoutarea position="left" title="Menu" splitter="true" collapsible="true" size="200" maxsize="200">
<p>
<a href="">Link One</a><br />
<a href="">Link Two</a><br />
<a href="">Link Three</a><br />
</p>
</cflayoutarea>
</cflayout>
I've set up a left area with both an initial size, a max size, and set it so that it can be collapsed. This is how the layout is rendered:

Now you may have noticed that my demo code created a menu in the left hand side. What happens when you put a real link in? It may not be what you expect. If you use this:
<a href="item1.cfm">Link One</a><br />
The contents of item1.cfm will actually load in the entire window. Most likely that isn't what you want. There is the new AjaxLink function:
<a href="#ajaxLink('item1.cfm')#">Link One</a><br />
But this simply keeps the link inside the layout area (the left hand menu). Luckily there is a nice API we can use with our Ajax UI controls. One of them is the ColdFusion.navigate function. It lets you take a layoutarea and load in another URL. For our left hand menu items to really work, they would need to look like so:
<a href="javaScript:ColdFusion.navigate('center2.cfm','center')">Link One</a><br />
In this example, the first value passed to navigate is the URL. The second value is the name of the layoutarea. For this to work, I changed my center area to this:
<cflayoutarea position="center" name="center">
Ok, so before we wrap up - imagine the left hand menu having a "Home" link. We would use it to return to the main welcome page, or in our nice new shiny Ajax app, the content we saw in the center when the page first loaded. How can we do that? Well obviously we can use the ColdFusion.navigate function again, but remember our original code looked like this:
<cflayoutarea position="top" title="Top Layout Area">
This is the top layout area.
</cflayoutarea>
In order to restore this text again, we can simply move it to a file, lets say center.cfm, and then we can update our layoutarea like so:
<cflayoutarea position="center" source="center.cfm" name="center"/>
I've added the source attribute which simply tells ColdFusion to load the data via an Ajax-based request.
Any questions?
Archived Comments
Appears to not work if you are using ports in urls: such as 127.0.0.1:83/playground/index.cfm.
The content is there but no formatting and and js error about Error: ColdFusion is not defined
Source File: http://127.0.0.1:83/play/layout.cfm
Line: 28
Works if I take it out of the vhost.
Has anybody noticed that this Ajax stuff doesn't create XHTML conform output? Just start your template with the DOCTYPE below and see, what happens...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1...">
Maybe this is just a RC issue and will be fixed in the final CF8? I hope so!
ups the above line has been truncated; here's the rest:
l.dtd">
so that the end looks like ...DTD/xhtml1-transitional.dtd">
just like Transitional HTML should look like...
I wonder how it would go through a screenreader for the blind . . .
And Jurgen, have you filed a bug report?
There's absolutely NO reason that Adobe should be writing anything other than compliant xHTML code. Using these tags, you should be able to validate a page perfectly against the W3 validator.
I do hope they fix it in the final release.
Found something in the release notes for RC1: Known Issues with this Release; Number 67448 =>
If you specify a DOCTYPE at the top of a page that includes a cflayout tag with type="border", the cflayout tag must have a style attribute with a height property; otherwise, the layout contents does not display properly.
If I validate the page through thw w3c-validator; I get two more error messages in the line
_cf_loadingtexthtml = "<div align='center'><img src='/CFIDE/scripts/ajax/images/loading.gif'/> Loading... </div>";
>> document type does not allow element "div" here.
and
>> required attribute "alt" not specified.
Juerg
@Juerg:
Truthfully, this is were the validator code fails. The problem is validator doesn't understand that the <div> tag is actually within a JavaScript string--and not within the actual DOM element.
You can work around this by actually creating DOM elements using native DOM creation methods (document.createElement("div").)
Anything special you have to add to get this to work? I just cut and pasted the code from the top box over at HostMySite and I got
ColdFusion is not defined
};ColdFusion.Event.registerOnLoad(_cf_layout_init_1181236422880);
http://h127882.cf8beta.com/...
Line 78
and
ColdFusion is not defined
ColdFusion.Ajax.importTag('CFLAYOUT-BORDER');
http://h127882.cf8beta.com/...
Line 18
I've seen a lot of people post with issues on HostMySite and the Ajax stuff. Check the other entries for how they solved it.
Gareth,
Contact HostMySite support for adding CFIDE mapping for your site. It would fix AJAX layout issue.
@Dan: Actually, it's ColdFusion that is creating this line of code; I don't think that I can take my hands on that code snipplet... I saw, that this cflayout stuff creates quite a lot additional code; includes...
Juerg
@Gareth: Had the same on my server; the CFIDE mapping solved it!
I love this CF 8 stuff!
I have an complex (frames-based) app. that I have been looking forward to re-working in a frames-free way.
I have struggling with a way to re-work the coding to retain the frames version (for older installs) while breaking free from frames - the biggest stumbling block was the 'whole' page nature of the application's templates.
I'm glad to see cflayoutarea accepts a (full file) source. So it now looks like the same templates can serve both a frameset and a Ajax setup!
cheers
David
Thanks for all the help everyone!
Nice but if the rays code is surrounded with normal <html> <body> tags the layout completely disappear with IE7 and is only partial visible in Firefox.
That's a big bug or only something wrong with my beta??
Thanks
Andrea
Solved with attribute style="height:500px;" but the code is still dirty against a w3c validator.
What you think ray about this problem?
Andrea
I would just tell you to report it to Adobe so they can try to fix it.
Raymond -
Can you give a demo page, so I can try it out.
Pat
Patrick, you can always download CF8 and try it. :)
Patrick, you can sign up for free CF8 Beta account at HostMySite.com. http://www.hostmysite.com/cf8. You can try Ray's example code. :-)
Well... i was very excited about the new cflayout stuff... but i just can't get it to work in IE7... am I missing something? i used the exact sample on this page (one with collapsible=true) and can't get it to look like that. anyone else get it to work in IE7?
i guess it helps to add the cfide folder to as an virtual directory. then it works great.
This stuff is fun and a lot quicker than defining layouts in css...although I played and played and ended up doing it the "old" manual stylesheet way anyhows. My main problem was getting rid of the borders. No matter where i set border to 0px or to my background color...they wont go away?anybody else experienced this or am I just overlooking something obvious?
I started messing around with the CFLayout commands. I don't see how you can hide the borders. I like the layout feature but I don't want my site to look like a bunch of gray boxes all the time. I tried the style attribute on the border but it doesn't seem to work for me. I can't seem to hide the default gray border or change it's color.
Well the border _must_ be there - that is part of the feature. But I'm sure you can change the CSS. Maybe try Firebug or the Web Dev toolbar to see what classes are being used.
Came across a weird bug while testing the CFLAYOUTAREA function. Not sure if it's my code or there's a bug in the Tab layout. Basically, I have a Tab layout, within which there's a split LEFT and CENTER. Clicking on links in the LEFT pane reloads the CENTER content using Coldfusion.navigate. Now the interesting part: the reloading of the CENTER content within a tab stops working once you have advanced to tabs to the right of a given tab. Probably easier to see in the attached 3-part example. I've taken out all the queries and plug in simple string-based logic for easy replication of the bug. Been trying different ways but to no avail.. Please advise. Thanks.
<!-- 1.cfm --->
<cfajaximport tags="cfform,cftree,cfgrid,cftooltip,cflayout-border,cflayout-tab">
<center>
<br>
<table width="750" cellpadding="0" cellspacing="0">
<tr><td>
<cflayout type="Tab" tabheight="600">
<cflayoutarea title="MMK Funds" source="2.cfm?categoryID=1" refreshOnActivate="true"></cflayoutarea>
<cflayoutarea title="Income Funds" source="2.cfm?categoryID=2" refreshOnActivate="true"></cflayoutarea>
<cflayoutarea title="Allocation Funds" source="2.cfm?categoryID=3" refreshOnActivate="true"></cflayoutarea>
<cflayoutarea title="Equity Funds" source="2.cfm?categoryID=4" refreshOnActivate="true"></cflayoutarea>
</cflayout>
</td></tr>
</table>
</center>
<!--- 2.cfm --->
<cfparam name="url.categoryID" default=1>
<cfif isdefined("url.categoryID")>
<cfset categoryID = val(url.categoryID)>
</cfif>
<cfoutput>
<cflayout type="border">
<cflayoutarea position="left" title="Funds" closable="true" collapsible="true" size="100" maxsize="300" splitter="True" >
<cfloop from="1" to="10" index="i">
<br><a href="javascript:ColdFusion.navigate('3.cfm?fundID=#evaluate(10*(categoryID-1)+i)#','centerBox')"><font color="gray">Fund #categoryid#-#i#</font></a>
</cfloop>
</cflayoutarea>
<cflayoutarea position="center" name="centerBox"><span class="tableFont"><br><br> Click on a fund to see its manager(s).</span></cflayoutarea>
</cflayout>
</cfoutput>
<!--- 3.cfm --->
<cfparam name="fundID" default=0>
<br>
<cfoutput>
This is manager #fundID#<br>
<cfif fundID mod 2 eq 1>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
<cfelse>
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
</cfif>
</cfoutput>
I see nothing specifically wrong with your code (except for evaluate, you dont need it). If it doesn't work in 801, you should file a bug report w/ adobe.
Hi Raymond - Thanks for reviewing the code. I'll check to see if I have 801 (probably do since I just downloaded in a few weeks ago) and file a bug report if it's still a problem. Thanks!
- Charlie
Also make sure you have the CHF (Cumulative Hot Fix)
First off thanks for running and excellent blog. I tried your demo above and it works. However once I modify the link in the CodlFusion.navigate tag to a full URL I get a javascript error. I want to use this type layout to replace a frameset and basically make the left column my nav and when they click the link it loads the content into the center layoutarea. For local pages on my site it works fine but I want to load a couple of pages that are not on my site. The error message is "Error Code -1 Error processing Javascript in markup for element center". That doesn't mean much to me anyway.
Here is the exact line of code I am using which generates the javascript error.
<code><a href="javaScript:ColdFusion.navigate('http://www.apple.com','center')">Apple</a><br /></code>
I have tried it on my site which uses CF8 on a Linux server and on the CF8 dev edition installed locally on my computer and both give me the same error. Does the CodlFusion.navigate only work with files on the same server?
Thanks
Jeff
You can't load content from another URL into your page like that. It is a browser restriction. Instead, hit a CFM on your server that uses CFHTTP to hit the remote server and output the contents.
the borders can be changed, add this at the top of the page and give any colour you want for the cflayout type="border"
.x-layout-panel {
position: absolute;
border: 1px solid #ffffff;
overflow: hidden;
background-color: white;
}
sorry about the repeat, but i figured this might be a better place for this question:
with the ajax ui stuff in coldfusion (specifically <cflayout type="tab"> in my case), is there a way to use window.onload events?
i am attempting to use a script for zebra striping tables, but i'm having a hard time nailing down exactly where to put this code to make it work.
as it stands, it is almost as if the browser never "sees" the html behind the content because if you view source on a tabbed cflayout, there is no source there, just empty divs for every tab. this is clearly impossible though, because the content is rendered.
can anyone help me understand what is going on?
@matt - see the docs for AjaxOnLoad.
Hey there, thanks for all your work.
Sorry, I'm pretty new at this so I apologize if it's a dumb question...
How do I change the path of the /CFIDE links if the page isn't in the root directory of coldfusion admin?
In the page source, it's trying to reference http://www.url.com/CFIDE/sc......
Look at the cfajaximport tag. It lets you define the scriptsrc for other ajax stuff on the page.
Thanks very much for the response, I appreciate it.
hey gers,
what i usually do is, upload the scripts folder, which i copied from my local machine. And link to the folder which i uploaded, it's easier.
but you can also ask you hosting provider to map the cfide folder for you. HOOstMysite does it for you, but i don't think godaddy hosting does
I have a template with 4 cfLayOutArea tags. I have forms in each one of them. When I save contents of one tab via an AJAX call, I then do this as the final JavaScript line: ColdFusion.navigate('updateContactInfo.cfm', 'phone') where updateContactInfo is the template that is loaded to display the tab layout and "phone" is the name of the tab I wish to re-display with the new update form info.
It works except that I always get a least one other tab's content below the one I want to re-display.
Help ?