Google Map v3 Editing & Saving Markers in Database – II

In previous article I discussed about loading the Google map on a HTML page, adding-removing the markers and displaying info windows. In this article we are moving to the next step, here we are going to load markers from PHP generated XML file, and we will edit/save marker information into the database, finally creating a total custom map for the website.

Edit Save Google Marker

I suggest you to go through previous post first, because you don’t want to get confused with markers and info windows of the map while reading this article.

In this article, I have created three functions create_marker(), remove_marker() and save_marker() to make things easier. As discussed in earlier post we can add event listeners in our JavaScript, we can simply call these function in our event listeners to do the required task.

Custom JavaScript Functions

Since our code is only going to expand, it’s a good idea to break them into small functions, so that we can just pass the arguments to these functions and use them rapidly in our programs. Take a look at these functions below, first function creates the marker with specified parameters, second one simply removes the marker from database and the map, the third function is used to save marker information into the database using jQuery ajax.

Create/Add Marker

As you can see, the create_marker function requires some familiar arguments to add a marker on the map. Map coordinates, map title, description, icon path and some boolean variables. The title and description will be used in info window, and then we add the event listeners to the marker object, which can make info window pop-open, or delete the marker from the map. The newly created markers are set as draggable, so the user can move the markers to any position before saving its information. It is bit difficult to explain each line from here, I just hope you’ll go through each comment lines, which will hopefully help you understand the codes more clearly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//############### Create Marker Function ##############
function create_marker(MapPos, MapTitle, MapDesc,  InfoOpenDefault, DragAble, Removable, iconPath)
{                
    //new marker
    var marker = new google.maps.Marker({
        position: MapPos,
        map: map,
        draggable:DragAble,
        animation: google.maps.Animation.DROP,
        title:"Hello World!",
        icon: iconPath
    });
   
    //Content structure of info Window for the Markers
    var contentString = $('<div class="marker-info-win">'+
    '<div class="marker-inner-win"><span class="info-content">'+
    '<h1 class="marker-heading">'+MapTitle+'</h1>'+
    MapDesc+
    '</span><button name="remove-marker" class="remove-marker" title="Remove Marker">Remove Marker</button>'+
    '</div></div>');   

   
    //Create an infoWindow
    var infowindow = new google.maps.InfoWindow();
    //set the content of infoWindow
    infowindow.setContent(contentString[0]);

    //Find remove button in infoWindow
    var removeBtn   = contentString.find('button.remove-marker')[0];

   //Find save button in infoWindow
    var saveBtn     = contentString.find('button.save-marker')[0];

    //add click listner to remove marker button
    google.maps.event.addDomListener(removeBtn, "click", function(event) {
        //call remove_marker function to remove the marker from the map
        remove_marker(marker);
    });
   
    if(typeof saveBtn !== 'undefined') //continue only when save button is present
    {
        //add click listner to save marker button
        google.maps.event.addDomListener(saveBtn, "click", function(event) {
            var mReplace = contentString.find('span.info-content'); //html to be replaced after success
            var mName = contentString.find('input.save-name')[0].value; //name input field value
            var mDesc  = contentString.find('textarea.save-desc')[0].value; //description input field value
            var mType = contentString.find('select.save-type')[0].value; //type of marker
           
            if(mName =='' || mDesc =='')
            {
                alert("Please enter Name and Description!");
            }else{
                //call save_marker function and save the marker details
                save_marker(marker, mName, mDesc, mType, mReplace);
            }
        });
    }
   
    //add click listner to save marker button        
    google.maps.event.addListener(marker, 'click', function() {
            infowindow.open(map,marker); // click on marker opens info window
    });
     
    if(InfoOpenDefault) //whether info window should be open by default
    {
      infowindow.open(map,marker);
    }
}

Remove Marker

The remove_marker() function removes the marker from the map using the exact marker coordinates. In the database it looks for longitude and latitude values to delete a marker record. As explained earlier new markers are set to draggable, but the saved markers are not. So, here we simply check this marker draggable state and determine whether it should be removed from the map only or from database as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//############### Remove Marker Function ##############
function remove_marker(Marker)
{
    /* determine whether marker is draggable
    new markers are draggable and saved markers are fixed */

    if(Marker.getDraggable())
    {
        Marker.setMap(null); //just remove new marker
    }
    else
    {
        //Remove saved marker from DB and map using jQuery Ajax
        var mLatLang = Marker.getPosition().toUrlValue(); //get marker position
        var myData = {del : 'true', latlang : mLatLang}; //post variables
        $.ajax({
          type: "POST",
          url: "map_process.php",
          data: myData,
          success:function(data){
                Marker.setMap(null);
                alert(data);
            },
            error:function (xhr, ajaxOptions, thrownError){
                alert(thrownError); //throw any errors
            }
        });
    }
}

