Implementing Auto-Suggestion in Input Field in Angular Template-Driven Forms

Template-driven forms in Angular offer a simple and declarative way to handle form creation and validation. In this article, we'll explore how to create a template-driven form with an input field that supports auto-suggestions. We'll use dummy data for demonstration purposes, but the same logic can be extended to fetch suggestions dynamically from an API.


Features

  • Input field for typing values.

  • Dropdown list of suggestions based on the user's input.

  • Ability to select a suggestion or continue typing.


Implementation Steps

1. HTML Template

We'll create an input field bound to ngModel for two-way data binding and display a dropdown of suggestions when the user types.

<div class="form-group col-md-4">
  <label for="packageName">Package Name</label>

  <!-- Input field for package name -->
  <input
    #packageName="ngModel"
    type="text"
    id="packageName"
    class="form-control"
    name="packageName"
    [(ngModel)]="packageNameModel"
    [ngClass]="{ 'is-invalid': myForm.submitted && packageName.invalid }"
    (input)="onInputChange()"  <!-- Detect input changes for suggestions -->
    required
  />

  <!-- Suggestions dropdown (shown when user starts typing) -->
  <div *ngIf="showSuggestions && packageNameModel.length > 0" class="dropdown-menu show">
    <div
      *ngFor="let suggestion of filteredSuggestions"
      class="dropdown-item"
      (click)="selectSuggestion(suggestion)"
    >
      {{ suggestion }}
    </div>
  </div>

  <!-- Validation feedback -->
  <div *ngIf="myForm.submitted && packageName.invalid" class="invalid-feedback">
    <div *ngIf="packageName.errors?.required">Package name is required</div>
  </div>
</div>

2. Component Logic

The component will handle the business logic for filtering suggestions and updating the model when a suggestion is selected.

export class PackageFormComponent {
  packageNameModel: string = '';
  showSuggestions: boolean = false;
  filteredSuggestions: string[] = [];

  // Predefined list of package names (dummy data for this example)
  allSuggestions: string[] = [
    'Package 1',
    'Package 2',
    'Package 3',
    'Package A',
    'Package B',
    'Package X'
  ];

  // Triggered when the user types in the input field
  onInputChange(): void {
    if (this.packageNameModel.length > 0) {
      this.filteredSuggestions = this.allSuggestions.filter(suggestion =>
        suggestion.toLowerCase().includes(this.packageNameModel.toLowerCase())
      );
      this.showSuggestions = this.filteredSuggestions.length > 0;
    } else {
      this.showSuggestions = false;
    }
  }

  // Updates the input field and hides the suggestions when a suggestion is selected
  selectSuggestion(suggestion: string): void {
    this.packageNameModel = suggestion;
    this.showSuggestions = false;
  }
}

3. Explanation of Logic

  • Text Input: The input field uses [(ngModel)] for two-way binding with packageNameModel.

  • Dropdown Display: The dropdown list is displayed conditionally based on whether suggestions are available (showSuggestions).

  • Filtering Suggestions: The onInputChange() method filters the list of suggestions based on the user's input, ignoring case.

  • Selecting a Suggestion: Clicking a suggestion updates the input value and hides the dropdown.


Enhancements

  • Dynamic Suggestions: Replace the allSuggestions array with an API call to fetch suggestions dynamically.

  • Keyboard Navigation: Add support for keyboard navigation (e.g., arrow keys) within the dropdown.

  • Styling: Customize the dropdown's appearance to match your application's design.


Conclusion

Using template-driven forms, we created a simple and intuitive interface for typing and selecting values. This functionality can be used in various scenarios, such as search bars, autocomplete fields, and more.

Feel free to extend this example based on your project requirements!

Last updated