CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vue-multiselect

Vue 3 compatible multiselect component with advanced selection, search, tagging, and grouping capabilities

Pending
Overview
Eval results
Files

search-filtering.mddocs/

Search and Filtering

Built-in search functionality with configurable filtering, custom search functions, and async option loading support.

Capabilities

Basic Search

Enable search functionality with a text input that filters available options.

/**
 * Basic search configuration props
 */
interface BasicSearchProps {
  /** Enable/disable search functionality (default: true) */
  searchable?: boolean;
  
  /** Enable/disable internal filtering (default: true) */
  internalSearch?: boolean;
  
  /** Input placeholder text (default: 'Select option') */
  placeholder?: string;
  
  /** Enable spellcheck on search input (default: false) */
  spellcheck?: boolean;
}

Usage Example:

<template>
  <VueMultiselect
    v-model="selectedUser"
    :options="users"
    :searchable="true"
    placeholder="Search users..."
    label="name"
    track-by="id">
  </VueMultiselect>
</template>

<script>
export default {
  data() {
    return {
      selectedUser: null,
      users: [
        { id: 1, name: 'John Doe', email: 'john@example.com' },
        { id: 2, name: 'Jane Smith', email: 'jane@example.com' },
        { id: 3, name: 'Bob Johnson', email: 'bob@example.com' }
      ]
    }
  }
}
</script>

Search Behavior Control

Configure how search interacts with selection and dropdown state.

/**
 * Search behavior configuration props
 */
interface SearchBehaviorProps {
  /** Clear search input after selecting an option (default: true) */
  clearOnSelect?: boolean;
  
  /** Preserve search value when component loses focus (default: false) */
  preserveSearch?: boolean;
  
  /** Close dropdown after selecting an option (default: true) */
  closeOnSelect?: boolean;
  
  /** Hide already selected options from dropdown (default: false) */
  hideSelected?: boolean;
}

Usage Example:

<template>
  <VueMultiselect
    v-model="selectedTags"
    :options="tags"
    :multiple="true"
    :searchable="true"
    :clear-on-select="false"
    :preserve-search="true"
    :hide-selected="true"
    placeholder="Search and select tags">
  </VueMultiselect>
</template>

Custom Search Logic

Implement custom filtering and sorting logic for search results.

/**
 * Custom search configuration props
 */
interface CustomSearchProps {
  /**
   * Custom function to generate display labels for options
   * @param option - The option object
   * @param label - The label property name
   * @returns Formatted display string
   */
  customLabel?: (option: any, label: string) => string;
  
  /**
   * Custom sorting function for filtered results
   * @param a - First option to compare
   * @param b - Second option to compare
   * @returns Comparison result (-1, 0, 1)
   */
  filteringSortFunc?: (a: any, b: any) => number;
  
  /** Limit number of displayed options (default: 1000) */
  optionsLimit?: number;
}

Usage Example:

<template>
  <VueMultiselect
    v-model="selectedProduct"
    :options="products"
    :searchable="true"
    :custom-label="customProductLabel"
    :filtering-sort-func="sortByRelevance"
    :options-limit="50"
    label="name"
    track-by="id">
  </VueMultiselect>
</template>

<script>
export default {
  data() {
    return {
      selectedProduct: null,
      products: [
        { id: 1, name: 'Laptop Pro', price: 1299, category: 'Electronics' },
        { id: 2, name: 'Office Chair', price: 299, category: 'Furniture' }
      ]
    }
  },
  methods: {
    customProductLabel({ name, price, category }) {
      return `${name} - $${price} (${category})`;
    },
    
    sortByRelevance(a, b) {
      // Custom sorting logic based on price, category, etc.
      if (a.category !== b.category) {
        return a.category.localeCompare(b.category);
      }
      return a.price - b.price;
    }
  }
}
</script>

Search Events

Events related to search functionality for implementing async or custom search.

/**
 * Search-related events
 */
interface SearchEvents {
  /** 
   * Emitted when search query changes
   * @param searchQuery - Current search string
   * @param id - Component identifier
   */
  '@search-change': (searchQuery: string, id: string | number) => void;
}

Async Search

Implement asynchronous option loading based on search queries.

/**
 * Async search configuration props
 */
interface AsyncSearchProps {
  /** Disable internal filtering for async search (default: true) */
  internalSearch: false;
  
  /** Show loading spinner during async operations */
  loading?: boolean;
  