Save Marker

The save_marker function is used to pass the POST variables to our PHP page using jQuery Ajax, and then the variables will be stored in database. On a successful response, it replaces the HTML content of info window, sets marker draggable state to false, and also changes the icon. Don’t forget to replace icon URL in the code for your markers, or you might start wondering why your markers are’t appearing on the map.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//############### Save Marker Function ##############
function save_marker(Marker, mName, mAddress, mType, replaceWin)
{
    //Save new marker using jQuery Ajax
    var mLatLang = Marker.getPosition().toUrlValue(); //get marker position
    var myData = {name : mName, address : mAddress, latlang : mLatLang, type : mType }; //post variables
    console.log(replaceWin);       
    $.ajax({
      type: "POST",
      url: "map_process.php",
      data: myData,
      success:function(data){
            replaceWin.html(data); //replace info window with new html
            Marker.setDraggable(false); //set marker to fixed
            Marker.setIcon('http://PATH-TO-YOUR-WEBSITE-ICON/icons/pin_blue.png'); //replace icon
        },
        error:function (xhr, ajaxOptions, thrownError){
            alert(thrownError); //throw any errors
        }
    });
}

Putting Functions Together

We now have all the required functions, we can now load the Google map into the page. Whenever required these functions will be called within the code to do the specific task. In previous article the jQuery was included in the page, here too we will be using jQuery to load Google Map and to make Ajax request to PHP page.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
$(document).ready(function() {
    var mapCenter = new google.maps.LatLng(47.6145, -122.3418); //Google map Coordinates
    var map;

    map_initialize(); // initialize google map
   
    //############### Google Map Initialize ##############
    function map_initialize()
    {
        var googleMapOptions =
        {
            center: mapCenter, // map center
            zoom: 17, //zoom level, 0 = earth view to higher value
            panControl: true, //enable pan Control
            zoomControl: true, //enable zoom control
            zoomControlOptions: {
            style: google.maps.ZoomControlStyle.SMALL //zoom control size
        },
            scaleControl: true, // enable scale control
            mapTypeId: google.maps.MapTypeId.ROADMAP // google map type
        };
   
        map = new google.maps.Map(document.getElementById("google_map"), googleMapOptions);        
       
        //Load Markers from the XML File, Check (map_process.php)
        $.get("map_process.php", function (data) {
            $(data).find("marker").each(function () {
                 //Get user input values for the marker from the form
                  var name      = $(this).attr('name');
                  var address   = '<p>'+ $(this).attr('address') +'</p>';
                  var type      = $(this).attr('type');
                  var point     = new google.maps.LatLng(parseFloat($(this).attr('lat')),parseFloat($(this).attr('lng')));

                  //call create_marker() function for xml loaded maker
                  create_marker(point, name, address, false, false, false, "http://PATH-TO-YOUR-WEBSITE-ICON/icons/pin_blue.png");
            });
        });
       
        //drop a new marker on right click
        google.maps.event.addListener(map, 'rightclick', function(event) {
            //Edit form to be displayed with new marker
            var EditForm = '<p><div class="marker-edit">'+
            '<form action="ajax-save.php" method="POST" name="SaveMarker" id="SaveMarker">'+
            '<label for="pName"><span>Place Name :</span><input type="text" name="pName" class="save-name" placeholder="Enter Title" maxlength="40" /></label>'+
            '<label for="pDesc"><span>Description :</span><textarea name="pDesc" class="save-desc" placeholder="Enter Address" maxlength="150"></textarea></label>'+
            '<label for="pType"><span>Type :</span> <select name="pType" class="save-type"><option value="restaurant">Rastaurant</option><option value="bar">Bar</option>'+
            '<option value="house">House</option></select></label>'+
            '</form>'+
            '</div></p><button name="save-marker" class="save-marker">Save Marker Details</button>';

            //call create_marker() function
            create_marker(event.latLng, 'New Marker', EditForm, true, true, true, "http://PATH-TO-YOUR-WEBSITE-ICON/icons/pin_green.png");
        });                            
    }
});

