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
Related
My objective is to obtain data from a table in a database and show it on the map. My table has three columns: LATITUD (stores the latitude)(type=float(10,6)), LONGITUD (stores the longitude)(type=float 10,6) and ASUNTO(stores the information)(type=VARCHAR). The first two have information of the location of the marker, while the third column stores information related to the marker. The content of this last column is the one I want to show with an info window.
To achieve this inside the body element of the page i have decided to insert a script element (javascript) which I use to create the map and to load all the information related to it.
Inside this javascript code I have included PHP code which is in charge of making a query to the database to obtain the content of the table we mentioned at the beggining in an associative array. Inside this code through a while loop I want to load all the markers with their corresponding info windows.
Loading the markers didn't gave me any problem, to load them I used this while loop code.
while ($row = $resultado->fetch( PDO::FETCH_ASSOC )) {
echo ' var myLatlng1 = new google.maps.LatLng('.
$row['LATITUD'].', '.$row['LONGITUD'].');
var marker1 = new google.maps.Marker({
position: myLatlng1,
map: map,
});';
}
Inside the PHP script I inserted this code and works fine to me. I have the problem when I want to add info windows for each marker which contain the information stored in the "ASUNTO" column mentioned at the beggining. When I modify the code shown above to add info windows I have problems. The code that is giving me problems is the one below.
while ($row = $resultado->fetch( PDO::FETCH_ASSOC )) {
echo ' var asunto = '. $row['ASUNTO'] . ';';
echo ' var myLatlng1 = new google.maps.LatLng('.
$row['LATITUD'].', '.$row['LONGITUD'].');
var marker1 = new google.maps.Marker({
position: myLatlng1,
map: map,
});
var infowindow = new google.maps.InfoWindow({
content: asunto
});
infowindow.open(map, marker1);
';
}
I think that the code line that is giving me problems is the first one inside the loop, which I will show now below.
echo ' var asunto = '. $row['ASUNTO'] . ';';
The reason I believe this, is because the "infowindow" variable when I change its content to a string which is not obtained through PHP and is directly inserted doesn't gives me any problem and displays an info window when it is called using the "open"method. The next code below doesn't gives me any problem.
while ($row = $resultado->fetch( PDO::FETCH_ASSOC )) {
echo ' var myLatlng1 = new google.maps.LatLng('.
$row['LATITUD'].', '.$row['LONGITUD'].');
var marker1 = new google.maps.Marker({
position: myLatlng1,
map: map,
});
var infowindow = new google.maps.InfoWindow({
content: "hello"
});
infowindow.open(map, marker1);
';
}
As you can see the content of the infowindow have changed and when I changed it, it worked correctly and the map was able to load. I would like to show info windows which display the information stored in the database rather than the string "hello" of the example above.
I would like to know why my approach is failing and how to resolve the problem in order to be able to show the info windows I want for each marker.
The problem is not with the database, nor the php. The problem is where you echo that data.
One simple example, it's quite obvious that this won't work
while ($row = $resultado->fetch( PDO::FETCH_ASSOC )) {
echo ' var myLatlng1 = new google.maps.LatLng('.
...
The while-loop creates multiple instances of this code. The variable myLatlng1 will simply be overwritten.
What you need to do, is separate the data from the functions.
So you generate 1 var.
It should be something like this (my php is a bit rusty, I hope I'm not generating errors):
<?php
$data = array(); // we make an empty object/array, we will fill it with the data in the rows
while ($row = $resultado->fetch( PDO::FETCH_ASSOC )) {
$data[] = array(
'LATITUD' => $row['LATITUD'],
'LONGITUD' => $row['LONGITUD'],
'ASUNTO' => $row['ASUNTO'],
);
}
// now we echo this variable, 1 variable containing all the data
$data_string = json_encode($data); // this turns php arrays into a javascript-readable object
echo 'var my_data = ' . $data_string .';'; // notice which ; is for javascript and which is for php
?>
var my_data will be something like this (I'll insert some locations in Brussels):
var my_data = [{"LATITUD":"50.89496405015655","LONGITUD":"4.341537103056892","ASUNTO":"Atomium"},{"LATITUD":"50.84501941894387","LONGITUD":"4.349947169423087","ASUNTO":"Manneken Pis"},{"LATITUD":"50.83847065124941","LONGITUD":"4.376028969883903","ASUNTO":"European Parliament"}];
Now the javascript. How do you use infowindows? I'll use my_data hard coded, so you can copy/paste this code and test the javascript.
don't forget your API key
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 90%;
}
</style>
<div id="map"></div>
<script>
var my_data = [{"LATITUD":"50.89496405015655","LONGITUD":"4.341537103056892","ASUNTO":"Atomium"},{"LATITUD":"50.84501941894387","LONGITUD":"4.349947169423087","ASUNTO":"Manneken Pis"},{"LATITUD":"50.83847065124941","LONGITUD":"4.376028969883903","ASUNTO":"European Parliament"}];
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 50.869754630095834, lng: 4.353812903165801},
zoom: 12
});
for(var i=0; i<my_data.length; i++) {
// marker
var position = {lat: Number(my_data[i].LATITUD), lng: Number(my_data[i].LONGITUD)};
var marker = new google.maps.Marker({
position: position,
title: my_data[i].ASUNTO,
map: map
});
// infowindow
var infowindow = new google.maps.InfoWindow({
content: my_data[i].ASUNTO,
map: map,
position: position
});
}
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?callback=initMap" async defer></script>
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,
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.
In 2 weeks I explored much about Google maps. I am try read a forum and tutorial. But I got this problem when I am going to develop a GIS web. I am using Google maps apiv3, postgre database, and php. I have so much row in my database. Now I only can show multiple marker based on my database, but what I after is the marker have a unique icon based on column content in database like a type 1 = 1.png type 2 = 2.png. the problem is the type is too many, so it is impossible to definition them by manual (because so many type, I already have about 30 type of content in database column ) . I get database value using json. I've already try read forum and some tutorial, but I can't find the answer. sorry for my bad english. please help me, thanks.
this is the code index.php and json.php :
<html lang="en">
<head>
<script type="text/javascript">
function initialize(){
var peta;
var gambar_tanda;
gambar_tanda = 'assets/images/enseval.jpg';
var x = new Array();
var y = new Array();
var customer_name = new Array();
var rayon_name = new Array();
// posisi default peta saat diload
var lokasibaru = new google.maps.LatLng( -1.2653859,116.83119999999997);
var petaoption = {
zoom: 5,
center: lokasibaru,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
peta = new google.maps.Map(document.getElementById("map_canvas"),petaoption);
var infowindow = new google.maps.InfoWindow({
content: ''
});
// memanggil function ambilpeta() untuk menampilkan koordinat
url = "json.php";
$.ajax({
url: url,
dataType: 'json',
cache: false,
success: function(msg){
for(i=0;i<msg.enseval.customer.length;i++){
x[i] = msg.enseval.customer[i].x;
y[i] = msg.enseval.customer[i].y;
customer_name[i] = msg.enseval.customer[i].nama_customer;
//rayon_name[i] = msg.enseval.customer[i].nama_rayon
var point = new google.maps.LatLng(parseFloat(msg.enseval.customer[i].x),parseFloat(msg.enseval.customer[i].y));
tanda = new google.maps.Marker({
position: point,
map: peta,
icon: gambar_tanda,
clickable: true
});
bindInfoWindow(tanda, peta, infowindow, msg.enseval.customer[i].nama_customer );
}
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
function bindInfoWindow(tanda, peta, infowindow, data) {
google.maps.event.addListener(tanda, 'click', function() {
infowindow.setContent(data);
infowindow.open(peta, tanda);
});
}
</script>
<?php
require ('config.php');
$rayon = $_POST['rayon'];
$cabang = $_POST['org_id'];
//echo "$rayon, $cabang, $rayonhasil";
$sql = "SELECT distinct org_id, customer_name, attribute16, attribute17 FROM hasilgis";
$data = pg_query($sql);
$json = '{"enseval": {';
$json .= '"customer":[ ';
while($x = pg_fetch_array($data)){
$json .= '{';
$json .= '"id_customer":"'.$x['org_id'].'",
"nama_customer":"'.htmlspecialchars($x['customer_name']).'",
"x":"'.$x['attribute17'].'",
"y":"'.$x['attribute16'].'"
},';
}
$json = substr($json,0,strlen($json)-1);
$json .= ']';
$json .= '}}';
echo $json;
?>
I'm not sure what's the problem :)
The only thing you must do is to generate icons for all types. You don't have to do it manually - just create a scipt that will generate icons of different colors for every type and name it like 1.jpg, 2.jpg, ...
Pass type via your json message and than on client side create icon url dynamically:
gambar_tanda = 'assets/images/'+msg.enseval.customer[i].type+'.jpg';
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);
});