Hone logo
Hone
Problems

Custom Date Range Picker Form Control in Angular

This challenge asks you to build a reusable Angular form control that allows users to select a date range. Creating custom form controls is a powerful technique for encapsulating complex UI logic and providing a consistent user experience across your application. This exercise will solidify your understanding of Angular's Reactive Forms and how to extend its functionality.

Problem Description

You need to create a custom Angular form control component called DateRangePicker. This component should:

  1. Display a date range selection interface: The interface should allow the user to select a start date and an end date. You can use any date picker library you prefer (e.g., ngx-bootstrap, material datepicker, or even a simple custom implementation). For simplicity, you can use plain HTML <input type="date"> elements for date selection if you don't want to introduce external dependencies.
  2. Integrate with Angular's Reactive Forms: The component should be a valid Angular form control, meaning it can be used within an AbstractControl and its value can be accessed and modified through the form.
  3. Emit a value: When the user selects a date range, the component should emit an object containing the start and end dates as strings in YYYY-MM-DD format. The emitted value should be of type { start: string; end: string }.
  4. Handle invalid dates: If the user selects an end date before the start date, the control should be marked as invalid. The component should emit a NgModelControl's valueChanges observable.
  5. Provide a writeValue method: Implement the writeValue method from ControlValueAccessor to allow the form to set the date range programmatically.
  6. Provide a registerOnChange method: Implement the registerOnChange method from ControlValueAccessor to allow the form to listen for changes to the date range.

Expected Behavior:

  • When the component is initialized, it should be in a clean state (no dates selected).
  • When the user selects a date range, the component should emit the { start: string; end: string } object.
  • If the end date is before the start date, the component should display an error message (e.g., "End date must be after start date") and be marked as invalid.
  • When the form updates the date range programmatically, the component's UI should reflect the new values.

Examples

Example 1:

Input: User selects start date: 2023-10-26, end date: 2023-10-28
Output: { start: "2023-10-26", end: "2023-10-28" } emitted.  Control is valid.
Explanation: The user selected a valid date range. The component emits the date range object.

Example 2:

Input: User selects start date: 2023-10-28, end date: 2023-10-26
Output: Control is invalid. An error message "End date must be after start date" is displayed. No value is emitted.
Explanation: The user selected an invalid date range (end date before start date). The component marks the control as invalid and displays an error.

Example 3:

Input: Form sets the date range programmatically to { start: "2023-10-27", end: "2023-10-29" }
Output: The date range pickers in the component are updated to display 2023-10-27 and 2023-10-29 respectively.
Explanation: The form programmatically sets the date range, and the component updates its UI accordingly.

Constraints

  • The component should be reusable and configurable.
  • The date format should be consistently YYYY-MM-DD.
  • The component should be compatible with Angular's Reactive Forms.
  • The component should handle edge cases such as empty date selections gracefully (consider them invalid).
  • The component should not introduce excessive external dependencies (using built-in HTML elements is acceptable).

Notes

  • You'll need to implement the ControlValueAccessor interface, which requires implementing writeValue, registerOnChange, and validate.
  • Consider using Angular's EventEmitter to emit the date range value.
  • Think about how to handle the component's state (start date, end date, validity) effectively.
  • Focus on creating a clean, well-structured, and testable component.
  • You can use a simple HTML structure for the date pickers initially. The focus is on the form control integration, not the date picker UI itself.
  • Error handling and validation are crucial for a robust form control.
Loading editor...
typescript