Browser können schon länger einmal in Dateifelder eingegebene Daten speichern, z.B. den Loginnamen und Passwort, und das kann im HTML mit autocomplete
gesteuert werden. Dies ist aber nicht, was ich im Folgenden mit Autovervollständigung meine. Ich wollte eine Tageingabe bauen und dafür im System vorhandene Tags autovervollständigen. Das kann HTML5, dafür gibt es das datalist-Element. Das sollte in modernen Browsern auch durchaus funktionieren:
Nur: Wie kann so eine kommaseparierte Liste vervollständigt werden? Wie kann mehr als ein einzelnes Wort vervollständigt werden? Zwar gibt es das Attribut multiple
, doch ist das für type="text"
nicht gültig. Mit Hausmitteln kann HTML5 das also nicht.
Aber: Mit ein bisschen Javascript kann das nachgerüstet werden. Die Idee samt Demo fand ich hier: Sobald ein Wort eingegeben wurde, bzw immer wenn ein Separator getippt wurde, muss nur die Datalist mit der bisherigen Eingabe ergänzt werden.
Also: gegeben sei ein Eingabefeld und eine Dataliste<input class="entryTagInput" type="text" list="tags" name="tags" placeholder="tag1, tag2, …"></input> <datalist id="tags> <option value="tag1"> <option value="tag2"> <option value="tag3"> </datalist>Dann braucht es nur noch diesen Brocken Javascript, um eine kommaseparierte Tagliste autozuvervollständigen
var tagInput = document.querySelector('.entryTagInput'); var rawTags = document.querySelector('#tags').cloneNode(); var tags = document.querySelector('#tags'); var oldTagInputValue = ""; tagInput.addEventListener('input', function(evt) { var autocompleteOccured = false; if (tagInput.value.length - oldTagInputValue.length > 1) { autocompleteOccured = true; tagInput.value += ", "; } if (tagInput.value.substr(-1) == ',' || autocompleteOccured) { tagOptions = []; for (var i=0;i < rawTags.options.length;i++) { var newTag = document.createElement('option'); if (autocompleteOccured) { newTag.value = tagInput.value + rawTags.options[i].value; } else { newTag.value = tagInput.value + " " + rawTags.options[i].value; } tagOptions[i] = newTag; } while (tags.hasChildNodes()) { tags.removeChild(tags.lastChild); } for (var i=0;i < tagOptions.length;i++) { tags.appendChild(tagOptions[i]); } } if (tagInput.value == "") { // user has deleted all tags tags.parentNode.appendChild(rawTags); tags.parentNode.removeChild(tags); tags = document.querySelector('#tags'); rawTags = document.querySelector('#tags').cloneNode(); } oldTagInputValue = tagInput.value; });In der
rawlist
-Datalist bleiben die originalen Tags, in tags
werden die neuen Permutationen gespeichert, was im Input-Event der Tageingabe immer dann geschieht, wenn ein Komma eingegeben oder die Autovervollständigung genutzt wurde. Dass sie genutzt wurde kann leider nur festgestellt werden, indem geschaut wird, wieviele Zeichen auf einmal eingegeben wurde. Da gibt es leider scheinbar kein eigenes Event für.