Hone logo
Hone
Problems

Dynamic Form Generator in Angular

Building dynamic forms is a common requirement in modern web applications, allowing for flexible and adaptable user interfaces based on data or configuration. This challenge asks you to implement a component in Angular that renders a form dynamically based on a JSON schema. This is useful for scenarios where the form structure isn't known at compile time, such as configuration panels or data entry forms driven by external data sources.

Problem Description

You need to create an Angular component that takes a JSON schema as input and dynamically generates an HTML form based on that schema. The schema will define the form fields, their types (e.g., text, number, select, checkbox), labels, and validation rules. The component should render the form elements appropriately and provide basic validation based on the schema.

What needs to be achieved:

  • Create an Angular component that accepts a JSON schema as input.
  • Dynamically generate HTML form elements based on the schema.
  • Render appropriate input types based on the schema's type property (e.g., text, number, select, checkbox).
  • Display labels for each form field as defined in the schema.
  • Implement basic validation based on the schema (e.g., required, minLength, maxLength, pattern). Display validation errors inline.
  • Provide a mechanism to access the form data when the form is submitted.

Key Requirements:

  • The component must be reusable and adaptable to different schemas.
  • The generated form should be visually appealing and user-friendly.
  • Validation errors should be clearly displayed to the user.
  • The component should handle different input types gracefully.

Expected Behavior:

When the component receives a schema, it should render a corresponding HTML form. Each form field should have a label and an appropriate input element. If a field is marked as required, the component should display an error message if the field is left blank upon submission. Other validation rules (minLength, maxLength, pattern) should also be enforced and errors displayed. The component should provide a method to retrieve the form data as a JavaScript object.

Edge Cases to Consider:

  • Invalid Schema: Handle cases where the input schema is malformed or incomplete. Display an appropriate error message.
  • Unsupported Input Types: Gracefully handle input types not explicitly supported (e.g., display a generic text field with a warning).
  • Nested Schemas: Consider how to handle schemas that define nested forms or sections. (This is a bonus, not a core requirement).
  • Dynamic Options for Select: If a field type is 'select', the schema should include an 'options' array.
  • Checkbox and Radio Button Handling: Correctly render and handle checkbox and radio button inputs.

Examples

Example 1:

Input:
{
  "fields": [
    {
      "name": "firstName",
      "label": "First Name",
      "type": "text",
      "required": true
    },
    {
      "name": "lastName",
      "label": "Last Name",
      "type": "text",
      "minLength": 3
    },
    {
      "name": "email",
      "label": "Email",
      "type": "email",
      "required": true
    }
  ]
}
Output:
A form with three fields: First Name (text, required), Last Name (text, minLength 3), and Email (email, required).  Validation errors are displayed inline if required fields are missing or minLength is not met.
Explanation: The component iterates through the `fields` array in the schema and creates the corresponding HTML elements.  It applies the `required` and `minLength` validation rules.

Example 2:

Input:
{
  "fields": [
    {
      "name": "age",
      "label": "Age",
      "type": "number"
    },
    {
      "name": "subscribe",
      "label": "Subscribe to Newsletter",
      "type": "checkbox"
    },
    {
      "name": "country",
      "label": "Country",
      "type": "select",
      "options": ["USA", "Canada", "Mexico"]
    }
  ]
}
Output:
A form with three fields: Age (number), Subscribe to Newsletter (checkbox), and Country (select with options USA, Canada, Mexico).
Explanation: The component handles different input types (number, checkbox, select) and renders them accordingly.  For the select field, it uses the `options` array to populate the dropdown.

Constraints

  • Angular Version: Use Angular 14 or higher.
  • Reactive Forms: Use Angular's Reactive Forms module for form management.
  • Schema Validation: Basic schema validation is expected. Full schema validation (e.g., using JSON Schema validator libraries) is not required for this challenge.
  • Performance: The component should render efficiently, even with a large number of fields (up to 50).
  • Input Schema Size: The input schema should not exceed 1MB in size.

Notes

  • Consider using Angular's FormBuilder to simplify form creation.
  • Use Angular's template-driven or reactive forms approach. Reactive forms are preferred.
  • Think about how to handle different validation rules and display error messages effectively.
  • Focus on creating a reusable and maintainable component.
  • You can use any CSS framework you prefer for styling (e.g., Bootstrap, Material). However, the core functionality is the dynamic form generation and validation.
  • The submission mechanism (e.g., a button to trigger form submission) is not required for this challenge. The focus is on the form generation and validation. You only need to provide a method to access the form data.
Loading editor...
typescript