This repository was archived by the owner on Jun 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
206 lines (190 loc) Β· 4.86 KB
/
script.js
File metadata and controls
206 lines (190 loc) Β· 4.86 KB
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
const input = document.querySelector("#fruit");
const suggestions = document.querySelector(".suggestions ul");
const fruits = [
"Apple π",
"Apricot",
"Avocado π₯",
"Banana π",
"Bilberry",
"Blackberry",
"Blackcurrant",
"Blueberry π«",
"Boysenberry",
"Currant",
"Cherry π",
"Coconut π₯₯",
"Cranberry",
"Cucumber π₯",
"Custard apple",
"Damson",
"Date",
"Dragonfruit",
"Durian",
"Elderberry",
"Feijoa",
"Fig",
"Gooseberry",
"Grape π",
"Raisin",
"Grapefruit",
"Guava",
"Honeyberry",
"Huckleberry",
"Jabuticaba",
"Jackfruit",
"Jambul",
"Juniper berry",
"Kiwifruit π₯",
"Kumquat",
"Lemon π",
"Lime πβπ©",
"Loquat",
"Longan",
"Lychee",
"Mango π₯",
"Mangosteen",
"Marionberry",
"Melon π",
"Cantaloupe",
"Honeydew",
"Watermelon π",
"Miracle fruit",
"Mulberry",
"Nectarine",
"Nance",
"Olive π«",
"Orange",
"Clementine",
"Mandarine",
"Tangerine π",
"Papaya",
"Passionfruit",
"Peach π",
"Pear π",
"Persimmon",
"Plantain",
"Plum",
"Pineapple π",
"Pomegranate",
"Pomelo",
"Quince",
"Raspberry",
"Salmonberry",
"Rambutan",
"Redcurrant",
"Salak",
"Satsuma",
"Soursop",
"Star fruit",
"Strawberry π",
"Tamarillo",
"Tamarind",
"Yuzu",
"Tomato π
",
];
/**
* Searches the fruits list for a fruit containing the given string of characters.
*
* @param {String} str A string of characters to find in a fruit name.
* @returns An array of fruits that contain the given string of characters.
*/
function search(str) {
return fruits.filter((fruit) =>
fruit.toLowerCase().includes(str.toLowerCase())
);
}
/**
* Handles the processing of the search text and displaying of possible results.
*
* @param {Event} e The event created from typing into the search bar.
*/
function searchHandler(e) {
const inputText = e.target.value;
if (inputText.length > 1) {
const fruitResults = search(inputText);
createSuggestions(fruitResults, inputText);
} else {
suggestions.replaceChildren();
}
showSuggestions();
}
/**
* Creates "li" elements for each fruit in the results and appends it to the unordered list in the suggestions div
* element. This also will bold the part of the fruit name that contains the inputVal text.
*
* @param {Array} results The array of fruits to show as suggestions.
* @param {String} inputVal The search bar text used to generate the results.
*/
function createSuggestions(results, inputVal) {
const liElements = results.map((fruit) => {
const separatedString = separateStringForBolding(fruit, inputVal);
const li = document.createElement("li");
const b = document.createElement("b");
b.innerText = separatedString[1];
li.append(separatedString[0]);
li.append(b);
li.append(separatedString[2]);
li.classList.add("suggestions__search-result");
return li;
});
suggestions.replaceChildren(...liElements);
}
/**
* Shows the unordered list of suggestions, whether or not it is hidden.
*/
function showSuggestions() {
suggestions.classList.remove("hide");
}
/**
* Hides the suggestions if the event target is an element in the search-container div.
*
* @param {Event} e The event that possibly contains an element in the search-container div.
*/
function hideSuggestions(e) {
if (
!(
e.target.tagName === "INPUT" &&
e.target.parentElement.classList.contains("search-container")
) &&
!(
e.target.tagName === "LI" &&
e.target.classList.contains("suggestions__search-result")
)
) {
suggestions.classList.add("hide");
}
}
/**
* Takes the event target's text, which will be a search result suggestion, and places it into the search bar.
*
* @param {Event} e The event that will contain the list item element of a suggested fruit search result.
*/
function useSuggestion(e) {
let li = e.target;
// In case the event target is the bold element that is within the list item element.
if (e.target.parentElement.tagName == "LI") {
li = e.target.parentElement;
}
input.value = li.innerText;
suggestions.replaceChildren();
}
/**
* Splits a string into an array according to a substring, so that it is easier to put a portion of the string into a
* bold HTML element.
*
* @param {String} str String to split.
* @param {String} substr The substring within the string.
* @returns An array containing the pieces of the string, with the piece to bold being the second element.
*/
function separateStringForBolding(str, substr) {
const i = str.toLowerCase().indexOf(substr.toLowerCase());
return [
str.slice(0, i),
str.slice(i, i + substr.length),
str.slice(i + substr.length),
];
}
input.addEventListener("keyup", searchHandler);
suggestions.addEventListener("click", useSuggestion);
input.addEventListener("click", showSuggestions);
document.body.addEventListener("click", hideSuggestions);