Skip to content

Commit 62f6fa9

Browse files
committed
Completed exercise#6 of JS30. Improved on the search algorithm.
1 parent 7437088 commit 62f6fa9

1 file changed

Lines changed: 74 additions & 1 deletion

File tree

06 - Type Ahead/index-START.html

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<body>
99

1010
<form class="search-form">
11-
<input type="text" class="search" placeholder="City or State">
11+
<input type="text" class="search" placeholder="City or State" autofocus>
1212
<ul class="suggestions">
1313
<li>Filter for a city</li>
1414
<li>or a state</li>
@@ -17,6 +17,79 @@
1717
<script>
1818
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
1919

20+
cities = [];
21+
22+
fetch(endpoint)
23+
.then(blob => blob.json())
24+
.then(data => cities.push(...data));
25+
26+
const searchBox = document.querySelector(".search");
27+
const searchForm = document.querySelector(".search-form");
28+
const suggestions = document.querySelector("form .suggestions");
29+
30+
searchBox.addEventListener('keyup', displayList);
31+
32+
function displayList(e) {
33+
e.preventDefault();
34+
if (this.value.length > 0) {
35+
const matchArray = searchList(this.value, cities);
36+
const html = matchArray.map(c => {
37+
const fullSearchText = `${c.city}, ${c.state}`;
38+
const indices = getMatchIndices(fullSearchText, this.value);
39+
const highlightedText = highlightLetters(fullSearchText, indices);
40+
41+
return (
42+
`<li>
43+
<span class="name">
44+
${highlightedText}
45+
</span>
46+
</li>`)
47+
})
48+
.join('');
49+
50+
suggestions.innerHTML = html;
51+
}
52+
else suggestions.innerHTML = "";
53+
}
54+
55+
function getMatchIndices(text, searchText) {
56+
let indices = [];
57+
let positionCounter = -1;
58+
59+
searchText.split('')
60+
.forEach( e => {
61+
index = text.toLowerCase().indexOf(e.toLowerCase(), positionCounter);
62+
if (index >= 0) {
63+
indices.push(index);
64+
positionCounter = index + 1;
65+
}
66+
}
67+
);
68+
69+
return indices;
70+
}
71+
72+
function highlightLetters(text, indices)
73+
{
74+
function highlightAtIndex(text, index, replacementStart, replacementEnd) {
75+
return text.substr(0, index) + replacementStart + text[index] + replacementEnd + text.substr(index + 1, text.length - 1);
76+
}
77+
78+
indices.reverse();
79+
indices.forEach(
80+
index => text = highlightAtIndex(text, index, `<span class="hl">`, `</span>`)
81+
);
82+
return text;
83+
}
84+
85+
function searchList(wordToSearch, cities) {
86+
const regex = new RegExp(wordToSearch.split('').join(`.*`), 'gi');
87+
return cities.filter(c => {
88+
const fullSearchText = `${c.city}, ${c.state}`;
89+
return fullSearchText.match(regex);
90+
});
91+
}
2092
</script>
2193
</body>
2294
</html>
95+

0 commit comments

Comments
 (0)