In this article, we will learn three different ways to create an AutoComplete textbox using Angular with Typescript. The first way will use HTML 5 DataList, second way will use the JQuery UI and the third way will use the Ng2-Completer and these implementations will be done in the Angular app. We will see three of these approaches with static and dynamic data. Here static data means, data is defined directly with controls and dynamic data means we will fetch data from somewhere and display it with these controls. 

Let's jump to create an Angular CLI project ad move to implementation of AutoComplete textbox. If you don't have an idea how to create an Angular CLI project with step by step instruction or if you are beginner then you can follow this article  Building an Angular 5 CLI project with ngx-bootstrap.

More articles on Angular which you may like.

 

At the end of this demonstration, the final output will be similar to as the following image shows. Here you can see how we are getting the similar data once we type some character inside the textbox. 

AutoComplete Textbox in Angular

So, let start the demonstration and before starting this step by step demonstration, we hope, you all have learned how to create an Angular CLI project. So, let move to implement an AutoComplete textbox using the first way. 

So, first create a folder as a name with 'data' and create a JSON file inside this with the name as 'users.json'. After creating the file, just create a JSON array similar as follows. Where you would define data from 1000 to 9999. This data will be used for dynamic data while searching something in the textbox and a service will hit to this file and get the data.

["1000",
    "1001",
    "1002",
    "1003",
    "1004",
    "1005",
    "1006",
    "1007",
    "1008",
    "1009",
    "1010",
    ......
    ......
    9999]

Now, let's create an Angular service as the name with 'UserService' and create a function getUserList() which will get the list of users. The function getUserList() will get the list of users from the data file 'users.json'. Here you need to take care of two points, don't forget to import HttpClientModule on AppModule, import HttpClient on UserService and secondly, set the header value of Content-type.

import { Injectable } from "@angular/core";
import { HttpClient } from '@angular/common/http';
import { HttpHeaders } from "@angular/common/http";


@Injectable()
export class UserService {
    constructor(private http: HttpClient) {
    }

    getUserList() {
        let headers = new HttpHeaders();
        headers.set('Content-Type', 'application/json');

        return this.http.get('/src/app/data/users.json', { headers });
    }
}

Here is our final AppModule, which importing HttpClientModule, so that we can process HTTP operations, importing UserService, so that can access the list of users from the 'users.json' file.

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

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { UserService } from 'src/app/service/user.service';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    AppRoutingModule
  ],
  providers:[UserService],
  bootstrap: [AppComponent]
  
})
export class AppModule { }
First way: Using HTML 5 DataList

Let's create an AutoComplete textbox using Html5 DataList. So, open app.component.html and add the code snippet as follows. Here we just create a table for simplicity, first, let talk about static data. We will create a textbox with list attribute and create a DataList just below to it and create some dummy value. Just pass the static DataList id as 'staticUserIds' with textbox list attribute. So, that while typing anything, it will search the similar records from the DataList as AutoComplete.

Now, let's talk about AutoComplete textbox with HTML 5 DataList using dynamic data. So, create an input control with Id and list attribute. Create the DataList just below to it, but this time we will generate the dynamic data using *ngFor directive and pass the DataList Id with textbox list attribute. Once the user will start typing and on the keyup, we will call the function 'getUserIdFirstWay($event)' which will take the input character as a parameter. Based on this parameter value, we will search the matching records and show in the textbox as AutoComplete value.

<input type="text" (keyup)="getUserIdsFirstWay($event)" id="userIdFirstWay" list="dynmicUserIds" />
<datalist id="dynmicUserIds">
   <option *ngFor="let item of userList1" [value]="item">{{item}}</option>
</datalist>

Here is the full HTML code for First Way of implementing AutoComplete textbox.

<router-outlet></router-outlet>

