A step-by-step guide to build a store locator map https://www.mapbox.com/foundations/building-a-store-locator/
A Pen by weedkiller on CodePen.
A step-by-step guide to build a store locator map https://www.mapbox.com/foundations/building-a-store-locator/
A Pen by weedkiller on CodePen.
<div class='sidebar'> | |
<div class='heading'> | |
<h1>Our locations</h1> | |
</div> | |
<div id='listings' class='listings'></div> | |
</div> | |
<div id='map' class='map'> </div> |
// update your access token here | |
// L.mapbox.accessToken = ''; | |
var map = L.mapbox.map('map', 'mapbox.light') // update with your own map id | |
.setView([38.909671288923, -77.034084142948], 16); | |
var listings = document.getElementById('listings'); | |
var locations = L.mapbox.featureLayer().addTo(map); | |
locations.loadURL('https://s3-us-west-2.amazonaws.com/s.cdpn.io/6362/sweetgreen.geojson'); // load in your own GeoJSON file here | |
function setActive(el) { | |
var siblings = listings.getElementsByTagName('div'); | |
for (var i = 0; i < siblings.length; i++) { | |
siblings[i].className = siblings[i].className | |
.replace(/active/, '').replace(/\s\s*$/, ''); | |
} | |
el.className += ' active'; | |
} | |
locations.on('ready', function() { | |
locations.eachLayer(function(locale) { | |
// Shorten locale.feature.properties to just `prop` so we're not | |
// writing this long form over and over again. | |
var prop = locale.feature.properties; | |
// Each marker on the map. | |
var popup = '<h3>Sweetgreen</h3><div>' + prop.address; | |
var listing = listings.appendChild(document.createElement('div')); | |
listing.className = 'item'; | |
var link = listing.appendChild(document.createElement('a')); | |
link.href = '#'; | |
link.className = 'title'; | |
link.innerHTML = prop.address; | |
if (prop.crossStreet) { | |
link.innerHTML += '<br /><small class="quiet">' + prop.crossStreet + '</small>'; | |
popup += '<br /><small class="quiet">' + prop.crossStreet + '</small>'; | |
} | |
var details = listing.appendChild(document.createElement('div')); | |
details.innerHTML = prop.city; | |
if (prop.phone) { | |
details.innerHTML += ' · ' + prop.phoneFormatted; | |
} | |
link.onclick = function() { | |
setActive(listing); | |
// When a menu item is clicked, animate the map to center | |
// its associated locale and open its popup. | |
map.setView(locale.getLatLng(), 16); | |
locale.openPopup(); | |
return false; | |
}; | |
// Marker interaction | |
locale.on('click', function(e) { | |
// 1. center the map on the selected marker. | |
map.panTo(locale.getLatLng()); | |
// 2. Set active the markers associated listing. | |
setActive(listing); | |
}); | |
popup += '</div>'; | |
locale.bindPopup(popup); | |
}); | |
}); | |
locations.on('layeradd', function(e) { | |
var marker = e.layer; | |
marker.setIcon(L.icon({ | |
iconUrl: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/6362/marker.png', // load your own custom marker image here | |
iconSize: [56, 56], | |
iconAnchor: [28, 28], | |
popupAnchor: [0, -34] | |
})); | |
}); |
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> | |
<script src="https://codepen.io/katydecorah/pen/96184ace01899efac9362ef3b705a969"></script> |
* { box-sizing: border-box; } | |
body { | |
color: #404040; | |
font: 400 15px/22px 'Source Sans Pro', 'Helvetica Neue', Sans-serif; | |
font-smoothing: antialiased; | |
} | |
h1 { | |
font-size: 22px; | |
margin: 0; | |
font-weight: 400; | |
} | |
a { | |
color: #404040; | |
text-decoration: none; | |
} | |
a:hover { color: #101010; } | |
.sidebar { | |
position: absolute; | |
width: 33.3333%; | |
height: 100%; | |
top: 0; left: 0; | |
overflow: hidden; | |
border-right: 1px solid rgba(0,0,0,0.25); | |
} | |
.pad2 { padding: 20px; } | |
.quiet { color:#888; } | |
.map { | |
position: absolute; | |
left: 33.3333%; | |
width: 66.6666%; | |
top: 0; bottom: 0; | |
} | |
.heading { | |
background: #fff; | |
border-bottom: 1px solid #eee; | |
height: 60px; | |
line-height: 60px; | |
padding: 0 10px; | |
} | |
.listings { | |
height: 100%; | |
overflow: auto; | |
padding-bottom: 60px; | |
} | |
.listings .item { | |
display: block; | |
border-bottom: 1px solid #eee; | |
padding: 10px; | |
text-decoration: none; | |
} | |
.listings .item:last-child { border-bottom: none; } | |
.listings .item .title { | |
display: block; | |
color: #00853e; | |
font-weight: 700; | |
} | |
.listings .item .title small { font-weight: 400; } | |
.listings .item.active .title, | |
.listings .item .title:hover { color: #8cc63f; } | |
.listings .item.active { background-color: #f8f8f8; } | |
::-webkit-scrollbar { | |
width: 3px; | |
height: 3px; | |
border-left: 0; | |
background: rgba(0,0,0,0.1); | |
} | |
::-webkit-scrollbar-track { | |
background: none; | |
} | |
::-webkit-scrollbar-thumb { | |
background: #00853e; | |
border-radius: 0; | |
} | |
.clearfix { display: block; } | |
.clearfix:after { | |
content: '.'; | |
display: block; | |
height: 0; | |
clear: both; | |
visibility: hidden; | |
} | |
/* Marker tweaks */ | |
.leaflet-popup-close-button { | |
display: none; | |
} | |
.leaflet-popup-content { | |
font: 400 15px/22px 'Source Sans Pro', 'Helvetica Neue', Sans-serif; | |
padding: 0; | |
width: 200px; | |
} | |
.leaflet-popup-content-wrapper { | |
padding: 0; | |
} | |
.leaflet-popup-content h3 { | |
background: #91c949; | |
color: #fff; | |
margin: 0; | |
display: block; | |
padding: 10px; | |
border-radius: 3px 3px 0 0; | |
font-weight: 700; | |
margin-top: -15px; | |
} | |
.leaflet-popup-content div { | |
padding: 10px; | |
} | |
.leaflet-container .leaflet-marker-icon { cursor: pointer; } |