-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
182 lines (149 loc) · 6.16 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sault Ste. Marie Ward Finder</title>
<meta name="description" content="A simple tool to find out the ward number for an address in Sault Ste. Marie, Ontario.">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css" integrity="sha256-rTpdO0HXBCNpreAHcu6tB2Ppg515Vo+5GtYSsnNLz+8=" crossorigin="anonymous">
</head>
<body>
<main class="container" style="max-width:500px">
<h1 class="title has-text-centered mt-2">
Sault Ste. Marie Ward Finder
</h1>
<form class="box" id="addressForm">
<input class="input" name="address" id="address" type="search" placeholder="Find an address" aria-label="Address" />
</form>
<p class="has-text-centered has-text-weight-bold" id="resultsCount" aria-live="polite"></p>
<div class="my-4" id="resultsContainer" style="min-height:80vh">
<p class="has-text-centered">
<em>Loading addresses...</em>
</p>
</div>
</main>
<footer class="footer">
<div class="columns">
<div class="column has-text-centered">
<a href="https://www.soomaps.com/" rel="noopener">
<img src="logo-soomaps.png" alt="SooMaps Logo" width="120" height="120" loading="lazy" /><br />
Find your ward visually with<br />
SooMaps.com
</a>
</div>
<div class="column has-text-centered">
<a href="https://saultstemarie.ca/Government/City-Departments/Corporate-Services/City-Clerk/Ward-Boundaries.aspx" rel="noopener">
<img src="logo-saultstemarie.png" alt="Sault Ste. Marie Logo" width="120" height="120" loading="lazy" /><br />
View ward maps on<br />
SaultSteMarie.ca
</a>
</div>
<div class="column has-text-centered">
<a href="https://github.com/cityssm/ward-finder" rel="noopener">
<img src="logo-github.png" alt="GitHub Logo" width="120" height="120" loading="lazy" /><br />
See the code on<br />
GitHub
</a>
</div>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/axios@0.26.1/dist/axios.min.js" integrity="sha256-iSkNRnKsHORmMCNgQIxzyW0QzHrWeko/lyVjyI78G2c=" crossorigin="anonymous"></script>
<script>
(() => {
const wardNumbers = [1, 2, 3, 4, 5];
let wardsToLoad = wardNumbers.length;
let addressesByWard = {};
let addressStringPieces = [""];
const maxRows = 50;
function addressFilter(possibleAddress) {
const addressLowerCase = possibleAddress.CIVICNUMBER + " " + possibleAddress.STREETNAME.toLowerCase();
for (const addressPiece of addressStringPieces) {
if (!addressLowerCase.includes(addressPiece)) {
return false;
}
}
return true;
}
function doSearch(formEvent) {
if (formEvent) {
try {
formEvent.preventDefault();
} catch {}
}
if (wardsToLoad > 0) {
return;
}
addressStringPieces = document.getElementById("address").value.toLowerCase().trim().split(" ");
const filteredAddressesByWard = {};
for (const [wardNumber, wardAddresses] of Object.entries(addressesByWard)) {
filteredAddressesByWard[wardNumber] = wardAddresses.filter(addressFilter);
}
const tableElement = document.createElement("table");
tableElement.className = "table is-fullwidth is-striped is-hoverable";
tableElement.innerHTML = "<thead><tr>" +
"<th>Civic Address</th>" +
"<th class=\"has-text-right\">Ward Number</th>" +
"</tr></thead>" +
"<tbody></tbody>";
let rowCount = 0;
let previousAddress = "";
for (const [wardNumber, filteredWardAddresses] of Object.entries(filteredAddressesByWard)) {
for (const address of filteredWardAddresses) {
const currentAddress = address.CIVICNUMBER + " " + address.STREETNAME;
if (currentAddress === previousAddress) {
continue;
}
rowCount += 1;
previousAddress = currentAddress;
const trElement = document.createElement("tr");
const addressCellElement = document.createElement("td");
addressCellElement.textContent = currentAddress;
trElement.append(addressCellElement);
const wardNumberCellElement = document.createElement("td");
wardNumberCellElement.className = "has-text-right";
wardNumberCellElement.textContent = wardNumber;
trElement.append(wardNumberCellElement);
tableElement.getElementsByTagName("tbody")[0].append(trElement);
if (rowCount >= maxRows) {
break;
}
}
if (rowCount >= maxRows) {
break;
}
}
document.getElementById("resultsContainer").innerHTML = "";
if (rowCount > 0) {
document.getElementById("resultsCount").innerHTML =
"Displaying " + rowCount +
(rowCount === 1 ? " address" : " addresses") +
(rowCount === maxRows ? "<br />(Row limit reached)" : "");
document.getElementById("resultsContainer").append(tableElement);
} else {
document.getElementById("resultsCount").innerHTML = "Your search returned zero addresses.";
}
}
function loadWard(wardNumber) {
axios.get("https://cityssm.github.io/soomaps-data/data/addresses-ward" + wardNumber + ".json")
.then((response) => {
return response.data;
})
.then((addresses) => {
addressesByWard[wardNumber.toString()] = addresses;
})
.finally(() => {
wardsToLoad -= 1;
if (wardsToLoad === 0) {
doSearch();
}
});
}
for (const wardNumber of wardNumbers) {
loadWard(wardNumber);
}
document.getElementById("addressForm").addEventListener("submit", doSearch);
document.getElementById("address").addEventListener("keyup", doSearch);
})();
</script>
</body>
</html>