  /** Current options array (updated asynchronously) */
  options: any[];
}

Usage Example:

<template>
  <VueMultiselect
    v-model="selectedUser"
    :options="searchResults"
    :internal-search="false"
    :loading="isLoading"
    :searchable="true"
    @search-change="searchUsers"
    label="name"
    track-by="id"
    placeholder="Search users...">
  </VueMultiselect>
</template>

<script>
export default {
  data() {
    return {
      selectedUser: null,
      searchResults: [],
      isLoading: false
    }
  },
  methods: {
    async searchUsers(query) {
      if (query.length < 2) {
        this.searchResults = [];
        return;
      }
      
      this.isLoading = true;
      try {
        const response = await fetch(`/api/users/search?q=${encodeURIComponent(query)}`);
        this.searchResults = await response.json();
      } catch (error) {
        console.error('Search failed:', error);
        this.searchResults = [];
      } finally {
        this.isLoading = false;
      }
    }
  }
}
</script>

Search with Suggestions

Implement search with predefined suggestions or recent searches.

<template>
  <VueMultiselect
    v-model="selectedLocation"
    :options="currentOptions"
    :searchable="true"
    @search-change="updateSearchOptions"
    label="name"
    track-by="id"
    placeholder="Search locations...">
    
    <template #noResult="{ search }">
      <span>No locations found for "{{ search }}"</span>
    </template>
    
    <template #noOptions>
      <span>Start typing to search locations</span>
    </template>
  </VueMultiselect>
</template>

<script>
export default {
  data() {
    return {
      selectedLocation: null,
      allLocations: [
        { id: 1, name: 'New York', country: 'USA' },
        { id: 2, name: 'London', country: 'UK' },
        { id: 3, name: 'Tokyo', country: 'Japan' }
      ],
      recentSearches: [],
      currentOptions: []
    }
  },
  methods: {
    updateSearchOptions(query) {
      if (!query) {
        // Show recent searches when no query
        this.currentOptions = this.recentSearches;
      } else {
        // Filter based on query
        this.currentOptions = this.allLocations.filter(location =>
          location.name.toLowerCase().includes(query.toLowerCase()) ||
          location.country.toLowerCase().includes(query.toLowerCase())
        );
      }
    }
  }
}
</script>

Performance Optimization

Options for optimizing search performance with large datasets.

/**
 * Performance optimization props
 */
interface SearchPerformanceProps {
  /** Maximum number of options to display (default: 1000) */
  optionsLimit?: number;
  
  /** Custom sorting function for performance optimization */
  filteringSortFunc?: (a: any, b: any) => number;
  
  /** Disable internal search for better async performance */
  internalSearch?: boolean;
}

Usage Example:

<template>
  <VueMultiselect
    v-model="selectedItem"
    :options="filteredItems"
    :options-limit="100"
    :internal-search="false"
    :searchable="true"
    @search-change="debounceSearch"
    placeholder="Search in large dataset...">
  </VueMultiselect>
</template>

<script>
export default {
  data() {
    return {
      selectedItem: null,
      allItems: [], // Large dataset
      filteredItems: [],
      searchTimeout: null
    }
  },
  methods: {
    debounceSearch(query) {
      clearTimeout(this.searchTimeout);
      this.searchTimeout = setTimeout(() => {
        this.performSearch(query);
      }, 300);
    },
    
    performSearch(query) {
      if (!query) {
        this.filteredItems = this.allItems.slice(0, 100);
        return;
      }
      
      this.filteredItems = this.allItems
        .filter(item => item.name.toLowerCase().includes(query.toLowerCase()))
        .slice(0, 100);
    }
  }
}
</script>

Search Input Customization

Customize the search input behavior and appearance.

/**
 * Search input customization props
 */
interface SearchInputProps {
  /** HTML name attribute for the search input */
  name?: string;
  
  /** Tab index for keyboard navigation */
  tabindex?: number;
  
  /** Enable/disable spellcheck */
  spellcheck?: boolean;
  
  /** Prevent automatic focus on component activation */
  preventAutofocus?: boolean;
  
  /** HTML required attribute when no selection made */
  required?: boolean;
}

Install with Tessl CLI

npx tessl i tessl/npm-vue-multiselect

docs

advanced-configuration.md

basic-selection.md

custom-rendering.md

grouped-options.md

index.md

search-filtering.md

tagging-mode.md

tile.json