I ran accross a noteworthy question on Experts-Exchange today regarding a javascript error that occurs when you have a cflayout that navigates to a page with a cfchart tag.
The setup is that the main page (home.cfm) has cflayoutareas and one of them has a link that navigates to chart.cfm targeting a specific layout area.
home.cfm:
chart.cfm:
If you run chart.cfm by itself the chart shows up, but if you rund the main page code you an generic error "Error processing javascript in markup". It seems cfchart doesnt work when linked to via Coldfusion.navigate from a cflayout area.
This error does not pop up in FireFox, but I was able to duplicate it in IE. The solution (revised 6-9-2008) is to add a script tag to define a CF_RunContent() function that uses the DOM to replace the innerHTML of the CFLayoutarea generated DIV layer.
home.cfm:
Center layoutarea. If you change the code on home.cfm to the code below, you can watch both layout areas disappear.
<code>
<script type="text/javascript" charset='utf-8' src='/CFIDE/scripts/CF_RunActiveContent.js'></script>
<a href="#" onclick="ColdFusion.navigate('chart.cfm','Center')">chart</a>
<cflayout type="border" name="layoutborder">
<cflayoutarea name="Center" position="top" style="width:500px;height:200px" maxSize="200">
test 1
</cflayoutarea>
<cflayoutarea name="Center2" position="center">
test 2
</cflayoutarea>
</cflayout>
</code>
Good Catch! I didn't notice that the first time because I was only using one cflayoutarea. I dug a little deeper and it turns out that cf_runactivecontent.js file just sets up a function that uses document.write to write the embed and object tags for the flash file. Unfortunately IE does not allow this to happen after the initial page load so it doesn't work as intended.
Fortunately, where there's a will there's a way =) Here is a workaround/hack for this problem where I used the DOM model instead of the document.write to write the source for the flash object. I also had to put a small delay in there to avoid conflict with the ajax processes. Change the home.cfm to be like this:
<html>
<head>
<script type="text/javascript" charset='utf-8'>
function CF_RunContent(src){
setTimeout(function(){document.getElementById('Center').innerHTML = src;},5);
}
</script>
</head>
<body>
<a href="#" onclick="ColdFusion.navigate('chart.cfm','Center');">chart</a>
<cflayout type="border" name="layoutborder">
<cflayoutarea name="Center" position="top" style="width:500px;height:200px" maxSize="200">
test 1
</cflayoutarea>
<cflayoutarea name="Center2" position="center">
test 2
</cflayoutarea>
</cflayout>
</body>
</html>
I have a cfdiv tag that is binded to a page called chart.cfm
for example:
<cfdiv bind="url:chart.cfm?searchClass={what_class}" name="thechart2" ID="thechart2">
the chart.cfm contains the cfchart of which I am trying to display (which is type="flash").
works fine in FF but I am getting the same javascript error that you just talked about in IE 7.
Any thoughts would be greatly appreciated!
Thank you in advance.
Thanks!
I am wondering if its because I am using source in my cflayout tag with a bind?
Any suggestions would be hugely appreciated - this is the only place on the net that is talking about this (or so it seems)
<script type="text/javascript" charset='utf-8' src='/CFIDE/scripts/CF_RunActiveContent.js'></script>
<cflayout type="tab" name="mainTab" style="width:900px">
<cflayoutarea title="Detail" name="tab1" style="padding:10px;" source="#cgi.script_name#?vw=detailChart&product_id={targetProduct_ID:product_id}" />
<cflayoutarea title="Summary" name="tab2" style="padding:10px;" source="#cgi.script_name#?vw=summaryChart&product_id={targetProduct_ID:product_id}" />
</cflayout>
If you look a few comments above, you will see that my original solution (the one in the article) was not really fixing the problem. Even my second solution, which works correctly for 1 cflayoutarea with a chart, will probably not work in your case because you have two cflayoutarea tags with a chart. And, short of modifying some of the js files in the CFIDE directory (which I don't suggest doing), I am not quite sure how I to make it so that the CF_RunContent() could take an extra parameter that when defined will cause the content to be loaded into the defined div layers innerHTML like my workaround does, and using the document.write() when the second parameter is not defined. Ultimately that is probably close to what Adobe will end up doing to resolve this issue.
In the mean time, off the top of my head, it is possible to create a separate AJAX function to pull the carts and then replace the innerHTML of each of the cflayoutarea generated divs with the charts, but I don't have time right at this moment to actually prove that theory with an example. If you (or anyone else) are able to take that suggestion and run with it, please post the solution here if you figure it out. Otherwise, I will do it sometime over the next couple days and post it myself.
I went ahead and modified this post so that the correct solution is in the actual article, that way people who don't read comments can still get the correct answers.
I am using the tab style of cflayoutarea and calling source pages that holds a form. After some time I deduced that in the source page I had a JS function
declared that I was going to be using. I would get "Error processing JavaScript in markup for element cf_layoutarea12404278981088:" everytime I would
select this tab. Once I removed the JS function out to the main cflayout page the issue was gone.
Now what I was wondering was why does this happen? I am running into this issue again but have not yet figured out a "hack" for it. Currently I have a
form in the source page and want to uses JS for a form field focus function. The main function is declared on the main page that houses the cflayout.
However I want to call this function when the source page is loaded thus resulting in the above error.
<script type="text/javascript">
window.onload = formFocus('area');
</script>
Any help would be appreciated.
Thanks for the help Scott!
My other option was to do a window.setTimeout and just call the function.
only the last cfchart is shown.
Any ideas on how I could try to solve this issue?
Basically I'm looking for a way to display two (or maybe more) different cfcharts with a "loading" message on one page (since they load too long for comfort).
I am interested in hacks to the hack itself though, that allow for handling multiple areas.
Please post back if you find the time to come up with a more versatile solution. Haven't seen any of the other CF heavyweights weight in on the issue yet, so you're breaking ground here =)
So take the CF_RunContent function you created above and change it so that it looks like this:
CF_RunContent(theDiv,src)
Also replace this line:
setTimeout(function(){document.getElementById('Center').innerHTML = src;},5);
With this ('Center' is replaced):
setTimeout(function(){document.getElementById(theDiv).innerHTML = src;},5);
Now, on the page where you're doing a CFChart or other such tag, wrap it in a CFSAVECONTENT.
After the closing tag for that CFSAVECONTENT, output it like this (or save it to a variable, etc.:
#Replace(YOURCFSAVECONTENTVARIABLE,"CF_RunContent(","CF_RunContent('bottomTD',")#
The "bottomTD" is the ID of the element where you want the graph to go.
Using this you can keep the hack in one spot and just alter the output of graphs and such so that you force it to send in the other variable of where to go :)