Hone logo
Hone
Problems

Angular Autocomplete Component

This challenge asks you to build a reusable Angular component that provides an autocomplete functionality for an input field. Autocomplete is a common feature in modern web applications that helps users find what they're looking for faster by suggesting relevant options as they type.

Problem Description

You need to create an Angular component that takes a list of potential suggestions and displays them in a dropdown list below an input field. As the user types into the input field, the component should filter the suggestions based on the input text and display only the matching ones. When the user selects an option from the dropdown, the input field should be updated with the selected value, and the dropdown should be hidden.

Key Requirements:

  • Input Field: A standard HTML input element for user interaction.
  • Suggestion List: A dynamic list of possible suggestions. These can be passed into the component as an array of strings or objects. For this challenge, assume an array of strings.
  • Filtering: Suggestions should be filtered based on whether they start with (or contain, depending on desired behavior - let's aim for "starts with" for simplicity in this challenge) the text currently in the input field. The comparison should be case-insensitive.
  • Dropdown Display: Matching suggestions should be displayed in a dropdown list that appears below the input field when there are matching suggestions and the input field has focus.
  • Selection: Users should be able to select a suggestion from the dropdown by clicking on it. Upon selection, the input field should update with the chosen suggestion, and the dropdown should disappear.
  • Hiding Dropdown: The dropdown should also hide when the user clicks outside of the component (i.e., clicks anywhere else on the page).
  • Reusability: The component should be designed for reusability, meaning it should accept data and configuration via @Input() properties.
  • Output: The component should emit an event (@Output()) when a suggestion is selected, passing the selected value to the parent component.

Expected Behavior:

  1. User focuses on the input field.
  2. User starts typing.
  3. As the user types, a dropdown appears below the input field, showing suggestions that start with the typed text (case-insensitive).
  4. If no suggestions match, the dropdown should be empty or hidden.
  5. User clicks on a suggestion in the dropdown.
  6. The input field is populated with the selected suggestion.
  7. The dropdown disappears.
  8. If the user clicks anywhere outside the input and dropdown, the dropdown disappears.

Edge Cases to Consider:

  • Empty suggestion list.
  • No matching suggestions for the current input.
  • User typing and then deleting all text.
  • User tabbing through the component.
  • Handling component destruction gracefully.

Examples

Example 1: Basic Autocomplete

Input to Component (as @Input()):
suggestions: ['Apple', 'Apricot', 'Banana', 'Blueberry', 'Cherry', 'Cranberry']
User Input: "ap"

Expected Behavior:
The input field will show "ap".
A dropdown will appear below the input field, displaying:
- Apple
- Apricot

Example 2: Selection and Output

Input to Component (as @Input()):
suggestions: ['Apple', 'Apricot', 'Banana', 'Blueberry', 'Cherry', 'Cranberry']
User Input: "b"

Dropdown is visible with:
- Banana
- Blueberry

User clicks on "Banana".

Expected Behavior:
Input field updates to "Banana".
Dropdown disappears.
The component emits an event with the value "Banana" to its parent.

Example 3: No Matches

Input to Component (as @Input()):
suggestions: ['Apple', 'Apricot', 'Banana', 'Blueberry', 'Cherry', 'Cranberry']
User Input: "xyz"

Expected Behavior:
The input field will show "xyz".
The dropdown will either be hidden or displayed empty.

Constraints

  • The autocomplete suggestions will be provided as an array of strings.
  • The filtering logic should be case-insensitive and match suggestions that start with the input text.
  • The component should use Angular's reactive forms or template-driven forms for input management. For this challenge, template-driven forms are sufficient.
  • The component should be implemented using TypeScript.
  • Aim for a clean and maintainable component structure.

Notes

  • Consider how to manage the visibility of the dropdown list. A simple boolean flag bound to *ngIf or [hidden] can be effective.
  • Think about event handling for clicks within and outside the component.
  • You will need to define an @Output() property to signal when a suggestion has been selected.
  • Consider using HostListener to detect clicks outside the component to close the dropdown.
  • For simplicity, you can assume a basic styling approach for the dropdown. The focus is on the component's logic.
Loading editor...
typescript