Angular search bar with icon example

In our previous tutorial, we learned about Angular search filters using the library and custom pipe. This tutorial will teach us how to make an Angular search bar with icons using material or a bootstrap library. We have already covered the different approaches to implementingAngular the search filter process in Angular search filter articles.

In this tutorial, we‘ll learn how to add an Angular search bar with an icon, We’ll demonstrate an example of an Angular material search bar with an icon example and an example of a bootstrap icon. Let’s get started.


Setting up and configuring the Angular Search bar project

Let’s first demonstrate the Angular search bar with icons using Angular material, here we had listed the abstract step of adding the Angular material library in our project.

  • Step 1: Create a project and install a material library
  • Step 2: Import FormsModule to our project.
  • Step 3: Add form and material icon with material input component.
ng new checkboxApp
cd checkboxApp
ng add @angular/material

We need a custom pipe to filter search, let’s create a custom pipe called search-filter.pipe.ts in separate pipes or in src and add the following code.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'searchFilter' })
export class SearchFilterPipe implements PipeTransform {

  transform(list: any[], filterText: string): any {
    return list ? list.filter(item => item.name.search(new RegExp(filterText, 'i')) > -1) : [];
  }
}

It is good practice to create separate modules for Angular material, but this is a demo I will add add all material components needed in the app.module.ts for this example. Let’s add the required Material component, we also need to import our custom search filter, HttpClientModule, FormsModule in the app.module.ts file.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';
import { SearchFilterPipe } from './search-filter.pipe';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatTableModule } from '@angular/material/table';
import { MatIconModule } from '@angular/material/icon';
import { MatSelectModule } from '@angular/material/select';

@NgModule({
  declarations: [AppComponent, SearchFilterPipe],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    FormsModule,
    BrowserAnimationsModule,
    MatTableModule,
    MatFormFieldModule,
    MatInputModule,
    MatInputModule,
    MatIconModule,
    MatSelectModule,
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

Angular material search bar example

Here is a screenshot of the Angular material search bar example.

Angular search bar example
Angular material search bar example

Angular material input with icon

Angular material doesn’t have a search bar component, we can use mat-form-field component with mat-icon to create input field with icon. Angular material icon can have value matPrefix and matSuffix to align icon before or after form input. Let’s demonstrate material input with an icon at prefix.

Angular material search bar example
Angular material search bar example
  <mat-form-field appearance="fill">
    <mat-label>Search countries by name</mat-label>
    <input matInput [(ngModel)]="searchTerm" />
    <mat-icon matPrefix>search</mat-icon>
  </mat-form-field>

In the example below we have Angular material input with an icon at the end using the matSuffix attribute.

We need dummy data to for our search let create folder data and file called countries.json file and add following information about countries.

[
  {
    "name": "Russia",
    "flag": "f/f3/Flag_of_Russia.svg",
    "area": 17075200,
    "population": 146989754,
    "description": "Russia, the largest country in the world, occupies one-tenth of all the land on Earth."
  },
  {
    "name": "France",
    "flag": "c/c3/Flag_of_France.svg",
    "area": 640679,
    "population": 64979548,
    "description": "France, the largest country in Western Europe, has long been a gateway between the continent's northern and southern regions."
  },
  {
    "name": "Germany",
    "flag": "b/ba/Flag_of_Germany.svg",
    "area": 357114,
    "population": 82114224,
    "description": "Germany is a country located in the heart of Western Europe."
  },
  {
    "name": "Portugal",
    "flag": "5/5c/Flag_of_Portugal.svg",
    "area": 92090,
    "population": 10329506,
    "description": "Portugal is a country full of wonders — charming castles, pristine beaches, and a metropolitan capital spattered in remnants of the past."
  },
  {
    "name": "Canada",
    "flag": "c/cf/Flag_of_Canada.svg",
    "area": 9976140,
    "population": 36624199,
    "description": "Canada is a vast and rugged land. From north to south it spans more than half the Northern Hemisphere."
  },
  {
    "name": "Vietnam",
    "flag": "2/21/Flag_of_Vietnam.svg",
    "area": 331212,
    "population": 95540800,
    "description": "Vietnam is a long, narrow nation shaped like the letter s. It is in Southeast Asia on the eastern edge of the peninsula known as Indochina."
  },
  {
    "name": "Brazil",
    "flag": "0/05/Flag_of_Brazil.svg",
    "area": 8515767,
    "population": 209288278,
    "description": "Brazil is the largest country in South America and the fifth largest nation in the world. "
  },
  {
    "name": "Mexico",
    "flag": "f/fc/Flag_of_Mexico.svg",
    "area": 1964375,
    "population": 129163276,
    "description": "Mexico is a land of extremes, with high mountains and deep canyons in the center of the country, sweeping deserts in the north, and dense rain forests in the south and east."
  },
  {
    "name": "United States",
    "flag": "a/a4/Flag_of_the_United_States.svg",
    "area": 9629091,
    "population": 324459463,
    "description": "The United States of America is the world's third largest country in size and nearly the third largest in terms of population."
  },
  {
    "name": "India",
    "flag": "4/41/Flag_of_India.svg",
    "area": 3287263,
    "population": 1324171354,
    "description": "India (Hindi: Bhārat), officially the Republic of India (Hindi: Bhārat Gaṇarājya) is a country in South Asia."
  },
  {
    "name": "Indonesia",
    "flag": "9/9f/Flag_of_Indonesia.svg",
    "area": 1910931,
    "population": 263991379,
    "description": "Background: Indonesia is the largest archipelago in the world. It consists of five major islands and about 30 smaller groups."
  },
  {
    "name": "Tuvalu",
    "flag": "3/38/Flag_of_Tuvalu.svg",
    "area": 26,
    "population": 11097,
    "description": "Tuvalu, formerly known as the Ellice Islands, is located midway between Hawaii and Australia in the South Pacific Ocean. "
  }
]

We have used angular material table to display our search data, let add following code in the app.component.ts file

  1. Add fetch data to retrieve countries data using HttpClient
  2. filterCountries() method to retrieve search method
  3. Angular table to display data.
import { HttpClient } from '@angular/common/http';
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';;
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { animate, state, style, transition, trigger} from '@angular/animations';

interface Country {
  name: string;
  flag: string;
  area: number;
  population: number;
}
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  animations: [
    trigger('detailExpand', [
      state('collapsed', style({height: '0px', minHeight: '0'})),
      state('expanded', style({height: '*'})),
      transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
    ]),
  ],
})
export class AppComponent implements OnInit, AfterViewInit {
  searchTerm = '';

