I try to use ContextMenu to run DeleteMaker function, but ContextMenu just get marker current Latlng, not like other leaflet events like "click", "dblclick" ... what can get marker options info.
Example :
var marker = new customMarker([28.63278, 77.21972],{
clickable: true,
name: 'Connaught Place',
type: 'Neighbourhood'
}).on('click', onClick).addTo(map);
function onClick(e) {
$('#content').html("
Name: "+this.options.name+"
Type: "+this.options.type+"
">;")
}
that code above can get Options value with event "click", HOW CAN I GET options value LIKE THIS WITH CONTEXTMENU
If you want to get marker options from outer, simply use variable name to get there.
marker.options.name
marker.options.type
See example in JSFiddle. Is this what you asked?
I'm using the context menu plugin for leaflet (https://github.com/aratcliffe/Leaflet.contextmenu) and I noticed the same situation. What I did was to use the "contextmenu" option for the marker event to create a global variable with the marker.options.id when a right click is detected. Then, using the context menu callback function, use that global variable (that has the marker id), fetch the marker associated to that id and THEN remove the marker from the markers array. Yes, I use a markers array because is easier to work when you have thousand of markers in the map.
It's not elegant but it works.
If you're using the contextmenu pluging, it's pretty straight forward.
You could use a global variable like Alberto said. Or just feed the callback property of the contextmenu item with a function call.
var type = "type";
var name = "name";
var marker = new customMarker(28.63278, 77.21972,
{
name: name,
type: type,
contextmenu: true,
contextmenuWidth: 140,
contextmenuItems: [ { text: 'Show name/type', callback: function () { SetContent(name, type) } }]
});
function SetContent(name, type)
{
$('#content').html("Name: " + name + "Type: " + type);
}
Related
I have a leaflet map with several markers on it. On click on a marker this one should get highlighted. I use divIcons and want to change the whole icon or the className of it, both would work for me. At the moment i'm just changing the class of the created div in the html tree to highlight it. This works great, but i ue a marker clusterer. Therefore the divs get created and dumped on and on again and my highlight class dissapears at each clustering.
Markers:
var markerIcon = L.divIcon({
className: 'marker--default',
html: "15",
iconAnchor: [20, 20]
});
var markerIconActive = L.divIcon({
className: 'marker--state--active',
html: "15",
iconAnchor: [20, 20]
});
Integration of Marker:
var markers = L.markerClusterGroup({});
markers.addLayer(L.marker([50.919523, 6.940621], {icon: markerIcon})).on('click', onClick);
map.addLayer(markers);
Clickevent:
function onClick(e) {
e.target.setIcon(markerIconActive);
}
Note:
It doesn't work. I get the error "e.target.setIcon is not a function". After reading the documentary it seems that there is no setIcon method for divIcons. As said it would be working for me too if just the className get changed, but i don't know how to change this one.
Documentation:
https://leafletjs.com/reference-1.4.0.html#divicon
Instead of trying to access the functions / properties via e.target.<function> use e.<function> or this.<function>:
function onClick(e) {
e.setIcon(markerIconActive);
}
alternatively, you can access it through e.layer:
function onClick(e) {
let marker = e.layer;
marker.setIcon(markerIconActive);
}
Reading Material
Is there a way to click on any map marker and retrieve the marker's lat/lng (or array index)?
If you want to change the class of your div, the native function is classList. You can use it along-side with stopPropagation to prevent the first bug you pointed out. like so
function onClick(e) {
e.stopPropagation();
e.target.classList.toggle('newclass');
}
You also can use replace method instead of toggle if you want a "switch"
function onClick(e) {
e.stopPropagation();
e.target.classList.replace('oldclass','newclass');
}
Don't forget to pass the event buble through the onClick function when you call it $.on('click', onClick(e))
markers.addLayer(L.marker([50.919523, 6.940621], {icon: markerIcon})).on('click', onClick(e));
I have a map with bingmap and I implemented waypoints. I would like when I click in a waypoint it displays an info window.
if (!$scope.directionsManager) { _createDirectionsManager(); }
if($scope.directionsManager.getAllWaypoints().length < 2)
{
$scope.directionsManager.resetDirections();
$scope.waypoints.forEach(function (waypoint) {
var order_waypoint = new Microsoft.Maps.Directions.Waypoint({ location: new Microsoft.Maps.Location(waypoint.lat, waypoint.lng) });
console.log("order_waypoint", order_waypoint)
$scope.directionsManager.addWaypoint(order_waypoint);
})
}
var renderOption = {
itineraryContainer: document.getElementById('directionsItinerary'),
waypointPushpinOptions:{
// icon: "http://vignette3.wikia.nocookie.net/freeciv/images/1/1c/Crystal_128_penguin.png/revision/latest?cb=20071106133132&path-prefix=es",
// hoverIcon: "http://vignette3.wikia.nocookie.net/freeciv/images/1/1c/Crystal_128_penguin.png/revision/latest?cb=20071106133132&path-prefix=es",
// height: 10,
// width: 10,
draggable: false,
textOffset: new Microsoft.Maps.Point(-1, 3)
}
}
$scope.directionsManager.setRenderOptions(renderOption);
$scope.directionsManager.calculateDirections();
Thanks!
I haven't used the Bing maps API, but the docs on the Waypoint class make it look like you might need a custom pushpin in order to intercept its click event.
var location = new Microsoft.Maps.Location(waypoint.lat, waypoint.lng);
var pushpin = new Microsoft.Maps.Pushpin(location);
Microsoft.Maps.Events.addHandler(pushpin, 'click', function() {
// Implementation can go here
});
var order_waypoint = new Microsoft.Maps.Directions.Waypoint(
{location: location, pushpin: pushpin});
$scope.directionsManager.addWaypoint(order_waypoint);
It is possible you can get a reference to the default pushpin on order_waypoint without creating your own custom one, and use addHandler to bind the click event to it. I don't have running code to test that on, and I don't see a way to get a reference to the default pushpin, only the custom one. You could try it anyway (order_waypoint.getPushpin()) and see if it works.
Thats it I want to create an onclick event on my marker, I'm using angular-openlayers-directive.
So far I've been able to make some markers show up, but I'm unable to get them after a click event.
I would like to perform some actions with these markers custom properties like name, remarks, etc. But it seems too hard to achieve this with openlayers 3.
<openlayers ol-center="ven" height="100vh">
<ol-layer ol-layer-properties="wms">
<ol-marker ng-repeat="marker in markers"
lat="marker.lat"
lon="marker.lon"
></ol-marker>
</ol-layer>
</openlayers>
So how could I handle an onclick event on these markers and get all their info, or a reference to the javascript object "marker" itself.
I wasn't sure if you wanted to have the click on the popover or the marker itself. Below there are instructions for both. Use the Plunker link at the bottom to see a working demo of both options.
To Register Click on Marker Popover:
If you take a look at the directive, you can see that the marker template uses ng-transclude, so you can do the following:
Markup:
<ol-marker ol-marker-properties="santiago" >
<p ng-click="showDetails(santiago)">Santiago de Compostela</p>
</ol-marker>
In your controller:
$scope.showDetails = function(id) {
alert('lat: '+ id.lat+', '+'lon: '+id.lon);
};
Here I'm passing in the marker object to the showDetails function. When you click the popover label for Santiago de Compostela in the Plunker Demo, you'll see the corresponding lat/lon in the alert.
To Register Click on the Marker:
You can add an onClick property to the marker object as follows:
In your controller:
finisterre: {
lat: 42.907800500000000000,
lon: -9.265031499999964000,
label: {
show: false,
},
onClick: function (event, properties) {
console.log(properties);
alert('lat: '+ properties.lat+', '+'lon: '+properties.lon);
}
}
When you click the marker associated with finisterre in the Plunker Demo, you'll see the corresponding lat/lon in the alert.
NOTE:
I could only get this to work though under the following conditions:
The marker object must have a label property defined
The show property of the label must be set to false.
The ol-marker html element must have some transcluded content OR the message property must be set in the marker label object.
I was able to use CSS to prevent the popover from displaying as you can see in the demo, but it seems a little hacky. If you want the popover to display on click as well, you're all set, just remove the css hidden class I added and add your pop-over html.
Plunker Demo
I just got this working today as it happens. What I am doing for now is adding the properties to my markers once I get them from mongo.
function addMarkerProperties ()
// needed to enable click events on a marker!
// Have a label property defined for the marker.
// Have the show property of the label set to false.
// Have some transcluded content in the marker.
{
for (var i = $scope.markers.length - 1; i >= 0; i--) {
$scope.markers[i].onClick = function (event, properties) { console.log('Clicked a marker'); console.log(this); console.log(properties); };
$scope.markers[i].label = {
// Note: Duplication of data here # message. Fix this later.
"message": $scope.markers[i].name,
"show": false,
"showOnMouseOver": false
};
};
}
Once the markers have all the properties they need. It just sort of works but I do have a bug to iron out as well where the marker titles repeat above the map for.... reasons.
As you click the markers the words disappear.
With the latest release (April 6 2016) of the angular-openlayers-directive library (correct) ngClick-handling seems to be implemented. After a bit of searching I came up with the following solution:
The HTML (simplified):
<html ng-controller="mapController">
<openlayers width="100%" height="400px">
<ol-marker ng-repeat="marker in markers" ol-marker-properties="marker" ng-click="showDetails(marker)"></ol-marker>
</openlayers>
</html>
The Angular Javascript for the map controller (expects that your API endpoint called '/api/markerlist' returns a list of JSON objects with the fields: 'latitude', 'longitude'):
$scope.markers = [];
$scope.initializeMarkers = function() {
var markerList = $http.get("yoursite/api/markerlist")
.succes( function(result) {
angular.forEach(result, function(value, key) {
$scope.markers.push({
lat: value.latitude,
lon: value.longitude,
label: {
message: "Your message",
show: false,
showOnMouseOver: false
}
});
});
}
function showDetails(marker) {
alert('Clicked a marker on the map');
console.log(marker);
}
Finally, be sure that you have included the angular-openlayer-directive CSS, so the messages for the labels are not visible.
So in JVector map I need a function that has each region linked to a URL. So if you click on South Africa it will take you to a page with information about South Africa. I know to start with onRegionClick: function () but where to go from there is a mystery to me.
Well, as the documentation says:
onRegionClick
Callback function which will be called when the user
clicks the region path. Region code will be passed to the callback as
argument.
So each time a region is clicked, the region's code is passed to the handler. Then if the code is all you need on your next page, you could just pass that as is in the query string.
onRegionClick: function (event, code) {
window.location.href = "yourpage?regionCode=" + code
},
If you need the actual name of the region instead of the code, there is a handy getRegionName method that you could use.
var regionName = map.getRegionName(code);
You can Use this html body
<div class="map_jvector"></div>
and the javascript
<script>
$('.map_jvector').vectorMap({
map: 'africa',
backgroundColor: '#ffffff',
onRegionClick:function(event, code){
var name = (code);
window.location.replace("http://your url address/"+code+"");
},
series: {
regions: [{
values: gdpData,
scale: ['#003471','#009eef', '#0076a3','#0d004c','#f26522','#9e0039'],
normalizeFunction: 'polynomial'
}]
},
onRegionTipShow: function(e, el, code){
el.html(el.html());
}
});
</script>
Change link "your url address" to your link address & the "+code+" is region of JVector Map, if you click on the map province area, it will be to link the region.
I'm trying to produce a mapping application with Bing Maps with a button that will retrieve a JSON string and places pins on the map based on the center of the map.
That is working fine, but I'm running into two issues that I'm having trouble diagnosing.
The first is that when I move the map after placing the pins, the majority of them disappear from the map except for 1-3. I've figured out that the pins are still being held in map.entities, but just aren't all displaying.
The second issue is that I have a click event on the pins, and sometimes when I click on a pin it will disappear (and sometimes reappear elsewhere on the map).
Here is my code:
function addPin() {
map.entities.clear();
var pinImg = "images/MapPin.jpg";
var latLong = {};
var name;
for (var i = 0; i < factualJson.response.data.length; ++i) {
latLong['latitude'] = factualJson.response.data[i].latitude;
latLong['longitude'] = factualJson.response.data[i].longitude;
name = factualJson.response.data[i].name;
var pin = new Microsoft.Maps.Pushpin(latLong, {
icon: pinImg,
anchor: new Microsoft.Maps.Point(latLong['latitude'], latLong['longitude']),
draggable: true,
width: 48,
height: 48
});
Microsoft.Maps.Events.addHandler(pin, 'click', displayName);
pin.title = name;
pin.id = 'pin' + i;
map.entities.push(pin);
}
document.getElementById("arrayLength").innerHTML = "Number of locations: " + map.entities.getLength();
}
function displayName(e) {
document.getElementById("name").innerHTML = "";
if (this.target.id != -1) {
document.getElementById("name").innerHTML = this.target.title;
}
}
function boot() {
Microsoft.Maps.loadModule('Microsoft.Maps.Overlays.Style', { callback: getMap });
}
function getMap() {
map = new Microsoft.Maps.Map($gel("bingMap"), {
credentials: getKey(),
customizeOverlays: true,
enableClickableLogo: true,
enableSearchLogo: true,
showDashboard: true,
showBreadcrumb: true,
showCopyright: true,
zoom: 10,
labelOverlay: Microsoft.Maps.LabelOverlay.hidden
});
setGeoLocation();
//setTimeout(optimizeMap, 100);
window.onresize = resizeWin;
resizeWin();
}
Currently I make an ajax call from the button, and the callback function calls 'AddPin' which adds the pins to the map. I thought I'd add in the map initialization code in case it was relevant. Currently boot() is called on body load.
For me the solution was similar to yours #canadian coder
Microsoft.Maps.Location() only accepts float values, no strings and Int.
I use MVC architecture and passed a string using a model. Later i converted that string to float and passed to Location.
Problem solved.
var pushpin = new Microsoft.Maps.Pushpin(
center, { icon: '/Content/BingPushpin.png', width: 50, height: 50, draggable: false });
pushpin.setLocation(new Microsoft.Maps.Location
(parseFloat(#Model.Latitude) , parseFloat(#Model.Longitude)));
dataLayer.push(pushpin);
locations.push(new Microsoft.Maps.Location
(parseFloat(#Model.Latitude) , parseFloat(#Model.Longitude)));
EDIT :
Later found out that problem still exist. Another reason can be that you are calling that Map to load twice. So check for any other instance of the map which is being loaded. In my case see below.
$(document).ready(function () {
loadSearchModule(); //calling Map to Load at a div without pushpins
//code to do something
getMapOnLocation();
}
function getMapOnLocation()
{//code to display map with pushpin
}
In the Above example I was telling the control to load my map with PushPins and when the page is fully Loaded load the map without pushpins.
Hope this helps :)
As always I need to ask the question before I figure it out myself.
The issue was that I needed to push a Microsoft location object into the pin and not an object. Like so:
var loc = new Microsoft.Maps.Location(47.592, -122.332);
And NOT my latLong object.
This also seemed to fix the issue of disappearing pins on click event.