Dynamic Form Builder in Angular
This challenge asks you to build a basic dynamic form builder in Angular. A dynamic form builder allows you to create forms based on a configuration object, rather than hardcoding the form structure. This is useful for scenarios where the form structure is determined at runtime, such as user-defined forms or configuration-driven applications.
Problem Description
You need to create an Angular component that renders a form dynamically based on a provided configuration. The configuration will be an array of objects, where each object represents a form control. Each control object will have the following properties:
type: A string representing the type of form control (e.g., "text", "number", "email", "select", "checkbox").label: A string representing the label for the form control.name: A string representing the name of the form control (used for data binding).required: A boolean indicating whether the control is required.options: (Optional) An array of objects for "select" controls, where each object has avalueand alabelproperty.value: (Optional) A default value for the control.
The component should:
- Accept the form configuration as an input.
- Dynamically generate form controls based on the configuration.
- Use Angular's reactive forms approach.
- Display appropriate labels and validation based on the configuration.
- Provide a submit button that logs the form values to the console.
Expected Behavior:
- The component should render a form with the controls specified in the configuration.
- Each control should have a label and a name.
- Required controls should be marked as such.
- "Select" controls should display the options provided in the
optionsarray. - The form should be validated before submission.
- Upon submission, the form values should be logged to the console.
Edge Cases to Consider:
- Invalid
typevalues in the configuration. Handle gracefully (e.g., display an error message or skip the control). - Missing
labelornameproperties in the configuration. - Empty
optionsarray for "select" controls. - Controls with no default
value.
Examples
Example 1:
Input:
[
{
"type": "text",
"label": "Name",
"name": "name",
"required": true
},
{
"type": "email",
"label": "Email",
"name": "email",
"required": true
},
{
"type": "select",
"label": "Country",
"name": "country",
"options": [
{ "value": "USA", "label": "United States" },
{ "value": "Canada", "label": "Canada" },
{ "value": "UK", "label": "United Kingdom" }
]
}
]
Output:
A form with three fields: Name (text, required), Email (email, required), and Country (select with USA, Canada, UK options). Submission logs: { name: "...", email: "...", country: "..." }
Explanation: The component iterates through the configuration array and creates the corresponding form controls. Validation ensures required fields are filled.
Example 2:
Input:
[
{
"type": "number",
"label": "Age",
"name": "age"
},
{
"type": "checkbox",
"label": "Agree to Terms",
"name": "terms"
}
]
Output:
A form with two fields: Age (number) and Agree to Terms (checkbox). Submission logs: { age: "...", terms: true/false }
Explanation: Demonstrates handling of number and checkbox input types.
Example 3: (Edge Case)
Input:
[
{
"type": "invalidType",
"label": "Invalid Field",
"name": "invalidField"
}
]
Output:
A form with no "invalidType" field. Potentially an error message indicating the invalid type. Submission logs: {}
Explanation: Handles an invalid control type gracefully, preventing errors and potentially informing the user.
Constraints
- The solution must be implemented in Angular using TypeScript.
- The solution must use Angular's reactive forms.
- The component should be reusable and accept the configuration as an input.
- The form should be validated before submission.
- The solution should be well-structured and maintainable.
- The component should handle at least the following control types: "text", "number", "email", "select", "checkbox".
- The solution should be able to handle a configuration with up to 20 form controls.
Notes
- Consider using Angular's
FormBuilderandFormControlclasses. - You can use Angular's built-in validators or create custom validators.
- Think about how to handle different control types and their specific properties.
- Focus on creating a flexible and reusable component that can handle various form configurations.
- Error handling and graceful degradation are important considerations. Don't crash if the configuration is malformed.
- Consider using a template-driven approach for the HTML structure, but manage the form logic reactively.