[Angular] Angular Material Autocomplete를 이용한 자동완성 만들기

2021. 2. 27. 22:59WEB.DEV/Angular

반응형

이번 포스팅에서는 Angular Material의 Autocomplete를 이용해서 input에 자동 완성 기능을 만들어 보도록 하겠습니다.

 

Angular Material

UI component infrastructure and Material Design components for Angular web applications.

material.angular.io

먼저 Input을 위한 MatInputModule과 MatFormFieldModule, 그리고 자동 완성을 위한 MatAutocompleteModule, 그리고 input에 formControl 등 form을 사용하기 위해 FormsModule과 ReactiveFormsModule 모듈을 추가해줍니다.

// app.module.ts
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';

import {AppComponent} from './app.component';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';

import {MatAutocompleteModule} from '@angular/material/autocomplete';
import {MatInputModule} from '@angular/material/input';
import {MatFormFieldModule} from '@angular/material/form-field';

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

 

그리고 컴포넌트 템플릿에 MatFormField와 MatInput을 먼저 추가해주도록 하겠습니다.

<mat-form-field
  appearance="standard"
  floatLabel="always"
>
  <mat-label>
    나라
  </mat-label>
  <input
    type="text"
    placeholder="나라를 입력해주세요"
    matInput
  />
</mat-form-field>

그러면 아래와 같이 보여지는 것을 볼수 있습니다.

다음으로 자동 완성을 위해 MatAutocomplete을 추가하고 MatInput에 추가해주도록 하겠습니다.

<mat-form-field
  appearance="standard"
  floatLabel="always"
>
  <mat-label>
    나라
  </mat-label>
  <input
    type="text"
    placeholder="나라를 입력해주세요"
    aria-label="나라"
    matInput
    [matAutocomplete]="autoCountry"
  />
</mat-form-field>

<mat-autocomplete #autoCountry="matAutocomplete">
  <mat-option
    value="대한민국"
  >
    대한민국
  </mat-option>
  <mat-option
    value="미국"
  >
    미국
  </mat-option>
  <mat-option
    value="캐나다"
  >
    캐나다
  </mat-option>
  <mat-option
    value="영국"
  >
    영국
  </mat-option>
  <mat-option
    value="프랑스"
  >
    프랑스
  </mat-option>
</mat-autocomplete>

위와 같이 코드를 작성한 후 확인을 하면 아래와 같이 볼수 있습니다.

그리고 자동 완성에 하드 코딩 부분을 Component에 배열을 추가해서 간단하게 변경을 해보겠습니다.

...

@Component({
    ...
})
export class AppComponent implements OnInit {
    countryList = [
        '대한민국',
        '미국',
        '캐나다',
        '영국',
        '프랑스'
    ];
    
    constructor() {
    }
    
    ngOnInit(): void {
    }
}
...
<mat-autocomplete #autoCountry="matAutocomplete">
  <mat-option
    *ngFor="let country of countryList"
    [value]="country"
  >
    {{country}}
  </mat-option>
</mat-autocomplete>

그런데 여기 까지 하면 입력에 따라서 자동 완성에 선택 옵션이 변경이 되지 않습니다.

필터 기능을 추가하여 입력에 따라 자동 완성 선택 옵션이 변경되록 해보겠습니다.

먼저 입력 처리를 위해 FormControl를 추가해주겠습니다.

...

import {FormControl} from '@angular/forms';

@Component({
    ...
})
export class AppComponent implements OnInit {

    country = new FormControl('');
    
    ...
}
<mat-form-field
  appearance="standard"
  floatLabel="always"
>
  ...
  
  <input
  
    ...
    
    [formControl]="country"
  />
</mat-form-field>

그리고 Input 값이 변경되는 이벤트에 필터를 추가해주도록 하겠습니다.

...

import {map, startWith} from 'rxjs/operators';
import {Observable} from 'rxjs';

@Component({
    ...
})
export class AppComponent implements OnInit {
    country = new FormControl('');
    filterCountry: Observable<string[]>;    // 필터된 목록을 보여주기 위한 비동기 목록
    
    ...
    
    ngOnInit(): void {
        this.filterCountry = this.country.valueChanges.pipe(
            startWith(''),
            map(val => this._filter(val))
        );
    }
    
    private _filter(value: string): string[] {
        return this.countryList.filter(val => val.indexOf(value) !== -1);
    }
}
...

<mat-autocomplete #autoCountry="matAutocomplete">
  <mat-option
    *ngFor="let country of filterCountry | async"
    [value]="country"
  >
    {{country}}
  </mat-option>
</mat-autocomplete>

위와 같이 작업을 해주면 입력하는 값에 따라 아래 선택 옵션이 변경되는 것을 볼수 있습니다.

여기 까지 부족한 글 읽어 주셔서 감사합니다.💛

728x90
반응형