1

Good day, I have a problem that has annoyed me for a couple of hours now. It's very straight forward. I try to invoke/execute a JavaScript when the composite component is rendered. Like what you can do with the html tag body and onload.

How can I reference the in-line JavaScript to be executed ?

<cc:implementation>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false" />
    <div id="#{cc.clientId}" >

        <div id="map_canvas" style="width: 850px; height: 350px; padding: 1px; border: darkblue" />

        <script>init();</script>

        <script type="text/javascript">
            var map = null;
            function init() {
                var latlng = new google.maps.LatLng(51.5001524, -0.12623619);
                var myOptions = {
                    zoom: 7,
                    center: latlng,
                    mapTypeId: google.maps.MapTypeId.ROADMAP
                };
                map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
            }
        </script>
    </div>
    </cc:implementation>

I have tried with this.init() , #{cc.clientId}.init() .But the JS can't be found in the context. If I execute it from a JSF/ajax component it works fine with just "init();"

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Chris
  • 712
  • 3
  • 16
  • 39
  • It works fine also when i put the JS in seperate file and include it with tag. – Chris Jun 15 '11 at 14:11
  • Why do you have the call to "init()" inside a separate ` – Pointy Jun 15 '11 at 14:15

1 Answers1

5

You're calling init() before the function has been definied.

Put the call after the function definition.

<script type="text/javascript">
    var map = null;
    function init() {
        var latlng = new google.maps.LatLng(51.5001524, -0.12623619);
        var myOptions = {
            zoom: 7,
            center: latlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    }
</script>
<script>init();</script>

Or just get rid of the function call and just execute it directly. It'll just work as it's been executed after <div id="map_canvas"> has been definied.

<script type="text/javascript">
    var map = null;
    var latlng = new google.maps.LatLng(51.5001524, -0.12623619);
    var myOptions = {
        zoom: 7,
        center: latlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
</script>

Unrelated to the concrete problem: you've another design flaw in your composite component. This component cannot be reused more than once in the same view. You would end up with multiple <div id="map_canvas"> elements in the HTML. Having multiple elements with the same id in HTML is illegal. Fix it accordingly:

<div id="#{cc.clientId}_map_canvas" ...>

and

... document.getElementById("#{cc.clientId}_map_canvas") ...
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks @BalusC. Yes I realise that is design flaw, to use the static name for the div. But the outer
    , helps as long their is only one component per form. Try to re-design that later.
    – Chris Jun 15 '11 at 15:17
  • By the way, I'll be adding more JS functions, so I try to wrap variables in functions. Hence the invoke tag. Hmm, not my most brightest day, thanks for the hint. – Chris Jun 15 '11 at 15:21
  • 1
    No, the ID of the outer div does not help in any way. HTML is not JSF. HTML does not prepend ID's of nested components or something as JSF does for components inside a `NamingContainer`. – BalusC Jun 15 '11 at 15:23
  • So that's why you can't give the Composite Component a id="someID". So its better to wrap them in panels with ID then, if you need more than one of the same CC on the same page ?! – Chris Jun 15 '11 at 15:38
  • 2
    No, that is not true. JSF won't change/prepend IDs of **plain HTML elements**. They will just be printed to response as-is. JSF will only change/prepend IDs of real JSF components. If you replace `
    ` by `` then JSF will prepend it automagically with `#{cc.clientId}`.
    – BalusC Jun 15 '11 at 15:40
  • I've tried before to use the panelGroup tag for the google map. But the problem is that the map won't render when I change the div to panelGroup. – Chris Jun 15 '11 at 16:00
  • Then you've omitted the `layout="block"` or not fixed the ID in `getElementById()`. – BalusC Jun 15 '11 at 16:08