Skip to content

Commit abb08fe

Browse files
committed
A searchable timeline
1 parent eb7d932 commit abb08fe

2 files changed

Lines changed: 80 additions & 0 deletions

File tree

docs/search/index.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Search TorontoJS Events</title>
7+
<style>
8+
.date {
9+
font-family: monospace;
10+
}
11+
.event_details {
12+
background-color: rgb(247, 253, 255);
13+
margin: 2em;
14+
padding: 1em;
15+
}
16+
</style>
17+
</head>
18+
<body>
19+
<div><p>Search: <input id="search" /></p></div>
20+
<div><ul id="timeline"></ul></div>
21+
<script src="main.js"></script>
22+
</body>
23+
</html>

docs/search/main.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
const el = document.getElementById.bind(document)
2+
const events = []
3+
const renderAll = throttle(renderEvents)
4+
5+
function throttle(fun, wait = 100) { // throttle but call it again at the end
6+
let throttled
7+
return function(...args) {
8+
if(throttled) return false
9+
throttled = true
10+
setTimeout(() => { throttled = false; fun(...args) }, wait)
11+
fun(...args)
12+
}
13+
}
14+
15+
function renderEvents() {
16+
let search = el('search').value.toLowerCase()
17+
let str = ''
18+
events.filter(e => (e.title+e.details).toLowerCase().includes(search)).forEach(event => {
19+
str += eventTemplate(event)
20+
})
21+
el('timeline').innerHTML = str
22+
}
23+
24+
function eventTemplate(event) {
25+
return `
26+
<details>
27+
<summary><span class="date">${new Date(event.startDate).toLocaleString('en-CA', {year: 'numeric', month: 'short', day: '2-digit'})}</span> :: ${event.title}</summary>
28+
<p class="tags">Tags: ${event.tags.join(', ')}</p>
29+
<p class="hosts">Hosts: ${event.hosts.join(', ')}</p>
30+
<p class="image">${event.image ? `<img src="${event.image}">` : ''}</p>
31+
<div class="event_details">${event.details.replace(/\n/g, '<br>')}</div>
32+
</details>`
33+
}
34+
35+
function fetchAll(data) {
36+
data.forEach(eventStub => {
37+
const srcPath = `events/${eventStub.file}`
38+
fetchJSON(srcPath, event => {
39+
event.time = (new Date(event.startDate)).getTime()
40+
events.push(event)
41+
events.sort((a, b) => b.time - a.time) // wasteful
42+
renderAll()
43+
})
44+
})
45+
}
46+
47+
function fetchJSON(srcPath, callback) {
48+
const prefix = 'https://raw.githubusercontent.com/torontojs/historical-archive/main/src/data/'
49+
fetch(prefix + srcPath)
50+
.then(resp => resp.json())
51+
.then(data => callback(data))
52+
.catch(err => console.error('Fetch went awry', err, srcPath, callback))
53+
}
54+
55+
// init
56+
fetchJSON('directory.json', fetchAll)
57+
el('search').addEventListener('input', renderAll)

0 commit comments

Comments
 (0)