Bing Maps v8 - Invoke Click Event on PushPin - javascript

Once i load the Bing map with multiple pushpin with infobox. I have added click Here anchor tag on HTML with specific pushpin index to display infobox on javascript click event. Somehow it's not working for me.
I do see Invoke event is being supported in v8
Here is the fiddle https://jsfiddle.net/pakpatel/9dc4oxfk/2/
var map, infobox;
map = new Microsoft.Maps.Map('#myMap', {
credentials: ''
});
//Create an infobox at the center of the map but don't show it.
infobox = new Microsoft.Maps.Infobox(map.getCenter(), {
visible: false
});
//Assign the infobox to a map instance.
infobox.setMap(map);
//Create random locations in the map bounds.
var randomLocations = Microsoft.Maps.TestDataGenerator.getLocations(5, map.getBounds());
for (var i = 0; i < randomLocations.length; i++) {
var pin = new Microsoft.Maps.Pushpin(randomLocations[i]);
//Store some metadata with the pushpin.
pin.metadata = {
title: 'Pin ' + i,
description: 'Discription for pin' + i
};
//Add a click event handler to the pushpin.
Microsoft.Maps.Events.addHandler(pin, 'click', pushpinClicked);
//Add pushpin to the map.
map.entities.push(pin);
}
function pushpinClicked(e) {
//Make sure the infobox has metadata to display.
if (e.target.metadata) {
//Set the infobox options with the metadata of the pushpin.
infobox.setOptions({
location: e.target.getLocation(),
title: e.target.metadata.title,
description: e.target.metadata.description,
visible: true
});
}
}
function showInfoboxByKey(Key) {
//Look up the pushpin by gridKey.
var selectedPin = map.entities.get(gridKey);
//Show an infobox for the cluster or pushpin.
Microsoft.Maps.Events.invoke(selectedPin, "click");
}
<script type='text/javascript'
src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap'
async defer></script>
<div id="myMap" style="position:relative;width:600px;height:400px;"></div>
<a href='javascript:void(0);' onclick='showInfoboxByKey(3);'> Click Here </a>

The issue is you haven't passed in any event arguments when you invoked the event. As such the event handler doesn't get past your if statement and thus doesn't do anything. See the documentation here and you will notice that you need to provide the event arguments: https://msdn.microsoft.com/en-us/library/mt750279.aspx
That said, I'm not a fan of the approach being taken in your app here. If you simply want to get this working quick an easy, replace your invoke line of code with this:
pushpinClicked({e:{target: selectedPin }});
I highly recommend adding your pushpins to a layer and adding your click event to the layer. This greatly reduces the complexity of the event system and has a small performance boast.

Related

Highlight L.divIcon on mouseover or programmatically in Leaflet map

I want to highlight L.divIcon svg markers on mouseover and/or from an "outside action" like pressing a button.
here is a simplified testcase https://jsfiddle.net/sxvLykkt/5/
Markers are generated dynamically (geoJson originally) and added to a L.FeatureGroup().
On mouseover I set a bigger version of the icon (divIconActive) on a temporary layer, that I remove on mouseout. Unfortunately this doesn't work as indented (it's flickering on mouseover, the event is firing mouseover and mouseout I believe). How can I solve this.
And how can I access the markers when clicking one of the buttons? Somehow over their index I believe?! I can't wrap my head around.
Here is a portion of the code how the markers are created:
// init map and tileLayer -> jsfiddle
var coords = [[53, 13],[49, 10],[46, 12],[51, 16]];
$.each(coords, function(i,e){
// create the button
$('#controls').append('<button>'+i+'</button>')
var marker = L.marker(e, {
icon: divIcon,
id: i
});
locationLayer.addLayer(marker);
marker.on('mouseover', function(e){
markerTemp = L.marker(e.latlng, {
icon: divIconActive
}).addTo(map);
});
marker.on('mouseout', function(e){
markerTemp.remove();
});
});
locationLayer.addTo(map);
$('button').on('click', function(e){
alert('Highlight the right marker!')
});
First, to fix out marker problem, replace this code
marker.on('mouseover', function(e){
markerTemp = L.marker(e.latlng, {
icon: divIconActive
}).addTo(map);
});
marker.on('mouseout', function(e){
markerTemp.remove();
});
for this other
marker.on('mouseover', function(e){
// place the hover State on a temp Layer
markerTemp = L.marker(e.latlng, {
icon: divIconActive
}).addTo(map);
markerTemp.on('mouseout', function(e){
markerTemp.remove();
});
});
Thus, the marker will be deleted when the mouse out the Big marker.
Then, one way to personalize the buttons click is:
Add one ID to the buttons when you create them:
$('#controls').append('<button id="button'+i+'">'+i+'</button>');
And later, after creating marker add the code for its button:
var marker = L.marker(e, {
icon: divIcon,
id: i
});
locationLayer.addLayer(marker);
//the button for this marker
$('#button'+i).on('click', function(e){
alert(i);
//Here you enter what you want to do
});

