Rob Featherpants asks:
I'm building ColdFusion sites again after a while away, and I wonder if you can help me with a little advice about cflayoutarea and tabs. I am building a tabbed interface as part of a form. Outside of the tabs is a textarea, with its height set as an inline style. I want to change this height when one of the tabs is selected and set a cookie to remember which tab was last active ... i.e. have onClick on the tab trigger a Javascript. Can I do this?
Yep, you can, although it does take a few lines of JavaScript.
ColdFusion provides an API to get access to the underlying Ext based TabPanel object. You can get this object by running:
var mytabs = ColdFusion.Layout.getTabLayout('mytabs');
If you check the Ext docs for TabPanel, you will see there is an 'on' API call that lets you easily add event listeners. I used this:
mytabs.on('tabchange', function(tabpanel,activetab) { console.log('changed to a new tab '+activetab.getText()); })
The tabchange event passes the tabpanel object and the active tab. I defined a function that simply uses Firebug to log the text of the selected tab. Here is a complete example. Please note I use AjaxOnLoad to run the code to register the event:
<html>
<head>
<script>
function setup() {
var mytabs = ColdFusion.Layout.getTabLayout('mytabs');
mytabs.on('tabchange', function(tabpanel,activetab) { console.log('changed to a new tab '+activetab.getText()); })
}
</script>
</head>
<body>
<cflayout type="tab" name="mytabs">
<cflayoutarea title="Tab 1">
tab 1
</cflayoutarea>
<cflayoutarea title="tab 2">
tab 2
</cflayoutarea>
</cflayout>
</body>
</html>
<cfset ajaxOnLoad('setup')>
Archived Comments
Just a note of thanks Ray, as I had an enhancement ticket for the project I'm working on which required something very similar. Just after I'd marked the ticket 'will not fix', (as I didn't think I'd be able to do it), I spotted your post.
Quickly changed the status and an hour later, I had a very happy client.
Cheers!
</cliff>
Awesome Ray ... many thanks. This has got me started in the right direction.
This AJAX stuff is cool and adds great depth to CF, but of course there is much more to learn, as the black box tags only go so far.
Also, it seems that there are a lot of gotchas with the tags themselves. I don't seem to be able to use cfcalendar within my cfdivs, and cfinput and cftextarea validation is ignored, in spite of importing the tags into the calling page. A lot of trial and error ahead!
I don't entirely get this function. The part I don't get is where do the parameters for function(tabpanel,activetab) come from? Are they members of mytabs or do they have to be instantiated somewhere else?
That data is passed automatically by the event.
Thanks! Got everything working now.
Ray, I've tried replicating this code in CF9 and firebug tells me that .getText() is not found. Also, it does not work. Did the ext-js attributes change in CF9?
Yes. The version of Ext in CF9 is 3.something or another - much newer. Any code you wrote making use of Ext APIs needs to be updated.
Ray, I have an existing ajax function for each tab that refreshes the tab using setTimeout. I would like to run clearTimeout() when a user clicks off of a tab so that the timer does not continue to update information that is not even being viewed. Do you know how I could accomplish this?
Ah interesting. Let me rephrase your question to make sure I get it.
You have some func that runs every N seconds. You want it to work with the current tab. So if you switch tabs, the current interval should stop a new one should start.
Dumb q- why not use the same interval and have it check to see which tab is active?
Yes, that is correct on what I am doing.
I could use the same interval/function I suppose but how do I identify the active tab at any given moment?
It's been a while since I used CF's built in tabs. I coulda sworn there was a simple API to get it but I don't see it. Most likely it is simple if you call getTabLayout first. Let me do a quick test... but it will be for CF9. That ok? CF9 has a much newer Ajax library then 8 so if not - um - then I'll figure something else out. ;)
We are using CF8, but maybe what you come up with will still be viable?
I appreciate the assistance.
Found it:
http://www.johncblandii.com...
His blog is a bit hard to read - but you can see where he gets the 'active' tab.
Thanks! I will give this a shot.
Ray, while we are on the subject of Ajax refreshing, I wanted to run this by you as well. I am using jQuery 1.4.4 and use the .get API to check to see if I need to refresh data on a page or not. The problem is that there is a memory leak somewhere in the snippet below that I cannot seem to find. You will notice that I do a lot of potentially useless things here like deleting and add back the timer all in an effort to figure out what is going on. I assumed that doing the .load was causing the problem, but at this point, the .load doesn't occur very frequently at all. Anyway, if I can figure out this memory leak issue, I will be able to hook it up to the CF tablayout and should have a nice thing going. Hopefully you or somebody else can easily identify something silly I may be missing here.
<script>
$(document).ready(function() {
function CheckAlerts() {
//Must tell Ajax not to cache results
$.ajaxSetup({ cache: false });
$.get("AjaxDataCheck/CheckForDataRefresh.cfm", { datacheck: "MyAlerts"},
function(data) {
if (data.indexOf("true") >= 0) {
$.ajaxSetup({ cache: false });
$('#responsecontainer').load('alertchecking_Inner.cfm');
//Clearing the timer and recreating may force gargage collection.
clearTimeout(CheckAlertsTimer);
delete CheckAlertsTimer;
CheckAlertsTimer = setTimeout(CheckAlerts,2000);
}
else
{
//Clearing the timer and recreating may force gargage collection.
clearTimeout(CheckAlertsTimer);
delete CheckAlertsTimer;
CheckAlertsTimer = setTimeout(CheckAlerts,2000);
}
});
CheckAlertsTimer = setTimeout(CheckAlerts,2000);
};
CheckAlerts()
});
</script>
Thanks!
Something else to note. This code works great in Mozilla. No leaking at all.
Not really sure. My knowledge of JS doesn't really get into memory leaks.
Besides getText(), is there any other way to get the tabs name? I am just getting [object object] as my value when I set a form value using jQuery. I used a js for-in-loop, and can see the data I want but I don't know the js code to get that specific data. Thanks
If you see the data in a key called foo, and ob is the result of getText(), then just use ob.foo. It's just like CFML structures.
Note: with CF 9 and higher, this function needs to be changed to:
function tabChangeListener(){
var mytabs = ColdFusion.Layout.getTabLayout('#tabName#');
mytabs.on('tabchange', doTabChange);
}
function doTabChange(){
var activeTabName = ColdFusion.Layout.getTabLayout('#tabName#').getActiveTab().title;
alert(activeTabName);
}
Thanks for sharing that update, Gregory.
Thanks Raymond!
On another note- I am getting very annoyed having to deal with the code changes in the plumbing every time CF is updated with their Ajax controls and I am going to make the transition to some other grid system. I read your comments on some alternatives, but have you played with JqxWidets or Kendo UI? I like Kendo as I can keep a consistent look and feel for both Cf and .Net apps, but the coldFusion docs for Kendo are sparse.
I have not used JqxWidgets and I haven't *really" used Kendo UI, but I know many of the folks at Telerik and they are top notch. I'd check Kendo first. Not fair for me to say it is better than JqxWidgets, but I'd start there. If you have trouble, let me know. I can maybe hook you up with the right people.
hi Gregory, Jen here from Telerik...if you have any questions about Kendo UI, please contact us on the Developer Relations team - I'm at jen.looper@telerik.com. You might also take a look at http://jqueryuiwidgets.com/ by Cody Lindley, also on our team.