Skip to content

FTxSelectBox

A powerful select component with advanced features including search, multiple selection with visual tags/chips, virtual scrolling with lazy loading, and async data loading on scroll.

Features

  • Multi-select with tags/chips - Select multiple items with visual chip/tag display
  • Virtual scrolling - Efficient handling of large datasets with lazy loading via API
  • Async select - Load data on scroll for better performance with large datasets
  • Search functionality - Built-in search with API-based filtering support
  • Custom rendering - Customizable option and selected item display

Props

PropTypeDefaultDescription
modelValueString | Number | Array-Selected value(s)
optionsArray[]Array of options to display (for static options)
optionLabelString | Function'name'Property or function to get option label
optionValueString | Function'id'Property or function to get option value
multipleBooleanfalseEnable multiple selection with chips
searchableBooleantrueEnable search functionality
clearableBooleanfalseShow clear button
labelString''Input label
placeholderString'Select...'Placeholder text
disableBooleanfalseDisable the select
rulesArray[]Validation rules
flatListBooleanfalseUse flat list display mode
apiUrlStringnullAPI endpoint URL for async data loading
lazyLoadBooleanfalseEnable lazy loading (data fetched when dropdown opens)
rowsPerPageNumber | String25Number of items per page for API pagination
maxSelectedPreviewNumber2Maximum number of chips to display before showing summary
scrollAreaHeightString'200px'Height of the scrollable dropdown area

Events

  • update:modelValue - Emitted when selection changes
  • search - Emitted when search query changes
  • clear - Emitted when selection is cleared

Slots

  • selected - Custom selected display
  • option - Custom option rendering
  • no-option - Custom no options message

Usage

Basic Usage

vue
<template>
  <FTxSelectBox
    v-model="selected"
    :options="options"
    label="Choose an option"
    searchable
    clearable
  />
</template>

<script setup>
import { ref } from 'vue';
import { FTxSelectBox } from '@ftx/ui';

const selected = ref(null);
const options = [
  { id: 1, name: 'Option 1' },
  { id: 2, name: 'Option 2' },
  { id: 3, name: 'Option 3' }
];
</script>

Custom Option Label/Value

vue
<template>
  <FTxSelectBox
    v-model="selected"
    :options="users"
    option-label="name"
    option-value="id"
    label="Select User"
  />
</template>

<script setup>
import { ref } from 'vue';
import { FTxSelectBox } from '@ftx/ui';

const selected = ref(null);
const users = [
  { id: 1, name: 'Alice', email: 'alice@example.com' },
  { id: 2, name: 'Bob', email: 'bob@example.com' }
];
</script>

Nested Property Paths

The optionLabel and optionValue props support nested property paths using dot notation. This is useful when your option objects have nested structures.

vue
<template>
  <FTxSelectBox
    v-model="selected"
    :options="products"
    option-label="vendor.name"
    option-value="id"
    label="Select Product"
  />
</template>

<script setup>
import { ref } from 'vue';
import { FTxSelectBox } from '@ftx/ui';

const selected = ref(null);
const products = [
  { id: 1, vendor: { name: 'Acme Corp', id: 10 } },
  { id: 2, vendor: { name: 'Tech Inc', id: 20 } }
];
</script>

Note: Nested paths work for both optionLabel and optionValue props, and are also supported when using comma-separated labels (e.g., option-label="vendor.name,product.name").

Multiple Selection with Tags/Chips

When multiple is enabled, selected items are displayed as removable chips/tags. The component automatically handles displaying a summary when many items are selected.

vue
<template>
  <FTxSelectBox
    v-model="selected"
    :options="options"
    multiple
    :max-selected-preview="3"
    label="Select Multiple"
  />
</template>

<script setup>
import { ref } from 'vue';
import { FTxSelectBox } from '@ftx/ui';

const selected = ref([]);
const options = [
  { id: 1, name: 'Option 1' },
  { id: 2, name: 'Option 2' },
  { id: 3, name: 'Option 3' },
  { id: 4, name: 'Option 4' },
  { id: 5, name: 'Option 5' }
];
</script>

Features:

  • Selected items appear as chips/tags with remove buttons
  • Chips can be individually removed
  • When many items are selected, shows a summary (e.g., "5 items selected")
  • Configurable maximum visible chips with maxSelectedPreview prop

Async Select with Virtual Scrolling (Lazy Load)

For large datasets, use lazyLoad with apiUrl to load data when the dropdown opens. Data loads progressively as you scroll (virtual scrolling).

vue
<template>
  <FTxSelectBox
    v-model="selected"
    api-url="/api/users"
    option-label="name"
    option-value="id"
    :lazy-load="true"
    :rows-per-page="25"
    label="Select User (Async)"
  />
</template>

<script setup>
import { ref } from 'vue';
import { FTxSelectBox } from '@ftx/ui';

const selected = ref(null);
</script>

Features:

  • Data is fetched when dropdown opens (lazy loading)
  • Additional data loads automatically as you scroll (virtual scrolling)
  • Efficient for large datasets
  • API-based pagination with configurable rowsPerPage

Async Select with Scroll Loading

Load data progressively via API as the user scrolls through the dropdown. This provides virtual scrolling behavior for better performance with large datasets.

vue
<template>
  <FTxSelectBox
    v-model="selected"
    api-url="/api/products"
    option-label="name"
    option-value="id"
    :rows-per-page="50"
    scroll-area-height="300px"
    label="Select Product (Scroll to Load)"
  />
</template>

<script setup>
import { ref } from 'vue';
import { FTxSelectBox } from '@ftx/ui';

const selected = ref(null);
</script>

How it works:

  • Initial data is fetched when component mounts (or when dropdown opens with lazyLoad)
  • As user scrolls near the bottom (80%), next page is automatically fetched
  • Continues loading until all data is fetched (hasMore is false)
  • Provides smooth scrolling experience for large datasets

With Validation

vue
<template>
  <FTxSelectBox
    v-model="selected"
    :options="options"
    :rules="[val => !!val || 'Please select an option']"
    label="Required Field"
  />
</template>

Released under the MIT License.