-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathscript.js
113 lines (101 loc) · 3.15 KB
/
script.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
import { $, $$, isTag, debounce } from './src/utils.js';
import { badWordExists } from './src/badwords.js';
import { bindSearchEvents } from './src/searchLinks.js';
const html = $('html');
const searchInput = $('#search-input');
const searchButton = $('#menu > .search-btn');
const autocomplete = $('#autocomplete');
const menuList = $('#menu > ul.list');
const baseUrl = 'https://api.datamuse.com';
const max = 500;
let str;
$('#year').textContent = new Date().getFullYear();
searchInput.focus();
bindSearchEvents($, searchInput);
const search = () => {
searchButton.classList.remove('hide');
menuList.classList.remove('hide');
searchInput.classList.remove('badword');
if (badWordExists(str) || isTag(str)) invalidInput();
getWords(str).then(list => {
const sortedList = list.sort((a, b) => a.word.localeCompare(b.word));
const found = findMatch(sortedList, str);
if (found.length && !badWordExists(str) && !isTag(str)) {
autocomplete.innerHTML = found;
autocomplete.classList.remove('hide');
searchInput.classList.add('results');
bindClickEvents();
}
});
}
// Generate dropdown list
['keyup', 'click'].forEach(event => {
searchInput.addEventListener(event, (e) => {
str = e.target.value.toLowerCase();
str ? debounce(search, 300) : emptyInput();
}, true);
});
// Event to close dropdown with outside click
html.addEventListener('click', (e) => {
if (e.target.tagName !== 'LI') {
autocomplete.classList.add('hide');
searchInput.classList.remove('results');
}
}, true);
// Events to fill input from dropdown
function bindClickEvents() {
const items = $$('#autocomplete > ul > li');
items.forEach(item => {
item.addEventListener('click', (e) => {
searchInput.value = e.target.textContent;
searchInput.focus();
autocomplete.classList.add('hide');
searchInput.classList.remove('results');
}, true);
});
}
// Get data from API
function getWords(str) {
return new Promise((resolve, reject) => {
const url = `${baseUrl}/sug?s=${str}&max=${max}`;
return fetch(url).then(response => {
if (response.ok) {
resolve(response.json());
} else {
reject(new Error('error'));
}
}, error => {
reject(new Error(error.message));
});
});
}
// Generate HTML for dropdown
function findMatch(arr, str) {
const list = arr.reduce((acc, item) => {
if (str === item.word.substring(0, str.length)) {
acc += `<li>${item.word}</li>`;
}
return acc;
}, '');
return list.length ? `<ul>${list}</ul>` : false;
}
function emptyInput() {
autocomplete.classList.add('hide');
searchInput.classList.remove('results');
searchButton.classList.add('hide');
menuList.classList.add('hide');
}
function invalidInput() {
autocomplete.classList.add('hide');
searchInput.classList.add('badword');
searchInput.classList.remove('results');
searchButton.classList.add('hide');
menuList.classList.add('hide');
}
(async () => {
const res = await fetch(
'https://node-api-serverless.vercel.app/api/sliders?page=1&orderBy=score&sortBy=desc&limit=10'
);
const data = await res.json();
console.log('data from silders scores:', data);
})();