Bing Map Drawing Tool Module - events

I'm using Bing Map Ajax Control V7 for test / learning.
I created a few pushpins with infobox, and added events:
function InsertEvent(mark, infoBox)
{
var obj = {marker : {}, infoWind : {}};
obj.marker.entity = mark;
obj.marker.eID = Microsoft.Maps.Events.addHandler(mark, "click", function(e) {toggleInfo(e, infoBox, true)});
obj.infoWind.entity = infoBox;
obj.infoWind.eID = Microsoft.Maps.Events.addHandler(infoBox, "mouseleave", function(e) {toggleInfo(e, infoBox, false)});
eventsID.push(obj);
}
So, these events work well, until I add DrawningToolModule to map.
function GetMap()
{
map = new Microsoft.Maps.Map(document.getElementById("mapDiv"),
{credentials: "My extra top secret Bing Map Key",
center: new Microsoft.Maps.Location(51.201547622680664, 16.16974449157715), zoom: 15 });
Microsoft.Maps.loadModule('Microsoft.Maps.Search', { callback: searchModuleLoaded });
Microsoft.Maps.registerModule("DrawingToolsModule", "DrawingToolsModule/DrawingToolsModule.js");
Microsoft.Maps.loadModule("DrawingToolsModule", { callback: function () {
drawTools = new DrawingTools.DrawingManager(map, {toolbarContainer : document.getElementById("toolbarContainer")});
}
});
}
After loading data, pushpins reaction on click is fine.
After adding custom pushpins by DrawingTool - events are fine.
After drawing any shape (polygon, polyfil, circle) - my events for pushpins aren't invoking.
I added a function helper to check if event is still available:
function showEventsCount()
{
alert("Registered events: " + eventsID.length + "\nFirst entity has click event: " +
Microsoft.Maps.Events.hasHandler(eventsID[0].marker.entity, "click") /*map.entities.getLength()*/);
}
And in result I get true.
Is this a bug with blocking events, or am I missing something?
The likely issue is that your polygon is above your pushpins thus blocking the click event or there is an issue. Alternatively there is an EntityCollection above the pushpins that has the polygons in them. This is a known issue with Bing Maps v7. Try flatting the way the map renders polygons with the following code:
map.getMode().setOptions({drawShapesInSingleLayer: true });

How To Identify Leaflet's Marker during 'popupopen/'dblclick ' event?(_source not working)

I tried this following source code:
map.on('popupopen', function(e) {
var identifyMarker= e.popupopen._source;
});
I just referred some guides from other sources that _source can identify the marker.
But when I run this source code, there is an error which is came from "_source".
So is there any other ways to identify leaflet's marker? Is it _source is not compatible with current version?
As you see in the doc, Marker has a getPopup() while Popup does not have a getMarker()
When you bind the popup to a marker, you have to keep this information in the popup object.
var marker = L.marker([lat, lng]);
var popup = L.popup().setContent("blabla");
var popup.marker = marker;
marker.bindPopup(popup);
The you can get access to the marker in the popupopen event (note e.popup and NOT e.popupopen)
map.on('popupopen', function(e) {
var identifyMarker = e.popup.marker;
});

Add a bootstrap 3 tooltip to google maps API v3 marker

I want to add a bootstrap tooltip to google map marker.
I cannot add HTML 5 atributes to it. So i tried to find the ID or class of the marker and adding the tooltip via javascript.
But, when I try to inspect the marker element using chrome tools the right click does not work inside the map canvas.
How should I go forward with it? Can I assign a custom ID to my google map marker.?? Or any other possible way?
My Code:
google.maps.event.addListener(map, 'click', function (event) {
if (POIMarker) {
POIMarker.setMap(null);
}
POIMarker = new google.maps.Marker({
position: event.latLng,
title: 'Double-Click me to feed information about this place',
icon: 'Images/POIMarker.png'
});
POIMarker.setMap(map);
google.maps.event.clearListeners(POIMarker, 'dblclick');
google.maps.event.addListener(POIMarker, 'dblclick', function (event) {
$('#POIModal').modal('show');
});
});
Here's a really hacked way of doing it, which tracks the mouse position and then positions a Bootstrap tooltip where the mouse is when the google map event is triggered. You could modify it to show the modal instead of a tooltip or use the click event instead of mouseover/out, as needed.
See http://jsfiddle.net/6o33fx6L/
var mouse = {
x: 0,
y: 0
};
document.addEventListener('mousemove', function (e) {
mouse.x = e.clientX || e.pageX;
mouse.y = e.clientY || e.pageY
}, false);
google.maps.event.addListener(marker, 'mouseover', function (event) {
$("#tt").css("left", mouse.x + "px").css("top", (mouse.y - 20) + "px").tooltip('show');
});
google.maps.event.addListener(marker, 'mouseout', function (event) {
$("#tt").tooltip('hide');
});
This version swaps in the marker's title for the tooltip:
http://jsfiddle.net/6o33fx6L/1/
You can asign more fields to the marker with this little snippet
marker.set("id", YOURVALUE);
I'd place this code in your function where you create your markers, because it will be called most likely within a for loop. So maybe you could just do something like
for(i = 0; i < markers.length; ++i)
{
// create marker
marker.set("id", i);
//set marker to map
}
Access is easy, just do
marker.get('id');
This should do what you need do clearly identify certain markers

