Gmaps.js - multiple markers with dynamic infoWindow content - javascript

I've been reading extensively on the topic of adding dynamically generated infoWindow content to Google Maps API v3 maps, but I'm having trouble finding answers that work for my implementation of the map (I'm using an existing script called gmaps.js). I have limited experience with javascript and PHP, so I'm hoping someone can point me in the right direction.
Currently, I have my markers set up on a map I'm using for a Wordpress site. The markers are properly placed in accordance with the location coordinates specified in the database, but the corresponding infoWindow content (a building name and address for each marker on the map) is displaying all at once in every instance of the infoWindow, rather than only the content that pertains to each specific marker.
Here's the code I'm using (along with the gmaps.js script):
<div id="map"></div>
<ul class="markers">
<?php
$markers = get_field('locations', $post->ID);
foreach($markers as $m): ?>
<li><a data-latlng="<?php echo $m['location']['coordinates']; ?>" data-icon="<?php bloginfo('template_url'); ?>/assets/img/map_icons/<?php echo $m['icon']; ?>.png"></a></li>
<?php
endforeach; ?>
</ul>
<script>
$(function() {
var $body = $('body'),
$window = $(window);
if($body.hasClass('page-template-page_map-php')){
var $map = $('#map');
function set_map_height(){
$map.height($(window).height() - $('#header').outerHeight());
}
set_map_height();
$window.on('resize', function(){
set_map_height();
})
var map = new GMaps({
div: '#map',
lat: 49.8994,
lng: -97.1392
});
$('.markers li a').each(function(){
var $this = $(this),
latlng = $this.data('latlng').split(',');
map.addMarker({
lat: latlng[0],
lng: latlng[1],
title: 'Development',
click: function(e) {
},
infoWindow: {
content: $("#location").html() + i
},
icon: $this.data('icon')
});
});
map.fitZoom();
}
});
</script>
<div id="location">
<?php
$markers = get_field('locations', $post->ID);
foreach($markers as $m): ?>
<h3><?php echo $m['name']; ?></h3>
<p><?php echo $m['location']['address']; ?></p>
<?php
endforeach; ?>
</div>
Thanks SO much for any help, and my apologies if I haven't included enough detail.

The reason you are getting all of the data in the info windows is because you are pulling the HTML from the "location" div. This div is getting populated with ALL of the data as you are looping over the list of markers.
The quickest way to get this to do what you want would be to add the name and address fields to the anchor tags in your list you generate at the top.
<ul class="markers">
<?php
$markers = get_field('locations', $post->ID);
foreach($markers as $m): ?>
<li><a data-latlng="<?php echo $m['location']['coordinates']; ?>" data-icon="<?php bloginfo('template_url'); ?>/assets/img/map_icons/<?php echo $m['icon']; ?>.png" data-name="<?php echo $m['name']; ?>" data-address="<?php echo $m['location']['address']; ?>></a></li>
<?php
endforeach; ?>
Then you can set the info window content directly in your javascript loop.
$('.markers li a').each(function(){
var $this = $(this),
latlng = $this.data('latlng').split(','),
name = $this.data('name'),
address = $this.data('address');
map.addMarker({
lat: latlng[0],
lng: latlng[1],
title: 'Development',
click: function(e) {
},
infoWindow: {
content: "<b>Name:</b>" + name + "<br /><b>Address:</b>" + address
},
icon: $this.data('icon')
});
});
Now, I would suggest changing the entire design for this to use AJAX calls and have your PHP return an array of JSON data rather than storing all of this data in the DOM. You can use JQuery's ajax function and PHP json_encode/json_decode to pass JSON data to/from the web client.

Related

Google maps only shows last marker from a MySQL database using PHP and JavaScript

When I try to show multiple markers from the database information, the map only shows the last of the markers returned with its infoWindow.
I read other post that talks about a clousure, but I can't resolve my problem.
This is the original code:
<body>
<?php
include("conexion.php");
$tipo = $_POST['type'];
?>
<div class="container">
<div class="row">
<div class="col-md-12">
<h1>Map</h1>
<div id="map" style="width:100%;height:360px;"></div><br><br>
<?php
$con = mysqli_connect($host, $user, $pass, $db_name) or die("Error");
$query = "select * from table where type_name='".$type."'";
$result = mysqli_query($con,$query);
$i=1;
while ($data = mysqli_fetch_assoc($result)) {
?>
<script type="text/javascript">
var cat = new google.maps.LatLng(41.652393,1.691895);
var mapOptions = {
center: cat,
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
var marker<?php echo $i;?> = new google.maps.Marker({
position: new google.maps.LatLng(<?php echo $data['lat']; ?>, <?php echo $data['lng']; ?>),
map: map,
title: <?php echo "'".$data['name']."'"; ?>
});
var infowindow<?php echo $i;?> = new google.maps.InfoWindow({
content: "<h1><?php echo "".$data['name'].""; ?></h1><p><b>Addres</b><br> <?php echo "".$data['addres'].""; ?></p><p><b>Description</b><br><?php echo "".$data['description'].""; ?></p>"
});
google.maps.event.addListener(marker<?php echo $i;?>, 'click', function() {
infowindow<?php echo $i;?>.open(map,marker<?php echo $i;?>);
});
</script>
<?php
$i++;
}
mysqli_close($con);
?>
</div>
</div>
</div>
</body>
nghngh
Just put all the markers on an array, also do the while inside the js, you are creating the map var for every interaction, or create the elements on the js with an ajax, this will improve a lot for performance.
also take a look to this
Google Maps JS API v3 - Simple Multiple Marker Example

Click on Google Map Marker, load wordpress post into div

I'm working on a Wordpress site with a google map as the main page. The markers on the map are created by the posts, which each have a location associated with them (by using Advanced Custom Fields). My goal is to click on any particular marker, and have it load that marker's associated post into a div at the bottom of the screen.
<div class="acf-map">
<?php if ( $query->have_posts() ) : while ($query->have_posts() ) : $query->the_post(); ?>
<?php
$location = get_field('location');
if( !empty($location) ):
?>
<div class="marker" data-lat="<?php echo $location['lat']; ?>" data-lng="<?php echo $location['lng']; ?>"></div>
<?php endif; ?>
<?php endwhile; ?>
<?php endif; ?>
</div>
The divs with class "marker" are not actually loaded onto the map directly, but rather they are collected from a script and passed with the following function to a google method
function add_marker( $marker, map ) {
// var
var latlng = new google.maps.LatLng( $marker.attr('data-lat'), $marker.attr('data-lng'))
var postid = $marker.attr('id');
// create marker
var marker = new google.maps.Marker({
position : latlng,
map : map,
idofpost : postid
});
// add to array
map.markers.push( marker );
var infowindow = new google.maps.InfoWindow({
content:"<?php the_field('sound_description'); ?>"
});
$.each()
marker.addListener('click', function() {
infowindow.open(map, marker);
});
}
As a beginner, I'm having difficulty figuring out the best workflow to achieve my above-stated goal. Any help would be appreciated.
Thank you,

Retrieve wordpress custom field (group) data inside jQuery function

Inside my themes’ included main.js I have to retrieve some data entered via wordpress into a range of custom fields (within field groups). How can I pass the php values into the jQuery code?
To be more specific I am creating multiple google map markers within my initializeMap() function as follows:
var markers = [
['First Center','First Address',50,50],
['Second Center','Second Address', -25.363882,131.044922],
['Third Center','Third Address', 10.363882,95],
['Fourth Center','Fourth Address', -50,-90],
['Fifth Center','Fifth Address', 30,5],
];
for( var i = 0; i < markers.length; i++ ) {
var latlng = new google.maps.LatLng(markers[i][2], markers[i][3]);
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: markers[i][0],
icon: image
});
}
With the help of the ACF wordpress plugIn it was easy to create the custom fields to edit from inside my wordpress. Each custom field group named "Center 1", "Center 2"… contains the 4 fields for "Center name", "Center address", "Latitude" and "Longitude". But now the task is to transfer this data into my markers field. Anyone with an idea? I know this is not easy. Thanks a lot, guys!
EDIT:
The guys from ACF plugin helped me out so far. Generally the code that I needed was:
<script type="text/javascript">
(function($) {
window.map_data = [];
window.map_data.push( ['<?php the_field('center_name'); ?>', '<?php the_field('center_address'); ?>', <?php the_field('latitude'); ?>, <?php the_field('longitude'); ?>]);
})(jQuery);
</script>
that I put at the very end inside my “az_google_maps.php” template given by my Wordpress theme. Then I managed to retrieve that “map_data” array inside my js file. The rest will be (as suggested by HdK) doing a loop and somehow tell the code how many fields are actually defined by the user inside the Wordpress editor. I am working on that. Have patience with my little js/php knowledge. Would be awesome not getting down voted a thousand times. But guess that’s part of the game here. So, ok ;-)
You can add your required javascript inside your theme template instead of your main.js and than do something like:
<script>
var markers = [
[<?php echo get_field('center-name'); ?>, <?php echo get_field('center-address'); ?>, <?php echo get_field('lat'); ?>, <?php echo get_field('lng'); ?>]
</script>
Also take a look at this example page: http://www.advancedcustomfields.com/resources/google-map/
You could list all your data on a <input type="hidden"> via WP_Query. Let me show you an example:
Create the query and pass all information to the <input type="hidden">
html:
<?php
$args = array('post_type' =>array('YOUR_CUSTOM_POST'), 'exclude' => 1, 'posts_per_page' => -1, 'order' => 'ASC');
$q = new WP_Query($args);
if ( $q->have_posts() ): while( $q->have_posts() ): $q->the_post();
$address = get_field('address');
?>
<!-- I created some data attributes to store all content -->
<input type="hidden" data-title="<?php the_title(); ?>" data-address="<?php echo $local['address']; ?>" data-lat="<?php echo $local['lat']; ?>" data-lng="<?php echo $local['lng']; ?>">
<?php endwhile; endif; wp_reset_query(); ?>
In jQuery inside your map's functions right after you create the map object, you can use .each() to loop through all <input type="hidden"> like this:
function createMarker(){
...
..
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
$('input[type="hidden"]').each(function(){
// vars to store all contents
title = $(this).data('title');
address = $(this).data('address');
lat = $(this).data('lat');
lng = $(this).data('lng');
//var to the box that will wrap the marker's content
content = '<div id="content">'+
'<div id="siteNotice">'+
'</div>'+
'<h1 id="firstHeading" class="firstHeading">'+title+'</h1>'+
'<div id="bodyContent">'+
'<p>Endereço: ' + address + '</p>'+
'</div>'+
'</div>';
// create a infowindow to display the content
var infowindow = new google.maps.InfoWindow({
content: content
});
//create marker
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
map:map,
title: title
});
// listener to open infowindow on click
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
});
}
createMarker();
Hope that'll help

