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:

<cflayout type="border" name="layoutborder">
<cflayoutarea name="Center" position="center">
<a href="#" onclick="ColdFusion.navigate('chart.cfm','Center')">chart</a>
</cflayoutarea>
</cflayout>

chart.cfm:

<cfchart>
<cfchartseries type="line" serieslabel="2008">
<cfchartdata item="January" value="100">
</cfchartseries>
</cfchart>

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:

<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>
</cflayout>

</body>
</html>

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Rand's Gravatar Thanks for the tip!
# Posted By Rand | 3/25/08 4:45 PM
Matt's Gravatar This still does not seem to be working correctly. Whenever the chart link is clicked, the chart does load, however the chart is shown on a new page rather than replacing the HTML in the
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>
# Posted By Matt | 5/30/08 6:50 PM
Scott Bennett's Gravatar @Matt,

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>
# Posted By Scott Bennett | 5/30/08 8:56 PM
Calvin's Gravatar Hello

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.
# Posted By Calvin | 6/6/08 2:59 PM
Calvin's Gravatar Oh nevermind i got it to work.!!

Thanks!
# Posted By Calvin | 6/6/08 4:10 PM
Gary's Gravatar I am also getting the javascript error, but adding the js call doesn't help.
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>
# Posted By Gary | 6/9/08 5:52 PM
Scott Bennett's Gravatar Gary,

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.
# Posted By Scott Bennett | 6/9/08 6:37 PM
Scott Bennett's Gravatar FYI to all readers,

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.
# Posted By Scott Bennett | 6/9/08 6:46 PM
Crowe182's Gravatar This seems to be on a similar level of an issue I ran across a month ago.

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.
# Posted By Crowe182 | 4/22/09 5:24 PM
Scott Bennett's Gravatar the window.onload would not run because the window itself is not being reloaded, the source is being retrieved via ajax then a div layer is being dynamically updated with the content. You will have to define a listener on the main layout page so that when that tab is selected, it focuses on the formfield.
# Posted By Scott Bennett | 4/22/09 5:42 PM
Crowe182's Gravatar Ahhh..

Thanks for the help Scott!

My other option was to do a window.setTimeout and just call the function.
# Posted By Crowe182 | 4/22/09 6:06 PM
jerr's Gravatar Thanks for this solution. However, when trying to display two cfcharts in one cfdiv (or two different cfdiv's with one cfchart each),
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).
# Posted By jerr | 5/18/09 11:22 AM
Eric's Gravatar This is the first instance I've seen with a correct fix (or hack) for the "How to load CFCHART in a CFWINDOW" problem!

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 =)
# Posted By Eric | 6/29/09 12:32 AM
Eric's Gravatar Yay! Found a good fix.


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 :)
# Posted By Eric | 6/29/09 12:44 AM
 
Home | Blog | Portfolio | Contact | © 2001 - 2007 The ColdFusion Guy - Scott Bennett. All rights reserved.
BlogCFC was created by Raymond Camden. This blog is running version 5.9.