Is it possible to implement marker dragging in Google Maps v3 using JavaScript? How can this be achieved?

I am currently using this code to search for an address, drop a marker, and drag it afterwards.

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Google AJAX Local Search API + Maps API v3 demo</title>
    <link href="http://www.google.com/uds/css/gsearch.css" rel="stylesheet" type="text/css"/>
    <link href="./places.css" rel="stylesheet" type="text/css"/>

    <script src="http://maps.google.com/maps/api/js?sensor=false"></script>
    <script src="http://www.google.com/uds/api?file=uds.js&amp;v=1.0&amp;key=ABQIAAAAjU0EJWnWPMv7oQ-jjS7dYxQ82LsCgTSsdpNEnBsExtoeJv4cdBSUkiLH6ntmAr_5O4EfjDwOa0oZBQ" type="text/javascript"></script>
    <script type="text/javascript">
    //<![CDATA[

    // My global variables
    var gLocalSearch;
    var gMap;
    var gInfoWindow;
    var gSelectedResults = [];
    var gCurrentResults = [];
    var gSearchForm;

    // Create custom marker icons
    var gYellowIcon = new google.maps.MarkerImage(
      "http://labs.google.com/ridefinder/images/mm_20_yellow.png",
      new google.maps.Size(12, 20),
      new google.maps.Point(0, 0),
      new google.maps.Point(6, 20));
    var gRedIcon = new google.maps.MarkerImage(
      "http://labs.google.com/ridefinder/images/mm_20_red.png",
      new google.maps.Size(12, 20),
      new google.maps.Point(0, 0),
      new google.maps.Point(6, 20));
    var gSmallShadow = new google.maps.MarkerImage(
      "http://labs.google.com/ridefinder/images/mm_20_shadow.png",
      new google.maps.Size(22, 20),
      new google.maps.Point(0, 0),
      new google.maps.Point(6, 20));

     // Setting up the map and local searcher.
    function OnLoad() {

      // Initialize the map with default UI.
      gMap = new google.maps.Map(document.getElementById("map"), {
        center: new google.maps.LatLng(37.4419, -122.1419),
        zoom: 13,
        mapTypeId: 'roadmap'
      });
      // Create one InfoWindow to open when a marker is clicked.
      gInfoWindow = new google.maps.InfoWindow;
      google.maps.event.addListener(gInfoWindow, 'closeclick', function() {
        unselectMarkers();
      });

      // Initialize the local searcher
      gLocalSearch = new GlocalSearch();
      gLocalSearch.setSearchCompleteCallback(null, OnLocalSearch);
    }

    function unselectMarkers() {
      for (var i = 0; i < gCurrentResults.length; i++) {
        gCurrentResults[i].unselect();
      }
    }

    function doSearch() {
      var query = document.getElementById("queryInput").value;
      gLocalSearch.setCenterPoint(gMap.getCenter());
      gLocalSearch.execute(query);
    }

    // Executed when Local Search results are returned, old results cleared, and new ones loaded.
    function OnLocalSearch() {
      if (!gLocalSearch.results) return;
      var searchWell = document.getElementById("searchwell");

      // Clear the map and the old search well
      searchWell.innerHTML = "";
      for (var i = 0; i < gCurrentResults.length; i++) {
        gCurrentResults[i].marker().setMap(null);
      }
      // Close the infowindow
      gInfoWindow.close();

      gCurrentResults = [];
      for (var i = 0; i < gLocalSearch.results.length; i++) {
        gCurrentResults.push(new LocalResult(gLocalSearch.results[i]));
      }

      var attribution = gLocalSearch.getAttribution();
      if (attribution) {
        document.getElementById("searchwell").appendChild(attribution);
      }

      // Move the map to the first result
      var first = gLocalSearch.results[0];
      gMap.setCenter(new google.maps.LatLng(parseFloat(first.lat),
                                            parseFloat(first.lng)));

    }

    // Cancels form submission and executes AJAX Search API search.
    function CaptureForm(searchForm) {
      gLocalSearch.execute(searchForm.input.value);
      return false;
    }

    // Class representing a single Local Search result returned by Google AJAX Search API.
    function LocalResult(result) {
      var me = this;
      me.result_ = result;
      me.resultNode_ = me.node();
      me.marker_ = me.marker();
      google.maps.event.addDomListener(me.resultNode_, 'mouseover', function() {
        // Highlight the marker and result icon on mouseover. 
        me.highlight(true);
      });
      google.maps.event.addDomListener(me.resultNode_, 'mouseout', function() {
        if (!me.selected_) me.highlight(false);
      });
      google.maps.event.addDomListener(me.resultNode_, 'click', function() {
        me.select();
      });
      document.getElementById("searchwell").appendChild(me.resultNode_);
    }

    LocalResult.prototype.node = function() {
      if (this.resultNode_) return this.resultNode_;
      return this.html();
    };

