Blog>
Snippets

Dynamic Form Generation from JSON

Design a component that takes a JSON schema and generates a corresponding form with inputs, selects, radio buttons, and checkboxes, complete with validation rules.
function createElementFromSchema(schemaElement) {
  const { type, id, label, options, validators } = schemaElement;
  const elementWrapper = document.createElement('div');
  elementWrapper.className = 'form-element';
  const labelElement = document.createElement('label');
  labelElement.setAttribute('for', id);
  labelElement.textContent = label;
  
  let inputElement;
  switch (type) {
    case 'text':
    case 'number':
    case 'email':
      inputElement = document.createElement('input');
      inputElement.type = type;
      inputElement.id = id;
      validators && applyValidators(inputElement, validators);
      break;
    case 'select':
      inputElement = document.createElement('select');
      inputElement.id = id;
      options.forEach(optionValue => {
        const optionElement = document.createElement('option');
        optionElement.value = optionValue;
        optionElement.textContent = optionValue;
        inputElement.appendChild(optionElement);
      });
      break;
    default:
      throw new Error('Unsupported input type');
  }
  
  elementWrapper.appendChild(labelElement);
  elementWrapper.appendChild(inputElement);
  return elementWrapper;
}
This code defines a function `createElementFromSchema` that takes a schema element object and generates the corresponding HTML form element. It supports input, select, and applies validators if they are defined.
function applyValidators(inputElement, validators) {
  validators.forEach(validator => {
    switch (validator.type) {
      case 'required':
        inputElement.required = true;
        break;
      case 'minLength':
        inputElement.minLength = validator.value;
        break;
      case 'maxLength':
        inputElement.maxLength = validator.value;
        break;
      default:
        console.warn(`Unsupported validator type: ${validator.type}`);
    }
  });
}
This code provides the `applyValidators` function to attach various validation rules to form input elements based on the validators specified in the schema.
function generateFormFromJSON(schema) {
  const form = document.createElement('form');
  schema.forEach(schemaElement => {
    const formElement = createElementFromSchema(schemaElement);
    form.appendChild(formElement);
  });
  const submitButton = document.createElement('button');
  submitButton.type = 'submit';
  submitButton.textContent = 'Submit';
  form.appendChild(submitButton);
  
  form.addEventListener('submit', function(event) {
    event.preventDefault();
    const formData = new FormData(form);
    for (let [key, value] of formData.entries()) {
      console.log(`${key}: ${value}`);
    }
  });
  
  return form;
}
This code defines the `generateFormFromJSON` function, which creates a complete form element from the provided JSON schema, appends input elements, and handles the form submission event, preventing the default action and logging the form data.
const jsonSchema = [
  {
    type: 'text',
    id: 'firstName',
    label: 'First Name',
    validators: [{ type: 'required' }]
  },
  {
    type: 'email',
    id: 'email',
    label: 'Email',
    validators: [{type: 'required'}]
  },
  // Add more schema elements as needed
];

const formContainer = document.getElementById('form-container');
const generatedForm = generateFormFromJSON(jsonSchema);
formContainer.appendChild(generatedForm);
This code contains a sample JSON schema for the form creation and appends the generated form to the DOM. The `jsonSchema` variable should be modified to suit the actual schema requirements.