---
title: "Vue Select Filtering Example | Mobiscroll"
component: "Select"
framework: "Vue"
library_version: "6.2.0"
url: "https://demo.mobiscroll.com/vue/select/filtering-values"
---

# Filtering - Vue Select demo

Vue select with filtering. Type in the header of the dropdown and filter values locally or remotely. For Vue and Nuxt.

- [Live demo](https://demo.mobiscroll.com/vue/select/filtering-values)
- [View SFC JS code on GitHub](https://github.com/acidb/mobiscroll-demos-vue/tree/main/src/demos/pickers/select/filtering-values)
- [View SFC TS code on GitHub](https://github.com/acidb/mobiscroll-demos-vue-ts/tree/main/src/demos/pickers/select/filtering-values)
- This demo in other frameworks: [JavaScript](https://demo.mobiscroll.com/javascript/select/filtering-values.md), [jQuery](https://demo.mobiscroll.com/jquery/select/filtering-values.md), [Angular](https://demo.mobiscroll.com/angular/select/filtering-values.md), [React](https://demo.mobiscroll.com/react/select/filtering-values.md)

## Description

Enable filtering by setting the [`filter` option](https://mobiscroll.com/docs/vue/select/api#opt-filter) to `true`. Filtering happens on the client side by default, however remote filtering can be implemented using the [`onFilter` event](https://mobiscroll.com/docs/vue/select/api#event-onFilter).

## What this demo shows

- Two select examples displayed side by side demonstrate filtering with local and remote data.
- **Select inputs** Focusing or clicking either input opens its picker below the input.
- **Input behavior** Clicking outside an open picker closes it.
- **Filtering** Entering a name in the search field filters the available options. The left example filters local data, while the right example filters remote data.
- **Picker content** Each picker displays a predefined list of options in a dropdown-style popup.
- **Hover state** Hovering over an option highlights it.
- **Selection** The selected option is marked with a checkmark.
- **Scrolling** Users can scroll through the available options.
- **Input value** Selecting an option updates the input with the selected value.

## Best for

- **Local reference lists** Filter a fixed list of countries, languages, departments, or categories stored in the application.
- **Product and service selection** Help users find an item quickly in a predefined catalog or service list.
- **Remote directories** Search customer, employee, or location records loaded from a remote data source.
- **Large or frequently updated datasets** Retrieve matching options remotely when loading and filtering the complete dataset in the browser is impractical.

## API used in this demo

- [`theme`](https://mobiscroll.com/docs/vue/select/api#opt-theme) - option
- [`themeVariant`](https://mobiscroll.com/docs/vue/select/api#opt-themeVariant) - option
- [`data`](https://mobiscroll.com/docs/vue/select/api#opt-data) - option
- [`filter`](https://mobiscroll.com/docs/vue/select/api#opt-filter) - option
- [`buttons`](https://mobiscroll.com/docs/vue/select/api#opt-buttons) - option
- [`display`](https://mobiscroll.com/docs/vue/select/api#opt-display) - option
- [`label`](https://mobiscroll.com/docs/vue/select/api#opt-label) - option
- [`labelStyle`](https://mobiscroll.com/docs/vue/select/api#opt-labelStyle) - option
- [`inputStyle`](https://mobiscroll.com/docs/vue/select/api#opt-inputStyle) - option
- [`filter`](https://mobiscroll.com/docs/vue/select/api#event-onFilter) - event

## Code

### SFC JS

```vue
<script setup>
import { getJson, MbscPage, MbscSelect, setOptions } from '@mobiscroll/vue'
import { onMounted, ref } from 'vue'

setOptions({
  theme: 'ios',
  themeVariant: 'light'
})

const remoteData = ref([])
const names = [
  { text: 'Abigail Hodges', value: 1 },
  { text: 'Adam Robertson', value: 2 },
  { text: 'Blake Nolan', value: 3 },
  { text: 'Dylan Manning', value: 4 },
  { text: 'Jane Clarkson', value: 5 },
  { text: 'Julian Parr', value: 6 },
  { text: 'Lily Blake', value: 7 },
  { text: 'Luke Wright', value: 8 },
  { text: 'Nathan Poole', value: 9 },
  { text: 'Olivia Vance', value: 10 },
  { text: 'Paul Hudson', value: 11 },
  { text: 'Rose Taylor', value: 12 },
  { text: 'Samantha Martin', value: 13 },
  { text: 'Steven Cameron', value: 14 },
  { text: 'Wanda Mills', value: 15 }
]

function remoteFiltering(filterText) {
  getJson(
    'https://trial.mobiscroll.com/airports/' + encodeURIComponent(filterText),
    (data) => {
      const airports = []
      for (const item of data) {
        airports.push({ text: item.name, value: item.code })
      }
      remoteData.value = airports
    },
    'jsonp'
  )
}

function handleFilter(ev) {
  remoteFiltering(ev.filterText)
  return false
}

onMounted(() => {
  remoteFiltering('')
})
</script>

<template>
  <MbscPage>
    <div class="mbsc-grid mbsc-form-grid">
      <div class="mbsc-row">
        <div class="mbsc-col-sm-12 mbsc-col-md-6">
          <MbscSelect
            :data="names"
            :filter="true"
            :buttons="undefined"
            display="center"
            label="Local data"
            labelStyle="stacked"
            inputStyle="box"
            placeholder="Please select..."
          />
        </div>
        <div class="mbsc-col-sm-12 mbsc-col-md-6">
          <MbscSelect
            :data="remoteData"
            :filter="true"
            display="anchored"
            label="Remote data"
            labelStyle="stacked"
            inputStyle="box"
            placeholder="Please select..."
            @filter="handleFilter"
          />
        </div>
      </div>
    </div>
  </MbscPage>
</template>
```

### SFC TS

```vue
<script setup lang="ts">
import { getJson, MbscPage, MbscSelect, setOptions } from '@mobiscroll/vue'
import { onMounted, ref } from 'vue'

setOptions({
  theme: 'ios',
  themeVariant: 'light'
})

const remoteData = ref<any>([])
const names = [
  { text: 'Abigail Hodges', value: 1 },
  { text: 'Adam Robertson', value: 2 },
  { text: 'Blake Nolan', value: 3 },
  { text: 'Dylan Manning', value: 4 },
  { text: 'Jane Clarkson', value: 5 },
  { text: 'Julian Parr', value: 6 },
  { text: 'Lily Blake', value: 7 },
  { text: 'Luke Wright', value: 8 },
  { text: 'Nathan Poole', value: 9 },
  { text: 'Olivia Vance', value: 10 },
  { text: 'Paul Hudson', value: 11 },
  { text: 'Rose Taylor', value: 12 },
  { text: 'Samantha Martin', value: 13 },
  { text: 'Steven Cameron', value: 14 },
  { text: 'Wanda Mills', value: 15 }
]

function remoteFiltering(filterText: string) {
  getJson(
    'https://trial.mobiscroll.com/airports/' + encodeURIComponent(filterText),
    (data) => {
      const airports = []
      for (const item of data) {
        airports.push({ text: item.name, value: item.code })
      }
      remoteData.value = airports
    },
    'jsonp'
  )
}

function handleFilter(ev: any) {
  remoteFiltering(ev.filterText)
  return false
}

onMounted(() => {
  remoteFiltering('')
})
</script>

<template>
  <MbscPage>
    <div class="mbsc-grid mbsc-form-grid">
      <div class="mbsc-row">
        <div class="mbsc-col-sm-12 mbsc-col-md-6">
          <MbscSelect
            :data="names"
            :filter="true"
            :buttons="undefined"
            display="center"
            label="Local data"
            labelStyle="stacked"
            inputStyle="box"
            placeholder="Please select..."
          />
        </div>
        <div class="mbsc-col-sm-12 mbsc-col-md-6">
          <MbscSelect
            :data="remoteData"
            :filter="true"
            display="anchored"
            label="Remote data"
            labelStyle="stacked"
            inputStyle="box"
            placeholder="Please select..."
            @filter="handleFilter"
          />
        </div>
      </div>
    </div>
  </MbscPage>
</template>
```

## Implementation notes

- `filter: true` turns on the search box in the picker header for both `Select` instances shown in this demo.
- **Local filtering** (left picker): `data` is a static in-memory array of `{ text, value }` objects; with only `filter: true` set and no filter handler, the component filters that array client-side by matching `text` against the typed query - no extra wiring is needed.
- **Remote filtering** (right picker): an `onFilter` handler intercepts the built-in filtering and returns `false` to suppress it, then issues its own request - `getJson('https://trial.mobiscroll.com/airports/' + encodeURIComponent(filterText), callback, 'jsonp')` in JS/React/Vue, or `HttpClient.jsonp(...)` in Angular - and repopulates the bound `data` array/ref from the response (`{ text: item.name, value: item.code }` per record) once results arrive.
- `onFilter`'s handler receives an event object exposing `filterText` (the current search-box value); returning `false` from the handler is what stops the component from also running its own client-side match against `data`.
- The remote example also calls the same fetch-and-populate function once on mount/init with an empty `filterText` so the picker has an initial option list before the user types anything.
- Event wiring differs per framework: React passes `onFilter` as a prop callback on `<Select>`; JS/jQuery pass `onFilter` as a function option inside `.select({ ... })`; Vue binds it as `@filter` on `<MbscSelect>`; Angular cannot bind `(onFilter)` as a template output - it must be set inside an `options` object (e.g. `remoteOptions: MbscSelectOptions = { onFilter: (ev) => {...; return false;} }`) passed via the `[options]="remoteOptions"` input.
- `display="center"` (local example) vs `display="anchored"` (remote example) are independent of filtering - they only control whether the picker opens as a centered modal or an anchored dropdown.

## Run it in your project

1. If not signed up yet, or don't own a license, you can [start a free trial](https://mobiscroll.com/starttrial).

2. Clone the repository:

   ```
   git clone https://github.com/acidb/mobiscroll-demos-vue.git
   ```

3. If not installed yet, install the Mobiscroll CLI from NPM:

   ```
   npm install -g @mobiscroll/cli
   ```

4. Config Mobiscroll - open a terminal window in the root directory and run:

   ```
   mobiscroll config vue
   ```

5. Install dependencies - open a terminal window in the root directory and run:

   ```
   npm install
   ```

6. Run the project:

   ```
   npm run dev
   ```

On a trial, add `--trial` to the config command: `mobiscroll config vue --trial`.

Running a demo locally requires a Mobiscroll trial or a license; setup is per framework at https://mobiscroll.com/docs/vue/getting-started/installation

## Related demos

- Previous: [Group options](https://demo.mobiscroll.com/vue/select/group-options.md) - Vue Select with group options and headers rendered as a hierarchy. With native look & feel, improved UX and source code.
- Next: [Multi level hierarchy](https://demo.mobiscroll.com/vue/select/linked-hierarchical-pickers.md) - Vue hierarchical select example. Dynamically populate linked lists based on previous selection.