function geocodePosition(pos) {
  geocoder.geocode({
    latLng: pos
  }, function(responses) {
    if (responses && responses.length > 0) {
      updateMarkerAddress(responses[0].formatted_address);
    } else {
      updateMarkerAddress('Cannot determine address at this location.');
    }
  });
}

    // Returns the GMap marker for this result, creating it with the given icon if not already created.
    LocalResult.prototype.marker = function() {
      var me = this;
      if (me.marker_) return me.marker_;
      var marker = me.marker_ = new google.maps.Marker({
        position: new google.maps.LatLng(parseFloat(me.result_.lat),
                                         parseFloat(me.result_.lng)),
        icon: gYellowIcon, shadow: gSmallShadow, map: gMap});
      google.maps.event.addListener(marker, "click", function() {
        me.select();
      });

  google.maps.event.addListener(marker, 'dragstart', function() {

  });

  google.maps.event.addListener(marker, 'drag', function() {

    updateMarkerPosition(marker.getPosition());
  });

  google.maps.event.addListener(marker, 'dragend', function() {

    geocodePosition(marker.getPosition());
  });

      return marker;
    };

    // Unselect any selected markers, highlight this result, and display the info window.
    LocalResult.prototype.select = function() {
      unselectMarkers();
      this.selected_ = true;
      this.highlight(true);
      gInfoWindow.setContent(this.html(true));
      gInfoWindow.open(gMap, this.marker());
    };

    LocalResult.prototype.isSelected = function() {
      return this.selected_;
    };

    // Remove highlighting on this result.
    LocalResult.prototype.unselect = function() {
      this.selected_ = false;
      this.highlight(false);
    };

    // Returns HTML displayed for a result before being saved.
    LocalResult.prototype.html = function() {
      var me = this;
      var container = document.createElement("div");
      container.className = "unselected";
      container.appendChild(me.result_.html.cloneNode(true));
      return container;
    }

    LocalResult.prototype.highlight = function(highlight) {
      this.marker().setOptions({icon: highlight ? gRedIcon : gYellowIcon});
      this.node().className = "unselected" + (highlight ? " red" : "");
    }


    GSearch.setOnLoadCallback(OnLoad);
    //]]>
    </script>
  </head>
  <body style="font-family: Arial, sans-serif; font-size: small;">
    <p>Perform a local search on the map below:</p>
    <div style="width: 500px;">
      <div style="margin-bottom: 5px;">
        <div>
          <input type="text" id="queryInput" value="pizza" style="width: 250px;"/>
          <input type="button" value="Find" onclick="doSearch()"/>
        </div>
      </div>
      <div style="position: absolute; left: 540px;">
        <div id="searchwell"></div>
      </div>
      <div id="map" style="height: 350px; border: 1px solid #979797;"></div>
    </div>

  </body>
</html>

The dragging of the marker appears to be malfunctioning. How can I resolve this issue? The code was sourced from Google's samples.

Answer №1

To enable marker dragging, the draggable option must be set to true for the markers as it is not enabled by default.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The behavior of Date's constructor differs when applied to trimmed versus untrimmed strings

Although it's commonly advised against creating a date from a string, I stumbled upon an interesting phenomenon: adding a space before or after the date string can impact the resulting date value. console.log([ new Date('2019-03'), ...

Connecting a pre-existing Angular 2 application to a Node.js server: A step-by-step guide

I am currently working on an Angular 2 application with the following structure : View Structure of my Angular app Furthermore, on the server side : View Structure of server app I have noticed that there are two module dependencies folders, but I am un ...

Creating a dynamic div and populating it with data from various elements in separate xhtml files: a step-by-step guide

I am looking to dynamically add a div under the div tag with id "includedContent" in the code below. Additionally, I would like to modify the load method to accept an array of ids instead of a hardcoded Id(123) and display the data in the dynamically creat ...

How can I effectively save data to a session using connect-redis?