Database Table

To retrieve and save the marker details, I’ve create a table in the MySQL database. It’s exactly the same table from Google Store Locator example page. Just run this SQL query in your phpMyAdmin page to have this table created.

1
2
3
4
5
6
7
CREATE TABLE `markers` (
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
  `name` VARCHAR( 60 ) NOT NULL ,
  `address` VARCHAR( 80 ) NOT NULL ,
  `lat` FLOAT( 10, 6 ) NOT NULL ,
  `lng` FLOAT( 10, 6 ) NOT NULL
) ENGINE = MYISAM ;

PHP XML Generator & Database Connector

Once our custom map page is created, we can now move on to server side coding with PHP, in other words, we need to create a PHP page that generates XML file for the marker, and also adds and removes the records from the database. The code below is derived from phpsqlajax_genxml.php, but I’ve modified it to implement MySQLi. The code block that saves and deletes markers from database record was added later. Code uses PHP DOMDocument to generate XML file. Saving & deletion of marker will occur only when the form data is sent with the HTTP POST method, else the file will generate XML document for the map using DB records as usual.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<?php
// database settings
$db_username = 'root';
$db_password = '';
$db_name = 'test';
$db_host = 'localhost';

//mysqli
$mysqli = new mysqli($db_host, $db_username, $db_password, $db_name);

if (mysqli_connect_errno())
{
    header('HTTP/1.1 500 Error: Could not connect to db!');
    exit();
}

################ Save & delete markers #################
if($_POST) //run only if there's a post data
{
    //make sure request is comming from Ajax
    $xhr = $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
    if (!$xhr){
        header('HTTP/1.1 500 Error: Request must come from Ajax!');
        exit();
    }
   
    // get marker position and split it for database
    $mLatLang   = explode(',',$_POST["latlang"]);
    $mLat       = filter_var($mLatLang[0], FILTER_VALIDATE_FLOAT);
    $mLng       = filter_var($mLatLang[1], FILTER_VALIDATE_FLOAT);
   
    //Delete Marker
    if(isset($_POST["del"]) && $_POST["del"]==true)
    {
        $results = $mysqli->query("DELETE FROM markers WHERE lat=$mLat AND lng=$mLng");
        if (!$results) {  
          header('HTTP/1.1 500 Error: Could not delete Markers!');  
          exit();
        }
        exit("Done!");
    }
   
        //more validations are encouraged, empty fields etc.
    $mName      = filter_var($_POST["name"], FILTER_SANITIZE_STRING);
    $mAddress   = filter_var($_POST["address"], FILTER_SANITIZE_STRING);
    $mType      = filter_var($_POST["type"], FILTER_SANITIZE_STRING);
   
    $results = $mysqli->query("INSERT INTO markers (name, address, lat, lng, type) VALUES ('$mName','$mAddress',$mLat, $mLng, '$mType')");
    if (!$results) {  
          header('HTTP/1.1 500 Error: Could not create marker!');  
          exit();
    }
   
    $output = '<h1 class="marker-heading">'.$mName.'</h1><p>'.$mAddress.'</p>';
    exit($output);
}


################ Continue generating Map XML #################

//Create a new DOMDocument object
$dom = new DOMDocument("1.0");
$node = $dom->createElement("markers"); //Create new element node
$parnode = $dom->appendChild($node); //make the node show up

// Select all the rows in the markers table
$results = $mysqli->query("SELECT * FROM markers WHERE 1");
if (!$results) {  
    header('HTTP/1.1 500 Error: Could not get markers!');
    exit();
}

//set document header to text/xml
header("Content-type: text/xml");

// Iterate through the rows, adding XML nodes for each
while($obj = $results->fetch_object())
{
  $node = $dom->createElement("marker");  
  $newnode = $parnode->appendChild($node);  
  $newnode->setAttribute("name",$obj->name);
  $newnode->setAttribute("address", $obj->address);  
  $newnode->setAttribute("lat", $obj->lat);  
  $newnode->setAttribute("lng", $obj->lng);  
  $newnode->setAttribute("type", $obj->type);  
}
echo $dom->saveXML();

