Implement Draggable Marker on Map And Move Marker on Map In Lightning Web Component.

Posted on March 31, 2022 Post Thumbnail

Yo Trailblazers,

Welcome back to heySalesforce (-_-)

In this blog post, I'm going to create a Lightning Web Component. In this component, We can drag marker on the Map to get current Coordinates.

Before reading this blog post, Have a look at following demo.

Demo for Draggable Marker on Map.

Map marker in Lwc

What you'll Learn from Blog Post :)

1. Map in Vf Page with draggable marker on Map.

2. Communication between LWC and Vf Page.

Let's Start :)

You must be thinking, Why we are going to create a LWC component instead of using Lightning-Map.

<template> 
<lightning-map map-markers="{mapMarkers}"> </lightning-map> 
</template>

https://developer.salesforce.com/docs/component-library/bundle/lightning-map/documentation

If you read this documentation, It says "Markers aren't draggable"

drag

As we are not able to do this using lightning-map.

I was searching about it, Then I found something on Google Maps Platform where, We can get coordinates by clicking on map. Check following link and screenshot.

It was: Getting Lat/Lng from a Click Event

Code for getting coordinates after clicking on Map.

Code for getting coordinates after clicking on Map.

function initMap() {
  const myLatlng = { lat: -25.363, lng: 131.044 };
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: myLatlng,
  });
  // Create the initial InfoWindow.
  let infoWindow = new google.maps.InfoWindow({
    content: "Click the map to get Lat/Lng!",
    position: myLatlng,
  });

  infoWindow.open(map);
  // Configure the click listener.
  map.addListener("click", (mapsMouseEvent) => {
    // Close the current InfoWindow.
    infoWindow.close();
    // Create a new InfoWindow.
    infoWindow = new google.maps.InfoWindow({
      position: mapsMouseEvent.latLng,
    });
    infoWindow.setContent(
      JSON.stringify(mapsMouseEvent.latLng.toJSON(), null, 2)
    );
    infoWindow.open(map);
  });
}

I made some changes to this code to work for Dragging Marker on Map too.

function initMap() {
const myLatlng = { lat: 1.363, lng: 103.044 };
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 4,
center: myLatlng,
});
// Create the initial InfoWindow.

let marker = new google.maps.Marker({
map,
draggable: true,
animation: google.maps.Animation.DROP,
position:myLatlng,
});
marker.addListener("drag", () => {
//infowindow.open(marker.get("map"), marker);
console.log(marker);
console.log(marker.get("position").toJSON());
});
}

Have a look at screenshot too.

Draggable Map marker in lwc

After making above change, We are able to move marker on Map.

Let's create a Visualforce page: dragMapMarkerPage

It's pretty simple, I have added comments too.

I'll use this Visualforce page in following LWC component as Iframe source.

<apex:page lightningStylesheets="true" showHeader="false" sidebar="false">
    <apex:slds />
    <head>
        <style type="text/css">
            html { height: 100% }
            body { height: 100%; margin: 0; padding: 0 }
            #map-canvas { width:100%;height:100%; }
        </style>
        <script src="https://maps.googleapis.com/maps/api/js"></script>
        <script>
            var map;
        //Getting parameters for initial position on map.
        var latitude = '{!$CurrentPage.parameters.latitude}';
        var longitude = '{!$CurrentPage.parameters.longitude}';
        //console.log(latitude);
        //console.log(longitude);
        let fullurl = window.location.href;
        //console.log('VF Url: '+fullurl);
        var lwcOrigin = fullurl.slice(0,fullurl.indexOf(".com/")+4);
        let host = '{!$CurrentPage.parameters.host}';
        //Checking if component placed on lightning /in community site.
        if(host ==='lightning')
            lwcOrigin = lwcOrigin.replace("--c.visualforce.com",".lightning.force.com");
        //Sending coordinates to Lightning Component.
        function sendToLigntningWC(latlng){
            //console.log('LWC Origin: '+lwcOrigin);
            let lightningOrigin = lwcOrigin;
            let messgaeToLWC = latlng;
            window.parent.postMessage(messgaeToLWC,lightningOrigin);
        }
        //initializing map
        google.maps.event.addDomListener(window, 'load', initialize);
        function initialize() {
            const myLatlng = { lat: parseFloat(latitude), lng: parseFloat(longitude)};
            const map = new google.maps.Map(document.getElementById("map-canvas"), {
                zoom: 15,
                center: myLatlng,
            });
            let marker = new google.maps.Marker({
                map,
                draggable: true,
                animation: google.maps.Animation.DROP,
                position:myLatlng
            });
            //function works on dragging of marker.
            marker.addListener("drag", () => {
                latitude = marker.get("position").toJSON().lat;
                longitude = marker.get("position").toJSON().lng;
                let coords = latitude +':'+longitude;
                sendToLigntningWC(coords);
            });
            }   
                </script>
    </head>
    <body>
        <div id="map-canvas"/>
    </body>
</apex:page>

Let's create a LWC Component: DragMapMarkerLwc 

DragMapMarkerLwc.html

<template>
    <lightning-card>
        <h3 slot="title">
            <lightning-icon class="slds-m-right_small" icon-name="action:map" size="large"></lightning-icon>
            Drag Map Marker in LWC!
        </h3>
        <lightning-input-location class="slds-m-horizontal_x-large slds-m-bottom_large" label="Default coordinates" latitude={latitude} longitude={longitude}></lightning-input-location>
            <iframe class="slds-m-horizontal_x-large slds-box" height="400px"  scrolling="no" src={mainIframeUrl} frameborder="0"  width="90%">
            </iframe>
    </lightning-card>
</template>

DragMapMarkerLwc.js

import { LightningElement,track } from 'lwc';
export default class DragMapMarkerLwc extends LightningElement {
    vfUrl ='/apex/dragMapMarkerPage?';
    mainIframeUrl='';
    latitude = 28.61;
    longitude = 77.21;
    connectedCallback(){
        let href = window.location.href;
        this.mainIframeUrl = this.vfUrl+'latitude='+this.latitude+'&longitude='+this.longitude+'&host=classic';
        if(href.includes("lightning.force.com")){
            this.mainIframeUrl = this.vfUrl+'latitude='+this.latitude+'&longitude='+this.longitude+'&host=lightning';
        }
        window.addEventListener( "message", this.handleCoordinates.bind(this), false);
    }
    handleCoordinates(message){
        if(message.data != null){
            let coords = message.data;
            this.latitude = coords.slice(0, coords.indexOf(":"));
            this.longitude = coords.slice(coords.indexOf(":")+1, coords.length);
            console.log(this.latitude);
            console.log(this.longitude);
        }
    }
}

DragMapMarkerLwc.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <isExposed>true</isExposed>
    <masterLabel>Drag Map Marker LWC</masterLabel>
    <targets>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
        <target>lightningCommunity__Page</target>
        <target>lightning__FlowScreen</target>
    </targets>
</LightningComponentBundle>

After Creating Visualforce Page and LWC Component.

Demo for Draggable Marker on Map.

Map in LwC

Use Api key in following code if you want to see clear Map.

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR-API-KEY"></script>

Have a look at the demo Again.

Demo for Draggable Marker on Map.

Note: This is just for Study Purposes And I above code may not follow best practices.

If you have any question Ask Me

Thanks for Reading :)

Write a comment for suggestions and hit the heart icon.


476
1

Tags: #salesforce #lwc

Comments

  • ponnisuresh Avatar
    ponnisuresh - 6 days ago
    Hi This is testing Purpose

Your message is required.

Get notified of new posts