  displayedColumns: string[] = ['Flag', 'Name', 'Area', 'Population'];
  public dataSource: MatTableDataSource<any> = new MatTableDataSource<Country>()
  @ViewChild(MatSort) sort!: MatSort;

  constructor(private http: HttpClient) { }

  ngOnInit(): void {
    this.http.get<Country[]>('./assets/data/countries.json')
      .subscribe((data: any) => {
        this.dataSource = new MatTableDataSource<Country>(data)
      });
  }

  ngAfterViewInit(): void {
    this.dataSource.sort = this.sort;
  }

  filterCountries(searchTerm: string) {
    this.dataSource.filter = searchTerm.trim().toLocaleLowerCase();
    const filterValue = searchTerm;
    this.dataSource.filter = filterValue.trim().toLowerCase();
  }

  onMatSortChange() {
    this.dataSource.sort = this.sort;
  }
}

In the app.component.html file add material input with the search bar icon and clicking on material icon-search will filter search data. We can also remove the click event on the search icon and add an input event on the input to search will typing.

<div class="material-table">
  <h3>Material search filter.</h3>
  <mat-form-field appearance="fill">
    <mat-label>Search countries by name</mat-label>
    <input
      matInput
      [(ngModel)]="searchTerm"
      placeholder="Search country by name"
    />
    <mat-icon class='search-icon' color="primary" matPrefix (click)="filterCountries(searchTerm)"
      >search</mat-icon
    >
  </mat-form-field>

  <table
    *ngIf="dataSource"
    mat-table
    [dataSource]="dataSource"
    matSort
    (matSortChange)="onMatSortChange()"
    matSortDirection="asc"
    multiTemplateDataRows
    class="mat-elevation-z8"
  >
    <!-- Position Column -->
    <ng-container matColumnDef="Flag">
      <th mat-header-cell *matHeaderCellDef>Flag</th>
      <td mat-cell *matCellDef="let element">
        <img
          [src]="
            'https://upload.wikimedia.org/wikipedia/commons/' + element.flag
          "
          height="50"
          width="50"
          alt="country flag"
        />
      </td>
    </ng-container>

    <!-- Position Column -->
    <ng-container matColumnDef="Name">
      <th mat-header-cell *matHeaderCellDef mat-sort-header="name">
        Country Name
      </th>
      <td mat-cell *matCellDef="let element">{{ element.name }}</td>
    </ng-container>

    <!-- Name Column -->
    <ng-container matColumnDef="Area">
      <th mat-header-cell *matHeaderCellDef mat-sort-header="area">Area</th>
      <td mat-cell *matCellDef="let element">{{ element.area }}</td>
    </ng-container>

    <!-- Weight Column -->
    <ng-container matColumnDef="Population">
      <th mat-header-cell *matHeaderCellDef mat-sort-header="population">
        Population
      </th>
      <td mat-cell *matCellDef="let element">{{ element.population }}</td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr
      mat-row
      *matRowDef="let row; columns: displayedColumns"
      class="example-detail-row"
    ></tr>
  </table>
</div>

Angular bootstrap search input with icon

We can install the bootstrap library using the ng-bootsrap or ngx-bootstrap library, both libraries are popular for using bootstrap in Angular projects. We have a complete tutorial on how to install it in the angular project. Bootstrap doesn’t have a search bar component, we can use bootstrap CSS and font awesome icons to create a search bar with icons.

Angular bootstrap search bar with icon
<div class="input-group">
  <div class="form-outline">
    <input type="search" id="form1" class="form-control" />
    <label class="form-label" for="form1">Search</label>
  </div>
  <button type="button" class="btn btn-primary">
    <i class="fas fa-search"></i>
  </button>
</div>

Conclusion
Finally, we have completed the Angular search bar with icons using material and bootstrap. I haven’t added any search functionality in bootstrap, as we can use the same search filter of material search example, and the only difference is CSS style. I hope you liked this tutorial, please consider it sharing with others.

Related posts

Leave a Comment

Your email address will not be published.

Scroll to Top