I am having some problems getting a fancybox gallery to load correctly when clicking on a marker within a leaflet map. I have got to the stage where I can trigger the event, but I am stuck with only getting a fancybox error message within the frame. I ran through the same workflow today with google maps api and got the same result, so there must be something I am doing wrong in calling fancybox. I have searched and searched but can't find an answer anywhere detailing my specific issue, which as I am new to JavaScript is surely a user error. My code is as follows:
//Array of locations
var locations = [
['Big Ben', 51.500625, -0.124624, 2, 'www.image1url.com/image1.jpg'],
['Tower Bridge', 51.506776, -0.074603, 1, 'www.image2url.com/image2.jpg'],
['London Eye', 51.503325, -0.119543, 3, 'www.image3url.com/image3.jpg']
];
//Calling the map
var map = L.map('map').setView([51.508529, -0.109949], 14);
mapLink =
'OpenStreetMap';
L.tileLayer(
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© ' + mapLink + ' Contributors',
maxZoom: 18,
}).addTo(map);
//Looping through the array to create the markers
for (i = 0; i < locations.length; i++) {
marker = new L.marker([locations[i][1], locations[i][2]], {
title: (locations[i][0]),
})
.addTo(map)
.on('click', function() {
$.fancybox({
href: locations[4],
width: 1000,
maxHeight: 666,
fitToView: true,
autoSize: false,
type: 'iframe',
padding: 0,
openEffect: 'elastic',
openSpeed: 150,
aspectRatio: true,
closeEffect: 'elastic',
closeSpeed: 150,
closeClick: true,
iframe: {
scrolling: 'no'
},
preload: true
});
});
}
Thanks in advance for any help
EDIT I've added a JSFiddle here: Fancybox on Leaflet Marker
Most probably, your error comes from this line of code:
href: locations[4]
The links are located in a nested array, and to access them you'll have to use:
href: locations[i][4]
UPDATE
OK, based on your JSFiddle, I've got a solution. You'll have to create a layer group and store the markers in it. Then, to access the 4th property of the locations array, you'll have to identify the position of the marker inside the layerGroup array.
//create a layergroup to store the markers inside it
var group = L.layerGroup().addTo(map)
for (i = 0; i < locations.length; i++) {
marker = new L.marker([locations[i][1], locations[i][2]], {
title: (locations[i][0]),
opacity: 1
})
.addTo(group) //add the markers to the group
marker.on('click', function() {
markerArray = group.getLayers(); //get an array with all the markers
//see which marker from the group was clicked and store the value for later use
position = markerArray.indexOf(group.getLayer(this._leaflet_id));
$.fancybox({
//acccess the locations array using the previously stored value
href: locations[position][4],
width: 1000,
maxHeight: 666,
fitToView: true,
autoSize: false,
type: 'iframe',
padding: 0,
openEffect: 'elastic',
openSpeed: 150,
aspectRatio: true,
closeEffect: 'elastic',
closeSpeed: 150,
closeClick: true,
iframe: {
scrolling: 'no'
},
preload: true
});
});
}
Here's an updated JSFiddle: http://jsfiddle.net/pufanalexandru/8mLxm820/2/
Related
I have the following code: in a St.ScrollView I have added a St.BoxLayout . The St.Scrollview is added in a menu.box.Now I want to create a St.Button, to remove the St.BoxLayout from St.ScrollView and add another St.BoxLayout there.I have tried to make a function "clicked" connected with the button, and do this:
this.buttonnotifications.connect('clicked', this.displayNotifications);
displayNotifications: function() {
this.scrollbox.remove(this.vbox);
this.menu.box.remove(this.scrollbox);
this.scrollbox.add_actor(this.vbox1);
this.menu.box.add(this.scrollbox);
},
but it does not work.A snippet of the code is below:
this.buttonbox = new St.BoxLayout();
this.buttontoday = new St.Button({ label: 'Today', width: 140, x_align: 1, style_class: 'selectbutton'});
this.buttonnotifications = new St.Button({ label: 'Notifications', width: 140, x_align: 1, style_class: 'selectbutton'});
this.buttonbox.add_actor(this.buttontoday);
this.buttonbox.add_actor(this.buttonnotifications);
this.menu.box.add(this.buttonbox);
this.scrollbox = new St.ScrollView({
height: 700,
width: 330,
hscrollbar_policy: 2,
vscrollbar_policy: 2,
enable_mouse_scrolling: true
});
this.vbox = new St.BoxLayout({
//height: 1400,
//width: 330,
vertical: true,
//y_expand: true,
style_class: "datemenu-displays-box",
style: "border:10px;"
});
this.vbox1 = new St.BoxLayout({
//height: 1400,
//width: 330,
vertical: true,
//y_expand: true,
style_class: "datemenu-displays-box",
style: "border:10px;"
});
this.vbox.add_actor(this._date.actor);
this.vbox.add_actor(this._calendar.actor);
this.vbox1.add_actor(this._eventsSection.actor, {
//x_fill: true
});
this.vbox.add_actor(this._mediaSection.actor);
this.vbox.add_actor(this._clocksSection.actor);
this.vbox.add_actor(this._weatherSection.actor, {
//x_fill: true
});
this.vbox1.add_actor(this._messageList.actor);
this.scrollbox.add_actor(this.vbox);
this.menu.box.add(this.scrollbox);
In other words I want to remove the vbox and add vbox1 pressing the buttonnotifications.
Any help will be appreciated.
Thanks in advance.
I have managed to solve this by adding this code:
this.buttonnotifications.connect('clicked', this.displayNotifications.bind(this));
The difference to the previous code is
.bind(this)
method.
I am able to draw multiple polygon by using Google Draw manager. Now I am not able to select specific polygon from multiple polygon and delete and edit it. Also not able to get new array after edit or delete.
My demo.js code is as follows :
$scope.map = {
center: { latitude: 19.997454, longitude: 73.789803 },
zoom: 10,
//mapTypeId: google.maps.MapTypeId.ROADMAP,
//radius: 15000,
stroke: {
color: '#08B21F',
weight: 2,
opacity: 1
},
fill: {
color: '#08B21F',
opacity: 0.5
},
geodesic: true, // optional: defaults to false
draggable: false, // optional: defaults to false
clickable: false, // optional: defaults to true
editable: false, // optional: defaults to false
visible: true, // optional: defaults to true
control: {},
refresh: "refreshMap",
options: { scrollwheel: true },
Polygon: {
visible: true,
editable: true,
draggable: true,
geodesic: true,
stroke: {
weight: 3,
color: 'red'
}
},
source: {
id: 'source',
coords: {
'latitude': 19.9989551,
'longitude': 73.75095599999997
},
options: {
draggable: false,
icon: 'assets/img/person.png'
}
},
isDrawingModeEnabled: true
};
$scope.drawingManagerOptions = {
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
//google.maps.drawing.OverlayType.CIRCLE,
google.maps.drawing.OverlayType.POLYGON,
]
},
circleOptions: {
fillColor: '#BCDCF9',
fillOpacity:0.5,
strokeWeight: 2,
clickable: false,
editable: true,
zIndex: 1
},
polygonOptions: {
fillColor: '#BCDCF9',
strokeColor: '#57ACF9',
fillOpacity: 0.5,
strokeWeight: 2,
clickable: false,
editable: true,
zIndex: 1
}
};
var coords = [];
var polygon;
$scope.eventHandler = {
polygoncomplete: function (drawingManager, eventName, scope, args) {
polygon = args[0];
var path = polygon.getPath();
for (var i = 0 ; i < path.length ; i++) {
coords.push({
latitude: path.getAt(i).lat(),
longitude: path.getAt(i).lng()
});
}
},
};
$scope.removeShape = function () {
google.maps.event.clearListeners(polygon, 'click');
google.maps.event.clearListeners(polygon, 'drag_handler_name');
polygon.setMap(null);
}
And My HTML code is as follows :
<ui-gmap-google-map center="map.center" zoom="map.zoom" options="map.options" control="map.control">
<ui-gmap-marker coords="map.source.coords"
options="map.source.options"
idkey="map.source.id">
</ui-gmap-marker>
<ui-gmap-drawing-manager options="drawingManagerOptions" control="drawingManagerControl" events="eventHandler"></ui-gmap-drawing-manager>
</ui-gmap-google-map>
You can find polygon image for reference:
Now I want to select one of polygon from following image and want to delete or update it.
Some help will be really appreciable.
By the ui-google-map plugin's drawing manager doc, you could get the google.maps.drawing.DrawingManager object by the control attributes (putting there an object)
<ui-gmap-drawing-manager control="drawingManagerControl" options="drawingManagerOptions"></ui-gmap-drawing-manager>
and
$scope.drawingManagerControl = {};
//Now get the drawingManager object
var drawingManager = $scope.drawingManagerControl.getDrawingManager();
Having this object is the main work.
Now you can look on everything you need. For your case you need the overlaycomplete events, it will listen for every time you have drawn a shape (=> polygon , circle, polyline)
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
var newShape = e.overlay;
});
newShape is the new shape drawn, polygon in your case, so you can use it like a Polygon object and can use all you need in this reference.
Now I want to select one of polygon from following image and want to
delete or update it.
For it, we'll distinct the polygon selected, by assigning it in a global variable: eg var selectedShape;
And now, Add a click event listener for this drawn polygon and update it as the selectedShape, and now to delete or update, you can use the selectedShape variable.
var selectedShape;
... ...
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
var newShape = e.overlay;
google.maps.event.addListener(newShape, 'click', function() {
selectedShape = newShape;
});
});
Finally you can delete the selected shape by setting his map to null selectedShape.setMap(null); and update the shape by setting it editable to true shape.setEditable(true);
And finally to make these click event possible you need to add clickable options to true for all shape.
PS: Use the IsReady Service to have map ready before working on it
Working plunker: https://embed.plnkr.co/qfjkT2lOu2vkATisGbw7/
Update:
But how to get all co-ordinates of multiple polygon after edit or
draw.
you already have this in your script, in polygonecomplete ($scope.eventHandler). Now you can add it in overlaycomplete events listener, and for everytime you updated the shape (see code bellow)
But challenge is how to identify which polygon is edited on the
map and how to update that specific polygon from my array
You can push in an array for each shape created and could manage it:
...
var allShapes = []; //the array contains all shape, to save in end
....
//get path coords: I use your code there
function getShapeCoords(shape) {
var path = shape.getPath();
var coords = [];
for (var i = 0; i < path.length; i++) {
coords.push({
latitude: path.getAt(i).lat(),
longitude: path.getAt(i).lng()
});
}
return coords;
}
....
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
var newShape = e.overlay;
google.maps.event.addListener(newShape, 'click', function() {
selectedShape = newShape;
});
...
// get coordinate of the polygon
var shapeCoords = getShapeCoords(newShape);
// pushing this shape to allShapes array
allShapes.push(newShape);
});
in the delete function you can delete id by the index of the selectedShape
//delete selected shape
function deleteSelectedShape() {
if (!selectedShape) {
alert("There are no shape selected");
return;
}
var index = allShapes.indexOf(selectedShape);
allShapes.splice(index, 1);
selectedShape.setMap(null);
}
Now you have the allShapes array, and in the end you can loop it then get for each coordinates and save in your db.
I updated the plunker and added some debug log do show you.
This snipet from github could help:
https://github.com/beekay-/gmaps-samples-v3/blob/master/drawing/drawing-tools.html
Hello I'm using d3 js with datamaps and I want to show the few countries of the world. I have checked the online forum for the help but not get cleared idea or response.
Source code :
<div id="container" style="position: relative; width: 900px; height: 500px;"></div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.9/topojson.min.js"></script>
<script src="http://datamaps.github.io/scripts/0.4.4/datamaps.world.min.js"></script>
<script>
var map = new Datamap({
element: document.getElementById('container'),
fills: {
HIGH: '#afafaf',
LOW: '#123456',
MEDIUM: 'blue',
UNKNOWN: 'rgb(0,0,0)',
defaultFill: 'green'
},
dataType: 'json', //for use with dataUrl, currently 'json' or 'csv'. CSV should have an `id` column
dataUrl: null,
geographyConfig: {
dataUrl: null, //if not null, datamaps will fetch the map JSON (currently only supports topojson)
hideAntarctica: true,
borderWidth: 1,
borderOpacity: 1,
borderColor: '#FDFDFD',
popupTemplate: function(geography, data) { //this function should just return a string
return '<div class="hoverinfo"><strong>' + geography.properties.name + '</strong></div>';
},
popupOnHover: true, //disable the popup while hovering
highlightOnHover: true,
highlightFillColor: '#FC8D59',
highlightBorderColor: 'rgba(250, 15, 160, 0.2)',
highlightBorderWidth: 2,
highlightBorderOpacity: 1
},
done: function(datamap) {
datamap.svg.selectAll('.datamaps-subunit').on('click', function(geography) {
console.log(geography);
var url = window.location.href;
var arr = url.split("/");
var result = arr[0] + "//" + arr[2]
window.open(result+'/countries/view/'+geography.properties.name);
});
}
});
</script>
It'll display all the countries. but i want to show few country.
How can I pass the country list over there?
I think with the help of custom.json or topojson. I don't know. Let me know if you have any solution or guidance.
I am creating a Google map with multiple markers that I want to popup into a Fancybox lightbox when clicked on. I must admit, I am quite a novice at javascript and Google Maps API.
I have put some pieces of different sample scripts together and come up with something that actually works decently. I have the markers the way I want them (well, without captions... which I still have to figure out), the style of map the way I want it, and I even have the markers popping up lightboxes when clicked on.
However, all markers end up opening one URL in the lightbox. I guess that makes a bit of sense. The Fancybox code is being distributed to all the markers, instead of each one individually. I tried to make another argument with a url and pass it into the Fancybox script, but it still just picks up the last marker's url and uses it for all the markers. How would I be able to get the URL to work for each marker instead of all the markers at once?
I did find a similar question on here:
Multiple fancybox google map
However, it seams to use a different route of attacking the same issue. Plus, I can't seem to get their script to work by itself, let alone integrate it with my code. So, while I get how the solution works for them, it doesn't seem to help me.
My code is as follows:
var map;
var MY_MAPTYPE_ID = 'custom_style';
function initialize() {
var featureOpts = [
{
stylers: [
{ hue: '#CCCCCC' },
{ saturation: '-100' },
{ visibility: 'simplified' },
{ gamma: 2 },
{ weight: .4 }
]
},
{
elementType: 'labels',
stylers: [
{ visibility: 'off' }
]
},
{
featureType: 'water',
stylers: [
{ color: '#efefef' }
]
}
];
var mapOptions = {
zoom: 9,
scrollwheel: false,
keyboardShortcuts: false,
disableDefaultUI: true,
center: new google.maps.LatLng(34.0531553, -84.3615928),
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP, MY_MAPTYPE_ID]
},
mapTypeId: MY_MAPTYPE_ID
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var styledMapOptions = {
name: 'Custom Style'
};
var customMapType = new google.maps.StyledMapType(featureOpts, styledMapOptions);
map.mapTypes.set(MY_MAPTYPE_ID, customMapType);
setMarkers(map, schools);
}
var schools = [
['Canton', 34.2352063, -84.4846274, 4, 'popup.htm'],
['Austell', 33.8158106, -84.6334938999999, 3, 'popup.htm'],
['Marietta', 33.9578674, -84.5532791, 2, 'popup.htm'],
['Atlanta', 33.7635085, -84.43030209999999, 1, 'popup2.htm']
];
function setMarkers(map, locations) {
var image = {
url: 'images/fml-home.png',
size: new google.maps.Size(67, 63),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(0, 63)
};
var shadow = {
url: 'images/fml-shadow.png',
size: new google.maps.Size(45, 18),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(0, 18)
};
var shape = {
coord: [1, 1, 1, 67, 60, 67, 60 , 1],
type: 'poly'
};
for (var i = 0; i < locations.length; i++) {
var schools = locations[i];
var myLatLng = new google.maps.LatLng(schools[1], schools[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
shadow: shadow,
icon: image,
shape: shape,
title: schools[0],
zIndex: schools[3]
});
var href = schools[4];
google.maps.event.addListener(marker, 'click', function() {
$.fancybox({
frameWidth : 800,
frameHeight : 600,
href : href,
type : 'iframe'
});
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
Try this:
marker["href"] = schools[4];
google.maps.event.addListener(marker, 'click', function() {
$.fancybox({
frameWidth : 800,
frameHeight : 600,
href : this.href,
type : 'iframe'
});
});
I need some help,I'm using mapSVG in this code that creates a map of my country, where every region has its own path, with its own id, so this is what I want:
When I click on a region, I need it to fade out(1000 ms) together with the whole map of the country,and then I need a delay of for example 500ms, after which only the region on which I clicked fades in (1000 ms).
And I need this to work for every region respectively.
<div id="italy" style="margin-left:135px;margin-right:135px;">
<!-- Here comes map code-->
<script type="text/javascript">
$('#italy').mapSvg({
source: 'maps/italy.svg',
colors: {
base: "#E1F1F1",
stroke: "#646464",
hover: "#548eac",
selected: "#548eac",
disabled: "#ffffff",
},
tooltipsMode: 'custom',
popover : {width: 300, height: 300},
cursor: 'pointer',
zoom: false,
pan: false,
responsive: true,
width: 900,
height: 600,
responsive: true,
zoomButtons: {'show': false,
},
regions : {
'Sicilia' : {tooltip: 'This is Sicilia'},
},
onClick : function(e,m){
this.animate({opacity: 0}, 1000 );
}
});
</script>
</div>
I'm developer of mapSVG :) Try this:
onClick: function (e, m) {
var rmap = m.getData().RMap;
var region = this;
var fadeBack = function () {region.animate({opacity: 1}, 500);};
rmap.animate({opacity: 0}, 500, fadeBack);
}