I am looking to save the username of an account into session storage. I am currently using node.js with the expressjs framework and have attempted to utilize connect-redis for storing sessions, following a tutorial on expressjs. Can someone please guide ...

Creating numerous pre-signed URLs using an Application Programming Interface

An API has been developed to generate pre-signed URLs for files stored in a private S3 bucket. The goal is to store these URLs in an array for access from another application. ["FILE1 pre-signed URL", "FILE2 pre-signed URL", etc..] However, there seems to ...

Is there a way to prevent a link from activating when I click on one of its internal elements?

Within a div nested inside an "a" tag (specifically in Link within next.js), there is another div labeled as "like." When clicking anywhere within the main div, the intention is for it to redirect to the destination specified by the "a" tag. However, if th ...

What's the secret behind generating a crisp 400 on paper?

Understanding Why it Prints 400 I'm struggling to comprehend the logic behind this var x = {}, y = { key: "y" }, z = { key: "z" }; x[y] = 100; x[z] = 200; console.log(x[y] + x[z]); ...

What is preventing Backbone from triggering a basic route [and executing its related function]?

Presenting My Router: var MyRouter = Backbone.Router.extend({ initialize: function(){ Backbone.history.start({ pushState:true }); }, routes: { 'hello' : 'sayHello' }, sayHello: function(){ al ...

Will my JavaScript function be triggered when the page is resized while printing?

I have a simple HTML layout where I am using the TextFill jQuery library to automatically adjust the text size based on available space. Everything looks good on screen, but when printed, it seems like the page is resized and the JavaScript needs to be re ...

Tips for accessing nested documents from Firebase in React.js

Here is a snippet of code from my React project: import React, { useState } from "react"; import { db } from "../firebase"; import { collection, Firestore, getDocs } from "firebase/firestore"; function Document() { const ...

Leveraging the power of JavaScript to reveal concealed div elements

I've got a collection of divs (five in total) with a hidden class applied to them in my CSS stylesheet. Each div also has its own unique ID. My goal is to use JavaScript to reveal these divs one by one. Here's an example of what I'm looking ...

PHP variables that are constantly changing

I recently developed a website that showcases random entries from a database to viewers. Here is the current code snippet I am using: $records = "SELECT * FROM xxx"; $records_query = mysql_query($records); $num_records = mysql_num_rows($records_query); $i ...

Achieving stylish CSS effects on dynamically loaded content post AJAX request

I am currently developing an application that utilizes AJAX to fetch JSON data and then uses an ES6 template literal to construct the view. It's a simple demonstration: let mountPoint = document.getElementById("mountPoint"); let view = document.cre ...

Obtaining various values for checkboxes using dynamic data in a React application

Retrieve all checkbox values dynamically import * as React from "react"; import Checkbox from "@mui/material/Checkbox"; import FormControlLabel from "@mui/material/FormControlLabel"; import axios from "axios"; expor ...

Understanding the moment when the DOM is fully rendered within a controller

I'm currently facing an issue with AngularJS. In my controller, I have a $watch setup like this: function MyController() { $watch('myModel', function() { $rootScope.$emit('do-oper'); }); } The value of 'myMod ...

Issues with making cross-domain requests using jQuery and PHP

I have stumbled upon a similar question that has been asked before, but unfortunately, the answer provided did not give me enough guidance to identify where my code is incorrect. I apologize if this question resembles a previously existing one; I have spen ...

Enhancing the Efficiency of Android Programming

For my application, I am currently displaying 12 markers on a map, each of which triggers a dialog box showing the location's address when tapped. However, I believe there is a more efficient way to handle this. I have been experimenting with creating ...

What is the best way to transform React API data into props that can be utilized in different components?

I've been struggling with this issue for quite some time now, unable to understand how to manipulate the data in a way that allows me to use it in other components. Although I can display the data correctly, I'm advised to structure it within a f ...

Guide on showing a dropdown menu depending on the data in the current array index within a table

I am working with an object array that I want to display in a table. My goal is to have a dropdown select if the 'validvalues' field is not empty. How can I achieve this so that each row in the table has different options from the array? When &ap ...

Guide on efficiently injecting data into a database using JavaScript and SQL from an array of objects

Let's simplify this process. I am creating a dynamic form for clients to submit data to a PostgreSQL database using React on the front end and NodeJs on the back end. Once the form is filled out, the inputs are stored in an array of objects like this ...