Getting database values in Javascript variable dynamically

I researched this subject many times but I could not find the right answer to my question. Let me explain it.
I'm creating an app with the Google Maps API where I want to have multiple locations shown on the map, based on my database values. I'm having an object called Locations in my javascript, where I store the the variables 'name', 'lat' and 'lon' (latitude, longtitude).
var Locations =
[{
name: 'test',
lat: 52.351753,
lon: 5.002035
},
{
name: 'test2',
lat: 52.390839,
lon: 4.908722
}];
This part is where I store my locations. Although this is working, it is hardcoded.
So, I want to get all my mysql database values out of the database into my javascript variable dynamically. I foreach'd through the database entry's with PHP:
foreach ($query as $post)
{
?> <h1><?php echo $post['naam'] ?></h1>
<p><?php echo $post['plaats'] ?></p>
<p><?php echo $post['categorie'] ?></p>
<?php
}
Now I tried to get all of those values and put them into my javascript variable, but without any succes.
var bedrijven = <?php echo json_encode($post); ?>;
When I console.log 'bedrijven' i'm only getting the last entry, but I want every row stored. Can someone help me with this? Would be really cool if it worked.
I hope I explained well enough.
Thanks!
$post is your iteration variable, so it only contains one element of the array at a time. If you want the entire array, assign that:
var bedrijven = <?php echo json_encode($query); ?>;
Try:
PHP:
function getMarkers(){
$response = array();
foreach ($query as $post) {
$response[] = array(
'name' => $post['naam'],
'lat' => $post['plaats'],
'lng' => $post['categorie'],
);
}
echo json_encode($response);
}
then JS:
function addMarkers(json){
var title =json[index]["naam"];
var lat =json[index]["plaats"];
var lng =json[index]["categorie"];
marker = new google.maps.Marker({
position: new google.maps.LatLng (lat, lng),
map: YOUR_MAP
});
}
jQuery.getJSON("URL OF PAGE",{
format: "json",
dataType: 'json',
contentType: "application/json; charset=utf-8"},
function(json){addMarkers(json);
});
better, to send the info with json and retrieve it with jQuery's getJSON, this may need some tweaking.. But I have created what your talking about. Shout if any further help is required.
You May have to look into this a tiny bit to configure it..
GOOD LUCK!
The examples on http://us1.php.net/json_encode should be helpful. It looks like your $post should be an associative array:
$post[] = ("name"=>"test","lat"=>52.351753, "lon"=> 5.002035); ?>
var bedrijven = <?php echo json_encode($post); ?>;
outputs:
var bedrijven = [{"name":"test","lat":52.351753,"lon":5.002035}];

