Typeahead
A basic, easily extended component for quickly creating elegant typeaheads with any form text input.
Example
Use v-model
to bind the input value, and target
to point to the ideal input element.
If you want to clear the v-model
of typeahead, simply set it to null
, the corresponding input value will also be cleared.
<template>
<Btn type="primary" @click="model = states[0]">Set to Alabama</Btn>
<Btn @click="model = null">Clear</Btn>
<hr />
<label for="input">States of America:</label>
<input
id="input"
class="form-control"
type="text"
placeholder="Type to search..."
autocomplete="off"
/>
<Typeahead v-model="model" target="#input" :data="states" item-key="name" />
<br />
<Alert v-show="model">You selected {{ model }}</Alert>
</template>
<script setup>
import { ref } from 'vue';
import { Alert, Typeahead, Btn } from 'uiv';
import { data as states } from './states.json';
const model = ref('');
</script>
Target
A target
can be:
- Selector that can be recognized by
querySelect
. - Reference to Element.
- Reference to Component.
TIP
If you use a component reference, the corresponding component's root element must be an input element.
An example using element reference target:
<template>
<label>States of America:</label>
<input
ref="input"
class="form-control"
type="text"
placeholder="Type to search..."
autocomplete="off"
/>
<Typeahead v-model="model" :target="input" :data="states" item-key="name" />
<br />
<Alert v-show="model">You selected {{ model }}</Alert>
</template>
<script setup>
import { ref } from 'vue';
import { Alert, Typeahead } from 'uiv';
import { data as states } from './states.json';
const input = ref(null);
const model = ref('');
</script>
Match start
Match from the head of item.
TIP
Only work in local data query mode.
<template>
<label for="input-2">States of America:</label>
<input
id="input-2"
class="form-control"
type="text"
placeholder="Type to search..."
autocomplete="off"
/>
<Typeahead
v-model="model"
target="#input-2"
match-start
:data="states"
item-key="name"
/>
<br />
<Alert v-show="model">You selected {{ model }}</Alert>
</template>
<script setup>
import { ref } from 'vue';
import { Alert, Typeahead } from 'uiv';
import { data as states } from './states.json';
const model = ref('');
</script>
Force select
Force user to select from the options or the model will be empty.
<template>
<label for="input-3">States of America:</label>
<input
id="input-3"
class="form-control"
type="text"
placeholder="Type to search..."
autocomplete="off"
/>
<Typeahead
v-model="model"
target="#input-3"
force-select
:data="states"
item-key="name"
/>
<br />
<Alert v-show="model">You selected {{ model }}</Alert>
</template>
<script setup>
import { ref } from 'vue';
import { Alert, Typeahead } from 'uiv';
import { data as states } from './states.json';
const model = ref('');
</script>
Async query
You can simply use async-src
to perform an AJAX query with built-in query function, or async-function
for a custom one if you need more than that.
TIP
ignore-case
and match-start
won't work in async query mode.
An example using async-src
:
<template>
<label for="input-4">Users of Github:</label>
<input
id="input-4"
class="form-control"
type="text"
placeholder="Type to search..."
autocomplete="off"
/>
<Typeahead
v-model="model"
target="#input-4"
async-src="https://api.github.com/search/users?q="
async-key="items"
item-key="login"
/>
<br />
<Alert v-show="model">You selected {{ model }}</Alert>
</template>
<script setup>
import { ref } from 'vue';
import { Alert, Typeahead } from 'uiv';
const model = ref('');
</script>
Custom template
Use the item
scoped slot to override the typeahead item's template.
- Use
scope="props"
. - The items list will be
props.items
. - The current active item index will be
props.activeIndex
. - Use
props.select(item)
to select item. - (Optional) Use
props.highlight(item)
to highlight search keywords in item.
An example with custom template and async-function
:
<template>
<label for="input-5">Users of Github:</label>
<input
id="input-5"
class="form-control"
type="text"
placeholder="Type to search..."
autocomplete="off"
/>
<Typeahead
v-model="model"
target="#input-5"
:async-function="queryFunction"
item-key="login"
>
<template #item="{ items, activeIndex, select, highlight }">
<li
v-for="(item, index) in items"
:key="item.id"
:class="{ active: activeIndex === index }"
>
<a role="button" @click="select(item)">
<img
style="width: 22px; height: 22px; margin-right: 5px"
:src="item.avatar_url + '&s=40'"
alt="avatar"
/>
<span v-html="highlight(item)"></span>
</a>
</li>
</template>
</Typeahead>
<br />
<Alert v-show="model">You selected {{ model }}</Alert>
</template>
<script setup>
import { ref } from 'vue';
import { Alert, Typeahead } from 'uiv';
import axios from 'axios'; // https://github.com/axios/axios
const model = ref('');
function queryFunction(query, done) {
axios
.get('https://api.github.com/search/users?q=' + query)
.then((res) => {
done(res.data.items);
})
.catch((err) => {
// any error handler
});
}
</script>
API Reference
Typeahead
Props
Name | Type | Default | Required | Description |
---|---|---|---|---|
v-model | ✔ | The input or selected value. | ||
target | ✔ | The input element to bind with. Can be a select or reference to Element / Component. | ||
data | Array | The local auto-complete query data. | ||
item-key | String | Value of each data[key] to show, leave blank to use the data object. | ||
append-to-body | Boolean | false | Append the typeahead dropdown to body. | |
ignore-case | Boolean | true | Ignore input case while matching. Only work in local data mode. | |
match-start | Boolean | false | Match from the head of item. Only work in local data mode. | |
force-select | Boolean | false | Force user to select from the options or the model will be empty. | |
force-clear | Boolean | false | Clear the input if no valid options has selected in force-select mode. | |
open-on-focus | Boolean | true | Open the typeahead dropdown on input focus. | |
open-on-empty | Boolean | false | Open the typeahead dropdown to show suggestions even if input is empty. | |
preselect | Boolean | true | Select the first item that matches the query automatically. | |
limit | Number | 10 | Limit the options size. | |
async-src | String | The ajax url to fetch data using GET method, query string will be append to the end of this prop value, should return JSON object or array. | ||
async-key | String | The async JSON key to render, leave blank to use the original json object (should be Array). | ||
async-function | Function | The custom async query function with 2 params: query as the user input, and done as the callback function with array data (note that async-key won't work with this). See the example in Custom Template section for details. | ||
debounce | Number | 200 | Debounce the input for specify milliseconds while in async mode. |
Slots
Name | Description |
---|---|
item | Use this scoped slot to override the typeahead item's template. |
empty | Slot content will be displayed while no results matched (if the slot exist). |
Events
Name | Description |
---|---|
loading | Async loading. |
loaded | Async load complete. |
loaded-error | Async load complete with error. |
input | Item selected |
selected-item-changed | On selected item changed, but not confirmed yet, i.e. using keyboard navigation |