Reputation: 1165
What is the best approach to show the user suggestions when he writes into a textbox? I have all possible values in a JS array. Take as an example the array ["TYPO3", "Javascript"]
. Now if the user enters the starting characters of such a string, he should get a suggestion like this:
I'm well aware of the placeholder html5 tag, but this would work only if the textbox is empty. I also know of the Datalist element or jQuery autocomplete but these only allow specific values. I also want content in my textbox that isn't predefined.
My idea would be to add a <span>
tag right after the cursor, alter its content upon a input keyup event and move the span to the place where the cursor currently is. This would also make it possible for me to style the suggestion text.
But for me this seems to be a bad hack, so is there a cleaner solution for that?
Upvotes: 4
Views: 7184
Reputation: 3081
This is what you want (I hope):
EDIT: Somehow it is NOT working here properly, so I put public jsfiddle as a backup :).
const names = [
'Predator_1', 'Semantic_RL', 'Thorn', 'Kill_09', 'One', 'Preclude'
];
const container = document.querySelector('#autocomplete-container');
const autocomplete = container.querySelector('#autocomplete');
const mainInput = container.querySelector('#main-input');
mainInput.addEventListener('keyup', onKeyUp, false);
let foundName = '';
function onKeyUp(e) {
// e.preventDefault();
console.log( mainInput.value, e );
console.log( autocomplete.textContent );
if (mainInput.value === '') {
autocomplete.textContent = '';
return;
}
if (keyChecker(e, 'Enter') || keyChecker(e, 'ArrowRight') ) {
console.log('keyChecker')
mainInput.value = foundName;
autocomplete.textContent = '';
}
let found=false;
for (let word of names) {
if (word.indexOf(mainInput.value) === 0) {
foundName = word;
autocomplete.textContent = word;
break;
} else {
foundName = '';
autocomplete.textContent = '';
}
}
}
function keyChecker(e, key) {
const keys = {
'ArrowRight':37,
'Enter':13,
'ArrowLeft':39
}
if (e.keyCode === keys[key] || e.which === keys[key] || e.key === key) return true;
return false;
}
div#autocomplete-container, input#main-input {
font: 14px Tahoma, Verdana, Arial, sans-serif;
}
#autocomplete-container {
position: relative;
box-sizing: border-box;
width: 300px;
height: 32px;
line-height: 32px;
margin: 0 auto;
}
#autocomplete {
width: 300px;
position: absolute;
top: 0;
left: 0;
padding: 0 8px;
line-height: 32px;
box-sizing: border-box;
height: 32px;
color: #999;
cursor: text;
}
#autocomplete-container input[type=text] {
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 32px;
line-height: 32px;
border: 1px solid #aaa;
border-radius: 4px;
outline: none;
padding: 0 8px;
box-sizing: border-box;
transition: 0.2s;
background-color: transparent;
cursor: text;
}
#autocomplete-container input[type=text]:focus {
border-color: dodgerBlue;
box-shadow: 0 0 8px 0 dodgerBlue;
}
<div id="autocomplete-container">
<div id="autocomplete"></div>
<input
id="main-input"
type="text"
placeholder="Enter route..." />
</div>
Upvotes: 0
Reputation: 1018
I can't tell you what is the best approach, but if you trust Google's approach, then their solution is pretty simple:
<input type='text' ...>
) for the actual input.<input>
element which is disabled
.The actual text box should be on top of the disabled one.
When the user starts typing and you found a match for the autocomplete, the suggested text should become the value
of the other disabled
input element (the text of the suggestion should be in a silver color).
Here's a small example: https://jsfiddle.net/e3L93o7g/
Upvotes: 6