0
# Search and Filtering
1
2
Built-in search functionality with configurable filtering, custom search functions, and async option loading support.
3
4
## Capabilities
5
6
### Basic Search
7
8
Enable search functionality with a text input that filters available options.
9
10
```typescript { .api }
11
/**
12
* Basic search configuration props
13
*/
14
interface BasicSearchProps {
15
/** Enable/disable search functionality (default: true) */
16
searchable?: boolean;
17
18
/** Enable/disable internal filtering (default: true) */
19
internalSearch?: boolean;
20
21
/** Input placeholder text (default: 'Select option') */
22
placeholder?: string;
23
24
/** Enable spellcheck on search input (default: false) */
25
spellcheck?: boolean;
26
}
27
```
28
29
**Usage Example:**
30
31
```vue
32
<template>
33
<VueMultiselect
34
v-model="selectedUser"
35
:options="users"
36
:searchable="true"
37
placeholder="Search users..."
38
label="name"
39
track-by="id">
40
</VueMultiselect>
41
</template>
42
43
<script>
44
export default {
45
data() {
46
return {
47
selectedUser: null,
48
users: [
49
{ id: 1, name: 'John Doe', email: 'john@example.com' },
50
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' },
51
{ id: 3, name: 'Bob Johnson', email: 'bob@example.com' }
52
]
53
}
54
}
55
}
56
</script>
57
```
58
59
### Search Behavior Control
60
61
Configure how search interacts with selection and dropdown state.
62
63
```typescript { .api }
64
/**
65
* Search behavior configuration props
66
*/
67
interface SearchBehaviorProps {
68
/** Clear search input after selecting an option (default: true) */
69
clearOnSelect?: boolean;
70
71
/** Preserve search value when component loses focus (default: false) */
72
preserveSearch?: boolean;
73
74
/** Close dropdown after selecting an option (default: true) */
75
closeOnSelect?: boolean;
76
77
/** Hide already selected options from dropdown (default: false) */
78
hideSelected?: boolean;
79
}
80
```
81
82
**Usage Example:**
83
84
```vue
85
<template>
86
<VueMultiselect
87
v-model="selectedTags"
88
:options="tags"
89
:multiple="true"
90
:searchable="true"
91
:clear-on-select="false"
92
:preserve-search="true"
93
:hide-selected="true"
94
placeholder="Search and select tags">
95
</VueMultiselect>
96
</template>
97
```
98
99
### Custom Search Logic
100
101
Implement custom filtering and sorting logic for search results.
102
103
```typescript { .api }
104
/**
105
* Custom search configuration props
106
*/
107
interface CustomSearchProps {
108
/**
109
* Custom function to generate display labels for options
110
* @param option - The option object
111
* @param label - The label property name
112
* @returns Formatted display string
113
*/
114
customLabel?: (option: any, label: string) => string;
115
116
/**
117
* Custom sorting function for filtered results
118
* @param a - First option to compare
119
* @param b - Second option to compare
120
* @returns Comparison result (-1, 0, 1)
121
*/
122
filteringSortFunc?: (a: any, b: any) => number;
123
124
/** Limit number of displayed options (default: 1000) */
125
optionsLimit?: number;
126
}
127
```
128
129
**Usage Example:**
130
131
```vue
132
<template>
133
<VueMultiselect
134
v-model="selectedProduct"
135
:options="products"
136
:searchable="true"
137
:custom-label="customProductLabel"
138
:filtering-sort-func="sortByRelevance"
139
:options-limit="50"
140
label="name"
141
track-by="id">
142
</VueMultiselect>
143
</template>
144
145
<script>
146
export default {
147
data() {
148
return {
149
selectedProduct: null,
150
products: [
151
{ id: 1, name: 'Laptop Pro', price: 1299, category: 'Electronics' },
152
{ id: 2, name: 'Office Chair', price: 299, category: 'Furniture' }
153
]
154
}
155
},
156
methods: {
157
customProductLabel({ name, price, category }) {
158
return `${name} - $${price} (${category})`;
159
},
160
161
sortByRelevance(a, b) {
162
// Custom sorting logic based on price, category, etc.
163
if (a.category !== b.category) {
164
return a.category.localeCompare(b.category);
165
}
166
return a.price - b.price;
167
}
168
}
169
}
170
</script>
171
```
172
173
### Search Events
174
175
Events related to search functionality for implementing async or custom search.
176
177
```typescript { .api }
178
/**
179
* Search-related events
180
*/
181
interface SearchEvents {
182
/**
183
* Emitted when search query changes
184
* @param searchQuery - Current search string
185
* @param id - Component identifier
186
*/
187
'@search-change': (searchQuery: string, id: string | number) => void;
188
}
189
```
190
191
### Async Search
192
193
Implement asynchronous option loading based on search queries.
194
195
```typescript { .api }
196
/**
197
* Async search configuration props
198
*/
199
interface AsyncSearchProps {
200
/** Disable internal filtering for async search (default: true) */
201
internalSearch: false;
202
203
/** Show loading spinner during async operations */
204
loading?: boolean;
205
206
/** Current options array (updated asynchronously) */
207
options: any[];
208
}
209
```
210
211
**Usage Example:**
212
213
```vue
214
<template>
215
<VueMultiselect
216
v-model="selectedUser"
217
:options="searchResults"
218
:internal-search="false"
219
:loading="isLoading"
220
:searchable="true"
221
@search-change="searchUsers"
222
label="name"
223
track-by="id"
224
placeholder="Search users...">
225
</VueMultiselect>
226
</template>
227
228
<script>
229
export default {
230
data() {
231
return {
232
selectedUser: null,
233
searchResults: [],
234
isLoading: false
235
}
236
},
237
methods: {
238
async searchUsers(query) {
239
if (query.length < 2) {
240
this.searchResults = [];
241
return;
242
}
243
244
this.isLoading = true;
245
try {
246
const response = await fetch(`/api/users/search?q=${encodeURIComponent(query)}`);
247
this.searchResults = await response.json();
248
} catch (error) {
249
console.error('Search failed:', error);
250
this.searchResults = [];
251
} finally {
252
this.isLoading = false;
253
}
254
}
255
}
256
}
257
</script>
258
```
259
260
### Search with Suggestions
261
262
Implement search with predefined suggestions or recent searches.
263
264
```vue
265
<template>
266
<VueMultiselect
267
v-model="selectedLocation"
268
:options="currentOptions"
269
:searchable="true"
270
@search-change="updateSearchOptions"
271
label="name"
272
track-by="id"
273
placeholder="Search locations...">
274
275
<template #noResult="{ search }">
276
<span>No locations found for "{{ search }}"</span>
277
</template>
278
279
<template #noOptions>
280
<span>Start typing to search locations</span>
281
</template>
282
</VueMultiselect>
283
</template>
284
285
<script>
286
export default {
287
data() {
288
return {
289
selectedLocation: null,
290
allLocations: [
291
{ id: 1, name: 'New York', country: 'USA' },
292
{ id: 2, name: 'London', country: 'UK' },
293
{ id: 3, name: 'Tokyo', country: 'Japan' }
294
],
295
recentSearches: [],
296
currentOptions: []
297
}
298
},
299
methods: {
300
updateSearchOptions(query) {
301
if (!query) {
302
// Show recent searches when no query
303
this.currentOptions = this.recentSearches;
304
} else {
305
// Filter based on query
306
this.currentOptions = this.allLocations.filter(location =>
307
location.name.toLowerCase().includes(query.toLowerCase()) ||
308
location.country.toLowerCase().includes(query.toLowerCase())
309
);
310
}
311
}
312
}
313
}
314
</script>
315
```
316
317
### Performance Optimization
318
319
Options for optimizing search performance with large datasets.
320
321
```typescript { .api }
322
/**
323
* Performance optimization props
324
*/
325
interface SearchPerformanceProps {
326
/** Maximum number of options to display (default: 1000) */
327
optionsLimit?: number;
328
329
/** Custom sorting function for performance optimization */
330
filteringSortFunc?: (a: any, b: any) => number;
331
332
/** Disable internal search for better async performance */
333
internalSearch?: boolean;
334
}
335
```
336
337
**Usage Example:**
338
339
```vue
340
<template>
341
<VueMultiselect
342
v-model="selectedItem"
343
:options="filteredItems"
344
:options-limit="100"
345
:internal-search="false"
346
:searchable="true"
347
@search-change="debounceSearch"
348
placeholder="Search in large dataset...">
349
</VueMultiselect>
350
</template>
351
352
<script>
353
export default {
354
data() {
355
return {
356
selectedItem: null,
357
allItems: [], // Large dataset
358
filteredItems: [],
359
searchTimeout: null
360
}
361
},
362
methods: {
363
debounceSearch(query) {
364
clearTimeout(this.searchTimeout);
365
this.searchTimeout = setTimeout(() => {
366
this.performSearch(query);
367
}, 300);
368
},
369
370
performSearch(query) {
371
if (!query) {
372
this.filteredItems = this.allItems.slice(0, 100);
373
return;
374
}
375
376
this.filteredItems = this.allItems
377
.filter(item => item.name.toLowerCase().includes(query.toLowerCase()))
378
.slice(0, 100);
379
}
380
}
381
}
382
</script>
383
```
384
385
### Search Input Customization
386
387
Customize the search input behavior and appearance.
388
389
```typescript { .api }
390
/**
391
* Search input customization props
392
*/
393
interface SearchInputProps {
394
/** HTML name attribute for the search input */
395
name?: string;
396
397
/** Tab index for keyboard navigation */
398
tabindex?: number;
399
400
/** Enable/disable spellcheck */
401
spellcheck?: boolean;
402
403
/** Prevent automatic focus on component activation */
404
preventAutofocus?: boolean;
405
406
/** HTML required attribute when no selection made */
407
required?: boolean;
408
}
409
```