Dynamic Form Field Generation with Angular FormArray
This challenge focuses on building a dynamic form in Angular where the number of form fields can be controlled by the user. You'll learn how to leverage Angular's FormArray to manage a collection of form controls, enabling flexible and interactive user input.
Problem Description
You are tasked with creating an Angular component that allows users to dynamically add and remove "item" entries. Each "item" should have at least two input fields: a "name" and a "quantity". The component should allow the user to add as many items as they wish and remove any existing item. The data from these dynamically generated fields needs to be accessible as a structured array.
Key Requirements:
- Dynamic Addition: Users must be able to click a button to add a new "item" entry.
- Dynamic Removal: Users must be able to click a button next to each "item" to remove it.
- Item Structure: Each "item" should consist of at least two input fields: "name" (string) and "quantity" (number).
- FormArray Implementation: Use Angular's
FormArrayto manage the collection of "item" form groups. - Data Retrieval: Provide a way to access the collected data from the
FormArrayas a plain JavaScript array of objects (e.g.,[{ name: 'Apple', quantity: 5 }, { name: 'Banana', quantity: 3 }]).
Expected Behavior:
- When the component loads, it should display at least one initial "item" entry.
- Clicking "Add Item" should append a new set of "name" and "quantity" input fields to the form.
- Clicking the "Remove" button next to an "item" should delete that specific "item" entry from the form.
- The "name" input should accept string values.
- The "quantity" input should accept numeric values.
- A button or mechanism should be available to display or submit the collected form data.
Edge Cases to Consider:
- Removing the last item from the form.
- Handling empty input fields.
- Ensuring the "quantity" field only accepts valid numbers.
Examples
Example 1:
Initial State (Component Loaded):
- UI: Displays one "Item 1" with empty "Name" and "Quantity" fields, and an "Add Item" button.
- Form Structure (Conceptual):
{ items: [ { name: '', quantity: '' } ] }
After Adding One Item:
- UI: Displays "Item 1" and "Item 2", each with empty input fields, and an "Add Item" button. Each item also has a "Remove" button.
- Form Structure (Conceptual):
{ items: [ { name: '', quantity: '' }, { name: '', quantity: '' } ] }
After Filling and Removing an Item:
- UI: User fills "Item 1" with
Name: 'Apple',Quantity: 5. User clicks "Add Item". User fills "Item 2" withName: 'Banana',Quantity: 3. User clicks the "Remove" button next to "Item 1". The UI now shows only "Item 2" (labeled as "Item 1" after removal). - Form Structure (Conceptual):
{ items: [ { name: 'Banana', quantity: 3 } ] } - Retrieved Data:
[ { "name": "Banana", "quantity": 3 } ]
Example 2:
Scenario: Removing the Last Item
- UI: User has two items. User clicks "Remove" on the second item, leaving only one. User then clicks "Remove" on the now-only item.
- Expected Behavior: The form should not be entirely emptied. It should ideally reset to a single empty item or prevent removal of the last item (depending on desired UX). For this challenge, allow removal, but consider the reset state. If all items are removed, a single new item should ideally be added automatically or the UI should clearly indicate no items are present.
Constraints
- Angular version: 14+
- TypeScript version: 4.0+
- Use
@angular/formsmodule for form handling. - The component should be a standalone component or part of a module.
- The solution should be implemented within a single Angular component (
.ts,.html,.cssif necessary).
Notes
- Consider using
FormBuilderto simplify the creation of your form controls and groups. - Think about how you will associate a "Remove" button with each individual item in the
FormArray. - When retrieving the data, ensure that the
quantityis a number, not a string, if it was entered as such. You might need to do some type casting or validation. - The "name" of the item in the UI (e.g., "Item 1", "Item 2") can be generated programmatically based on its index in the
FormArray.