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

72 Comments Add Comment