Last active
August 24, 2022 16:05
-
-
Save boazsender/9cbb8a600e05574b09c767873f01c755 to your computer and use it in GitHub Desktop.
An example of a webpage rendering information from a google form as both a list and a map. Demo sheet is here: https://docs.google.com/spreadsheets/d/1l6FZYfeMx5nSz3diE60PeFrvJmJtC3_9W5BvhNhd7fA/edit?resourcekey#gid=64148024
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<title> google form backed list and map</title> | |
<meta name="description" content="a google form backed map."> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> | |
<meta name="keywords" content="map"> | |
<!-- included the leaflet CSS --> | |
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"/> | |
<!-- include the various leaflet and esri scripts you--> | |
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script> | |
<script src="https://unpkg.com/[email protected]/dist/esri-leaflet.js"></script> | |
<script src="https://unpkg.com/@esri/[email protected]/dist/bundled/request.umd.js"></script> | |
<script src="https://unpkg.com/@esri/[email protected]/dist/bundled/geocoding.umd.js"></script> | |
<script type='text/javascript'> | |
// Wrapp everything in a DOMContentLoaded callback so we don't start trying | |
// to run code before the document is ready | |
window.addEventListener('DOMContentLoaded', ()=> { | |
// Setup your Esri ReST API Key, and google Sheet ID | |
const config = { | |
esrikey: "your Esri api key", // get one from https://developers.arcgis.com/documentation/mapping-apis-and-services/security/api-keys/ | |
googlesheet: "1l6FZYfeMx5nSz3diE60PeFrvJmJtC3_9W5BvhNhd7fA/Responses" // the scheme is "sheetID/tabName" get this from the URL of your google sheet. You can use this demo to get started. | |
}; | |
// Initialize the map | |
var map = L.map('map').setView([40, -95], 2); | |
// Add the open streetmap tile set. This is the base example from | |
// https://leafletjs.com/examples/mobile/ | |
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { | |
maxZoom: 19, | |
attribution: '© OpenStreetMap' | |
}).addTo(map); | |
// Create an authentication object for the esri ReST API | |
// You'll need to register your own and pass it into the fromKey method | |
const authentication = arcgisRest.ApiKeyManager.fromKey(config.esrikey); | |
// Fetch the google spreadhseet data from the elk.sh json proxy | |
// more info here https://benborgers.com/posts/google-sheets-json | |
// you'll need to pass in your own sheet ID and sheet name | |
// use the full doc ID + / + tab name. Make sure the doc is also | |
// published to the web. Here's a template for you to get started with: | |
// https://docs.google.com/spreadsheets/d/e/2PACX-1vQp2Mq32XQ3Y_WhVYmTR765HkotbVIZi1_Ld-gugxQ8gcmp9k3k-t1xKkIYdDVYYQiC5uoWxdww9gBZ/pubhtml | |
fetch("https://opensheet.elk.sh/" + config.googlesheet).then((res) => res.json()) | |
.then((data) => { | |
// Itererate over the data | |
data.forEach((row) => { | |
// Check to see if there is a "TRUE" string in the "Approved" column | |
if (row['Approved'] === "TRUE") { | |
// Create an off DOM figure element | |
let fig = document.createElement('figure') | |
// Fill that figure elemement with the content of the sheet using a | |
// template. You can adjust as needed. | |
fig.innerHTML = ` | |
<h2>${row['Title']} </h2> | |
<sub>${row['Date']}</sub> | |
<p>${row['Description']} <a href="${row['Call to action link']}"> ${row['Call to action']}</a></p> | |
`; | |
// Select the parent element to add this row of the sheet to and add it. | |
document.querySelectorAll('#list')[0].prepend(fig); | |
// Look up the latitude and longitude of the city and state from | |
// the sheet. You can adjust as needed. | |
arcgisRest.geocode({ | |
params: { | |
address: row['City'] + " " + row['State'], | |
maxLocations: 1 | |
}, | |
outFields: ["PlaceName", "Place_addr", "Phone"], | |
authentication | |
}).then((places) => { | |
// When you get the data back, plot it on a map and add the | |
// figure we made above to the popup. | |
L.marker([places.candidates[0].location.y, places.candidates[0].location.x]).addTo(map) | |
.bindPopup(fig); | |
}); | |
} | |
}); | |
}); | |
// Grab references to the list and map container elements | |
let listEl = document.querySelectorAll("#list")[0]; | |
let mapEl = document.querySelectorAll("#mapcontainer")[0]; | |
// Grab a reference to the element we'll use to switch between | |
// list and map, note that we start with a hidden (display: none) | |
// map container, and a visible (display:block) list. | |
document.querySelectorAll("#uichanger")[0].onpointerdown = (e) => { | |
// use the text in the element we're using to chang UIs as the source | |
// of truth for which UI is currently shown. | |
let state = e.target.innerHTML; | |
// If it's a list, change over to map. | |
if (state === "list") { | |
e.target.innerHTML = 'map'; | |
mapEl.style.display = 'none'; | |
listEl.style.display = 'block'; | |
} | |
// If its a map, change over to list. | |
if( state==="map" ) { | |
e.target.innerHTML = 'list'; | |
listEl.style.display = 'none'; | |
mapEl.style.display = 'block'; | |
map.invalidateSize() | |
} | |
} | |
}); | |
</script> | |
<style> | |
html, body { | |
height: 100%; | |
width: 100vw; | |
padding: 0px; | |
margin: 0px; | |
} | |
#uichanger { | |
text-decoration: underline; | |
color: blue; | |
cursor: pointer; | |
} | |
section, header, footer { | |
width: 400px; | |
margin: 0 auto; | |
padding: 0px; | |
} | |
p, footer, header { | |
line-height: 1.15; | |
font-size: 16px; | |
} | |
p { | |
margin-top: 6px; | |
margin-bottom: 15px; | |
} | |
section .leaflet-popup-content p { | |
font-size: 12px; | |
} | |
header { | |
height: 145px; | |
padding-top: 40px; | |
} | |
footer { | |
padding-top: 30px; | |
height: 20px; | |
font-size: 12px; | |
text-align: center; | |
} | |
footer nav { | |
font-size: 16px; | |
margin-bottom: 15px; | |
} | |
figure { | |
margin: 0px; | |
} | |
section#mapcontainer { | |
padding: 0; | |
} | |
#mapcontainer, #map { | |
width: 100%; | |
} | |
#map { | |
height: 100%; | |
} | |
#mapcontainer, #list { | |
height: 60%; | |
width: 400px; | |
overflow: scroll; | |
} | |
#mapcontainer { | |
display: none; | |
} | |
@media (max-width: 600px) { | |
header, footer { | |
width: 94%; | |
} | |
section#mapcontainer, section#list { | |
width: 72%; | |
padding-left: 14%; | |
padding-right: 14%; | |
font-size: 14px; | |
height: 60%; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<header> | |
<h1>A google form backed list and map</h1> | |
<nav> | |
view this as a <span id="uichanger" role="button">map</span>. | |
</nav> | |
</header> | |
<section id="mapcontainer"> | |
<div id="map"></div> | |
</section> | |
<section id="list"></section> | |
<footer> | |
<nav> | |
<a href="https://forms.gle/FCUpuHP3MesL4GxZ8">submit an point</a> | |
</nav> | |
</footer> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment