When working with Angular forms, ng-select
is a powerful and flexible library for building dropdowns. One of its key features is the ability to customize search behavior within a dropdown using the searchFn
property. By default, ng-select
performs a simple case-insensitive search across the entire text of the dropdown items, but with searchFn
, you can override this functionality and implement custom search logic to meet more complex requirements.
In this blog post, we will dive into the searchFn
feature of ng-select
, explore how to customize search logic, and provide a step-by-step guide to implementing it in your Angular application.
ng-select
?ng-select
is a popular Angular component used to create dropdowns with extensive features like:
It is easy to integrate and offers several customization options, making it a great choice for building feature-rich forms in Angular.
searchFn
?The searchFn
is a property in ng-select
that allows you to define a custom search function for filtering the dropdown options. This comes in handy when you need more control over the search behavior—such as searching by specific fields, handling complex data structures, or implementing advanced search algorithms.
By default, ng-select
searches for matches across the label text of each option. However, with searchFn
, you can create custom search rules.
ng-select
Before we dive into custom search functionality, let’s start by setting up ng-select
in an Angular application.
ng-select
First, install the ng-select
package:
npm install @ng-select/ng-select --save
NgSelectModule
Next, import the NgSelectModule
in your app’s main module (or in the specific feature module where you plan to use it):
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { NgSelectModule } from '@ng-select/ng-select'; import { AppComponent } from './app.component'; @NgModule({ declarations: [AppComponent], imports: [BrowserModule, FormsModule, NgSelectModule], bootstrap: [AppComponent] }) export class AppModule {}
ng-select
to a TemplateHere’s a basic usage example of ng-select
in a template:
<ng-select [items]="items" bindLabel="name" [(ngModel)]="selectedItem" placeholder="Select an item"> </ng-select>
In the component, define the list of items and the selected item:
export class AppComponent { items = [ { id: 1, name: 'Option 1' }, { id: 2, name: 'Option 2' }, { id: 3, name: 'Option 3' } ]; selectedItem: any; }
With this, you have a simple ng-select
dropdown with basic search functionality.
searchFn
Now let’s extend the default search functionality using the searchFn
property.
searchFn
in the ComponentThe searchFn
is a function that takes two arguments:
The function should return true
if the item matches the search term, and false
if it does not.
Let’s create a custom searchFn
in the component:
export class AppComponent { items = [ { id: 1, name: 'Apple', category: 'Fruit' }, { id: 2, name: 'Banana', category: 'Fruit' }, { id: 3, name: 'Carrot', category: 'Vegetable' } ]; selectedItem: any; searchFn = (term: string, item: any) => { // Custom search logic: search by name and category term = term.toLowerCase(); return item.name.toLowerCase().includes(term) || item.category.toLowerCase().includes(term); } }
searchFn
to ng-select
Now, use the searchFn
in your template:
<ng-select [items]="items" bindLabel="name" [(ngModel)]="selectedItem" placeholder="Select an item" [searchFn]="searchFn"> </ng-select>
In the example above, our searchFn
is designed to search for matches in both the name
and category
fields of each item. This means users can search for an item by its name ("Apple", "Banana") or its category ("Fruit", "Vegetable"). If the search term matches either of these fields, the item will appear in the filtered results.
searchFn
You can further enhance your searchFn
based on your specific requirements. Here are a few ideas:
Here’s an example using a simple fuzzy search algorithm that checks for matches even if the user mistypes part of the word:
fuzzySearch(term: string, item: any) { term = term.toLowerCase(); const name = item.name.toLowerCase(); // Allow up to one mismatch (levenshtein distance of 1) let mismatchCount = 0; for (let i = 0; i < Math.min(term.length, name.length); i++) { if (term[i] !== name[i]) { mismatchCount++; } if (mismatchCount > 1) { return false; } } return true; }
This function will return true
even if there is one character mismatch between the search term and the item’s name.
searchFn
Customizing search functionality with searchFn
offers several benefits: