I need some help as I'm trying to call back a JavaScript function with PHP. I created 2 classes which work together perfectly. In the first one exploiting a Google API, I extract the latitude and longitude of a city chosen by a user on my form, and then I pass these values to the second class which exploits another API to show a weather forecast service for that city.
I'd like to add a Google map too, to create this way a more complete service showing a dynamic map with the chosen city.
I noticed with Firebug that the browser is not able to parse correctly the two mentioned properties of the object $map, as you can easily see by yourself.
I really don't know how to call back the js function inside the tag , I need for my purpose.
The simple echo I'm using here with PHP doesn't work here.
Hope someone can help me.
Here's my page
and here's the piece of my code that is not working:
/**
* Check for the real existence of the city, using the
* property $status of the instanced GeoLocalization class, here the object $map.
* This class exploits a Google API.
*/
if ( isset($missing) && empty($missing) && strlen($citta) > 1 && $map->status == 'OK' )
{
/**
* Use some properties of the object $map to show my user
* the chosen city and state in Italian.
* Show even the latitude and the longitudine.
* These values are those passed to the GeoWeather class.
*/
// show the location
echo '<ul id="display_location">' .
'<li class="rosso centra sottolineato grassetto">' . $map->formatted_address . '</li>' .
'<li>' . 'Latitudine: ' . $map->latitude . '</li>' .
'<li>' . 'Longitudine: ' . $map->longitude . '</li>' .
</ul>';
echo '<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>';
echo '<script type="text/javascript">
var map;
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(<?php echo $map->latitude . ", " . $map->longitude; ?>)
};
map = new google.maps.Map(document.getElementById("googleStaticMap"), mapOptions);
}
</script>';
echo '<script type="text/javascript">initialize();</script>';
echo '<div id="googleStaticMap"></div>';
}
</body>
You can't start a new PHP-block inside a PHP-block.
This:
echo '<script type="text/javascript">
var map;
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(<?php echo $map->latitude . ", " . $map->longitude; ?>)
};
map = new google.maps.Map(document.getElementById("googleStaticMap"), mapOptions);
}
</script>';
should be:
echo '<script type="text/javascript">
var map;
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng('. $map->latitude . ','
. $map->longitude .')
};
map = new google.maps.Map(document.getElementById("googleStaticMap"),
mapOptions);
}
</script>';
Other issues:
you must switch the order of these 2 lines(otherwise #googleStaticMap is unknown when you call the function):
echo '<script type="text/javascript">initialize();</script>';
echo '<div id="googleStaticMap"></div>';
Additionaly:
#googleStaticMap currently doesn't have a height. You've set a height of 100%, but as long as the parent element of #googleStaticMap doesn't have a height set via CSS this will not have any effect.
Related
I just placed a google map on my website following the instructions from google maps API: https://developers.google.com/maps/documentation/javascript/adding-a-google-map
Copying that example works perfectly but I would like to get the position of the marker depending on a custom field created in each post from WordPress
<div id="map"></div>
<?php $lati = get_field( "gmapslat" ); ?>
<?php $lat = get_field( "gmapslng" ); ?>
<script>
function initMap() {
var lat = '<?php echo $lat; ?>';
var lng = '<?php echo $lng; ?>';
var uluru = {lat: lat, lng: lng};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: uluru
});
var marker = new google.maps.Marker({
position: uluru,
map: map
});
}
</script>
<script async defer
src="http://maps.googleapis.com/maps/api/js?key=AIzaSyDPGx6I2w6hzEmQNR2IrRKlFC9oUT-COvs&callback=initMap">
</script>
</div>
When do that the map just shows grey.
It seems there's a problem with your PHP variables. This PHP Variable $lng is not declared. So you are setting an undeclared PHP variable in Javascript variable lng.
I also noticed these lines:
<?php $lati = get_field( "gmapslat" ); ?>
<?php $lat = get_field( "gmapslng" ); ?>
Is this variable $lat value a longitude? If so, use $lng instead. Using meaningful names for variables would be helpful. Variable names must define the exact explanation of its content, regardless of programming language. Checking this blog 15 Best Practices of Variable & Method Naming might help.
Important: Use parseFloat() on each javascript variable width coordinates to return a floating point number. Else, it won't work and you'll just see a grey map. To learn more about definition and usage of parseFloat(), you can check JavaScript parseFloat() Function.
Below is a sample code using "-25.363, 131.044" as a sample coordinates returned by your PHP get_field() function:
<div id="map"></div>
<?php
function get_field($args) {
switch ($args) {
case 'gmapslat':
return '-25.363';
break;
case 'gmapslng':
return '131.044';
break;
}
}
$lat = get_field('gmapslat');
$lng = get_field('gmapslng');
?>
<script>
function initMap() {
var lat = parseFloat("<?php echo $lat; ?>");
var lng = parseFloat("<?php echo $lng; ?>");
var myLatLng = {lat: lat , lng: lng};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng
});
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: 'Hello World!'
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
Hope it could help and happy coding!
I have got my Coordinates from my Database, the problem is that, I can not add a marker with data.
If I put the coordinates manually then it works fine without any problems, but if I get the coordinates value from my Database, google maps, it doesn't work.
This is my code:
function myFunction() {
var latitud = <?php echo '["' . implode('", "', $dbLatitud) . '"]' ?>;
var longitud = <?php echo '["' . implode('", "', $dbLongitud) . '"]' ?>;
document.getElementById("demo").innerHTML = latitud + longitud;
// document.getElementById("demo").innerHTML = fruits[1]; --- especifico slot
var a = latitud.toString();
var b = longitud.toString();
var myLatLong = {lat: a, lng: b};
var marker = new google.maps.Marker({
position: myLatLong,
map: map,
title: 'Colectivo N°: 1'
});
marker.setMap(map);
}
I think the problem is with data types. Type of the database coordinates are in double, but I can't make a marker with other type data neither.
I could solve it!
I changed .toString()
function myFunction() {
var latitud = <?php echo '["' . implode('", "', $dbLatitud) . '"]' ?>;
var longitud = <?php echo '["' . implode('", "', $dbLongitud) . '"]' ?>;
var a = latitud.toString();
var b = longitud.toString();
var myLatLong = {lat: a, lng: b};
}
with parseFloat();
function myFunction() {
var latitud = <?php echo '["' . implode('", "', $dbLatitud) . '"]' ?>;
var longitud = <?php echo '["' . implode('", "', $dbLongitud) . '"]' ?>;
var a = parseFloat(latitud);
var b = parseFloat(longitud);
var myLatLong = {lat: a, lng: b};
}
More simply don't cast the values as strings to begin with -- in other words remove the double quotes.
You can use <?= and ?> as short hand to echo php variable without writing echo.
I haven't tested my assertion, but the documentation seems to suggest that you can't simply implode multiple values into myLatLong. Do you actually only have one value for lat and long? If so, this will do:
var marker = new google.maps.Marker({
position: {lat:<?=$dbLatitud[0]);?>, lng:<?=$dbLongitud[0];?>},
map: map,
title: 'Colectivo N°: 1'
});
Furthermore, you could prep your data for direct insertion into the javascript using an associated array and json_encode():
<?php
$lats=['lat'=>-33.890542];
$lng=['lng'=>151.274856];
?>
...
position: <?=json_encode($lats+$lng);?>
If you do have multiple markers, then see this demo which uses a multidimensional array of data and uses a loop to apply all of the markers. In which case, you again can/should use json_encode() in your php to prepare/format your database values for javascript.
So I have an issue with mapbox.js, I cannot attach a onclick event inside a custom popUp.
What I am doing is, I have a custom worpdress mapbox.js widget and I am dynamically adding custom markers, title and description and etc.
I want to have a onclick event inside 'description:' property of a marker.
I am aware that the way I have created a mapbox.js script is a bad practise, but I needed a quick solution.
So here is a php script that creates a javascript.
<?php
$pins = $instance['pinpoint'];
$pinsnumber;
$j = 0;
for ($i=0;$i<count($pins);$i++) {
$pinsnumber++;
}
?>
<div id="map-holder">
<div id='map'></div>
</div>
<script>
<?php $token = $instance['token'];
$latitude = $instance['latitude'];
$longitude = $instance['longitude'];
$zoom = $instance['zoom'];
$style = $instance['style'];
?>
L.mapbox.accessToken = <?php echo "'$token'";?>;
var map = L.mapbox.map('map')
.setView([<?php echo $latitude?>, <?php echo $longitude ?>], <?php echo $zoom?>);
// Use styleLayer to add a Mapbox style created in Mapbox Studio
L.mapbox.styleLayer(<?php echo "'$style'"; ?>).addTo(map);
var features = [];
var myLayer = L.mapbox.featureLayer(
{
type: 'FeatureCollection',
features: [
<?php
for($j;$j<$pinsnumber;$j++) {
echo "{
type: 'Feature',
properties: {
'marker-color': '#003460',
'marker-size': 'large',
'marker-symbol': 'circle',
'description': '<div class=\"img\"><img src=" . $instance['pinpoint'][$j]['image'] . " width=\"225\" height=\"110\"></img></div><div class=\"title-popup\"><h5>" . $instance['pinpoint'][$j]['title'] . "</h5><p>" . $instance['pinpoint'][$j]['descr'] . "</p></div><div class=\"book-now btnBook\" onclick=\"console.log(\"Hello\")\">Book Now ></div>'
},geometry: {
type: 'Point',
coordinates: [" . $instance['pinpoint'][$j]['lat'] . "," . $instance['pinpoint'][$j]['long'] . "]
}";
if ($j===$pinsnumber-1)
{
echo "}";
}
else {
echo "},";
}
}
echo "]";
?>
}).addTo(map);
map.scrollWheelZoom.disable();
</script>
So the output would be an array of features.
What I want is to when a user click on .book now I can fire a function
I have tried accessing it with Jquery, but it just does not recognize that there is a div with a .book-now, but I can attach an onclick to a .leaflet-popup-content but not for the html that is created inside it.
I just wonder do I need to find a different approach to this problem or there is a quick way that I am not aware of.
Also, I did try to create an onclick event inside the 'description:' but it does not work for some reason.
The default sanitizer method for the L.mapbox.featureLayer class will remove JavaScript because, in the broad case, it's a potential security threat. To fix this example, you'd disable sanitization.
Where your code says
}).addTo(map);
You'd write
}, { sanitizer: function(x) { return x; } }).addTo(map);
I am trying to create a javascript array using content that is pulled from a php database.
<?php
//This creates an array from the database and allows us to use it later in the jquery
//CREATE SQL STATEMENT
$sql_locations = "SELECT * FROM tbllocations";
//CONNECT TO MYSQL SERVER
require('test-connection.php');
//EXECUTE SQL STATEMENT
$rs_locations = mysqli_query($vconnection, $sql_locations);
$rs_locations_rows = mysqli_fetch_assoc($rs_locations);
foreach( $rs_locations as $rs_location ) {
$markers[] = array(
"{$rs_location['place']}, {$rs_location['city']}",
$rs_location['long'],
$rs_location['lat']
);
}
?>
<div id="map_wrapper">
<div id="map_canvas" class="mapping"></div>
</div>
<style>
#map_wrapper {
height: 400px;
}
#map_canvas {
width: 100%;
height: 100vh;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script>
function initialize() {
var map;
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
mapTypeId: "roadmap",
center: new google.maps.LatLng(47.608941, -122.340145), // somewhere in the uk BEWARE center is required
zoom: 3,
};
// Display a map on the page
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setTilt(45);
// Multiple Markers
var markers = <?php echo json_encode( $markers ); ?>;
// Info Window Content
var infoWindowContent = [
<?php while($rs_location_rows = mysqli_fetch_assoc($rs_location)) { ?>
['<div class="info_content">' +
'<h3><?php echo $rs_locations_rows['branch']; ?></h3>' +
'<p><?php echo $rs_locations_rows['content']; ?></p>' +
'<p><?php echo $rs_locations_rows['phone']; ?></p>' +
'</div>']
<?php } ?>
];
// Display multiple markers on a map
var infoWindow = new google.maps.InfoWindow();
var marker, i;
// Loop through our array of markers & place each one on the map
for (i = 0; i < markers.length; i++) {
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0]
});
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.open(map, marker);
}
})(marker, i));
// Automatically center the map fitting all markers on the screen
map.fitBounds(bounds);
}
//Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function (event) {
this.setZoom(10);
google.maps.event.removeListener(boundsListener);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
I have updated the code to show my whole page. I have tried this while loop in the meantime and adding that in stops my page from generating and outputting my map, so my page will hang.
I am thinking to do a for each loop the same way that I have done for the markers, but I have not succeeded thus far
As you are basically trying to build a string containing some js code and then pass it directly to the browser, I would build a string in PHP and then echo the lot in one go. Its easier to see what you are doing.
<?php
$js = '<script type="text/javascript">';
$js .= 'var infoWindowContent = [';
while( $row = mysqli_fetch_assoc($rs_location)) {
$js .= "['" . '<div class="info_content">';
$js .= "<h3>{$row['branch']}</h3>";
$js .= "<p>{$row['content']}</p>";
$js .= "<p>{$row['phone']}</p>";
$js .= "</div>'],";
}
// trim off the js interpreter breaking trailing comma
$js = rtrim( $js, ',' );
// close the outer array
$js .= '];';
$js .= '</script>';
echo $js;
?>
You just need to change the do while structure to while:
As also mentioned by #RiggsFolly. (sorry I see now)
var infoWindowContent = [
<?php while($rs_location_rows = mysqli_fetch_assoc($rs_location)) { ?>
['<div class="info_content">' +
'<h3><?php echo $rs_locations_rows['branch']; ?></h3>' +
'<p><?php echo $rs_locations_rows['content']; ?></p>' +
'<p><?php echo $rs_locations_rows['phone']; ?></p>' +
'</div>'],
<?php } ?>
];
This is the approach i would use to do that:
var myArray = [
<?php while ($rs_location_rows = mysqli_fetch_assoc($rs_location)) : ?>
{
'branch' : '<?= $rs_locations_rows["branch"] ?>',
'content' : '<?= $rs_locations_rows["content"] ?>',
'phone' : '<?= $rs_locations_rows["phone"] ?>'
},
<?php endwhile; ?>
];
console.log(myArray);
Now you have the array in your js.
I am super new to web development and building a web app that has a google map and would like to continuously update the map with the user location. I am able to read values from my db properly and can display it on the map, but only one time. I could not find anywhere how to continuously update the position (hopefully without reloading the page also). Can someone help with some direction on how to approach this? Here some of my code for reference:
<?php include_once('location.php') ?>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>My GeoLocation</title>
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<script>
var map;
function initialize() {
var myLatlng = new google.maps.LatLng(<?php echo $current_lat ?>, <?php echo $current_long ?>);
var mapOptions = {
zoom: 14,
center: myLatlng
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'TEST'
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
//READ FROM CLIENT (POST)
$content = file_get_contents('php://input');
$post_data = json_decode($content , true);
$lat = $post_data['lat'];
$long = $post_data['long'];
$speed = $post_data['speed'];
$hacc = $post_data['hacc'];
$vacc = $post_data['vacc'];
$timestamp = $post_data['timestampe'];
//CONNECT TO MYSQL
$con1 = mysql_connect("localhost", "xxxxxxxx", "bbbbbb", "yyyyyy");
if ($con1->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$db_selected = mysql_select_db('yyyyyy');
if (!$db_selected) {
die ('Can\'t use foo : ' . mysql_error());
}
if (!empty($lat)) {
$sql = "INSERT INTO LocationInfo (latitude, longitude, speed, hor_acc, ver_acc, d)
VALUES ('$lat', '$long', '$speed', '$hacc', '$vacc', '$timestamp');";
mysql_query($sql) or die ('Error updating database: ' . mysql_error());
}
$read_query = "SELECT * FROM LocationInfo;";
$results = mysql_query($read_query) or die ('Error reading from database: ' . mysql_error());
$column = array();
while($row = mysql_fetch_array($results)){
$column[] = $row;
}
$current_lat = $column[sizeof($column) - 1]['latitude'];
$current_long = $column[sizeof($column) - 1]['longitude'];
?>
Google Maps JavaScript reference
You can update the marker with marker.setPosition( new LatLng(...) ), or in other words just assigning a new position. It seems to me you're putting your position in an input field, than submitting, reading the field and setting the marker and saving the position in a database. If you want to update the position of the marker, you can use an input field again, read the field value with JavaScript, and update the marker's position (with marker.setPosition()). If you want to pass this to your DB again, you can additionally pass the data to your script using AJAX. It depends on what you're doing and want you want to do.
edited after comment
You can setup a JavaScript function that will make an AJAX request to your PHP script and update the position once it gets the data. And then call the script every x number of seconds. use setTimeout to create a delay and then make the function call itself with another timeout once it gets the data. Save yourself the trouble and use a library to handle your AJAX calls - jQuery gives you indirectly a lot of support because a lot of people use it. You also need to make sure your PHP script doesn't give you anything back except the position information, not the whole html file as you have now. So simplified something like this: you have a PHP file that sends you the lat/lng pair as JSON, and this script gets called from the browser around every 10 seconds. There are ofcourse little things that might pop out ... and please note, I don't do PHP.
get_position.php
...
$latLng = array('lat' => $lat, 'lng' => $lng);
echo json_encode($latLng);
JS, using jQuery.ajax
var marker = ....
var delay = 10000; // 10 second delay
function updatePosition() {
$.ajax({
url: path/to/get_position.php,
dataType: 'json'
})
.done(function callDone(data) {
// update marker position
var latLng = new google.maps.LatLng( data.lat, data.lng );
marker.setPosition( latLng );
// call the function again
setTimeout( updatePosition, delay );
});
}
// call the function initally
setTimeout( updatePosition, delay );