Level: beginner • Mithril.js Version: latest
autocomplete form input m.mount
This example shows an autocomplete component with local options.
The code is a conversion from a React component example from https://blog.bitsrc.io/building-a-react-autocomplete-component-from-scratch-3f4d5618aa14.
In this snippet several events like onclick
, oninput
, and onkeydown
are used.
The last one allows you to select and accept a suggestion using the up, down, and enter key.
Type | Name | URL |
---|---|---|
script | mithril@latest | https://unpkg.com/mithril@latest |
// Autocomplete.js
const KEY_CODE_ENTER = 13
const KEY_CODE_UP = 38
const KEY_CODE_DOWN = 40
function Autocomplete ({attrs}) {
const options = attrs.options
let activeOption = 0
let filteredOptions = []
let showOptions = false
let userInput = ''
const oninput = (e) => {
userInput = e.target.value
showOptions = true
activeOption = 0
filteredOptions = options.filter(
optionName => optionName.toLowerCase().indexOf(userInput.toLowerCase()) > -1
)
}
const onclick = (e) => {
filteredOptions = []
showOptions = false
userInput = e.currentTarget.innerText
}
const onkeydown = (e) => {
if (e.keyCode === KEY_CODE_ENTER) {
userInput = filteredOptions[activeOption]
activeOption = 0
showOptions = false
} else if (e.keyCode === KEY_CODE_UP) {
if (activeOption === 0) {
return;
}
activeOption--
} else if (e.keyCode === KEY_CODE_DOWN) {
if (activeOption === filteredOptions.length - 1) {
return;
}
activeOption++
}
};
function view() {
let optionList
if (showOptions && userInput) {
if (filteredOptions.length) {
optionList = m(
'ul.options',
filteredOptions.map((optionName, index) => m(
'li',
{
className: index === activeOption ? 'option-active' : '',
key: optionName,
onclick
},
optionName
))
)
} else {
optionList = m('.no-options', m('em', 'No Option!'))
}
}
return [
m('.search', [
m('input.search-box[type=text]', {
oninput,
onkeydown,
value: userInput
}),
m('input.search-btn[type=submit][value=]')
]),
optionList
]
}
return { view }
}
// App.js
m.mount(document.body, {
view: () => m(Autocomplete, {
options: [
'Papaya',
'Persimmon',
'Paw Paw',
'Prickly Pear',
'Peach',
'Pomegranate',
'Pineapple'
]
})
});
body {
background: #00b4cc;
}
.search {
width: 30rem;
margin: 10rem auto 2rem auto;
text-align: right;
position: relative;
}
.search-box {
border: 4px solid transparent;
border-radius: 2px;
font-size: 2rem;
width: 100%;
padding: 1rem;
transition: width 0.3s;
}
.search-box:focus {
width: 100%;
outline: none;
border: 4px solid #08a1b6;
}
.search-btn {
height: 100%;
width: 4em;
margin-top: -2em;
position: absolute;
top: 50%;
right: 0.5rem;
opacity: 0.2;
background-color: transparent;
border: 0;
background-repeat: no-repeat;
background-size: 100%;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAQAAAAAYLlVAAACnElEQVR4AcXZsUsbYRjH8e+dh2s1SyAGJwMJuDj1BIcEhJQIOnTq5F+QOf0jIq79A7oFh7aYyVBEkaZDC3awECc1AUXRIqUQotfFocnjJe/dk+b9PKP65Md7z13ee3Uwk2SNHKmngs5TnbDLJQqjA+RYZ4OXuDzvkSYf+cAJ44fPAYFhHeAzVhlqBBGrRoax8KjSJYhRXap4KCVoECiqQQKFLC0CZbXIElOBOwJ9cUchzm2Y5QsveN4tdfY4o00HSDHHPKuUmOV5v/D5SSSJ0MXfIY+HBB55dkIvRIIIvJDR28dnFJ/9kHH0MFaVDehRxlSZnuxAFUMZunKQKBJFUQ4wXTIYqcmPZ5GoFmUEahjw5eJTJI6ivBD4jCS/csrEVZZfU4yQk5OPhrwjcoRygQ0GVdCQf73OUEfisaMkHk1HDJHkYeDX82jlBzo+kCSEyxruwDP/EK1DbsWnhHDFgNTpodWjLgY9NECKfnvoyS4p8wBngN5Z/ABtQK8dP0AH0OuYB5iMqfAAMque7HJtHmAOPdnlxjzAPHqyy5V5gFX0ZJfj8AAn9CvhoeVRol8zPMAuj/xrlhW0Vpg1D3ApflhGR3b4wTlDvI24i4u+w9y0uyVrM213U1qxuy2/Z8bui8m23VezgGW7L6cBLdIWXs9FBAsHFCLCJI9opFMKXEzkkEp/IbK0bEdI0LARQRzVWoigPKy+Z5tlWooIiuP6NhVmAEiPNwLkqHDEw5CGx2wyDQDRI8T7l80U19xwxTFNmpwzKM1nFsyeCw7jFymCAxYjrHDp8r9cUOCUYRZ4Bw6AxVV47QJYXIVXLliNsOSC1Qh/XLAa4ZuDmmIcH1l2AaytwhZfmaAkn/qOb7eYBofJekOJJX7znfccAvwFyB3OeNys7d4AAAAASUVORK5CYII=");
}
.search-btn:hover {
outline: none;
opacity: 0.4;
cursor: pointer;
}
.search-btn:focus {
outline: none;
opacity: 0.6;
}
ul.options {
display: block;
list-style: none;
width: 30rem;
transition: width 0.3s;
margin: auto;
position: relative;
}
ul.options li {
display: block;
background: white;
margin: 10px auto;
padding: 10px;
font-size: 1.2rem;
width: 100%;
border-radius: 2px;
}
ul.options li:hover {
font-weight: bold;
color: #00b4cc;
cursor: pointer;
transition: 0.3s all;
}
ul.options li.option-active {
background: whitesmoke;
font-size: 1.5rem;
color: #00b4cc;
}
.no-options {
color: white;
}
The snippet requires the latest version of Mithril.js framework. It is ideal for beginners showing some basic recipes.
In this example we can see an example of Mithril.js' m.mount
API method, besides it core m() hyperscript function.
The code sample was authored by stephanhoyer. It was last modified on 26 October 2021. Want to see more examples written by stephanhoyer? Then Click here.
Do you see some improvements, that could be addressed here? Then let me know by opening an issue. As an alternative, you can fork the repository on GitHub, push your commits and send a pull request. To start your work, click on the edit link below. Thank you for contributing to this repo.