Angular2/4 search suggestion

I'm develop a drop down suggestion search box in angular 2/4. When typing on text box and press search button the searched details are displayed.But Here i want to show the searching, ‘as-you-type’ suggestion want to displayed(Like a dropdown search) .I saw so many techniques in different place but its not working. Here i install angular material I got some error in my node modules

i want like this enter image description here

here I will try the pipe but its not working..Can any one please help me..

my html is

<div class="form-group">
     <div class="input-group">
           <div [innerHTML]="highlighted"></div>
         <input name="search" class="form-control" type="text" placeholder="Search"
              (keyup)="FetchItemDetailsSearch(searchcontent)"
              [(ngModel)]="searchcontent">                       
          <span class="input-group-btn">
              <button class="btn btn-success ProductSearchBtn" type="button" 
                  (click)='FetchItemDetailsSearch(searchcontent)'>
                    <i class="glyphicon glyphicon-search" aria-hidden="true"></i>
                    <span style="margin-left:10px;">Search</span>
              </button>
           </span>
      </div>                  
</div>

component.ts

 FetchItemDetailsSearch(itemcodeordesc: string): void {

    {
        this.highlight= this.searchcontent
            ? itemcodeordesc.replace(new RegExp('(' + this.searchcontent + ')', 'ig'),
                '<span class=highlight>$1</span>')
            : itemcodeordesc;
    }

    this.pageIndex = 1;
    this.searchflag = 1;

    if (itemcodeordesc.length > 0)
        this.searchcontent = itemcodeordesc;
    else {
        itemcodeordesc = undefined
        this.searchcontent = itemcodeordesc;
    }
    this.prevScrollPosition = 0;
    this._enqService.FetchItemDetailsSearch(this.searchcontent,this.pageIndex).subscribe(itemsData => this.itemdetails = itemsData,
        error => {
            console.error(error);
            this.statusMessage = "Problem with the service.Please try again after sometime";
        });
}

Here i got like this(this is the problem, not showing the suggestion)

enter image description here

