
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-selectBefore we dive into custom search functionality, let’s start by setting up ng-select in an Angular application.
ng-selectFirst, install the ng-select package:
npm install @ng-select/ng-select --save
NgSelectModuleNext, 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.
searchFnNow 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-selectNow, 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.
searchFnYou 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.
searchFnCustomizing search functionality with searchFn offers several benefits: