Simple autocomplete
by volter9
HTML
<div id="wrapper">
<div id="autocomplete"></div>
<textarea id="editor"></textarea>
<div id="mirror"></div>
</div>
CSS
#wrapper {
position: relative;
top: 0px;
left: 0px;
height: 200px;
width: 400px;
}
#editor,
#mirror {
font-family: monospace;
font-size: 12px;
line-height: 100%;
white-space: pre;
padding: 8px;
height: 200px;
width: 400px;
}
#mirror {
visibility: hidden;
}
#autocomplete {
background-color: #fff;
border: 1px solid #ccc;
font-size: 14px;
position: absolute;
top: 0px;
left: 0px;
display: none;
padding: 4px;
}
JavaScript
function $ (id) {
return document.getElementById(id);
}
var autocomplete = $('autocomplete'),
editor = $('editor'),
mirror = $('mirror');
var words = [
'str_replace',
'strstr',
'die',
'true',
'false',
'exit',
'md5'
],
match = '';
function reflect (textarea, position) {
var text = textarea.value,
span = document.createElement('span');
span.innerHTML = text.substr(position);
text = text.substr(0, position);
mirror.innerHTML = '';
mirror.appendChild(document.createTextNode(text));
mirror.appendChild(span);
return {
x: span.offsetLeft - mirror.offsetLeft,
y: span.offsetTop - mirror.offsetTop
};
}
function getMatched (match) {
if (!match) {
return [];
}
return words.filter(function (value) {
return value.indexOf(match) === 0;
});
}
function count (occurence, string) {
return string.split(occurence).length - 1;
}
editor.addEventListener('keyup', function (e) {
var character = String.fromCharCode(e.keyCode).toLowerCase();
if (e.keyCode === 16) {
return;
}
if (e.keyCode === 189) {
character = '_';
}
if (e.keyCode === 8) {
match = match.substr(0, match.length - 1);
}
else if (character.match(/[^a-z\_0-9]+/i)) {
match = '';
}
else {
match += character;
}
var matches = getMatched(match);
if (matches.length) {
autocomplete.innerHTML = matches.join('<br/>');
autocomplete.style.display = 'block';
var position = reflect(this, this.selectionStart - match.length);
autocomplete.style.left = editor.offsetLeft + position.x + 'px';
autocomplete.style.top = editor.offsetTop + 14 + position.y + 'px';
}
else {
autocomplete.style.display = 'none';
}
});