4 answers

  • answered 2018-07-11 05:31 Debojyoti

    For the dropdown implementation, you can use angular material
    Use the the autocomplete component for ui


    Demo template

    HTML

    <form class="example-form">
      <mat-form-field class="example-full-width">
        <input type="text" placeholder="search" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto" (keyup)="updated()" [(ngModel)]="data">
        <mat-autocomplete #auto="matAutocomplete">
          <mat-option *ngFor="let option of options" [value]="option">
            {{option}}
          </mat-option>
        </mat-autocomplete>
      </mat-form-field>
    </form>
    


    Now to search with in an array of string (In this example all[]), you can use this logic

    Here I am using regex to match any substring of those strings in the array

    Typescript

    export class AppComponent  {
      myControl = new FormControl();
      options: string[] = [];
      data : any;
      constructor() {
      }
    
      public updated() {
        this.options = [];
        if (this.myControl.value.length > 0) {
          let all = ['John', 'Jenny', 'Jonson']
          let searchedWord = this.myControl.value
          for(let key in all) {
            let r = all[key].search(new RegExp(searchedWord, "i"));
            if (r != -1) {
              this.options.push(all[key])
            }
          }
        } else {
          this.options = []
        }
      }
    }
    

    Working example : stackblitz







    Guide to install angular material and animations (Asked to explain)

    Step - 1 : Delete all node modules

    Delete all the files from node modules folder

    Step - 2 : Update all the packages to latest version

    npm i -g npm-check-updates

    ncu -u

    npm install

    Step - 3 : Install angular material and animation

    npm install --save @angular/material @angular/cdk

    npm install --save @angular/animations

    Step - 4 : Import any theme as it is required to use the libarary

    @import "~@angular/material/prebuilt-themes/indigo-pink.css";

    Step - 4 : Modify app.modules.ts file

    Imports

    import { FormsModule, ReactiveFormsModule } from '@angular/forms';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
    import {MatAutocompleteModule} from '@angular/material/autocomplete';
    import {MatFormFieldModule} from '@angular/material/form-field';
    import {MatInputModule} from '@angular/material/input';
    

    NgModule Meta data

    @NgModule({
      imports: [ BrowserModule, FormsModule,MatFormFieldModule,MatAutocompleteModule,MatInputModule,ReactiveFormsModule,BrowserAnimationsModule ]
      ...
    })
    export class AppModule { 
        ...
    }
    

  • answered 2018-07-11 05:43 UnluckyAj

    Material autocomplete example

    intsall angular material:

    npm install --save @angular/material @angular/cdk
    

    for Animation:

    npm install --save @angular/animations
    

    Include Theme in style.css:

    @import "~@angular/material/prebuilt-themes/indigo-pink.css";
    

    app.module.ts:

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule, ReactiveFormsModule } from '@angular/forms';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; // angular animation module
    
    
    import {MatAutocompleteModule} from '@angular/material/autocomplete';
    import {MatFormFieldModule} from '@angular/material/form-field';
    import {MatInputModule} from '@angular/material/input';
    import { AppComponent } from './app.component';
    import { HelloComponent } from './hello.component';
    
    @NgModule({
      imports:      [ BrowserModule, FormsModule,MatFormFieldModule,MatAutocompleteModule,MatInputModule,ReactiveFormsModule,BrowserAnimationsModule ],
      declarations: [ AppComponent, HelloComponent ],
      bootstrap:    [ AppComponent ]
    })
    export class AppModule { }
    

    app.component.html:

    <form class="example-form">
      <mat-form-field >
        <input type="text" placeholder="Filter Name" aria-label="Assignee" matInput [formControl]="myControl" [matAutocomplete]="auto">
        <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
          <mat-option *ngFor="let option of filteredOptions | async" [value]="option">
            {{option.name}}
          </mat-option>
        </mat-autocomplete>
      </mat-form-field>
    </form>
    

    app.component.ts:

    import { Component, OnInit } from '@angular/core';
    import { FormControl } from '@angular/forms';
    import { Observable } from 'rxjs';
    import { map, startWith } from 'rxjs/operators';
    
    export interface User {
      name: string;
    }
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
      name = 'Angular 6';
      myControl = new FormControl();
      options: User[] = [
        { name: 'Mary' },
        { name: 'Masy' },
        { name: 'Maty' },
        { name: 'Mvry' },
        { name: 'Mbry' },
        { name: 'Shelley' },
        { name: 'Igor' }
      ];
      filteredOptions: Observable<User[]>;
    
      ngOnInit() {
        this.filteredOptions = this.myControl.valueChanges
          .pipe(
          startWith<string | User>(''),
          map(value => typeof value === 'string' ? value : value.name),
          map(name => name ? this._filter(name) : this.options.slice())
          );
      }
    
      displayFn(user?: User): string | undefined {
        return user ? user.name : undefined;
      }
    
      private _filter(name: string): User[] {
        const filterValue = name.toLowerCase();
    
        return this.options.filter(option => option.name.toLowerCase().indexOf(filterValue) === 0);
      }
    }
    

  • answered 2018-07-11 05:46 Ali Rida

    Try using (input) instead of (keyup) in the input like this:

    <input name="search" class="form-control" type="text" placeholder="Search"
              (input)="FetchItemDetailsSearch(searchcontent)"
              [(ngModel)]="searchcontent">
    

    Edit:

    Try replacing this.searchcontent with itemcodeordesc in the FetchItemDetailsSearch function like below:

    this._enqService.FetchItemDetailsSearch(itemcodeordesc,this.pageIndex)
    .subscribe(itemsData => this.itemdetails = itemsData,
    

  • answered 2018-07-11 07:24 zmr

    Use Pipe which will use [(ngModel)]="searchcontent" over the mainList declared and defined in your component.ts file

    mainList: any[] = [];

    inside constructor -> define which properties you want for search results

    this.mainList= ['property1', 'property2',..,'propertyN'];

    Use for loop to display the results in your page-

    *ngFor="let x of xs| pipe: searchcontent: mainList"