Skip to main content

Overview

The dynamic form generation system is the cornerstone of ITV Gestion Concesionario. It automatically creates customized vehicle inspection forms based on the number of vehicles specified by the user, streamlining the data collection process for dealerships managing multiple vehicles.
The system can generate forms for 1 to 50 vehicles in a single session, with built-in validation to ensure data integrity.

How It Works

The form generation process follows a three-step workflow:
1

User Input Validation

The system validates customer information (name, surname, company) and the number of vehicles before proceeding.
2

Form Generation

Individual forms are dynamically created for each vehicle with motorization and ITV status options.
3

Interactive Display

Forms are rendered in a responsive grid layout with smooth animations and loading indicators.

Core Functions

Main Entry Point: enviar()

The enviar() function (script.js:8) serves as the main entry point for form generation:
function enviar() {
    // Validar campos obligatorios
    const nombre = document.getElementById("nombre").value.trim();
    const apellidos = document.getElementById("apellidos").value.trim();
    const razonSocial = document.getElementById("razonSocial").value.trim();
    const nAutosInput = document.getElementById("nAutos").value.trim();

    // Validaciones básicas
    if (!nombre || !apellidos || !razonSocial || !nAutosInput) {
        mostrarError("Por favor, complete todos los campos obligatorios.");
        return;
    }

    numeroAutos = parseInt(nAutosInput);
    if (isNaN(numeroAutos) || numeroAutos <= 0 || numeroAutos > 50) {
        mostrarError("Por favor, ingrese un número válido de vehículos (1-50).");
        return;
    }

    // Limpiar formularios previos
    document.getElementById("formularios").innerHTML = "";
    vehiculosData = [];

    // Generar formularios para cada vehículo
    generarFormulariosVehiculos();

    // Agregar botón de calcular
    agregarBotonCalcular();

    // Mostrar animación de carga
    mostrarAnimacionCarga();
}
The function performs comprehensive validation before generating forms, including:
  • Required field validation
  • Numeric range validation (1-50 vehicles)
  • Data type validation

Form Generator: generarFormulariosVehiculos()

This function (script.js:44) iterates through the vehicle count and generates individual forms:
script.js:44-51
function generarFormulariosVehiculos() {
    const contenedor = document.getElementById("formularios");

    for (let i = 1; i <= numeroAutos; i++) {
        const vehiculoHTML = crearFormularioVehiculo(i);
        contenedor.innerHTML += vehiculoHTML;
    }
}

HTML Builder: crearFormularioVehiculo()

The crearFormularioVehiculo() function (script.js:58) creates the HTML structure for each vehicle form:
script.js:58-102
function crearFormularioVehiculo(numeroVehiculo) {
    return `
        <div class="bloque" data-vehiculo="${numeroVehiculo}">
            <h3>🚙 Vehículo Nº ${numeroVehiculo}</h3>

            <p>🔧 Motorización:</p>
            <label>
                <input type="radio" id="radio1${numeroVehiculo}" name="motorizacion${numeroVehiculo}" value="Diesel" required>
                🛢️ Diesel
            </label>
            <label>
                <input type="radio" id="radio2${numeroVehiculo}" name="motorizacion${numeroVehiculo}" value="Gasolina">
                ⛽ Gasolina
            </label>
            <label>
                <input type="radio" id="radio3${numeroVehiculo}" name="motorizacion${numeroVehiculo}" value="Hibrido">
                🔋 Híbrido
            </label>
            <label>
                <input type="radio" id="radio4${numeroVehiculo}" name="motorizacion${numeroVehiculo}" value="Electrico">
                ⚡ Eléctrico
            </label>
            <div class="aprobados">
                <p>📋 Estado de la ITV:</p>
                <label>
                    <input type="radio" id="radio5${numeroVehiculo}" value="Aprobo" name="aprobados${numeroVehiculo}">
                    ✅ Aprobado
                </label>
                <label>
                    <input type="radio" id="radio6${numeroVehiculo}" value="NoAprobo" name="aprobados${numeroVehiculo}">
                    ❌ No Aprobado
                </label>
            </div>
            <label for="observaciones${numeroVehiculo}">📝 Observaciones del vehículo:</label>
            <textarea
                id="observaciones${numeroVehiculo}"
                name="observaciones${numeroVehiculo}"
                class="caja-texto"
                placeholder="Ingrese observaciones sobre el estado del vehículo..."
                maxlength="250"
                rows="4">
            </textarea>
        </div>
    `;
}

Form Structure

Each dynamically generated vehicle form includes:

Motorization Options

  • 🛢️ Diesel
  • ⛽ Gasoline
  • 🔋 Hybrid
  • ⚡ Electric

ITV Status

  • ✅ Approved
  • ❌ Not Approved

Observations

Free-text field with 250-character limit for additional vehicle notes

Unique Identifiers

Each form element uses unique IDs based on vehicle number for proper data isolation

User Experience Features

Loading Animation

The mostrarAnimacionCarga() function (script.js:469) provides visual feedback during form generation:
script.js:469-482
function mostrarAnimacionCarga() {
    const btnEnviar = document.getElementById("enviar");
    const textoOriginal = btnEnviar.innerHTML;

    btnEnviar.classList.add("loading");
    btnEnviar.innerHTML = "⏳ Generando formularios...";
    btnEnviar.disabled = true;

    setTimeout(() => {
        btnEnviar.classList.remove("loading");
        btnEnviar.innerHTML = textoOriginal;
        btnEnviar.disabled = false;
    }, 1000);
}

Real-Time Validation

The system includes event listeners (script.js:487) that validate input as users type:
script.js:489-499
const nAutosInput = document.getElementById("nAutos");
nAutosInput.addEventListener("input", function() {
    const valor = parseInt(this.value);
    if (valor > 50) {
        this.value = 50;
        mostrarError("El número máximo de vehículos es 50.");
    }
    if (valor < 0) {
        this.value = "";
    }
});

Responsive Layout

Forms are displayed in a responsive grid layout (styles.css:173-178):
styles.css:173-178
.formulario {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
    gap: 2rem;
    margin-top: 2rem;
}
The grid automatically adjusts to screen size, displaying multiple columns on desktop and stacking on mobile devices.

Best Practices

  • Forms are generated in a single batch to minimize DOM reflows
  • Template strings are used for efficient HTML construction
  • Previous forms are cleared before generating new ones to prevent memory leaks
  • All radio buttons include proper name attributes for grouping
  • Labels are semantically connected to form inputs
  • Required fields are marked appropriately
  • Focus states are clearly visible (styles.css:482-491)
  • Each vehicle form uses unique IDs to prevent data collision
  • Global vehiculosData array maintains form state
  • Validation occurs at multiple stages (input, submission)

Error Handling

The system uses a custom error notification function (script.js:381):
script.js:381-464
function mostrarError(mensaje) {
    // Remover alertas anteriores
    const alertaAnterior = document.querySelector(".alert-error");
    if (alertaAnterior) {
        alertaAnterior.remove();
    }

    // Crear nueva alerta
    const alerta = document.createElement("div");
    alerta.className = "alert-error";
    alerta.innerHTML = `
        <div class="alert-content">
            <span class="alert-icon">⚠️</span>
            <span class="alert-message">${mensaje}</span>
            <button class="alert-close" onclick="this.parentElement.parentElement.remove()">×</button>
        </div>
    `;
    // ... (styles and auto-removal logic)
}
Error messages automatically disappear after 5 seconds but can be manually dismissed by the user.

Next Steps

Data Validation

Learn how form data is validated before processing

Cost Calculation

Understand the automatic pricing system

Build docs developers (and LLMs) love