I want to remove event listener for click added by:
var events = {
click: function () {
// crazy stuff here :- )
}
};
$(where).gmap3(
{
events: events
}
);
Need something like:
$(where).gmap3().removeEventListener('click');
Didn't realize gmap3 was a wrapper library. Ill remove the duplicate comment.
Browsing through the gmaps3 documentation, I did not see anything specific to remove listeners with the libraries functions, but you can grab the marker with action: 'get' and then clear the listener.
Here is a example that a altered from the documentation. I added a name and tag property to the markers and at the end of this script I remove the mouseover listener from the marker with tag:'2'. For some reason this library is fickle and wants both the name and tag property to find the marker.
$('#test').gmap3({
action: 'init',
options: {
center: [46.578498, 2.457275],
zoom: 5
}
}, {
action: 'addMarkers',
markers: [
{
name : 'marker',
tag: '1',
lat: 48.8620722,
lng: 2.352047,
data: 'Paris !'},
{
name : 'marker',
tag: '2',
lat: 46.59433,
lng: 0.342236,
data: 'Poitiers : great city !'},
{
name : 'marker',
tag: '3',
lat: 42.704931,
lng: 2.894697,
data: 'Perpignan ! GO USAP !'}
],
marker: {
options: {
draggable: false
},
events: {
mouseover: function(marker, event, data) {
var map = $(this).gmap3('get'),
infowindow = $(this).gmap3({
action: 'get',
name: 'infowindow'
});
if (infowindow) {
infowindow.open(map, marker);
infowindow.setContent(data);
} else {
$(this).gmap3({
action: 'addinfowindow',
anchor: marker,
options: {
content: data
}
});
}
},
mouseout: function() {
var infowindow = $(this).gmap3({
action: 'get',
name: 'infowindow'
});
if (infowindow) {
infowindow.close();
}
}
}
}
});
//get the marker by name and tag
var mark = $('#test').gmap3({
action: 'get',
name:'marker',
tag: '2'
});
//remove the event listener
google.maps.event.clearListeners(mark, 'mouseover');
Here is an example of this script working: http://jsfiddle.net/5GcP7/. The marker in the middle will not open an infowindow when moused over.
I solved this problem in different way:
var events = {
click: function () {
if (P.settings.mapPinActive === false) {
return;
}
// crazy stuff here :- )
}
};
Instead of detaching and attaching events, global properties in settings object.
Related
Trying to implement google map into Vue component. But having a hard time. Actually, there is no error. But no map also :) Okay, what I tried so far down below.
In laravel blade I set my api.
<script async defer src="https://maps.googleapis.com/maps/api/js?key={{env('GOOGLE_MAPS_API')}}&callback=initMap"></script>
Then in Vue component;
data() {
return {
mapName: "map",
//some other codes
}
},
mounted() {
this.fetchEstates();
},
methods: {
fetchEstates(page = 1) {
axios.get('/ajax', {
params: {
page
}}).then((response) => {
// console.log(response);
this.estates = response.data.data;
//some other codes....
//some other codes....
},
computed: {
//some other functions in computed...
//
initMap: function(){
var options =
{
zoom : 6,
center : {
lat:34.652500,
lng:135.506302
}
};
var map = new google.maps.Map(document.getElementById(this.mapName), options);
var marker = new google.maps.Marker({
map: map,
icon: 'imgs/marker.png',
url: "/pages/estates.id",
label: {
text: this.estates.price,
color: "#fff",
},
position: {
lat: this.estates.lat,
lng: this.estates.lng
}
});
google.maps.event.addListener(marker, 'click', function () {
window.location.href = this.url;
});
}
<div id="map"></div>
and last marker url id bind is in controller like this,
public function details($id)
{
$estates = allestates::where('id', $id)->first();
return view('pages.details', compact('estates'));
}
Do I missing something in Vue js? Thank you!
From our discussion in the comments, I realise that your issue is because this.estates is still not defined when initMap() is executed. Remember that you are using an asynchronous operation (via axios) to populate this.estates, so it is undefined at runtime. What you can do is:
Keep the map initialisation logic in initMap()
Move all the Google Map marker creation until after the axios promise has been resolved. You can abstract all that into another method, e.g. insertMarkers()
Also, remember that you need to define estates in the app/component data, otherwise it will not be reactive.
Here is an example:
data() {
return {
mapName: "map",
// Create the estate object first, otherwise it will not be reactive
estates: {}
}
},
mounted() {
this.fetchEstates();
this.initMap();
},
methods: {
fetchEstates: function(page = 1) {
axios.get('/ajax', {
params: {
page
}}).then((response) => {
this.estates = response.data.data;
// Once estates have been populated, we can insert markers
this.insertMarkers();
//pagination and stuff...
});
},
// Iniitialize map without creating markers
initMap: function(){
var mapOptions =
{
zoom : 6,
center : {
lat:34.652500,
lng:135.506302
}
};
var map = new google.maps.Map(document.getElementById(this.mapName), mapOptions);
},
// Helper method to insert markers
insertMarkers: function() {
var marker = new google.maps.Marker({
map: map,
icon: 'imgs/marker.png',
url: "/pages/estates.id",
label: {
text: this.estates.price,
color: "#fff",
},
position: {
lat: this.estates.lat,
lng: this.estates.lng
}
});
google.maps.event.addListener(marker, 'click', function () {
window.location.href = this.url;
});
}
},
Update: It also turns out that you have not addressed the issue of the data structure of this.estates. It appears that you are receiving an array from your endpoint instead of objects, so this.estates will return an array, and of course this.estates.lat will be undefined.
If you want to iterate through the entire array, you will have to use this.estates.forEach() to go through each individual estates while adding the marker, i.e.:
data() {
return {
mapName: "map",
// Create the estate object first, otherwise it will not be reactive
estates: {}
}
},
mounted() {
this.fetchEstates();
this.initMap();
},
methods: {
fetchEstates: function(page = 1) {
axios.get('/ajax', {
params: {
page
}}).then((response) => {
this.estates = response.data.data;
// Once estates have been populated, we can insert markers
this.insertMarkers();
//pagination and stuff...
});
},
// Iniitialize map without creating markers
initMap: function(){
var mapOptions =
{
zoom : 6,
center : {
lat:34.652500,
lng:135.506302
}
};
var map = new google.maps.Map(document.getElementById(this.mapName), mapOptions);
},
// Helper method to insert markers
insertMarkers: function() {
// Iterate through each individual estate
// Each estate will create a new marker
this.estates.forEach(estate => {
var marker = new google.maps.Marker({
map: map,
icon: 'imgs/marker.png',
url: "/pages/estates.id",
label: {
text: estate.price,
color: "#fff",
},
position: {
lat: estate.lat,
lng: estate.lng
}
});
google.maps.event.addListener(marker, 'click', function () {
window.location.href = this.url;
});
});
}
},
From what I can see in the screenshot you posted, this.estates is an array of objects? If that's the case you need to iterate through the array using forEach
this.estates.forEach((estate, index) => {
console.log(estate.lat);
//handle each estate object here
});
or use the first item in the array like so this.estates[0].lat, if you're only interested in the first item.
I've been having a problem very similar to this
However that persons question was never answered and my situation is subtly different.
I'm trying to add a click event to my map that will change the center of the map to the location of the click. My code to do this works great, but it only works once and then when I click again I get this error:
angular-google-maps.js:6815 Uncaught TypeError: Cannot read property 'click' of undefined
Here is my map object:
vm.map = {
center: {
latitude: l.latitude,
longitude: l.longitude
},
zoom: 13,
events: {
click: function(map, event, coords) {
vm.map = {
center: {
latitude: coords[0].latLng.lat(),
longitude: coords[0].latLng.lng()
},
};
$scope.apply();
}
}
};
And here's my html:
<ui-gmap-google-map center="location.map.center" zoom="location.map.zoom" draggable="true" options="tabLocations.map.options" events=location.map.events>
<ui-gmap-search-box template="'scripts/components/tab-locations/searchbox.tpl.html'" events="location.map.searchbox.events" parentdiv="'searchbox-container'"></ui-gmap-search-box>
<ui-gmap-marker ng-if="location.active" idKey="1" coords="location" options="{draggable: false, icon: 'images/icons/gps-marker-active.svg'}"></ui-gmap-marker>
<ui-gmap-marker ng-if="!location.active" idKey="1" coords="location" options="{draggable: false, icon: 'images/icons/gps-marker-inactive.svg'}"></ui-gmap-marker>
</ui-gmap-google-map>
After your first click you are redefining a brand new map with no click event:
vm.map = {
center: {
latitude: coords[0].latLng.lat(),
longitude: coords[0].latLng.lng()
},
};
This is overriding all the previous properties you had set before, which includes click.
Use setCenter instead:
click: function(map, event, coords) {
var latLng = new google.maps.LatLng(latitude: coords[0].latLng.lat(), latitude: coords[0].latLng.lng());
vm.map.setCenter(latLng);
}
Reference: Google Maps API
I am using Angular-google-maps, HTML code follows
<ui-gmap-google-map center='mapData.map.center' zoom='mapData.map.zoom'
events="mapEvents">
<ui-gmap-markers models="mapData.map.markers" coords="'self'">
</ui-gmap-markers>
</ui-gmap-google-map>
in JS calling
angular.extend(this, $controller('MapsMixinController',
{$scope:$scope, map:mapData.data[0].map}));
MapsMixinController as follows. Calling this controller from js code. Markers are showing & on click able to mark.
MapsMixinController.js
/**
* Controller providing common behaviour for the other map controllers
*/
angular
.module('app')
.controller('MapsMixinController', ['$scope', 'GeolocationService', 'uiGmapGoogleMapApi', 'map',
function($scope, GeolocationService, GoogleMapApi, map) {
var _this = this;
$scope.mapEvents = {
click: function(mapModel, eventName, originalEventArgs) {
var e = originalEventArgs[0];
if (e.latLng) {
$scope.mapData.map.markers.push({
id: new Date().getTime(),
latitude: e.latLng.lat(),
longitude: e.latLng.lng()
});
// This event is outside angular boundary, hence we need to call $apply here
$scope.$apply();
}
}
};
// Returns a default map based on the position sent as parameter
this.getDefaultMap = function(position) {
return {
markers: [],
center: {
latitude: position.coords.latitude,
longitude: position.coords.longitude
},
zoom: 14
};
};
// Initialize the google maps api and configure the map
GoogleMapApi.then(function() {
GeolocationService().then(function(position) {
$scope.mapData.map = map || _this.getDefaultMap(position);
}, function() {
$scope.error = "Unable to set map data"; // TODO use translate
});
});
}
]);
How can I show title on mouse hover on markers? And on click how to show description on markers?
You can add title property alone with latitude and longtitude property while creating marker data.
/**
* Controller providing common behaviour for the other map controllers
*/
angular
.module('app')
.controller('MapsMixinController', ['$scope', 'GeolocationService', 'uiGmapGoogleMapApi', 'map',
function($scope, GeolocationService, GoogleMapApi, map) {
var _this = this;
$scope.mapEvents = {
click: function(mapModel, eventName, originalEventArgs) {
var e = originalEventArgs[0];
if (e.latLng) {
$scope.mapData.map.markers.push({
id: new Date().getTime(),
latitude: e.latLng.lat(),
longitude: e.latLng.lng(),
title: "Mouse over text"
});
// This event is outside angular boundary, hence we need to call $apply here
$scope.$apply();
}
}
};
// Returns a default map based on the position sent as parameter
this.getDefaultMap = function(position) {
return {
markers: [],
center: {
latitude: position.coords.latitude,
longitude: position.coords.longitude
},
zoom: 14
};
};
// Initialize the google maps api and configure the map
GoogleMapApi.then(function() {
GeolocationService().then(function(position) {
$scope.mapData.map = map || _this.getDefaultMap(position);
}, function() {
$scope.error = "Unable to set map data"; // TODO use translate
});
});
}
]);
I have a functioning Google Map running on Google Appengine.
I want to turn this into a mobile friendly interface by using (maybe) Sencha Touch 2. Maybe I'm supposed to know Sencha EXT JS4 as well but I can't see it stated anywhere in their docs.
I don't know JavaScript very well. This is my 'learn by doing' app.
I've been reading the examples in documentation for Sencha Touch 2 but it stops short after getting some TabPanels with basic html and images.
There are some other examples on github for Sencha Touch 2 MVC & forms which I'd like to work on but the first step is to re-create my functional map.
I have included the current working Google Maps loop:
for(var i = 0; i < pubs.length; ++i) {
(function (address, name, phone, price, icon, lat, lng, boing) {
var posi = new google.maps.LatLng(lat, lng);
if(boing == 'true') {
var bounce = google.maps.Animation.BOUNCE;
};
var marker = new google.maps.Marker({
animation: bounce,
map: beerMap.map,
//changed this to beerMap
icon: icon,
shadow: shadow,
position: posi,
title: name
});
google.maps.event.addListener(marker, 'click', function () {
content_string = '<div id=content>' + '<div id="infoWindow">' + '</div>' + '<h2 id="pubName" class="pubName">' + name + '</h2>' + '<div id="pubAddress">' + '<p><b>' + address + '</b>' + '<div id="pubPhone" class="pubPhone">' + '<p>Phone: ' + phone + '<p>Halvliterpris: NOK <b>' + price + '</b>';
bubble.setContent(content_string);
bubble.open(beerMap.map, marker);
});
})(pubs[i], pub_name[i], pub_phone[i], beer_price[i], marker_icon[i], pub_lat[i], pub_lng[i], pub_bounce[i]);
}
./app/app.js
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
name: 'app',
appFolder: 'static/app',
controllers: ['Home'],
launch: function () {
console.log('Ext.application ~ launch');
Ext.create('Ext.tab.Panel', {
fullscreen: true,
tabBarPosition: 'bottom',
items: [{
title: 'Home',
iconCls: 'home'
}, {
title: 'Beer',
iconCls: 'locate',
xtype: 'map'
}, {
title: 'Gigs',
iconCls: 'star'
}]
});
}
});
./app/controller/Home.js
Ext.define('app.controller.Home', {
extend: 'Ext.app.Controller',
views: ['HomePage'],
init: function() {
console.log('Home controller init method...');
}
});
./app/view/HomePage.js
Ext.define('app.view.HomePage', {
extend: 'Ext.Panel',
alias: 'widget.homepage',
config: {
html: '<img src="http://staging.sencha.com/img/sencha.png" />'
},
initialize: function () {
console.log("InitComponent for homepage");
this.callParent();
}
});
In my demo APP I have put my marker logic in the maprender method:
First the controller's init method:
/**
* The init method will be executed first. Here we define how this controller should behave.
*/
init: function() {
this.control({
'viewport' : {
activeitemchange : 'handleItemChange'
},
'map' : {
maprender : 'onGMapRender'
}
});
},
Then my method GMapRender():
/**
* This method will be invoked after the google maps is rendered.
* Here we will define the current user location.
*/
onGMapRender: function(comp, map) {
},
In the method GMapRender (actually it is the method maprender You have the map object where you can do fun stuff with the Google Maps object.
Hope this help you in the right direction.
I am having trouble with the goMap plugin for jquery. I want to obtain all the markers on my map, however, when calling the getMarkers() function, it returns an empty array.
I am guessing it has something to do with scopes?
I add the markers by querying the database with an ajax call.
$("#canvas").goMap({
latitude: 44.230065,
longitude: -76.50000,
zoom: 14,
maptype: 'ROADMAP'
});
load_markers();
function load_markers(query_url) {
if (query_url == undefined) {
query_url = '/posts/get_markers';
}
$.getJSON(query_url, function(data) {
$.each(data, function(pair) {
var id = data[pair]['posts']['id'];
$.goMap.createMarker({
latitude: data[pair]['posts']['lat'],
longitude: data[pair]['posts']['lng'],
draggable: false,
id: id,
html: {
ajax: "posts/ajax_show/"+id,
content: 'loading...',
popup: false
}
});
});
});
}
console.log(($.goMap.getMarkers()));
Thanks!
Try to print it in the success handler of the getJSON call, otherwise you donĀ“t know if you got the data yet. More a timing issue than scope if im correct.
$.getJSON(query_url, function(data) {
$.each(data, function(pair) {
var id = data[pair]['posts']['id'];
$.goMap.createMarker({
latitude: data[pair]['posts']['lat'],
longitude: data[pair]['posts']['lng'],
draggable: false,
id: id,
html: {
ajax: "posts/ajax_show/"+id,
content: 'loading...',
popup: false
}
});
});
console.log(($.goMap.getMarkers()));
});