-
Notifications
You must be signed in to change notification settings - Fork 0
/
simple-search.js
59 lines (52 loc) · 1.96 KB
/
simple-search.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
/**
* @param items - items to search amongst. Expecting { value, searchable }
* @param inputEl - the text input element we will watch
* @param selectEl - the select element in which to put the results
*/
const SimpleSearch = (items, inputEl, selectEl) => {
// Actually fills in the selectEl with options
const fillOptions = (items, selectEl) => {
let optionsHTML = '';
items.forEach(r => {
optionsHTML += `<option value="${r.value}">${r.searchable}</option>`;
});
selectEl.innerHTML = optionsHTML;
};
// Start with all items
fillOptions(items, selectEl);
// Listen for keyup and update the list on the fly
inputEl.addEventListener('keyup', e => {
const value = e.target.value;
const results = items.filter(i => {
// toLowerCase() on both terms makes the search case-insensitive
return i.searchable.toLowerCase().indexOf(value.toLowerCase()) !== -1;
});
fillOptions(results, selectEl);
});
// Down arrow key (40) moves focus to selectEl
inputEl.addEventListener('keydown', e => {
if (
e.keyCode === 40 &&
selectEl.options.length > 0 &&
// Only do this if insertion point is at end of text
inputEl.selectionStart === inputEl.value.length
) {
selectEl.selectedIndex = 0;
selectEl.focus();
}
});
selectEl.addEventListener('keydown', e => {
if (selectEl.selectedIndex === 0 && e.keyCode === 38) {
/* If at top of selectEl, up arrow key (38) moves focus to inputEl. Put
* the insertion point at the end of the current input. A tiny delay is
* needed since Chrome fires the focus event before the cusor is moved.
* See https://stackoverflow.com/questions/511088/use-javascript-to-place-cursor-at-end-of-text-in-text-input-element
*/
setTimeout(() => {
// Safe to assume the input text length is less than 10000 chars
inputEl.selectionStart = inputEl.selectionEnd = 10000;
}, 0);
inputEl.focus();
}
});
};