How to get some information in google maps without click event on marker and show this in a div, other than infoWindow

Hi I am showing some markers on my google map and on click of the marker, I am calling the click event and showing some info about that place to the right side(area other than Map and not as an infoWindow). Now this event gets fired on click, and by default when page loads my div remains blank, How can I have the div the basic information being shown up once the map loads up. I need to show the information that corresponds to the marker that is the center point of the map, and later when the users click the marker icons the info should change and correspond to the particular marker being clicked
I have tried something but it doesn't work:
function loadMap() {
var myLatlng = new google.maps.LatLng(40.46998, -3.68705);
var myOptions = {
zoom: 3,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
var places = [];
places.push(new google.maps.LatLng(51.43581, -0.51744));
places.push(new google.maps.LatLng(48.87187, 2.31764));
places.push(new google.maps.LatLng(45.45979, 9.19681));
var infowindow;
for(var i = 0; i<places.length; i++) {
var marker= new google.maps.Marker({
position: places[i],
map: map,
title: 'Place' + i
});
(function (i,marker){
google.maps.event.addListener(marker, 'click' , function() {
infowindow.setContent('PLace Number' + i)
infowindow.open(i, marker)
});
});(i, marker);
}
}
$("document").ready(function () {
loadMap();
});
UPDATE EDITED
Basically I need something like Layer KML features
But the info should come on the right hand side by default for the first time. Later on when the marker is clicked, the info should change. I am also not adamant that I need this info in a kml file(xml is fine with me as well). I can just have a marker and info should popup on click and for the first time be default as well depending on the location of the user.
Bottom Line: I need the info to appear on click of a marker and by default when the page loads the info should appear corresponding to the center point of the map. which means users coming from different locations will see different info's corresponding to their location from where they are coming.(I am centering the map based on users location)
You can use the addDomListener event of the google maps api. Something like this:
<script>
function initialize() {
// Map initialization
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<body>
<div id="map_canvas"></div>
</body>
Although the above code is Maps Javascript API code, the addDomListener() method binds to the window object of the browser and allows the API to communicate with objects outside of the API's normal domain.
further reading
Actually the basic Idea is that you need to read an XMl and parse the data and and show this in a seperate div on right side., This div you can create dynamically when you load the map e-g:
$("#body").append("<div class='newdiv'></div>")
From the google Docs in the section about InfoWindow:
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 in your code, why don't you simply init your infoWindow and call the open() method? I am not particularly familiar with the api, but how about:
var infowindow = new google.maps.InfoWindow({
content: 'your initial text'
});
infowindow.open();
Or if you need the marker for special purposes on the infowindow, init an marker with the center position and use that in the infowindow.open(your_initial_pos) call.
You can use jQuery to .triger() a click event on the first marker on document.ready:
$(marker).trigger('click');
This will run the code you have already written and make it so when the page loads your div will be populated with data from whatever element you trigger the click on.
When you bind to document.ready you don't need encapsulate document in quotes:
$(document).ready(function () {...});
Or you could use the short-hand if you're into that sort of thing:
$(function () {...});
UPDATE
You can place the trigger function call after your for loop where you are setting up the markers:
for(var i = 0; i<places.length; i++) {
var marker= new google.maps.Marker({
position: places[i],
map: map,
title: 'Place' + i
});
(function (i,marker){
google.maps.event.addListener(marker, 'click' , function() {
infowindow.setContent('PLace Number' + i)
infowindow.open(i, marker)
});
});(i, marker);
//only run on the first marker
if (i === 0) {
//trigger a click event to show the first info-window
$(marker).trigger('click');
}
}
You can fire a tilesloaded event on the map object. Check out the Map reference for events
tilesloaded waits until the map tiles are actually loaded before firing. Using your code, you could do something like this:
function loadMap() {
var myLatlng = new google.maps.LatLng(40.46998, -3.68705);
var myOptions = {
zoom: 3,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
google.maps.event.addListener(map, 'tilesloaded', function() {
doSomething();
});

Categories