Skip to content

Commit 886e03b

Browse files
committed
finished type ahead
1 parent 84aa759 commit 886e03b

1 file changed

Lines changed: 81 additions & 4 deletions

File tree

06 - Type Ahead/index-START.html

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<!DOCTYPE html>
22
<html lang="en">
3+
34
<head>
45
<meta charset="UTF-8">
56
<title>Type Ahead 👀</title>
67
<link rel="stylesheet" href="style.css">
78
</head>
9+
810
<body>
911

1012
<form class="search-form">
@@ -14,9 +16,84 @@
1416
<li>or a state</li>
1517
</ul>
1618
</form>
17-
<script>
18-
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
19+
<script>
20+
const debounce = (fn, ms = 0) => {
21+
let timeoutId;
22+
return function (...args) {
23+
clearTimeout(timeoutId);
24+
timeoutId = setTimeout(() => fn.apply(this, args), ms);
25+
};
26+
};
27+
28+
const endpoint =
29+
'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
30+
31+
const dataArr = []
32+
33+
fetch(endpoint)
34+
.then(blob => blob.json())
35+
.then(data => dataArr.push(...data))
36+
37+
function findMatches(itemToMatch, data, props) {
38+
if (!itemToMatch) {
39+
console.log('empty')
40+
return []
41+
}
42+
const matches = []
43+
if (props) {
44+
props = typeof props === 'string' ? [props] : props
45+
} else {
46+
props = Object.keys(data[0])
47+
}
48+
props.forEach(prop => {
49+
const filtered = data.filter(item => {
50+
const regex = new RegExp(itemToMatch, 'gi')
51+
return item[prop].toString().match(regex)
52+
})
53+
matches.push(
54+
...filtered
55+
)
56+
})
57+
return matches
58+
}
1959

20-
</script>
60+
function numberWithCommas(x) {
61+
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
62+
}
63+
64+
function displayMatches(e) {
65+
const matchArray = findMatches(e.target.value, dataArr)
66+
let html
67+
if (!matchArray.length) {
68+
html = `
69+
<li>Filter for a city</li>
70+
<li>or a state</li>
71+
`
72+
} else if (matchArray.length) {
73+
html = matchArray.map(matchedItem => {
74+
const regex = RegExp(e.target.value, 'gi')
75+
const cityName = matchedItem.city.replace(regex, `<span class="hl">${e.target.value}</span>`)
76+
const stateName = matchedItem.state.replace(regex, `<span class="hl">${e.target.value}</span>`)
77+
return `
78+
<li>
79+
<span class="name">${cityName}, ${stateName}</span>
80+
<span class="population">${numberWithCommas(matchedItem.population)}</span>
81+
</li>
82+
`
83+
84+
}).join('')
85+
}
86+
suggestions.innerHTML = html
87+
}
88+
89+
const inputSearch = document.querySelector('.search')
90+
const suggestions = document.querySelector('.suggestions')
91+
92+
inputSearch.addEventListener('change', displayMatches)
93+
inputSearch.addEventListener('keyup', debounce((e) => {
94+
displayMatches(e)
95+
}, 300))
96+
</script>
2197
</body>
22-
</html>
98+
99+
</html>

0 commit comments

Comments
 (0)