-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.js
158 lines (138 loc) · 6.13 KB
/
main.js
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
let countries;
fetch("https://restcountries.eu/rest/v2/all")
.then(res => {
return res.json()
})
.then(data => {
storeData(data)
})
.catch(err => {
console.log(err, "cannot fetch api")
})
function storeData(data) {
countries = data;
}
// functions to add and remove classes from elements
// added condition to prevent adding and removing classes
// from the last non-existent divs
function addClass(element, className) {
if (element) {
element.classList.add(className)
}
}
function removeClass(element, className) {
if (element) {
element.classList.remove(className)
}
}
function addSearchBorderRadius() {
search.style.borderBottomLeftRadius = "0px"
search.style.borderBottomRightRadius = "0px"
}
function removeSearchBorderRadius() {
search.style.borderBottomLeftRadius = "10px"
search.style.borderBottomRightRadius = "10px"
}
function go() { // handle onclick event
search.value = event.target.innerHTML
console.log(search.value)
}
function setPos() { // handle onmouseover event
removeClass(su_divs[pos], "suhl")
pos = parseInt(event.target.id)
addClass(su_divs[pos], "suhl")
}
function resetPos() { // handle onmouseout event
removeClass(su_divs[pos], "suhl")
pos = len - 1
}
let search = document.getElementById("search")
let search_suggestions = document.getElementsByClassName("search-suggestions")[0]
let search_icon = document.getElementById("search-icon")
let usr_input = ""
let slen = 9 // maximum length of list of suggestion divs
let su_divs = [] // intialise empty array of suggestion divs
let len = 1 // length is always one greater than actual length
let pos = len - 1 // initialise highlight position at last index (non-existing suggestion div)
// for navigation purposes
search.focus() //focus on search intitally
search.addEventListener("input", function() {
let suggestions = []
// if the search value is not empty after an input
// filter the countries with names starting with search value
if (search.value != "") {
suggestions = countries.filter(function(country) {
return country.name.toLowerCase().startsWith(search.value.toLowerCase())
})
}
//truncate results to maximium length of list if it exceeds
if (suggestions.length > slen) {
suggestions = suggestions.slice(0, slen)
}
let htmlstring = ""
suggestions.forEach( (country, index) => {
htmlstring += "<div id='" + index + "' class='sunl' onclick='go()' onmouseover='setPos()' onmouseout='resetPos()'>" + country.name + "</div>"
})
// square and restore bottom borders of search box
// when showing suggestions box
if (htmlstring != "") {
addSearchBorderRadius()
} else {
removeSearchBorderRadius()
}
search_suggestions.style.display = "block" // show block if it is hidden due to blur
usr_input = search.value // retain state of original user input
search_suggestions.innerHTML = htmlstring
su_divs = document.getElementsByClassName("sunl") // get array of suggestion divs
len = su_divs.length + 1 // assign len to one more than actual length
pos = len - 1
// reset position to last index (non-existing suggestion div)
})
// handling arrows in onkeydown event as they can't
// be handled in oninput event and defaults can be prevented in keydown
search.addEventListener("keydown", function(event) {
if (event.keyCode == 38) { // up arrow
event.preventDefault()
if (search_suggestions.style.display == "none") {
addSearchBorderRadius()
search_suggestions.style.display = "block" // show block and return if it is
return // hidden due to blur
}
removeClass(su_divs[pos], "suhl")
pos = ((pos-1)%len+len)%len
search.value = su_divs[pos] ? su_divs[pos].innerHTML : usr_input
addClass(su_divs[pos], "suhl")
} else if (event.keyCode == 40) { // down arrow
event.preventDefault()
if (search_suggestions.style.display == "none") {
addSearchBorderRadius()
search_suggestions.style.display = "block" // show block and return if it is
return // hidden due to blur
}
removeClass(su_divs[pos], "suhl")
pos = (pos+1)%len
search.value = su_divs[pos] ? su_divs[pos].innerHTML : usr_input
addClass(su_divs[pos], "suhl")
} else if (event.keyCode == 27) { // escape key
search_suggestions.style.display = "none";
removeSearchBorderRadius()
search.value = usr_input
removeClass(su_divs[pos], "suhl") // escape resets highlight state
pos = len - 1
} else if (event.keyCode == 13) { // enter key
console.log(search.value)
search_suggestions.style.display = "none"; // clicking outside retains highlight state
removeSearchBorderRadius()
}
})
// remove suggestino box when user clicks outside the search box
search.addEventListener("blur", function() {
setTimeout(() => {
search_suggestions.style.display = "none"; // clicking outside retains highlight state
removeSearchBorderRadius()
}, 100)
})
// focus search when search icon is clicked
search_icon.addEventListener("click", function() {
search.focus()
})