<table>
  <tr>
    <td colspan="2" style="text-align: center;">
      <h3>Auto Complete Demo</h3>
    </td>
  </tr>
  <tr>
    <td colspan="2" style="text-align: center;">
      <h4> First Way: Using HTML 5 DataList</h4>
    </td>
  </tr>
  <tr>
    <td>
      User ID with static data:
    </td>
    <td>
      <input type="text" list="staticUserIds" />
      <datalist id="staticUserIds">
        <option>1000</option>
        <option>1100</option>
        <option>1110</option>
        <option>1200</option>
        <option>1220</option>
        <option>1340</option>
        <option>1567</option>
        <option>1678</option>
        <option>1789</option>
      </datalist>
    </td>
  </tr>
  <tr>
    <td>
      User ID with dynamic data:
    </td>
    <td>
      <input type="text" (keyup)="getUserIdsFirstWay($event)" id="userIdFirstWay" list="dynmicUserIds" />
      <datalist id="dynmicUserIds">
        <option *ngFor="let item of userList1" [value]="item">{{item}}</option>
      </datalist>
    </td>
  </tr>  
</table>

Now, let's move to AppComponent and prepare the data for the textbox. First, we will get the whole users data on the page initialization and if user types anything and keyup then getUserIdFirstWay() function will be called. This function will not call continuously while typing anything, because it will make multiple calls asynchronously, that will cause for the hanging of browser. So, to resolve this, we will wait for 200 milliseconds and then call the next call for filtering the data. And filtered data based on the textbox's entered value will show as an AutoComplete textbox value.

import { Component, OnInit } from '@angular/core';
import { UserService } from 'src/app/service/user.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  userData: any[] = [];

  lastkeydown1: number = 0;
  subscription: any;

  constructor(private userService: UserService) {
    //Get the user data from users.json
    this.userService.getUserList().subscribe(
      data => {
        Object.assign(this.userData, data);
      },
      error => {
        console.log("Something wrong here");
      });    
  }  

  getUserIdsFirstWay($event) {
    let userId = (<HTMLInputElement>document.getElementById('userIdFirstWay')).value;
    this.userList1 = [];

    if (userId.length > 2) {
      if ($event.timeStamp - this.lastkeydown1 > 200) {
        this.userList1 = this.searchFromArray(this.userData, userId);
      }
    }
  }  

  searchFromArray(arr, regex) {
    let matches = [], i;
    for (i = 0; i < arr.length; i++) {
      if (arr[i].match(regex)) {
        matches.push(arr[i]);
      }
    }
    return matches;
  };
}

 

Second Way: Using JQueryUI

In the second approach, we will use JQuery UI library to create AutoComplete textbox with Angular and Typescript. Most of us, have already used Jquery UI and Jquery libraries without Angular. But this time, we will use these with Angular. So, it will be a little interesting to see how to use Jquery with Angular.

So, first let open the Visual Studio Code terminal windows of the project and execute the following commands to install Jquery and Jquery UI using NPM.

npm install jquery jquery-ui-dist

Once these libraries will install, we have to configure first inside scripts section of the angular.json. After configuration, we can use it.

"scripts": [
              "node_modules/jquery/dist/jquery.min.js",
              "node_modules/jquery-ui-dist/jquery-ui.js"
            ]

Now, let's prepare the HTML template for creating AutoComplete textbox with static and dynamic data both using Jquery UI. So, here we are creating two textboxes with unique IDs. The first textbox, we will pass the static data, second textbox will bind with dynamic data.

<tr>
    <td colspan="2">
      <br>
      <hr>
      <br>
    </td>
  </tr>
  <tr>
    <td colspan="2" style="text-align: center;">
      <h4> Second Way: Using Jquery UI</h4>
    </td>
  </tr>
  <tr>
    <td>
      User ID with static data:
    </td>
    <td>
      <input type="text" id="staticUserIdsSecondWay" />
    </td>
  </tr>
  <tr>
    <td>
      User ID with dynamic data:
    </td>
    <td>
      <input type="text" id="dynamicUserIdsSecondWay" (keyup)="getUserIdsSecondtWay($event)" />
    </td>
</tr>

Now, let move to AppComponent and understand, how we can use the Jquery inside the Typescript file. So, using the Jquery or $ which is an alias for JQuery. first, we need to declare the var as $ with type any. And then we can write any jquery code using the $, it automatically points to Jquery $.

declare var $: any;

Create an Angular's life cycle event 'ngOnInit()' and set some static values with textbox which have 'staticUserIdSecondWay'.

ngOnInit(){
    //Using Jquery --- $ is declared at the top
    $('#staticUserIdsSecondWay').autocomplete({
      source: ['1101', '1202', '1303']
    });
  }

Let's move to AppComponent again and create the function 'getUserIdsSecondtWay' which is responsible for binding dynamic data to the textbox. First, we will find the textbox using $('textbox id goes here') and bind the data with this textbox using autocomplete function, which is available in Jquery UI library. Following is the whole code for AppComponent.

import { Component, OnInit } from '@angular/core';
import { CompleterService, CompleterData } from 'ng2-completer';
import { UserService } from 'src/app/service/user.service';

declare var $: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  userData: any[] = [];
  userList1: any;
  userList2: any;

  lastkeydown1: number = 0;
  lastkeydown2: number = 0;
  subscription: any;

  constructor(private userService: UserService) {
    //Get the user data from users.json
    this.userService.getUserList().subscribe(
      data => {
        Object.assign(this.userData, data);
      },
      error => {
        console.log("Something wrong here");
      });    
  }

  ngOnInit(){
    //Using Jquery --- $ is declared at the top
    $('#staticUserIdsSecondWay').autocomplete({
      source: ['1101', '1202', '1303']
    });
  }

  getUserIdsFirstWay($event) {
    let userId = (<HTMLInputElement>document.getElementById('userIdFirstWay')).value;
    this.userList1 = [];

    if (userId.length > 2) {
      if ($event.timeStamp - this.lastkeydown1 > 200) {
        this.userList1 = this.searchFromArray(this.userData, userId);
      }
    }
  }

  getUserIdsSecondtWay($event) {
    
    let userId = (<HTMLInputElement>document.getElementById('dynamicUserIdsSecondWay')).value;

    this.userList2 = [];

    if (userId.length > 2) {
      if ($event.timeStamp - this.lastkeydown2 > 200) {
        this.userList2 = this.searchFromArray(this.userData, userId);

        $('#dynamicUserIdsSecondWay').autocomplete({
          source: this.userList2,
          messages: {
            noResults: '',
            results: function () { }
          }
        });
      }
    }
  }

  searchFromArray(arr, regex) {
    let matches = [], i;
    for (i = 0; i < arr.length; i++) {
      if (arr[i].match(regex)) {
        matches.push(arr[i]);
      }
    }
    return matches;
  };
}

We have done some modification with .ui-autocomplete CSS as follows.

.ui-autocomplete {
    list-style: none;
    background-color: gainsboro;
    width: 80px;
    padding-left: 10px;
  }

.ui-helper-hidden-accessible { display:none; }
Third Way: Using Ng2-Completer

Let's create an AutoComplete textbox using Ng2-Completer component, you can install it from NPM using following command.

npm install ng2-completer --save

Once, it will install, just define the ng2-completer.umd.js path with angular.json's scripts section.

"scripts": [
              "node_modules/jquery/dist/jquery.min.js",
              "node_modules/jquery-ui-dist/jquery-ui.js",
              "node_modules/ng2-completer/bundles/ng2-completer.umd.js"
            ]

We have to also update the AppModule to import Ng2CompleterModule. So, finally, our AppMoudle will look like as follows.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';
import { Ng2CompleterModule } from 'ng2-completer';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { UserService } from 'src/app/service/user.service';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    AppRoutingModule,
    FormsModule,
    Ng2CompleterModule 
    
  ],
  providers:[UserService],
  bootstrap: [AppComponent]
  
})
export class AppModule { }

Now add one table row for third way demonstration of adding an AutoComplete textbox using Ng2-Completer as follows. Here <ng2-completer> will be your tag name and data source will be that from where we will get the actual data, minSearchLenght property takes input that defines how many characters required to start searching matching data.

<tr>
    <td colspan="2" style="text-align: center;">
      <h4> Third Way: Using NG2-Completer</h4>
    </td>
  </tr>
  <tr>
    <td>
      User ID with dynamic data:
    </td>
    <td>
      <ng2-completer [datasource]="userData" [minSearchLength]="2"></ng2-completer>
    </td>
</tr>

Once we will do all the implementation, we can run the project using ng serve command from CLI terminal window and we will find the similar output as we have shown at the beginning of the article.

Conclusion

So, today we have seen three different ways of creating an AutoComplete textbox in Angular using typescript, HTML 5 DataList, Jquery, Jquery UI and Ng2-Completer.

I hope this post will help you. Please put your feedback using comment which helps me to improve myself for next post. If you have any doubts please ask your doubts or query in the comment section and If you like this post, please share it with your friends. Thanks