Skip to content

Select async

The async select fetches its options on demand instead of receiving them up front. Provide fetch-relevant, fetch-search and fetch-options to load the initial set, respond to the search query, and resolve selected values by their id. Enable is-multiple to allow several values at once.

TIP

When the popup opens with an active search query, fetch-search is called with that query; otherwise fetch-relevant is used. This keeps a previously typed search reflected in the initial result set.

Required icons

angles-up-down
magnifying-glass
xmark

Props

model-value: FluxFormSelectValue
The selected value(s) of the select element.

search-query?: string
The current search query. Use `v-model:search-query` to control or observe the search input.

auto-focus?: boolean
Focus the select when the form is mounted.

disabled?: boolean
If the select element is disabled.

error?: string | null
Error message describing why the select is invalid. Sets aria-invalid and a red border.

is-loading?: boolean
Shows a loading spinner inside the select (in addition to fetch-driven loading).

is-multiple?: boolean
If the select element allows multiple values to be selected.

is-readonly?: boolean
If the select is readonly. Blocks opening the popup.

is-secondary?: boolean
If the field is secondary and is rendered in an alternative style.

name?: string
The name attribute passed to a hidden form control.

placeholder?: string
The placeholder text to display when no value is selected.

fetch-options: fetchOptions(ids: FluxFormSelectValueSingle[]): Promise<FluxFormSelectEntry[]>
The function to call when the form select needs options by their id.

fetch-relevant: fetchRelevant(): Promise<FluxFormSelectEntry[]>
The function to call when the form select needs relevant options.

fetch-search: fetchSearch(searchQuery: string): Promise<FluxFormSelectEntry[]>
The function to call when the form select needs options based on the given search query.

Emits

update:model-value: [FluxFormSelectValue]
Triggered when the value is changed.

update:search-query: [string]
Triggered when the search query changes. Use `v-model:search-query` to control or observe the search input.

Examples

Basic

A basic asynchronous form select.

<template>
    <FluxPane style="max-width: 390px">
        <FluxPaneBody>
            <FluxFormSelectAsync
                v-model="selectedValue"
                :fetch-options="fetchOptions"
                :fetch-relevant="fetchRelevant"
                :fetch-search="fetchSearch"
                placeholder="Select an option..."/>
        </FluxPaneBody>
    </FluxPane>
</template>

<script
    setup
    lang="ts">
    import { FluxFormSelectAsync, FluxPane, FluxPaneBody } from '@flux-ui/components';
    import { FluxFormSelectEntry } from '@flux-ui/types';
    import { ref } from 'vue';
    import dataset from '../../../../../assets/select-dataset.json' with { type: 'json' };

    const selectedValue = ref(null);

    async function fetchOptions(values: string[]): Promise<FluxFormSelectEntry[]> {
        return dataset.filter(o => values.includes(o.value));
    }

    async function fetchRelevant(): Promise<FluxFormSelectEntry[]> {
        await new Promise(resolve => setTimeout(resolve, 1000));
        return dataset.toSorted();
    }

    async function fetchSearch(searchQuery: string): Promise<FluxFormSelectEntry[]> {
        return dataset.filter(o => o.label.toLowerCase().includes(searchQuery.toLowerCase()));
    }
</script>

Multiple

An asynchronous form select in where you can select multiple options.

<template>
    <FluxPane style="max-width: 390px">
        <FluxPaneBody>
            <FluxFormSelectAsync
                v-model="selectedValue"
                :fetch-options="fetchOptions"
                :fetch-relevant="fetchRelevant"
                :fetch-search="fetchSearch"
                is-multiple
                placeholder="Select an option..."/>
        </FluxPaneBody>
    </FluxPane>
</template>

<script
    setup
    lang="ts">
    import { FluxFormSelectAsync, FluxPane, FluxPaneBody } from '@flux-ui/components';
    import { FluxFormSelectEntry } from '@flux-ui/types';
    import { ref } from 'vue';
    import dataset from '../../../../../assets/select-dataset.json' with { type: 'json' };

    const selectedValue = ref([]);

    async function fetchOptions(values: string[]): Promise<FluxFormSelectEntry[]> {
        return dataset.filter(o => values.includes(o.value));
    }

    async function fetchRelevant(): Promise<FluxFormSelectEntry[]> {
        await new Promise(resolve => setTimeout(resolve, 1000));
        return dataset.toSorted();
    }

    async function fetchSearch(searchQuery: string): Promise<FluxFormSelectEntry[]> {
        return dataset.filter(o => o.label.toLowerCase().includes(searchQuery.toLowerCase()));
    }
</script>

Used components