Last active
May 13, 2016 21:31
-
-
Save mishelen/e8e4243a1d80ef415a373ea400c3de0f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class AutoComplete { | |
constructor(input, config) { | |
this.input = typeof input == "string" ? document.querySelector(input) : input; | |
this.wholeSuggestList = config.wholeSuggestList; | |
this.suggestListMathes = []; | |
this.options = Object.assign({ | |
delay: 150, | |
suggestListClassName: 'suggestions list-unstyled', | |
maxSuggestions: 7, | |
minChars: 1 | |
}, config.options); | |
this.init(); | |
} | |
set newSuggestions(list) { | |
this.wholeSuggestList = list; | |
} | |
get value() { | |
return this.input.value; | |
} | |
createList() { | |
this.list = document.createElement('ul'); | |
this.listActiveItem = 0; | |
this.list.className = this.options.suggestListClassName; | |
this.input.parentNode.appendChild(this.list); | |
} | |
showList(suggestions) { | |
const template = document.createDocumentFragment(); | |
// вспомогательная фальш-строка в списке. Для кажущегося перескока на инпут | |
template.appendChild(document.createElement('li')).setAttribute('hidden', 'hidden'); | |
suggestions.forEach(item => { | |
const li = document.createElement('li'); | |
const text = document.createTextNode(item); | |
li.appendChild(text); | |
template.appendChild(li); | |
}); | |
this.list.innerHTML = ''; | |
this.list.appendChild(template); | |
this.list.style.opacity = 1; | |
} | |
closeList() { | |
this.list.style.opacity = 0; | |
this.listActiveItem = 0; | |
} | |
destroy() { | |
this.input.removeEventListener("input", this.onAutocompleteChange); | |
this.input.removeEventListener("keydown", this.keyDownHandler); | |
this.list.remove(); | |
} | |
onAutocompleteChange(e) { | |
const val = e.target.value | |
if (val.length < this.options.minChars) { | |
this.closeList(); | |
return; | |
} | |
this.suggestListMathes = this.wholeSuggestList.filter(item => (new RegExp(val, 'i')).test(item)); | |
this.suggestListMathes.length > 0 ? this.showList(this.suggestListMathes) : this.closeList(); | |
} | |
onChange() { | |
console.log('user choosed'); | |
} | |
keyDownHandler(e) { | |
const keyCode = e.keyCode; | |
if (keyCode == 33) {// page up | |
return; // ничего | |
} | |
if (keyCode == 34) {// page down (do nothing); | |
return; // ничего | |
} | |
if (keyCode == 27) { //escape | |
// todo сбрасываем выбор на последнее введенное. | |
this.closeList(); | |
} | |
if (keyCode == 39 || keyCode == 35 || keyCode == 9) { // right, end, tab -- сработал автокомплит | |
if (keyCode == 9) { // для таба перебиваем стандартное поведение, что бы не прыгало | |
e.preventDefault(); | |
e.stopPropagation(); | |
} | |
// todo заполнение пользовательского инпута подсказкой. Проверка существования подсказки. | |
this.onChange(); | |
this.closeList(); | |
} | |
if (keyCode == 13) { // enter -- сработал автокомплит | |
// todo заполнение пользовательского инпута подсказкой. Проверка существования подсказки. | |
this.onChange(); | |
this.closeList(); | |
} | |
if (keyCode == 38 || keyCode == 40) { // up & down | |
let listItems = this.list.childNodes; | |
Array.prototype.forEach.call(listItems, item => item.classList.remove('text-danger')); | |
this.listActiveItem += keyCode - 39; | |
if (this.listActiveItem < 0) { | |
this.listActiveItem = listItems.length - 1; | |
} else if (this.listActiveItem >= listItems.length) { | |
this.listActiveItem = 0; | |
} | |
listItems[this.listActiveItem].classList.add('text-danger'); | |
// todo дополнение пользовательского инпута подсказкой. Проверка существования подсказки. | |
return; | |
} | |
} | |
init() { | |
this.input.addEventListener("input", e => this.onAutocompleteChange(e)); | |
this.input.addEventListener("keydown", e => this.keyDownHandler(e)); | |
this.createList(); | |
} | |
} | |
let input = document.querySelector('#auto_complete-input'); | |
suggestor = new AutoComplete(input, { | |
wholeSuggestList: ['one', 'two', 'three', 'four'], | |
options : {delay: 250} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment