Javascript – Execute JavaScript from a Composite Component

composite-component, google-maps, javascript, jsf

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();"

Best Solution

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") ...