1

I have incorporated google map to display pins on a map for Account records. I am using navigator.geolocation.getCurrentPosition(function(position) to center the map when it load and to get the users position.

When a user chooses a pin on the map and redirects to the account record, I want to populate the LAT/LNG back to the account. I am using a combination of Visualforce page and Lightning controller as shown below.

Can it be added as part of the marker.addListener('click', function()), which calls back to the lightning controller? Is so, how would it be incorporated?

Visualforce page:

<apex:page showHeader="false">
    <html>
        <head>
            <!-- 
                This stylesheet contains specific styles for displaying the map on this page. Replace it with your own styles as described in the documentation:
                https://developers.google.com/maps/documentation/javascript/tutorial 
            -->
            <link rel="stylesheet" href="{!$Resource.GoogleMap}"/>
        </head>
        <body>

            <div id="map"></div>
            <script>
            var lexOrigin = 'https://{!$CurrentPage.parameters.lcHost}';

            //Data for Google map
            var data;

            //Send message to LC
            function sendToLC(message) {
                if(typeof(lexOrigin) != 'undefined'){
                    parent.postMessage(message, lexOrigin);
                }
            }

            //Receive message from LC
            window.addEventListener("message", function(event) {
                //If page is public (like used in force.com sites) then be careful about the origin
                //if (event.origin !== lexOrigin) {
                    // Not the expected origin: reject message!
                    //return;
                //}
                // Handle message
                console.log('Data Sent to VF: ', event.data);
                data = event.data;


                if(typeof(event.data.loadGoogleMap) != 'undefined'){
                    //Load Google Map Script
                    var script = document.createElement("script");
                    script.src = "https://maps.googleapis.com/maps/api/js?key=xxxxxxxxxxxxxxxxxxxx&callback=initMap";
                    document.getElementsByTagName("head")[0].appendChild(script);        
                }
            }, false);

            //Callback when Google Map is loaded
            function initMap() {
                //Add marker for each point along with text
                function addMarker(feature) {
                console.log('feature ===> ' + JSON.stringify(feature));

                    var markerColour;
                    var basePinUrl = "https://chart.apis.google.com/chart?chst=d_map_xpin_letter&chld=";
                    if(feature.pintype == "New"){
                        markerColour = basePinUrl.concat("pin|%E2%80%A2|0099ff");
                    } else if(feature.pintype == "Sale") {
                        markerColour =  basePinUrl.concat("pin|%E2%80%A2|00e600");
                    } else if(feature.pintype == "Follow-up") {
                        markerColour =  basePinUrl.concat("pin|%E2%80%A2|ff9900");
                    }else if(feature.pintype == "No Sale") {
                        markerColour = basePinUrl.concat("pin|%E2%80%A2|cc2900");
                    }else if(feature.pintype == "Appointment") {
                        markerColour = basePinUrl.concat("pin|%E2%80%A2|9933FF");
                    }else {
                        markerColour = basePinUrl.concat("pin|%E2%80%A2|cc2900");
                    }

                    var marker = new google.maps.Marker({
                        position: feature.position,
                        //icon: icons[feature.type].icon,
                        map: map,
                        title:feature.markerText,
                        icon:markerColour
                    });
                    var infoWindow = new google.maps.InfoWindow({
                        content: feature.markerText
                    });

                    marker.addListener('click', function() {
                        infoWindow.open(map, marker);
                        sendToLC({'state':'NavigateToAct', 'id':feature.id});
                    });
                }

                //Create new map
                var map = new google.maps.Map(document.getElementById("map"), JSON.parse(data.mapOptions));

                 //Set map center
                infoWindow = new google.maps.InfoWindow;
                if (navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition(function(position) {
                        var pos = {
                            lat: position.coords.latitude,
                            lng: position.coords.longitude
                        };

                      //  infoWindow.setPosition(pos);
                     //   infoWindow.setContent('Location found....you are here.');
                     //   infoWindow.open(map);
                        map.setCenter(pos);
                    });
                } else {
                    map.setCenter(data.mapOptionsCenter);
                }

                //iterate through map data for each point (even if 1)
                var mapData = data.mapData;
                for(var i=0, j=mapData.length; i<j; i++){
                    //Add marker for each point
                    var myLatlng = new google.maps.LatLng(mapData[i].lat, mapData[i].lng);
                    addMarker({position: myLatlng, markerText: mapData[i].markerText, id: mapData[i].id, pintype:mapData[i].pintype});
                }
            }

            //Let LC know that VF page been loaded along with it's URL
            //LC will then send the data
            //This is done because LC has no way to know that VF page in iFrame has been loaded, event listener set and ready for data
            var vfHost = "{!LEFT($CurrentPage.URL,FIND('/',$CurrentPage.URL,9))}";
            sendToLC({'state':'LOADED', 'vfHost': vfHost});
            </script>      
    </body>
    </html>
</apex:page>

GoogleMap controller:

({
    doInit : function(component, event, helper) {
        //Send LC Host as parameter to VF page so VF page can send message to LC; make it all dynamic
        component.set('v.lcHost', window.location.hostname);

        //Add message listener
        window.addEventListener("message", function(event) {
            //Can enable origin control for more security
          /* if (event.origin != vfOrigin) {
                console.log('Wrong Origin');
                 //Not the expected origin: Reject the message!
                return;
            }*/

            // Handle the message
            if(event.data.state == 'LOADED'){
                //Set vfHost which will be used later to send message
                component.set('v.vfHost', event.data.vfHost);

                //Send data to VF page to draw map

                helper.sendToVF(component, helper);
            }
            if(event.data.state == 'NavigateToAct'){
                console.log('account id ===> ' + event.data.id);
                var urlEvent = $A.get("e.force:navigateToURL");
                urlEvent.setParams({
                    "url": '/'+event.data.id,
                    "isredirect" :false
                });
                urlEvent.fire();
            }
        }, false);
    }
})

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.