Conclusion

At this point, I am sure you are able to clutch few things about Google Map, in this brief article. There are many more things you can do with your own custom map, create local directory, restaurant or the store locator, sky is the limit. I have put everything together in downloadable file, just download it from link below and try it yourself in your local testing environment. Good luck!

Download Demo

69 Comments Add Comment

  • Hello my friend
    Thank you on your code
    but
    ajax-save.php file not project inside
    Help me my friend

     Reply
  • can u help me how to full zoom and full out the map and default location set in india

     Reply
  • thanks a lot, you save my day

     Reply
  • It’s important to set your lat and lng columns to DECIMAL rather than FLOAT as MySQL uses FLOAT to store approximations – the exact value would be better.

     Reply
  • I can’t download the sample!!

     Reply
  • Hi i did all the things here but i really cannot solve the problem, everytime i need to enter data it says could not create marker please help

     Reply
    • Im assuming your sql is incorrect try this one:
      CREATE TABLE IF NOT EXISTS `markers` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(60) NOT NULL,
      `address` varchar(80) NOT NULL,
      `lat` float(10,6) NOT NULL,
      `lng` float(10,6) NOT NULL,
      `type` varchar(30) NOT NULL,
      PRIMARY KEY (`id`)
      ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

  • Hi there,

    Great job. I have a question though. In my case, when I am trying to delete a marker that I have just inserted it, it does not work. It removes from the UI bu the marker still remains in the database. Only when I refresh the page it removes it from the database.

    Any ideas?

     Reply
  • Hi, nice job man!

     Reply
  • Nice share.. great code. Any idea how could i create path link between markers.

    thanks a lot.

     Reply
  • nice share, big thanks, so help

     Reply
  • hello, i want to ask , how can the centre map auto detect location/geolocation

    Thanks

     Reply
  • thanks a lot san, you’re awesome

     Reply
  • Can somebody help me try to find this type of demo in asp.net C#!!!

     Reply
  • 1st of all – great piece of code.. after doing lots on my own i have stumbled in to it, made some changes and its grate.
    in order to render back my markers i have splited map_process (the part with the dome creation) to a different php file and debugged it on its on – was easier.
    i didn’t use the mysqli as i am using wcf and sqlserver

    note that sometimes the image path causes the script to fail…
    working like a charm , saving markers (with different icons) and rendering them from db (sqlserver)

     Reply
  • Hi

    Has the Author ever responded to anybodies questions?

     Reply
  • Hi,

    how to populate the map with all the marker details stored in database. Its like when the page loads, the map should be populated with all pre marked markers stored in database

     Reply
  • Great Job!
    The example allow multiple marker. How we could only allow one marker for each of the user?

    Thanks

     Reply
  • I am interested on your project Google Map v3 Editing & Saving Markers in Database http://www.sanwebe.com/2013/10/google-map-v3-editing-saving-marker-in-database

    But the code given creating multiple form. How can I just have one form for every user?

    Thanks
    Victor

     Reply
  • Hi, nice article..
    Is it possible to save custom polylines and routes in a similar manner?
    Thanks.

     Reply
  • no database selected– Thank for the nice tutorial, really helpfull. Av got this mysql error no database selected when I deleted action=”ajax-save.php” to action=”” since no ajax-save.php was provided. my db connection at maps_process.php are correct. What could I be missing?

    I will appreciate any suggestion

     Reply
  • Great work!

    I’m trying to add a “Edit Marker” function that would allow to edit all fields (Names, Address, Type, etc) and even change the location of the marker (by making it draggable again) but to no avail.

    Anyone have any ideas?

     Reply
  • Good work. thanks for share it.

    I have a problem, i need to do the same that you helped in this post http://www.sanwebe.com/forums/topic/filtershow-or-hide-markers-by-their-type-on-google-maps.

    Like your post, in this, when i run the project the markers aren’t show because i don’t have the map_process.php file.

    Can you help me? i’m begginer and i don’t know do it very well

     Reply
  • Can you make a moving marker with dummy gps data.

     Reply
  • This is so great, thanks for sharing!

     Reply
  • Quintin van Straaten

    Hi

    How can i make it that the user can only add one marker to the map and multiple?

    Thanks for the code.

     Reply
  • I want to put a search bar, thanks, great tutorial

     Reply
  • Please add a upload image on form u use in this project

     Reply
  • i want to add image in the form and save image to database .can you help me to add image with data

     Reply
  • Great code!
    I was wondering if you could help me to see how can I add the function of Geolocation and have the first view of the map as your current location!!

    Thank you very much!

     Reply
  • “Save Marker Details” not works. There is no effect when I am clicking on it. Any ideas?
    Thx

     Reply
  • Hi,
    When i try to save the marker i get this error message : Error: Invalid XML folllowed by the code inside “map_process.php”

     Reply
  • Hi,

    I just addes the code to my Hoster. The Database connections works fine. I have the problem that the markers are not loaded from the Database (i can’t see them) . If I open the demo there are the markers. I have no idea what went wrong. Can you help me?

     Reply
    • Hi,

      I tried to upload and test the code with another webspace provider. The same problem, i am able to save new markers in the database. But they are not loaded when I open the page. (example http://service.luehe-online.de ) . On this site I want to build a issue-management for our community. I’d appreciate a little help. ;-)

      Thanks,
      Dennis

    • I have the same problem, and I can see that you solved it, Can you please tell me how?

      Thank you in advance :)

  • how can I add a search form to find places I have marked?

     Reply
  • Hi, Great work done.

    Please let me know how can I add a checkbox to filter markers based on their “type” attribute to your existing code.

    Thanks!

     Reply
  • Hi! Nice post, thanks for share this tutorial.
    My friend, How I can create a map with categories using the categories saved in the database of your tutorial?.

     Reply
  • Hi,
    How would you display the type in the info window?
    Thanks,
    Jason

     Reply
  • thanks for the interesting tutorial . . . . .
    I would like to ask, how to make lines from point to point which take the data from database (MySql) . . . .
    success for you . . . .

     Reply
  • hello this is very interesting your code. I am newbie in js I would like to know how to add an item while clicking a button and not a right click with the opportunity to update a marker
    thank you

     Reply
  • hi, thank for share…
    i have a problem when i try to save them marker… (internal server error)
    any suggest?

    Thank you

     Reply
  • hi
    i want to use this in my register form that user can define Their place now i have some problem with that
    1- i want to user just can define 1 place
    2-how we can send input with action of form no with ajax

     Reply
  • Hey! Nice article bro thanks. I’ve question for you If you answer, I’ll really appreciate it. Is it possible to insert users location (lat-long) into the mysql table with geolocation(sharing location permission)? If it is, how? I need a sample for my project. Thanks, take care.

     Reply
  • My Map wont load. I did enter my API key and all but my map still wont load

     Reply
  • I did not see the ajax-save.php file and not included. But it works in my localhost. Is that action can be made just = “” only? Thanks for great tutors in your website. Help me a lot.

     Reply
  • Great article, have you written an “edit marker” version to modify existing database entries?

     Reply
  • Unfortunately I keep getting error, can not create marker!!!
    which is from the map_process.php file
    I entered in some data manually and put the map_process.php into my browser and the markers show, therefore i am reading the data and the connection is good.. i have looked at the script and cant see what is wrong?
    Any sugestions?

     Reply
    • In index.php double check that you’ve correctly modified the lines addrssing the path to the icons. Line 15, 35, 52 something linke PATH-TO-YOUR-WEBSITE-ICONS

    • HI… did you already find what causes the problem? i keep getting the same error as Jon…please let me know

      thanks

    • Majo,

      I found that the MySQL query that adds the columns to your database misses out the “type” column.

      If you go into PhpAdmin and manually add the column in, I chose the same settings as the name column in terms of: “type and length”.

      As soon as I did that it worked fine.

      Obviously if you don’t need the type setting you can remove it from index.php and map_process.php

      I hope that helps.

    • Majo,

      I found that the query supplied to add the columns to your MySQL database misses out the “Type” column.

      I manually created one in PHPAdmin with the same settings as the “Name” column and it worked. Just like magic.

      I hope that helps a little bit.

  • How to create a Google Maps, save map location,search & display saved positions with info box popup..P

     Reply
  • Hi, great article. But is there away of allowing users to upload a photograph to the marker also?

     Reply
  • How can I do to show the current position on Google Maps where a web visitor load the website ?

     Reply
  • Thanks for article.

     Reply
  • Nice post!Thanks for share!

     Reply