update cached information and add a little paragraph about the boroughs
This commit is contained in:
parent
2cd3020151
commit
5b2f60992c
406
index.html
406
index.html
@ -1,29 +1,61 @@
|
||||
<html><head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>Independent Bookstores in New York City - Best Community Bookstores in NYC</title>
|
||||
<meta name="google-site-verification" content="hEfog9h0E3JQW91ZUZM5ayPb6DND0WbUa2_W8yTIuVw">
|
||||
<link rel="icon" type="image/png" href="/img/favicon.png">
|
||||
<link rel="apple-touch-icon" href="/img/social.jpg">
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge" />
|
||||
<title>
|
||||
Independent Bookstores in New York City - Best Community Bookstores in NYC
|
||||
</title>
|
||||
<meta
|
||||
name="google-site-verification"
|
||||
content="hEfog9h0E3JQW91ZUZM5ayPb6DND0WbUa2_W8yTIuVw"
|
||||
/>
|
||||
<link rel="icon" type="image/png" href="/img/favicon.png" />
|
||||
<link rel="apple-touch-icon" href="/img/social.jpg" />
|
||||
<script type="text/javascript" src="js/jquery.js"></script>
|
||||
<script type="text/javascript" src="js/mustache.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-scrollTo/2.1.0/jquery.scrollTo.min.js"></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<script src="https://api.mapbox.com/mapbox-gl-js/v0.34.0/mapbox-gl.js"></script>
|
||||
<link href="https://api.mapbox.com/mapbox-gl-js/v0.34.0/mapbox-gl.css" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css?family=Acme|Lato" rel="stylesheet">
|
||||
<link media="screen" rel="stylesheet" type="text/css" href="css/site.css">
|
||||
<meta property="title" name="title" content="Independent Bookstores in New York City - Best Community Bookstores in NYC">
|
||||
<meta property="description" name="description" content="A guide to and map of every independent bookstore in New York City. We have a full list of community bookstores in NYC with locations and descriptions.">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:site" content="www.nycbookstores.org">
|
||||
<meta name="twitter:title" content="NYC Bookstores">
|
||||
<meta name="twitter:description" content="A Guide To The Many Independent Bookstores Of New York City">
|
||||
<meta name="twitter:image" content="https://www.nycbookstores.org/img/social.jpg">
|
||||
<meta property="og:url" content="https://www.nycbookstores.org/">
|
||||
<meta property="og:title" content="NYC Bookstores">
|
||||
<meta property="og:description" content="A Guide To The Many Independent Bookstores Of New York City">
|
||||
<meta property="og:image" content="https://www.nycbookstores.org/img/social.jpg">
|
||||
<link
|
||||
href="https://api.mapbox.com/mapbox-gl-js/v0.34.0/mapbox-gl.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Acme|Lato"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link media="screen" rel="stylesheet" type="text/css" href="css/site.css" />
|
||||
<meta
|
||||
property="title"
|
||||
name="title"
|
||||
content="Independent Bookstores in New York City - Best Community Bookstores in NYC"
|
||||
/>
|
||||
<meta
|
||||
property="description"
|
||||
name="description"
|
||||
content="A guide to and map of every independent bookstore in New York City. We have a complete list of community bookstores in NYC with locations and descriptions."
|
||||
/>
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="www.nycbookstores.org" />
|
||||
<meta name="twitter:title" content="NYC Bookstores" />
|
||||
<meta
|
||||
name="twitter:description"
|
||||
content="A Guide To The Many Independent Bookstores Of New York City"
|
||||
/>
|
||||
<meta
|
||||
name="twitter:image"
|
||||
content="https://www.nycbookstores.org/img/social.jpg"
|
||||
/>
|
||||
<meta property="og:url" content="https://www.nycbookstores.org/" />
|
||||
<meta property="og:title" content="NYC Bookstores" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="A Guide To The Many Independent Bookstores Of New York City"
|
||||
/>
|
||||
<meta
|
||||
property="og:image"
|
||||
content="https://www.nycbookstores.org/img/social.jpg"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
@ -32,16 +64,70 @@
|
||||
<ul class="nav">
|
||||
<li><h2>The Many Independent Bookstores of New York City</h2></li>
|
||||
<li><a id="viewInfo">info</a></li>
|
||||
<li><a href="https://git.yetaga.in/alazyreader/nyc-bookstores/" target="_blank">git</a></li>
|
||||
<li><a href="https://www.twitter.com/alazyreader" target="_blank">@alazyreader</a></li>
|
||||
<li>
|
||||
<a
|
||||
href="https://git.yetaga.in/alazyreader/nyc-bookstores/"
|
||||
target="_blank"
|
||||
>git</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.twitter.com/alazyreader" target="_blank"
|
||||
>@alazyreader</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div id="map"></div>
|
||||
<div id="info">
|
||||
<p>New York City loves its independent bookstores. It <a href="https://www.nytimes.com/2006/10/15/nyregion/thecity/15book.html" target="_blank">eulogizes those that have faded</a> and celebrates when new ventures are launched. And while the historic <a href="https://untappedcities.com/2015/08/26/4th-avenue-the-history-of-nycs-book-row/" target="_blank">Book Row may have passed away in the 80s</a>, there are still many indie bookstores dotting the map. Here, I have attempted to collect all of the currently-open general-interest independent booksellers in NYC. Any store with regular-ish hours (excluding religious booksellers and appointment-only rare book sellers) is included.</p>
|
||||
<p>The listings here are kept up-to-date to the best of my ability; however, I make no promises about either the accuracy or reliability of the information. If you spot an error, or I've missed a shop, please let me know by <a href="mailto:delta.mu.alpha@gmail.com" target="_blank">email</a> or <a href="https://www.twitter.com/alazyreader" target="_blank">twitter</a>. Based on the "<a href="https://github.com/jlord/hack-spots" target="_blank">Hack Spots</a>" website by <a href="https://www.twitter.com/jllord" target="_blank">@jllord</a>.</p>
|
||||
<p>There are currently <span id="storeCount"></span> stores indexed on this page.</p>
|
||||
<p>
|
||||
New York City loves its independent bookstores. It
|
||||
<a
|
||||
href="https://www.nytimes.com/2006/10/15/nyregion/thecity/15book.html"
|
||||
target="_blank"
|
||||
>eulogizes those that have faded</a
|
||||
>
|
||||
and celebrates when new ventures are launched. And while the
|
||||
historic
|
||||
<a
|
||||
href="https://untappedcities.com/2015/08/26/4th-avenue-the-history-of-nycs-book-row/"
|
||||
target="_blank"
|
||||
>Book Row may have passed away in the 80s</a
|
||||
>, there are still many indie bookstores dotting the map, across all
|
||||
five boroughs. Here, I have attempted to collect all of the
|
||||
currently-open general-interest independent booksellers in NYC. Any
|
||||
store with regular-ish hours (excluding religious booksellers and
|
||||
appointment-only rare book sellers) is included.
|
||||
</p>
|
||||
<p>
|
||||
While Manhattan and Brooklyn still lead the pack, Queens has a
|
||||
respectable number of stores, and all five boroughs are represented,
|
||||
with the Bronx and Staten Island both hosting independent stores.
|
||||
Lower Manhattan has the highest density of booksellers, however.
|
||||
</p>
|
||||
<p>
|
||||
The listings here are kept up-to-date to the best of my ability;
|
||||
however, I make no promises about either the accuracy or reliability
|
||||
of the information. If you spot an error, or I've missed a
|
||||
shop, please let me know by
|
||||
<a href="mailto:delta.mu.alpha@gmail.com" target="_blank">email</a>
|
||||
or
|
||||
<a href="https://www.twitter.com/alazyreader" target="_blank"
|
||||
>twitter</a
|
||||
>. Orignally based on the "<a
|
||||
href="https://github.com/jlord/hack-spots"
|
||||
target="_blank"
|
||||
>Hack Spots</a
|
||||
>" website by
|
||||
<a href="https://www.twitter.com/jllord" target="_blank">@jllord</a>
|
||||
(although I don't believe any of the actual underlying code
|
||||
still survives at this point).
|
||||
</p>
|
||||
<p>
|
||||
There are currently <span id="storeCount">97</span> stores indexed
|
||||
on this page.
|
||||
</p>
|
||||
</div>
|
||||
<div id="selected"></div>
|
||||
</div>
|
||||
@ -51,7 +137,11 @@
|
||||
<div class="container">
|
||||
<div id="Stores">
|
||||
<table>
|
||||
<tbody><tr><th class="tHeader">Name</th><th class="tHeader">Address</th></tr>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="tHeader">Name</th>
|
||||
<th class="tHeader">Address</th>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">192 Books</td>
|
||||
<td>192 10th Ave, New York</td>
|
||||
@ -84,14 +174,6 @@
|
||||
<td class="name">Avoid The Day Bookstore & Cafe</td>
|
||||
<td>99-04 A Rockaway Beach Blvd, Rockaway Park</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Bankstreet Bookstore</td>
|
||||
<td>2780 Broadway, New York</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Ben's Books</td>
|
||||
<td>145 Ainslie St, Brooklyn</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Berl's Brooklyn Poetry Shop</td>
|
||||
<td>126A Front St, Brooklyn</td>
|
||||
@ -108,6 +190,10 @@
|
||||
<td class="name">Bonnie Slotnick Cookbooks</td>
|
||||
<td>28 East 2nd St, New York</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Book Club Bar</td>
|
||||
<td>197 E 3rd St, New York</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Book Culture</td>
|
||||
<td>536 W 112th St, New York</td>
|
||||
@ -142,7 +228,7 @@
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Books Of Wonder</td>
|
||||
<td>18 West 18th St, New York</td>
|
||||
<td>42 West 17th St, New York</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Books Of Wonder (Upper West Side)</td>
|
||||
@ -180,6 +266,10 @@
|
||||
<td class="name">Community Bookstore</td>
|
||||
<td>143 7th Ave, Brooklyn</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Cups and Books</td>
|
||||
<td>2024 Bedford Ave, Brooklyn</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Dashwood Books</td>
|
||||
<td>33 Bond St, New York</td>
|
||||
@ -193,7 +283,9 @@
|
||||
<td>99 St. Mark's Place, New York</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Every Thing Goes Book Cafe and Neighborhood Stage</td>
|
||||
<td class="name">
|
||||
Every Thing Goes Book Cafe and Neighborhood Stage
|
||||
</td>
|
||||
<td>208 Bay St, Staten Island</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
@ -205,7 +297,9 @@
|
||||
<td>686 Fulton St, Brooklyn</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Greenlight Bookstore (Prospect Lefferts Gardens)</td>
|
||||
<td class="name">
|
||||
Greenlight Bookstore (Prospect Lefferts Gardens)
|
||||
</td>
|
||||
<td>632 Flatbush Ave, Brooklyn</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
@ -297,8 +391,8 @@
|
||||
<td>2 W 14th St, New York</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Pioneer Books</td>
|
||||
<td>159 Pioneer St, Brooklyn</td>
|
||||
<td class="name">Pillow-Cat Books</td>
|
||||
<td>328 East 9th St, New York</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Posman Books Chelsea Market</td>
|
||||
@ -345,7 +439,9 @@
|
||||
<td>939 Lexington Ave, New York</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Shakespeare & Company (Upper West Side)</td>
|
||||
<td class="name">
|
||||
Shakespeare & Company (Upper West Side)
|
||||
</td>
|
||||
<td>2020 Broadway, New York</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
@ -364,6 +460,10 @@
|
||||
<td class="name">Strand Bookstore</td>
|
||||
<td>828 Broadway, New York</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Sweet Pickle Books</td>
|
||||
<td>47 Orchard St, New York</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Terrace Books</td>
|
||||
<td>242 Prospect Park West, Brooklyn</td>
|
||||
@ -394,7 +494,7 @@
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Three Lives & Company</td>
|
||||
<td>154 West 10th St, New York</td>
|
||||
<td>238 West 10th St, New York</td>
|
||||
</tr>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Topos Bookstore Cafe</td>
|
||||
@ -432,14 +532,23 @@
|
||||
<td class="name">Word Up Books</td>
|
||||
<td>2113 Amsterdam Ave, New York</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<tr id class="spotRow">
|
||||
<td class="name">Yu and Me Books</td>
|
||||
<td>44 Mulberry St, New York</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- end wrapper -->
|
||||
</div>
|
||||
<!-- end wrapper -->
|
||||
|
||||
<script id="Table" type="text/html">
|
||||
<table>
|
||||
<tr><th class="tHeader">Name</th><th class="tHeader">Address</th></tr>
|
||||
<tr>
|
||||
<th class="tHeader">Name</th>
|
||||
<th class="tHeader">Address</th>
|
||||
</tr>
|
||||
{{#rows}}
|
||||
<tr id="{{rowNumber}}" class="spotRow">
|
||||
<td class="name">{{name}}</td>
|
||||
@ -452,65 +561,75 @@
|
||||
<script id="selectedStore" type="text/html">
|
||||
{{#store}}
|
||||
<h2>{{name}}</h2>
|
||||
<p class="address">{{address}}<p>
|
||||
<p class="address">{{city}},NY {{#postcode}} {{postcode}} {{/postcode}}</p>
|
||||
<p class="address">{{address}}</p>
|
||||
<p></p>
|
||||
<p class="address">
|
||||
{{city}},NY {{#postcode}} {{postcode}} {{/postcode}}
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://maps.google.com/maps?q={{name}} {{address}},{{city}},NY" target="_blank">View in Google Maps</a>
|
||||
<a
|
||||
href="https://maps.google.com/maps?q={{name}} {{address}},{{city}},NY"
|
||||
target="_blank"
|
||||
>View in Google Maps</a
|
||||
>
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<span class="store-details">Events:</span> {{events}}
|
||||
<span class="store-details">Events:</span>
|
||||
{{events}}
|
||||
<span class="store-details">Café:</span> {{cafe}}
|
||||
</li>
|
||||
{{#website}}
|
||||
<li><a href='{{website}}' target="_blank">{{website}}</a></li>
|
||||
<li><a href="{{website}}" target="_blank">{{website}}</a></li>
|
||||
{{/website}}
|
||||
</ul>
|
||||
{{#description}}
|
||||
<p class="description">{{description}}</p>
|
||||
{{/description}}
|
||||
{{/store}}
|
||||
{{/description}} {{/store}}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
mapboxgl.accessToken = 'pk.eyJ1IjoiYWxhenlyZWFkZXIiLCJhIjoiY2lucDZhb2JxMHp6MHRxa2pvaTFoOWpuZyJ9.DILGYYxxt7A-A_lHHwp6tQ';
|
||||
mapboxgl.accessToken =
|
||||
"pk.eyJ1IjoiYWxhenlyZWFkZXIiLCJhIjoiY2lucDZhb2JxMHp6MHRxa2pvaTFoOWpuZyJ9.DILGYYxxt7A-A_lHHwp6tQ";
|
||||
var map = new mapboxgl.Map({
|
||||
container: 'map',
|
||||
style: 'mapbox://styles/mapbox/basic-v9',
|
||||
container: "map",
|
||||
style: "mapbox://styles/mapbox/basic-v9",
|
||||
center: [-73.957292, 40.729071], // arbitrary center point
|
||||
zoom: 10,
|
||||
minZoom: 9,
|
||||
maxZoom: 17,
|
||||
dragRotate: false
|
||||
dragRotate: false,
|
||||
});
|
||||
|
||||
var popup = new mapboxgl.Popup({
|
||||
closeOnClick: false,
|
||||
closeButton: false
|
||||
closeButton: false,
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
$.getJSON('./stores.json', function(data) {
|
||||
data.sort(
|
||||
function(a, b) {
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
$.getJSON("./stores.json", function (data) {
|
||||
data.sort(function (a, b) {
|
||||
var aname = a.name.toLowerCase();
|
||||
var bname = b.name.toLowerCase();
|
||||
return aname === bname ? 0 : +(aname > bname) || -1;
|
||||
}
|
||||
)
|
||||
});
|
||||
$.each(data, function (key, value) {
|
||||
value.rowNumber = key;
|
||||
value.slug = slugify(value.name);
|
||||
});
|
||||
$('#storeCount').html(data.length);
|
||||
$("#storeCount").html(data.length);
|
||||
window.data = data;
|
||||
loadMap(data);
|
||||
});
|
||||
});
|
||||
|
||||
window.addEventListener("hashchange", function(e){
|
||||
updateViewBySlug(e.newURL.split('#')[1]);
|
||||
}, false);
|
||||
window.addEventListener(
|
||||
"hashchange",
|
||||
function (e) {
|
||||
updateViewBySlug(e.newURL.split("#")[1]);
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
function updateHash(slug) {
|
||||
history.pushState(null, null, "#" + slug);
|
||||
@ -519,13 +638,13 @@
|
||||
function slugify(str) {
|
||||
return str
|
||||
.toLowerCase()
|
||||
.replace(/é/g,'e')
|
||||
.replace(/&/g,' and ')
|
||||
.replace(/ /g,'-')
|
||||
.replace(/[']+/g,'')
|
||||
.replace(/[^\w-]+/g,'-')
|
||||
.replace(/-+/g,'-')
|
||||
.replace(/^-|-$/g,'');
|
||||
.replace(/é/g, "e")
|
||||
.replace(/&/g, " and ")
|
||||
.replace(/ /g, "-")
|
||||
.replace(/[']+/g, "")
|
||||
.replace(/[^\w-]+/g, "-")
|
||||
.replace(/-+/g, "-")
|
||||
.replace(/^-|-$/g, "");
|
||||
}
|
||||
|
||||
function getStoreBySlug(slug) {
|
||||
@ -552,32 +671,33 @@
|
||||
|
||||
function boundingBox(point) {
|
||||
// add some buffer to a point to give the user some leeway
|
||||
return [[point.x - 5, point.y - 5], [point.x + 5, point.y + 5]]
|
||||
return [
|
||||
[point.x - 5, point.y - 5],
|
||||
[point.x + 5, point.y + 5],
|
||||
];
|
||||
}
|
||||
|
||||
function updateSelectedStore(store, pushState = false) {
|
||||
map.flyTo({ center: [store.long, store.lat] });
|
||||
|
||||
popup.setLngLat([store.long, store.lat])
|
||||
.setHTML(store.name)
|
||||
.addTo(map);
|
||||
popup.setLngLat([store.long, store.lat]).setHTML(store.name).addTo(map);
|
||||
|
||||
$('#info').hide();
|
||||
var template = $('#selectedStore').html();
|
||||
$("#info").hide();
|
||||
var template = $("#selectedStore").html();
|
||||
var rendered = Mustache.render(template, { store: store });
|
||||
$('#selected').html(rendered);
|
||||
$('#selected').show();
|
||||
$("#selected").html(rendered);
|
||||
$("#selected").show();
|
||||
if (pushState) {
|
||||
updateHash(store.slug);
|
||||
}
|
||||
}
|
||||
|
||||
function showInfo(pushState = true) {
|
||||
$('#selected').hide();
|
||||
$("#selected").hide();
|
||||
popup.remove();
|
||||
$('#info').show();
|
||||
$("#info").show();
|
||||
if (pushState) {
|
||||
updateHash('info');
|
||||
updateHash("info");
|
||||
}
|
||||
}
|
||||
|
||||
@ -587,43 +707,47 @@
|
||||
var points = [];
|
||||
$.each(data, function (key, value) {
|
||||
points.push({
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [value.long, value.lat]
|
||||
type: "Feature",
|
||||
geometry: {
|
||||
type: "Point",
|
||||
coordinates: [value.long, value.lat],
|
||||
},
|
||||
"properties": value
|
||||
properties: value,
|
||||
});
|
||||
});
|
||||
map.on('load', function () {
|
||||
map.on("load", function () {
|
||||
map.addLayer({
|
||||
"id": "stores",
|
||||
"type": "circle",
|
||||
"source": {
|
||||
"type": "geojson",
|
||||
"data": {
|
||||
"type": "FeatureCollection",
|
||||
"features": points
|
||||
}
|
||||
id: "stores",
|
||||
type: "circle",
|
||||
source: {
|
||||
type: "geojson",
|
||||
data: {
|
||||
type: "FeatureCollection",
|
||||
features: points,
|
||||
},
|
||||
"paint": {
|
||||
},
|
||||
paint: {
|
||||
"circle-radius": 5,
|
||||
"circle-color": "#B9FCFC",
|
||||
"circle-stroke-width": 2,
|
||||
"circle-stroke-color": "#000000"
|
||||
}
|
||||
})
|
||||
map.addControl(new mapboxgl.NavigationControl(), 'top-left');
|
||||
map.addControl(geolocate, 'top-right');
|
||||
"circle-stroke-color": "#000000",
|
||||
},
|
||||
});
|
||||
map.addControl(new mapboxgl.NavigationControl(), "top-left");
|
||||
map.addControl(geolocate, "top-right");
|
||||
updateViewBySlug(window.location.hash.split("#")[1]);
|
||||
});
|
||||
|
||||
map.on('click', function (e) {
|
||||
if (!map.getLayer('stores')) { return; }
|
||||
map.on("click", function (e) {
|
||||
if (!map.getLayer("stores")) {
|
||||
return;
|
||||
}
|
||||
|
||||
popup.remove();
|
||||
// Use queryRenderedFeatures to get features at a click event's point
|
||||
var features = map.queryRenderedFeatures(boundingBox(e.point), { layers: ['stores'] });
|
||||
var features = map.queryRenderedFeatures(boundingBox(e.point), {
|
||||
layers: ["stores"],
|
||||
});
|
||||
// fly to the location of the click event
|
||||
if (features.length) {
|
||||
var store = features[0];
|
||||
@ -633,40 +757,60 @@
|
||||
});
|
||||
|
||||
// indicate that the symbols are clickable by changing the cursor style to 'pointer'.
|
||||
map.on('mousemove', function (e) {
|
||||
if (!map.getLayer('stores')) { return; }
|
||||
var features = map.queryRenderedFeatures(boundingBox(e.point), { layers: ['stores'] });
|
||||
map.getCanvas().style.cursor = features.length ? 'pointer' : '';
|
||||
map.on("mousemove", function (e) {
|
||||
if (!map.getLayer("stores")) {
|
||||
return;
|
||||
}
|
||||
var features = map.queryRenderedFeatures(boundingBox(e.point), {
|
||||
layers: ["stores"],
|
||||
});
|
||||
map.getCanvas().style.cursor = features.length ? "pointer" : "";
|
||||
});
|
||||
|
||||
geolocate.on('geolocate', function (e) {
|
||||
geolocate.on("geolocate", function (e) {
|
||||
map.setZoom(14);
|
||||
popup.setLngLat([e.coords.longitude, e.coords.latitude])
|
||||
.setHTML('Current Location')
|
||||
popup
|
||||
.setLngLat([e.coords.longitude, e.coords.latitude])
|
||||
.setHTML("Current Location")
|
||||
.addTo(map);
|
||||
});
|
||||
|
||||
var template = $('#Table').html();
|
||||
var template = $("#Table").html();
|
||||
var rendered = Mustache.render(template, { rows: data });
|
||||
$('#Stores').html(rendered);
|
||||
$("#Stores tbody tr").not(':first').on("click", function() {
|
||||
$("#Stores").html(rendered);
|
||||
$("#Stores tbody tr")
|
||||
.not(":first")
|
||||
.on("click", function () {
|
||||
updateSelectedStore(data[$(this)[0].id], true);
|
||||
$(window).scrollTo($("#selected"), 250, { offset: { top: -15 } });
|
||||
});
|
||||
|
||||
$('#viewInfo').on("click", showInfo);
|
||||
};
|
||||
|
||||
$("#viewInfo").on("click", showInfo);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
(function (i, s, o, g, r, a, m) {
|
||||
i["GoogleAnalyticsObject"] = r;
|
||||
(i[r] =
|
||||
i[r] ||
|
||||
function () {
|
||||
(i[r].q = i[r].q || []).push(arguments);
|
||||
}),
|
||||
(i[r].l = 1 * new Date());
|
||||
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
|
||||
a.async = 1;
|
||||
a.src = g;
|
||||
m.parentNode.insertBefore(a, m);
|
||||
})(
|
||||
window,
|
||||
document,
|
||||
"script",
|
||||
"https://www.google-analytics.com/analytics.js",
|
||||
"ga"
|
||||
);
|
||||
|
||||
ga('create', 'UA-100418882-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
ga("create", "UA-100418882-1", "auto");
|
||||
ga("send", "pageview");
|
||||
</script>
|
||||
|
||||
|
||||
</body></html>
|
||||
</body>
|
||||
</html>
|
||||
|
27
index.js
27
index.js
@ -1,24 +1,25 @@
|
||||
const cheerio = require('cheerio');
|
||||
const mustache = require('./js/mustache.js');
|
||||
const fs = require('fs');
|
||||
const stores = require('./stores.json');
|
||||
const cheerio = require("cheerio");
|
||||
const mustache = require("./js/mustache.js");
|
||||
const fs = require("fs");
|
||||
const stores = require("./stores.json");
|
||||
|
||||
fs.readFile('./index.html', function (err, data) {
|
||||
if (err) { throw err; }
|
||||
fs.readFile("./index.html", function (err, data) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
const $ = cheerio.load(data);
|
||||
|
||||
stores.sort(
|
||||
function(a, b) {
|
||||
stores.sort(function (a, b) {
|
||||
var aname = a.name.toLowerCase();
|
||||
var bname = b.name.toLowerCase();
|
||||
return aname === bname ? 0 : +(aname > bname) || -1;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$('#Stores').html(mustache.render($('#Table').html(), {rows: stores}));
|
||||
$("#Stores").html(mustache.render($("#Table").html(), { rows: stores }));
|
||||
$("#storeCount").html(stores.length);
|
||||
|
||||
fs.writeFile('./index.html', $.html(), (err) => {
|
||||
fs.writeFile("./index.html", $.html(), (err) => {
|
||||
if (err) throw err;
|
||||
console.log('Default view updated.');
|
||||
console.log("Default view updated.");
|
||||
});
|
||||
});
|
177
package-lock.json
generated
177
package-lock.json
generated
@ -1,8 +1,183 @@
|
||||
{
|
||||
"name": "nyc-bookstores",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "nyc-bookstores",
|
||||
"version": "1.0.0",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"cheerio": "^1.0.0-rc.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "14.6.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.4.tgz",
|
||||
"integrity": "sha512-Wk7nG1JSaMfMpoMJDKUsWYugliB2Vy55pdjLpmLixeyMi7HizW2I/9QoxsPCkXl3dO+ZOVqPumKaDUv5zJu2uQ=="
|
||||
},
|
||||
"node_modules/boolbase": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
|
||||
},
|
||||
"node_modules/cheerio": {
|
||||
"version": "1.0.0-rc.3",
|
||||
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz",
|
||||
"integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==",
|
||||
"dependencies": {
|
||||
"css-select": "~1.2.0",
|
||||
"dom-serializer": "~0.1.1",
|
||||
"entities": "~1.1.1",
|
||||
"htmlparser2": "^3.9.1",
|
||||
"lodash": "^4.15.0",
|
||||
"parse5": "^3.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/css-select": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
|
||||
"integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
|
||||
"dependencies": {
|
||||
"boolbase": "~1.0.0",
|
||||
"css-what": "2.1",
|
||||
"domutils": "1.5.1",
|
||||
"nth-check": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/css-what": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
|
||||
"integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-serializer": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
|
||||
"integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
|
||||
"dependencies": {
|
||||
"domelementtype": "^1.3.0",
|
||||
"entities": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/domelementtype": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
|
||||
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
|
||||
},
|
||||
"node_modules/domhandler": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
|
||||
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
|
||||
"dependencies": {
|
||||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/domutils": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
|
||||
"integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
|
||||
"dependencies": {
|
||||
"dom-serializer": "0",
|
||||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/entities": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
|
||||
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
|
||||
},
|
||||
"node_modules/htmlparser2": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
|
||||
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
|
||||
"dependencies": {
|
||||
"domelementtype": "^1.3.1",
|
||||
"domhandler": "^2.3.0",
|
||||
"domutils": "^1.5.1",
|
||||
"entities": "^1.1.1",
|
||||
"inherits": "^2.0.1",
|
||||
"readable-stream": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
},
|
||||
"node_modules/nth-check": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
|
||||
"integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
|
||||
"dependencies": {
|
||||
"boolbase": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/parse5": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
|
||||
"integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "14.6.4",
|
||||
|
Loading…
Reference in New Issue
Block a user