I am trying to combine these three things into one.
http://jsfiddle.net/Dansker/hk5fgbzr/3/ (fiddle 1)
http://jsfiddle.net/Dansker/rnrba8so/10/ (fiddle 2)
data.illinois.gov/resource/wsms-teqm.json (data source)
I want to add pins like I did in fiddle 1 two the code I have in fiddle 2. However I need to use the data different data source. The way I made it work in fiddle 1 was with the latitude and longitude. But because I can not do that with the new data source I need to find a new way. That is why I am trying to add it to fiddle one. Will that work? If so how can I do it? If it wont work what would you suggest using the google maps api?
$.getJSON(URL, function(data, textstatus) {
$.each(data, function(i, entry) {
var contentString = '<div id="content">'+
'<div id="siteNotice">'+
'</div>'+
'<h1 id="firstHeading" class="firstHeading">' + entry.name_ + " Library" + '</h1>'+ '<hr>' +
'<div id="bodyContent">'+
'<p>' + entry.address + " " + entry.zip + '.<br>' +
'<p>' + '' + entry.website.url + '' + '</p>'+
'<p>' + entry.hours_of_operation + '</p>'+
'</div>'+
'</div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: new google.maps.LatLng(entry.location.latitude,
entry.location.longitude),
map: map,
title: entry["dba_name"] + "\n" + entry["address"]
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
});
});
Since you have 2 callback functions, the correct way to do this is to first finish work for first callback, in this case, downloading the JSON and parse them, also I would store all the entry into entries just so that we can use the data when we add the markers, which is called at the end of the first callback.
about the API access limit, sadly I think you have to use the paid google maps geocoding API, or other services like openStreetmaps.
I also have a jsfiddle setup, hope this help.
Related
I'm unable to create a clickable url link for Google Map's infowindow. I'm sure it's a syntax error, just not sure where exactly.
Here's a snippet of my code
var marker = new google.maps.Marker({
map: map,
title: eventName,
position: loc
});
var content =
"<strong>" + "#location.venue_name" + "</strong><br>" +
"#location.venue_address" + " " + "#location.city_name" + "<br>" +
"#location.description" + "<br>" +
"#location.url" + "<br>" + //displays url eg. 'www.google.com'
//"More Details<br>"; // map won't show if this line is uncommented
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, 'click', (function (marker, content) {
return function () {
infowindow.setContent(content);
infowindow.open(map, marker);
};
})(marker, content));
Thank you in advance
Please try this one:
var content =
"<strong>" + "#location.venue_name" + "</strong><br>" +
"#location.venue_address" + " " + "#location.city_name" + "<br>" +
"#location.description" + "</div>" +
"#location.url" + "<br>" +
"<a href='" + "#location.url" + "' target='_blank'>More Details</a><br>";
Notice I have changed quotes a little bit in the last line. Hope it helps
preferably in one single string :
"<a href='#location.url' target='_blank'>More Details</a><br>"
thats easier for the eyes
pretty sure the #... injections works in longer strings as well
syntax got a bit messy there on content variable.
change your line as follows
<a href='" + "#location.url" + "' target='_blank'>More Details</a><br>"
also take a look at template literals for js which will make you code much more readable with a "`" (backtick)
var content = `<strong>${#location.venue_name}</strong>
<br>
${#location.venue_address} ${#location.city_name} ${#location.url}
<a href='${#location.url}' target='_blank'>More details</a>
`
this way you can avoid a lot of mess trying to build a string. ${} will allow you to put Js variables inside a backticked string.
I'm building a store locator type of page. The user types in his/her zip code and then is taken to the results page.
On the results page, I first run geoencode to get the LatLng of the zip code and center the map to it. Then I go through the results div (which is populated from the database) and run geoencode for each of them and set markers for each. All the distance calculations are done on the database side, so I don't have to deal with them here. Then I set an info window and a click event so that when they open they get the appropriate info on their info window. This part all works fine.
The problem I'm having is dealing with when I get more than 10 results from the database. Google maps has a maximum of 10 api calls per second. So I tried creating a more results button, then when click, would display the next 10 results on the page and on the map.
$('#more-results').click(function(){
var $elements = $('#dealer-results-dev li[data-index='+base+']').nextUntil( '#dealer-results-dev li[data-index='+(base + 11)+']' );
$elements.slideDown();
$elements.each(function(index, element){
$element = $(element);
var address = $element.find('span.address').html() + ' ' +$element.find('span.address2').html();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', function() {
var $element = $('#dealer-results li:nth-child('+(index +1)+')')
var contentString = '<div class="content">'+
'<h3>'+ $element.find('h3').html()+'</h3>'+
'<span>' + $element.find('span.distance').html() +'</span><br>'+
'<span>' + $element.find('span.address').html() +'</span><br>'+
'<span>' + $element.find('span.address2').html() +'</span><br>'+
'<span>' + $element.find('span.phone').html() + '</span><br>'+
'<span>Link</span>'+
'</div>';
infowindow.setContent(contentString);
infowindow.open(map,marker);
map.setCenter(results[0].geometry.location);
});
}else{
alert("Geocode was not successful for the following reason: " + status);
}
});
});
base += 10;
});
I tried setting it to 5, but I was still getting the error at the 4th element.
I have a leaflet map showing points for public art pieces, rendered from GeoJSON. Next to the map, I created a list of the pieces from the same GeoJSON data and want to be able to click on an item from the list outside of the map and have the related marker's popup come up on the map.
How can I link the list of items to their respective markers through a click event?
My map.js file looks like this:
var map;
var pointsLayer;
$(document).ready(function () {
map = new L.Map('mapContainer');
var url = 'http://{s}.tiles.mapbox.com/v3/mapbox.mapbox-streets/{z}/{x}/{y}.png';
var copyright = 'Map data © 2011 OpenStreetMap contributors, Imagery © 2011 CloudMade';
var tileLayer = new L.TileLayer(url, {
attribution: copyright
});
var startPosition = new L.LatLng(41.883333, - 87.633333);
map.on('load', function (e) {
requestUpdatedPoints(e.target.getBounds())
});
map.setView(startPosition, 13).addLayer(tileLayer);
map.on('moveend', function (e) {
requestUpdatedPoints(e.target.getBounds())
})
});
function requestUpdatedPoints(bounds) {
$.ajax({
type: 'GET',
url: '/SeeAll',
dataType: 'json',
data: JSON.stringify(bounds),
contentType: 'application/json; charset=utf-8',
success: function (result) {
parseNewPoints(result);
addToList(result)
},
error: function (req, status, error) {
alert('what happen? did you lose conn. to server ?')
}
})
}
function addToList(data) {
for (var i = 0; i < data.features.length; i++) {
var art = data.features[i];
$('div#infoContainer').append('<div class="info-list-item">' + '<div class="info-list-txt">' + '<div class="title">' + art.properties.wrknm + '</div>' + '<br />' + art.properties.location + '</div>' + '<div class="info-list-img">' + art.properties.img_src + '</div>' + '<br />' + '</div>')
}
$('a.list-link').click(function (e) {
alert('now you see what happens when you click a list item!');
e.preventDefault()
})
}
function parseNewPoints(data) {
if (pointsLayer != undefined) {
map.removeLayer(pointsLayer)
}
pointsLayer = new L.GeoJSON();
var geojsonMarkerOptions = {
radius: 8,
fillColor: "#FF6788",
color: "YELLOW",
weight: 1,
opacity: 1,
fillOpacity: 0.5
};
L.geoJson(data, {
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng, geojsonMarkerOptions)
},
onEachFeature: function (feature, pointsLayer) {
pointsLayer.bindPopup(feature.properties.img_src + "<br />" + feature.properties.wrknm + "<br />" + feature.properties.artist + "<br />" + feature.properties.location + '<div class="description">' + feature.properties.descfin + '</div>')
}
}).addTo(map)
}
Felix Kling is right but I'll expand on his comment a little bit...
Since L.LayerGroup and L.FeatureGroup (which L.GeoJSON extends from) don't have methods to retrieve individual layers you will need to either extend from L.GeoJSON and add such a method or keep your own seperate mapping from unique ID to CircleMarker from GeoJSON.
GeoJSON does not require a unique ID but I'll assume that markers in your feed have a unique ID attribute called "id". You will need to add this unique ID to the links that the user can click on so that the links can select the right marker on the map. Then you'll need to store a map of ids to markers in order to retrieve the marker to select it on the map.
markerMap = {}; // a global variable unless you extend L.GeoJSON
// Add the marker id as a data item (called "data-artId") to the "a" element
function addToList(data) {
for (var i = 0; i < data.features.length; i++) {
var art = data.features[i];
$('div#infoContainer').append('<div class="info-list-item">' + '<div class="info-list-txt">' + '<div class="title">' + art.properties.wrknm + '</div>' + '<br />' + art.properties.location + '</div>' + '<div class="info-list-img">' + art.properties.img_src + '</div>' + '<br />' + '</div>')
}
$('a.list-link').click(function (e) {
alert('now you see what happens when you click a list item!');
//Get the id of the element clicked
var artId = $(this).data( 'artId' );
var marker = markerMap[artId];
//since you're using CircleMarkers the OpenPopup method requires
//a latlng so I'll just use the center of the circle
marker.openPopup(marker.getLatLng());
e.preventDefault()
})
}
You need to build the markerMap when you get the data from the server. Your pointToLayer method could be modified to do that:
L.geoJson(data, {
pointToLayer: function (feature, latlng) {
var marker = new L.CircleMarker( latlng, geojsonMarkerOptions );
markerMap[feature.id] = marker;
return marker;
},...
I know this is an older question but Leaflet is on it's way to providing a built-in solution and there is a (somewhat) built-in way to achieve it now...
The approach would be use the layerGroup interface. It provides a method, getLayer, that sounds like it would be perfect get our markers using an ID. However, at this time, Leaflet does not provide any way to specify a custom ID or name.
This issue on Github discusses how this should be done. With that said, you can get and save the auto-generated ID of any Marker (or iLayer for that matter) like so:
let people = [...],
group = L.layerGroup()
people.forEach(person => {
let marker = // ... create marker
group.addLayer( marker );
person.marker_id = group.getLayerId(marker)
})
Now that we have every marker's ID saved with each backing object in our array of data we can easily get the marker later on like so:
group.getLayer(person.marker_id)
See this pen for a full example and this question for more options...
In my code, how can I get the name of the User that someone clicked on in the marker?
Currently my code has:
function createMarker(point, user, studytopic) {
var marker = new GMarker(point);
var currUser = user;
var html = '<b>' + user + '</b> <br/>' + studytopic + '<br/>' +
' Contact ' + user + '' ;
GEvent.addListener(marker, 'click', function() {
marker.openInfoWindowHtml(html);
});
return marker;
}
currUser is a global field, however, it's not updated every time I click on a different marker in Google maps.
Basically what I'm looking for is a event to fire when a link (id=contactSBLink) within any marker is clicked. I want it to get the Username(which is a link) to pass the user variable to another function.
I'm not sure what's the best way to go about to get this?
You can pass the user u to the javascript:showContactSB(u). This is an exercise in setting quotes properly:
var u = "'" + user + "'";
var html = '<b>' + user + '</b> <br/>' + studytopic + '<br/>' +
' Contact ' + user + '' ;
Now, you get the user in the click-function:
function showContactSB(user) {
alert("Hi " + user);
}
BTW, I would recommend you to upgrade to Google Maps v3.
I'm building a webpage based around the Google maps API, per client request. I'm pulling data from a database into xml that is then linked to markers on the map (part of the data for each record is latitude and longitude, which sets the marker). When the user clicks on the marker, they see content relating to that place in a page div (the content is a title, photo, audio file, and transcript of the audio file).
Everything is working except... I can't figure out how to display the transcript, which is a text file. The xml node contains the full pathname, and the folder with the actual file is stored on the server. I know how to do this with php, but can't rename my file with a php extension because the Google Maps API won't allow it (the map disappears).
Here is the relevant part of the code:
downloadUrl("xmlTest.php", function(data)
{
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("Sound_xcrpt");
for (var i = 0; i < markers.length; i++)
{
var title = markers[i].getAttribute("se_title");
var desc = markers[i].getAttribute("se_desc");
var type = markers[i].getAttribute("se_contrib");
var ph_title = markers[i].getAttribute("ph_title");
var ph_web = markers[i].getAttribute("ph_web");
var ph_thumb = markers[i].getAttribute("ph_thumb");
var trans_ex = markers[i].getAttribute("trans_xcrpt");
var audio = markers[i].getAttribute("se_audio_file");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("se_lat")),
parseFloat(markers[i].getAttribute("se_lng")));
var html =
'<head>' +
'<link rel="stylesheet" href="infoStyle.css" type="text/css">' +
'</head>' +
'<html>' +
'<body>' +
'<header id="title">' + title + '</header>' +
'</section id="desc">' + desc +
'</section>' +
'<section id="photo_thumb">' +
'<img src="'+ph_thumb+'"/>' +
'</section>' +
'</body>' +
'</html>';
var winHtml =
'<head>' +
'<link rel="stylesheet" href="styleWin2.css">' +
'</head>' +
'<body>' +
'<header id="title2">' + ph_title + '</header>' +
'<div class="photos">' +
'<img src="'+ph_web+'"/>' +
'</div>' +
'<div class="trans">' +trans_ex+
'</div>' +
'<footer id="audio">' +
'<audio autoplay="autoplay" controls="controls">' +
'<source src="'+audio+'">' +
'</audio>' +
'</footer>' +
'</body>';
var icon = customIcons[type] || {};
var marker = new google.maps.Marker(
{
map: map,
position: point,
icon: icon.icon,
animation: google.maps.Animation.DROP,
shadow: icon.shadow
});
bindInfoWindow(marker, map, infoWindow, html);
contentBox(marker, map, content, winHtml, infoWindow);
}
});
}
"trans_ex" holds the path name array. The way the code is set up above, it displays the actual path name in the div, not the content of the text file to which that path name points.
Is there a javascript (or jquery) method to do this? I know it's tricky because I've got a server-side request in here.
Thanks for your help, Cheryl
What you need is to call AJAX to get the transcript from the server and append it to the DIV once the marker is clicked. XMLHttpRequest object in your second comment is the foundation of AJAX and jquery has a very nice abstraction to do that via jQuery.ajax() (http://api.jquery.com/jQuery.ajax/).
It basically hides the complexities in your second comments and let you deal with what you want to do once the response comes in. In your case, you would want the DIV for the transcript to be populated with the response from the transcript.
In fact, jQuery made further abstraction by providing load() function (http://api.jquery.com/load/). You need to call this function upon click event for the marker and providing it with the right path for the transcript
Are you wanting to display the contents of the text file? The guy at the following URL needed to read the contents of a text file as well. Maybe this will help?
jquery - Read a text file?