Google Maps API v3 (one infowindow open at a time)

Does someone know how to modify this code so that google maps closes infowindows when you open another?
In other words, I want only one infowindow open at all times. I looked around on stackoverflow but couldn't seem to implement people's solutions in this code.
function initMapsDealers(){
objectLocation = new google.maps.LatLng(25.64152637306577, 1.40625);
var myOptions = {
scrollwheel: false,
zoom: 2,
center: objectLocation,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map-canvas-dealers"), myOptions);
var image1 = '/gfx/iconPloegerGreen.png';
var image2 = '/gfx/iconPloegerGreen.png';
var image3 = '/gfx/iconPloegerDealer.png';
/* Info windows */
<?
function replace_newline($string) {
return (string)str_replace(array("\r", "\r\n", "\n"), '', $string);
}
$i = 0;
foreach($dealers as $dealer)
{
$dealerLanden[$dealer['Land']][] = $dealer;
if($dealer['lat'] != "" && $dealer['lon'] != "")
{
$i++;
?>
objectLocation<?= $i; ?> = new google.maps.LatLng(<?= $dealer['lat']; ?>, <?= $dealer['lon']; ?>);
var contentString<?= $i; ?> =
'<div class="infoWindow">'+
'<strong><?= str_replace("'","", $dealer['name']); ?></strong><br>'+
'<?= replace_newline($dealer['content']); ?>'+
'</div>';
var infowindow<?= $i; ?> = new google.maps.InfoWindow({
content: contentString<?= $i; ?>
});
var marker<?= $i; ?> = new google.maps.Marker({
position: objectLocation<?= $i; ?>,
title:"<?= $dealer['name']; ?>",
map: map,
icon: <?
if($dealer['group'] == "Hoofdkantoor"){ ?>image1<? }
elseif($dealer['group'] == "Oxbo"){ ?>image2<? }
elseif($dealer['group'] == "Dealers"){ ?>image3<? }
else{ ?>image1<? }?>
});
google.maps.event.addListener(marker<?= $i; ?>, 'click', function() {
infowindow<?= $i; ?>.open(map,marker<?= $i; ?>);
});
<?
}
}
?>
resizeSection();
};
There is a google recommendation what to do if you only want one InfoWindow API documentaion for InfoWindow.
It is:
InfoWindows may be attached to either Marker objects (in which case
their position is based on the marker's location) or on the map itself
at a specified LatLng. If you only want one info window to display at
a time (as is the behavior on Google Maps), you need only create one
info window, which you can reassign to different locations or markers
upon map events (such as user clicks). Unlike behavior in V2 of the
Google Maps API, however, a map may now display multiple InfoWindow
objects if you so choose.
To change the info window's location you may either change its
position explicitly by calling setPosition() on the info window, or by
attaching it to a new marker using the InfoWindow.open() method. Note
that if you call open() without passing a marker, the InfoWindow will
use the position specified upon construction through the InfoWindow
options object.
So try to follow these suggenstions.
This is my solution to have only one infowindow open at one time:
infowindow = new google.maps.InfoWindow({
content: infocontent,
maxWidth: 200
});
google.maps.event.addListener(marker, 'click', function() {
if($('.gm-style-iw').length) {
$('.gm-style-iw').parent().hide();
}
infowindow.open(map,marker);
});

Categories

Resources