views:

1327

answers:

6

Hi, I am trying to use the Google Maps API in a Coldfusion template that is a border type cflayoutarea container. However the map simply doesn't show up:

<cfif isdefined("url.lat")>
    <cfset lat="#url.lat#">
    <cfset lng="#url.lng#">
</cfif>    
<head>
<script src=         "http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key=xxxx" type="text/javascript">
        function getMap(lat,lng){    
      if (GBrowserIsCompatible()) {        
       var map = new GMap2(document.getElementById("map_canvas"));
       var pt= new GLatLng(lat,lng);
       map.setCenter(pt, 18,G_HYBRID_MAP);      
       map.addOverlay(new GMarker(pt));
      }    
     }    
</script>
</head>  
<cfoutput>
<body onLoad="getMap(#lat#,#lng#)" onUnload="GUnload()">
    Map:<br>
    <div id="map_canvas" style="width: 500px; height: 300px"/>
</body>
</cfoutput>"

where lat and lng are the co-ordinates in degree.decimal format. I have traced down to the line where GBrowserIsCompatible() somehow never returns TRUE and thus no further action was taken.

If opened separately the template works perfectly but just not when opened as a cflayoutarea container. Anyone has experience in this? Any suggestions is much appreciated.

Lawrence

Using Cf 8.01, Dreamweaver 8

A: 

Maybe the layout area doesn't have the right style. I think you may have to give the map_canvas a

position: absolute

or

position: relative

That's just a hunch.

wykyd
A: 

CFLayoutArea is a new AJAX tag added with ColdFusion version 8. (In addition to tags like CFWindow, CFDiv, etc.)

Within the AJAX-loaded content of any of these new tags, external JavaScript must be included from the containing page. In your case, that would be the page that includes the <cflayout> tag.

Try something like this:

in index.cfm (or whatever your containing file is):

<script src="http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key=xxxx" type="text/javascript">
    function getMap(lat,lng){               
        if (GBrowserIsCompatible()) {        
            var map = new GMap2(document.getElementById("map_canvas"));
            var pt= new GLatLng(lat,lng);
            map.setCenter(pt, 18,G_HYBRID_MAP);      
            map.addOverlay(new GMarker(pt));
        }    
    }
</script>
<cflayout>...</cflayout>

map.cfm (content of your map CFLayout tab):

<cfif structKeyExists(url, "lat")>
    <cfset variables.lat = url.lat />
    <cfset variables.lng = url.lng />
</cfif>    
<head></head>  
<cfoutput>
    <body onLoad="getMap(#variables.lat#,#variables.lng#)" onUnload="GUnload()">
        Map:<br>
        <div id="map_canvas" style="width: 500px; height: 300px"/>
    </body>
</cfoutput>
Adam Tuttle
A: 

Hi Adam,

Thanks for your advice. I can see the logic behind your suggestions, doing what is similar to the cfajaximport tag requirement of declaring functions at the container, instead of the containee, level.

Alas, the code does not work. No maps appeared inside the containee. The containee somehow just refuses to call the getMap function.

It is very frustrating indeed. If all else fails, I may have to make the map inside a pop-up window, but that's kind of ugly and inconvenient.

Again, thanks for your advice.

lawrencem49
+1  A: 

Success! (sort of...)

Finally got it working, but not in the way Adam suggested:

<script src= "http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key=xxxx" type="text/javascript"></script>
<script type="text/javascript">
    getMap=function(lat,lng){               
        if (GBrowserIsCompatible()){
            var map = new GMap2(document.getElementById("map_canvas"));
            var pt = new GLatLng(lat,lng);
      map.setCenter(pt, 18,G_HYBRID_MAP);      
            map.addOverlay(new GMarker(pt));  
        }    
    }
</script>  

 <cflayout name="testlayout" type="border">
    <cflayoutarea name="left" position="left" size="250"/>
     <cflayoutarea name="center" position="center"> 
            <!--- sample hard-coded co-ordinates --->
        <body onLoad="getMap(22.280161,114.185096)">
        Map:<br />
        <div id="map_canvas" style="width:500px; height: 300px"/>
        </body>
      </cflayoutarea> 
<!---       <cflayoutarea name="center" position="center" source="map_content.cfm?lat=22.280161&lng=114.185096"/> --->
</cflayout>

The whole thing must be contained within the same file or it would not work. My suspicion is that the getElementByID function, as it stands, cannot not reference an element that is outside of its own file. If the div is in another file (as in Adam's exmaple), it results in an undefined map, ie a map object is created but with nothing in it.

So I think this question is now elevated to a different level: how do you reference an element that is inside an ajax container?

lawrencem49
Well it turns out that the problem has nothing to do with js but an oddity with ColdFusion.navigate; if you use ColdFusion.navigate to point to a .cfm that calls a google map, the map won't show up (but if you call the map file it works fine.)
lawrencem49
+1  A: 

So I think this question is now elevated to a different level: how do you reference an element that is inside an ajax container?

It should be possible reference an element loaded via AJAX -- just not until the element is on screen (so not on page load). It looks like getMap() triggers everything. (Is that right?)

Try this: Take exactly what you have as your inline-content for the map tab, and make it the content of map_content.cfm; then instead of using body onload to fire the event, write it inline, after the div is defined:

<body>
    Map:<br />
    <div id="map_canvas" style="width:500px; height: 300px"/>
    <script type="text/javascript">
        getMap(22.280161,114.185096);
    </script>
</body>
Adam Tuttle
A: 

Hi Adam,

Tried your suggestion but still doesn't work; the map only shows when the calling code is inline. However, if this container page was called from yet another div the map disappears again.

I suspect this issue is related to the cflayout container; I'll look up the Extjs doc to see if there're any leads to a solution.

lawrencem49