Type name or alter-ego of your favourite DC superhero. Type *
to see all heroes.
To display autocomplete you will need two major elements, input
and list
.
<p> <input id="filter-box" type="text" placeholder="Hero name"> </p> <ul id="heroes-container" data-t5="heroes" class="ac off"> <li repeat="hero in heroes | flat" data-idx="{{ hero.name }}"> <span class="name">{{ hero.name }}</span> <span class="alt">{{ hero.alt }}</span> </li> </ul>
JS code is very simple in this example. Most of it is just setting up a data model, getting references to DOM elements and handling events. Full code can be downloaded from here. Here I'd like to point out three things.
Heroes data structure is quite simple, but nothing stands in our way to make it more complex if you'd need that kind of structure.
See advanced data example.
const heroes = [
{ name: 'Batman', alt: 'Bruce Wayne', all: "*" },
{ name: 'Flash', alt: ' Barry Allen', all: "*" },
{ name: 'Cyborg', alt: 'Victor Stone', all: "*"},
{ name: 'Wonder Woman', alt: 'Diana', all: "*" },
{ name: 'Superman', alt: 'Clark Kent', all: "*" },
{ name: 'Green Lantern', alt: 'Hal Jordan', all: "*" }
];
In orde to render autocomplete template you need to do there things.
render()
method with heroes
array.t5.template() .filter('flat', (hero) => ~stringifyKeys(hero).indexOf(model.toLocaleLowerCase()) && model.length > 0) .render('heroes', {heroes});
On each input field update you need to re-render the template. Code below shows the most straightforward way of doing that. This could be optimised for example by adding a debouncing function, to make render more efficient.
filterBox.addEventListener('keyup', (event) => { model = event.target.value; t5.render('heroes', {heroes}); container.children.length > 0 ? container.classList.remove('off') : container.classList.add('off'); });