Search code examples
plsqloracle-apexproceduregeocode

Google map disappearing in APEX region


I'm trying to display map in one of my apex pages region, this map will have draggable marker which links to text-fields on other region and displays geocode for latitude and longitude. Everythings works except one thing the map is appearing just for 0.5 second and disappears. I think the problem is somewhere within coding as I have other similar program where map works perfectly fine. I'm using PL/SQL to retrieve map from procedure in a database.

Here is my PROCEDURE:

create or replace PROCEDURE SHOW_LOCATION (
    map_div IN VARCHAR2 DEFAULT 'map-canvas',
    issue_street_address IN VARCHAR2,
    issue_post_code IN VARCHAR2,
    city IN VARCHAR2,
    lat_item IN VARCHAR2,
    long_item IN VARCHAR2)
is
    a_mapstr VARCHAR2 (32000);
begin
    a_mapstr := '

<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false">   </script>
<script type="text/javascript">
    var map;
    var marker;
    function initialize(myAddress, myLat, myLng) {
        var mapOptions = {
            zoom: 12,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        }    
        map = new google.maps.Map(document.getElementById('||''''|| map_div   ||''''||'),mapOptions);
        geocoder = new google.maps.Geocoder();
        geocoder.geocode( { '||''''||'address'||''''||': myAddress},   function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                var markerOptions = {
                    map: map,
                    draggable: true,
                    animation: google.maps.Animation.DROP,
                    flat: false,
                    position: results[0].geometry.location
                }
                map.setCenter(results[0].geometry.location);
                marker = new google.maps.Marker(markerOptions);
                google.maps.event.addListener(marker, '||''''||'dragstart'||''''||', function() {map.closeInfoWindow();} );
                google.maps.event.addListener(marker, '||''''||'dragend'||''''||', function(event) {
                  document.getElementById("'||lat_item||'").value=event.latLng.lat();
                   document.getElementById("'||long_item||'").value=event.latLng.lng();
                });
            } 
            else {
                document.getElementById("'||map_div||'").innerHTML = "No mapdata found for given address. Did you enter a correct address?";
            }
        });
    }

    google.maps.event.addDomListener(window, ''load'', initialize);
</script>';
--

sys.htp.p (a_mapstr);
EXCEPTION
    WHEN OTHERS
    THEN
        raise_application_error (-20000, 'error in show_map: ' || SQLERRM);
  END SHOW_LOCATION;

This is my PL/SQL to call the procedure:

SHOW_LOCATION('map_canvas','P20_ISSUE_STREET_NAME','P20_ISSUE_POST_CODE','P20_CITY','P20_LONGITUDE','P20_LATITUDE');
sys.htp.p('<script type="text/javascript">');
sys.htp.p('initialize('||''''||'Leidscheplein, Amsterdam,NL'||''''||');');
sys.htp.p('</script>');

and here is my html code for the region:

<div align="center" style="width: 100%; height: 300px;">
<div id="map_canvas" style="width: 500px; height: 300px"></div>

Solution

  • In your procedure code:

    google.maps.event.addDomListener(window, ''load'', initialize);
    

    In your call:

    SHOW_LOCATION('map_canvas','P20_ISSUE_STREET_NAME','P20_ISSUE_POST_CODE','P20_CITY','P20_LONGITUDE','P20_LATITUDE');
    sys.htp.p('<script type="text/javascript">');
    sys.htp.p('initialize('||''''||'Leidscheplein, Amsterdam,NL'||''''||');');
    sys.htp.p('</script>');
    

    So the region is rendered, and the procedure code is called. In this code is a call which is registered on the document onload event. Obviously, the document is not ready at this time.
    Secondly, you run a script which again initializes the map. This one will instantiate because it is not delayed until the load event.
    Shortly after, the document has been generated and the onload will fire, with no parameters. I suspect this causes the brief appearance of the map which then blips out.

    Try by removing the onload code from the procedure, and use this code after the function call (jQuery is safe because apex includes it by default, unless you happen to be on version 3.2 or the like):

    sys.htp.p('<script type="text/javascript">');
    sys.htp.p('$(document).ready(function(){ initialize("'||'Leidscheplein, Amsterdam,NL'||'"); });');
    sys.htp.p('</script>');