I work on a wordpress page, using the google maps api.
my file functions:
function liceoucatolica_estilo() {
// API google maps
wp_enqueue_script('maps', 'https://maps.googleapis.com/maps/api/js?key=AIzaSyAJq5xO31rYRAqv5h6yUZTOaHwDX2zjNlo&callback=initMap', array(), false);
// Cargar scripts
wp_enqueue_script('main', get_template_directory_uri() . '/js/main.js',null,false);
}
add_action( 'wp_enqueue_scripts','liceoucatolica_estilo');
my file main.js (In which is the function of the map):
window.onload = function(){
function initMap(){
var campus = {lat: 4.634241, lng: -74.068513};
// Create a map object and specify the DOM element for display.
var map = new google.maps.Map(document.getElementById('mi_mapa'), {
center: campus,
scrollwheel: false,
zoom: 17
});
var marker = new google.maps.Marker({
position: campus,
map: map,
title: 'Liceo de la Universidad Católica'
});
}
};
If I copy the function in the header or footer if it works, but if I only leave it in Main.js does not work
There can be two causes:
1.- You're declaring the function when the window.onload event has already happened, so it keeps listening for something that will never happen.
2.- Google maps's script resolves before you get the chance to declare function initMap.
I'd try switching the order of the scripts, and removing window.onload at all. Just declare the initMap function in the global scope.
Related
Introducing the problem
Building this theme using jaredpalmer/presspack for docker, I'm struggling for a few days now as I try to insert this pair of Google Maps instances within an element that will be called in every page. The maps won't load and Chrome tells me my function is not there.
Some context
Presspack is serving the DB and uses yarn to make a environment. It keeps scripts separately for general purposes and specific ones, as it has a common.js - where I code everything it should load on every page - and a .js - which loads only on specific pages. I'm working on common now, since I believe this contact section will be used on every page and blog post of this site. The calling function for this section is WP basic <?php get_template_part( 'content', 'contato-std' ); ?>
I've added a code in functions.php to load the API key script after the footer of my pages.
It's important to mention that I've tried the js code I'm using in common.js on another HTML only environment.
My files
common.js
export default {
init() {
// JavaScript to be fired on all pages
console.log('common');
},
finalize() {
// JavaScript to be fired on all pages, after page specific JS is fired
var isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
if (isMobile) { // Tudo o que for pra navegadores mobile
(...)
} else { // Tudo o que for pra navegadores padrão
(...)
// GOOGLE MAPS LOAD
var markers = [{
GPS1: -15.7954901,
GPS2: -47.8926766,
client_address: "Corpus - Fisioterapia & Pilates, Unidade Asa Sul"
}];
function initialize() {
initMap();
initMap2();
};
function initMap() {
var latlng = new google.maps.LatLng(-15.7954901, -47.8926766); // default location
var myOptions = {
zoom: 16,
center: latlng,
mapTypeId: google.maps.MapTypeId.MAP,
mapTypeControl: true
};
var map = new google.maps.Map(document.getElementById('mapaAsaSul'), myOptions);
var infowindow = new google.maps.InfoWindow(),
marker, lat, lng;
for (i = 0; i < markers.length; i++) {
lat = (markers[i].GPS1);
lng = (markers[i].GPS2);
name = (markers[i].client_address);
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
name: name,
map: map
});
google.maps.event.addListener(marker, 'click', function(e) {
infowindow.setContent(this.name);
infowindow.open(map, this);
}.bind(marker));
}
}
var markers2 = [{
GPS1: -15.7187167,
GPS2: -47.8867326,
client_address: "Corpus - Fisioterapia & Pilates, Unidade Lago norte"
}];
function initMap2() {
var latlng = new google.maps.LatLng(-15.7187167, -47.8867326); // default location
var myOptions = {
zoom: 16,
center: latlng,
mapTypeId: google.maps.MapTypeId.MAP,
mapTypeControl: true
};
var map = new google.maps.Map(document.getElementById('mapaLagoNorte'), myOptions);
var infowindow = new google.maps.InfoWindow(),
marker, lat, lng;
for (i = 0; i < markers2.length; i++) {
lat = (markers2[i].GPS1);
lng = (markers2[i].GPS2);
name = (markers2[i].client_address);
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
name: name,
map: map
});
google.maps.event.addListener(marker, 'click', function(e) {
infowindow.setContent(this.name);
infowindow.open(map, this);
}.bind(marker));
}
}
},
};
function.php
<?php
...
function add_google_maps() {
wp_enqueue_script(
'my-google-maps',
'http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize',
NULL,
NULL,
true
);
add_filter( 'script_loader_tag', function ( $tag, $handle ) {
if ( 'my-google-maps' !== $handle )
return $tag;
return str_replace( ' src', ' async defer src', $tag );
}, 10, 2 );
}
add_action('wp_enqueue_scripts', 'add_google_maps');
?>
The JS handling the routing from common.js and .js is index.js
import jQuery from 'jquery';
import './style.scss';
import Router from './util/Router';
import common from './routes/common';
import home from './routes/home';
/**
* Populate Router instance with DOM routes
* #type {Router} routes - An instance of our router
*/
const routes = new Router({
/** All pages */
common,
/** Home page */
home
/** About Us page, note the change from about-us to aboutUs. */
});
/** Load Events */
jQuery(document).ready(() => routes.loadEvents());
Bad response
It should load both instances of maps within the respective div's #mapaAsaSul and #mapaLagoNorte, but it won't and Chrome's console returns this:
(index):1
Uncaught (in promise) Xc {message: "initialize is not a function", name: "InvalidValueError", stack: "Error↵ at new Xc (http://maps.googleapis.com/ma…KEY&callback=initialize:125:107"}message: "initialize is not a function"name: "InvalidValueError"stack: "Error↵ at new Xc (http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize:56:227)↵ at Object._.Yc (http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize:56:337)↵ at Uh (http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize:125:221)↵ at http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize:125:107"__proto__: Error
Promise.then (async)
Vh # js?key=KEY&callback=initialize:125
google.maps.Load # js?key=KEY&callback=initialize:21
(anonymous) # js?key=KEY&callback=initialize:212
(anonymous) # js?key=KEY&callback=initialize:212
This initialize is written in common.js. The file is listed in console, red by webpack (which presspack uses).
I'm running this #localhost so won't be able to provide a link for this page.
And I'm sorry if I've done any mistakes formatting this post or provide wrong info. Not really experienced at creating posts here in stack. :(
Any thoughts and ideas on this problem will be most welcome.
Edit: corrected that mistake as Evan suggested in the comments, where the calling was for maps.google.com and not maps.googleapis.com
Edit2: As Evan kept helping me on the comment section, I've made some additions to my code as follows.
The callback function that was returning a problem in console, was removed and I replaced it as a new callback for initialize function that appears on common.js.
var markers = [{(...)}];
function initialize() {(...)};
function initMap() {(...)};
var markers = [{(...)}];
function initMap2() {(...)};
google.maps.event.addDomListener(window, 'load', initialize); //This is the new callback for my maps
This did solved something, since the first map appeared. Still, there was still some error which console would point at:
"Uncaught ReferenceError: i is not defined at initMap (common.js?a395:77) at initialize (common.js?a395:56)" pointing at this line of common.js: for (i = 0; i < markers.length; i++) {.
I didn't get it. Just guessed that it had something to do with my markers code, since the first map appeared after the callback being made in common.js but with no marker.
Then, Evan pointed that if i was initialized globally, that error made sense. So he suggested changing the code to for (let i = 0; i < markers.length; i++) {, which did it for me. Adding it to both instances of markers in the code, made both maps appear properly and with markers.
Thanks for your help, Evan!
First of all, the JavaScript API should be called via https://maps.googleapis.com/, not http://maps.google.com/.
The "initialize is not a function" scope error can be worked around by loading the Maps API script synchronously on page load, e.g. by using google.maps.event.addDomListener(window, 'load', initialize), but in general the recommended approach is to load the API asynchronously via a callback:
<script async defer src="https://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize"></script>
Then there's an issue with both markers loops, e.g. for (i = 0; i < markers.length; i++), as they're missing i initialization. Try using for (let i = 0; i < markers.length; i++).
You can find here a working jsbin that shows both your maps and markers loading successfully after the above code changes.
I'm trying to append a button to a page that when clicked will display my google map in a new page. I have a button that when clicked either gives an error or gives a blank page.
My code:
$('.content--body__wrapper').append('<button id="show-map" />')
$('.content--body__wrapper').append(`<script>
document.getElementById("show-map").addEventListener("click", function(){
var center = {lat: -25.363, lng: 131.044};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: center
});
var marker = new google.maps.Marker({
position: center,
map: map,
});
})
</script>`);
$('.content--body__wrapper').append(`<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBcwtM8EBe7BE1NyPbU5SDYVYoBBtbtpTI&libraries=drawing" asyncdefer></script>`);
Error Code:
Edit: I took the callback out of the script source and I still don't get a page to load but I do have a lot less errors.
$('.content--body__wrapper').append('<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBcwtM8EBe7BE1NyPbU5SDYVYoBBtbtpTI&libraries=drawing&callback=initMap" async defer></script>');
In this line you say : when the API is loaded run the function called InitMap.
The problem is that this function is not definied in your js.
So remove this callback to use the documentReady event or remove documentReadyListener and create a function name initMap
I'm write this code for show my position on the map:
<script src="http://maps.googleapis.com/maps/api/js"></script>
<script>
function initialize(x, y) {
alert(x);
alert(y);
var mapProp = {
center: new google.maps.LatLng(x, y),
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
up code run the initialize function when page load or postback,but i write this code for asp button:
Page.ClientScript.RegisterStartupScript(this.GetType(), "beh", "initialize(38.076306,46.279637);", true);
and i want when button fire,send value to function and java script function change the map position,it's work,but when button fire,function run ,and run again when web form loaded!,and in first time show correct position,but when page load event occurred,send null value to function and show empty position, i think when run java script function in asp button fire,and not run java script function when page load occurred?
The problem with your code is the execution order of the code blocks. Execution time of code that is added via the ClientScriptManager.RegisterStartupScript according to the msdn:
The script block added by the RegisterStartupScript method executes when the page finishes loading but before the page's OnLoad event is raised.
So, you could solve your problem by adding a boolean variable in your script tag (which get's executed while the page is loading), set it to false initially and change it to true in your button click handler (which is executed once the page has finished loading). Then in your window.onload event listener, check if the variable is false. If it is, you can initialize the map.
So, your javascript would change to this:
<script>
var isButtonClick = false;
function initialize(x, y) {
var mapProp = {
center: new google.maps.LatLng(x, y),
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
}
google.maps.event.addDomListener(window, 'load', function () { if(!isButtonClick)initialize(0, 0) });
</script>
and your button click handler to this:
void ButtonClick(object sender, EventArgs e)
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "beh", "isButtonClick=true;initialize(38.076306,46.279637);", true);
}
I tested it locally and it worked fine
I am attempting to create a google map with markers on my page. I have an unordered list where each item has data attributes for latitude, longitude and title. Using JQuery I pull these values and produce a marker on the map for each item in the list. Everything seems to work OK except google maps will not load tiles as you pan around the map.
This is how I initialize the map:
var map;
// initialize google map
$(function () {
var myOptions = {
zoom: 10,
center: new google.maps.LatLng(CoordinatesLat, CoordinatesLong),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false
}
// initiate map
map = new google.maps.Map($("#map")[0], myOptions);
// when map is loaded, add events and behaviors to it
google.maps.event.addListenerOnce(map, 'tilesloaded', addEventsToMap(".event")); //commenting this line prevents GMAP problems
});
FYI - before I was using maps.event.addListener() and the map would work momentarily and then become completely unresponsive. Changing it to maps.event.addListenerOnce() stopped the freezing but still has the tile loading problem.
And this is the callback, where evidently I've done something wrong:
//add events from event list to map. add behavior to events ie. mouseover
function addEventsToMap(selector) {
$(selector).each(function (i, $e) {
$e = $($e);
var latlng;
if ($e.attr("data-geo-lat") && $e.attr("data-geo-long")) {
latlng = new google.maps.LatLng($e.attr("data-geo-lat"), $e.attr("data-geo-long"));
$e.marker = new google.maps.Marker({
position: latlng,
map: map,
title: $e.attr("data-title")
});
google.maps.event.addListener($e.marker, 'click', function () { window.location = $e.attr("data-href"); });
google.maps.event.addListener($e.marker, 'mouseover', function () { $e.addClass("event-hover"); });
google.maps.event.addListener($e.marker, 'mouseout', function () { $e.removeClass("event-hover"); });
//when mouse hovers over item in list, center map on it's marker
$e.mouseenter(function () {
map.panTo(latlng);
});
}
});
}
Any idea what could be causing this?
I see a problem, though I'm not sure if it's the issue here. If you examine this line:
google.maps.event.addListenerOnce(map, 'tilesloaded', addEventsToMap(".event"));
What you are intending to do is call your 'addEventsToMap' once the map is loaded, but instead what you are doing is calling the function and then assigning the return value of that as a listener.
You need this instead, and I think it shouldn't crash anymore.
google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
addEventsToMap(".event");
});
If that doesn't work, I would recommend looking at the Javascript Console of whatever browser you are using, to see what error is happening to make the map crash.
I'm building a Qt app with Python where you can point and click at a (google) map and get the coordinates of the location. The map is shown through a QWebView loading a simple HTML page and the user can create markers by clicking. Screenshot of the widget after clicking on the map.
However, I'm having trouble to retrieve the just-clicked location coordinates back to Qt (so that I can use them as variables -- and, for example, show them in the QLineEdits on the topleft corner above, as current location of the marker).
This is the relevant part of the HTML file:
<script type="text/javascript">
var map;
function initialize() {
var local = new google.maps.LatLng(-23.4,-40.3);
var myOptions = {
zoom: 5,
center: local,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, 'rightclick', function(event) {
placeMarker(event.latLng);
});
}
function placeMarker(location) {
var clickedLocation = new google.maps.LatLng(location);
var marker = new google.maps.Marker({
position: location,
map: map
});
map.setCenter(location);
}
function dummyTxt() {
return 'This works.';
}
</script>
I've been trying with evaluateJavaScript, but was not able to retrieve the coordinates. I tried to created a function to access the position with marker.getPosition(), but with no luck. The dummy below works though..
newplace = QWebView.page().mainFrame().evaluateJavaScript(QString('dummyTxt()'))
>>> print newplace.toString()
This works.
Any suggestions on how to get the coordinates back to Qt?
Edit:
Here is the code that worked for me:
def update_geo(self):
# Capture coordinates of the last marker on the map.
mark = self.map.page().mainFrame().evaluateJavaScript('document.getElementById("markerlocation").value').toString()
# Convert string to list of floats, stripping parentheses.
marker = str(mark).strip('()').split(', ')
decimals = [float(c) for c in marker]
Full source in https://github.com/nelas/veliger/blob/master/veliger.py#L2374
I found a work around to make it work but I'm not pretty sure that it will be the right approach. Anyway, this is what I did:
Create a hidden input in the body section of your html document to save the position data of the marker:
<body>
(...)
<input id="locationData" type="hidden">
(...)
</body>
In the javascript code, save the position of the marker in the hidden input every time it's created:
function placeMarker(location) {
(...)
document.getElementById("locationData").value = marker.position;
(...)
}
In your Qt code, read the value of the hidden input with the instruction:
webView->page()->mainFrame()->findFirstElement("#locationData").evaluateJavaScript("this.value").toString();
I hope it helps!
Source: http://opendocs.net/qt/4.6/webkit-formextractor.html