etto
small javascript autocomplete and select componentfull readme on github
note: etto is intended for use in modern browsers
install
npm install etto
or
<script src="https://unpkg.com/etto/dist/etto.min.js">
and (optional) styles
<link rel="stylesheet" href="https://unpkg.com/etto/dist/etto.css">
examples
input mode
choices = [
{ label: 'Alabama', value: 'Alabama' },
{ label: 'Alaska', value: 'Alaska, USA' },
{ label: 'Wyoming', value: 'WY' }
];
etto = new Etto(document.getElementById('demo-1'), {}, choices);
select mode
choices = [
{ label: 'Minnesota', value: 'Minnesota' },
{ label: 'Wyoming', value: 'Wyoming' },
{ label: 'New York', value: 'New York' }
];
etto = new Etto(document.getElementById('demo-2'), { selectMode: true }, choices);
ajax source (example using star wars api)
try searching for "darth vader".
this example uses fetch
, and AbortController
to abort requests that don't need to be completed. Remember to abort requests you don't intend to complete. Read more here.
let controller = null;
etto = new Etto(document.getElementById('demo-3'), {
source: async (query, done) => {
if (controller) controller.abort();
controller = new AbortController();
try {
const choices = [];
const response = await fetch(`https://swapi.dev/api/people/?search=${query}`, {
signal: controller.signal
});
controller = null;
const json = await response.json();
json.results.forEach(person => {
choices.push({ label: person.name, value: person.name })
});
done(choices);
} catch(err) {
if (err.name !== 'AbortError') {
done([]);
throw err;
}
}
}
});
using custom properties
etto has a few customizable properties for you to use.
emptyHtml
etto = new Etto(document.getElementById('demo-4'), { emptyHtml: '<b>Nothing here chief!</b>' }, choices);
createItemFn
use the createItemFn
property to tell etto how to render li
items in the dropdown list. a couple of parameters are passed, which you can use to return an html string.
Note: elements must be li
tags and must include a data-index
attribute with the value provided by the index
parameter. see below for an example.
createItemFn(choice: object, index: number, inputVal: string, isHighlighted: boolean, isSelected: boolean): string
choices = [
{ label: 'Minnesota', value: 'Minnesota' },
{ label: 'Wyoming', value: 'Wyoming' },
{ label: 'New York', value: 'New York' }
];
etto = new Etto(document.getElementById('demo-5'), {
createItemFn: (choice, index, inputVal, isHighlighted, isSelected) => {
return `<li class="etto-li" data-index="${index}">` +
'<img src="https://kevinfiol.github.io/etto/img.png" />' +
`<b>label: ${choice.label}, value: ${choice.value}</b>` +
'</li>';
}
}, choices);
filterFn
use the filterFn
property to tell etto how to filter the choices list.
filterFn(inputVal: string, choices: array, matchFullWord: boolean, maxResults: number): array
This example uses a filter function that only matches against choice.value
, and does not consider choice.label
choices = [
{ label: 'banana', value: 'yellow' },
{ label: 'apple', value: 'red' },
{ label: 'kiwi', value: 'green' }
];
etto = new Etto(document.getElementById('demo-6'), {
filterFn: (inputVal, choices, matchFullWord, maxResults) => {
const v = inputVal.toUpperCase();
return choices.filter(choice => {
return choice.value.toUpperCase().indexOf(v) > -1;
});
}
}, choices);
onSelect & onClear
pass a callback function as onSelect
to tell etto to trigger something upon selecting a choice. similarly, use onClear
to trigger an event upon programmatically clearing the input.
choices = [
{ label: 'The Legend of Zelda', value: 'The Legend of Zelda', year: 1986 },
{ label: 'Yoshi\'s Island', value: 'Yoshi\'s Island', year: 1995 },
{ label: 'Animal Crossing', value: 'Animal Crossing', year: 2002 }
];
const box = document.getElementById('demo-7-box');
etto = new Etto(document.getElementById('demo-7'), {
selectMode: true,
onSelect: choice => {
box.innerText = `Selected: ${choice.label} was released in ${choice.year}.`;
},
onClear: () => {
box.innerText = 'None selected.';
}
}, choices);
onValue
you can also use the onValue
callback which triggers after every new value to the input
element.
choices = [
{ label: 'Apples' },
{ label: 'Bananas' },
{ label: 'Animal Crossing' }
];
const demo8box = document.getElementById('demo-8-box');
etto = new Etto(document.getElementById('demo-8'), {
onValue: value => {
demo8box.innerText = value.trim() ? value : 'Input is currently empty.';
}
}, choices);