Skip to main content

Overview

The results display system transforms validated vehicle inspection data into a professional, visually appealing presentation. It includes customer information, itemized cost breakdowns, ITV status indicators, and vehicle observations, all presented in a responsive, card-based layout.
Results are displayed in a responsive grid layout with smooth animations and professional styling, optimized for both desktop and mobile viewing.

Display Architecture

The results section is structured into multiple information cards:

Customer Information

Name, surname, company, and vehicle count

Total Cost

Itemized breakdown and grand total

ITV Status

Pass/fail status for each vehicle

Observations

Detailed notes for each vehicle (full-width)

HTML Structure

The results section container (index.html:68-105):
<section id="muestra" class="results-section">
    <!-- Tarjeta con información del cliente -->
    <div class="info-card">
        <div class="informacion" id="informacion">
            <h3>👤 Información del Cliente</h3>
        </div>
    </div>

    <!-- Tarjeta con el total a pagar -->
    <div class="info-card">
        <div class="total">
            <h3>💰 Total a Pagar</h3>
            <div class="total-amount">
                <span id="total">€0</span>
            </div>
        </div>
    </div>

    <!-- Tarjeta con el estado de la ITV -->
    <div class="info-card">
        <div id="resultados" class="resultados">
            <h3>✅ Estado ITV</h3>
            <div class="status-content">
                <span id="raprobado"></span>
            </div>
        </div>
    </div>

    <!-- Tarjeta con observaciones (ancho completo) -->
    <div class="info-card full-width">
        <div class="observacion">
            <h3>📝 Observaciones</h3>
            <div class="observations-content">
                <span id="robservaciones"></span>
            </div>
        </div>
    </div>
</section>
The results section is initially hidden and revealed with animations after calculation completes.

Display Functions

Main Orchestration: calcular()

The calcular() function (script.js:119) coordinates all display operations:
1

Customer Data Display

mostrarInformacionCliente() renders customer details
2

ITV Status Display

mostrarEstadosITV() shows pass/fail status for each vehicle
3

Observations Display

mostrarObservaciones() displays vehicle-specific notes
4

Cost Display

calcularYMostrarTotal() shows itemized costs and total

Customer Information Display

The mostrarInformacionCliente() function (script.js:210-218) renders customer data:
script.js:210-218
function mostrarInformacionCliente(datos) {
    document.getElementById("informacion").innerHTML = `
        <h3>👤 Información del Cliente</h3>
        <div>Nombre: <span>${datos.nombre}</span></div>
        <div>Apellidos: <span>${datos.apellidos}</span></div>
        <div>Razón Social: <span>${datos.razonSocial}</span></div>
        <div>Nº de Vehículos: <span>${datos.nAutos}</span></div>
    `;
}
Customer data comes from obtenerDatosCliente() (script.js:154-161):
script.js:154-161
function obtenerDatosCliente() {
    return {
        nombre: document.getElementById("nombre").value.trim(),
        apellidos: document.getElementById("apellidos").value.trim(),
        razonSocial: document.getElementById("razonSocial").value.trim(),
        nAutos: numeroAutos
    };
}

ITV Status Display

The mostrarEstadosITV() function (script.js:223-239) displays vehicle inspection results:
function mostrarEstadosITV() {
    let estadosHTML = "";

    vehiculosData.forEach(vehiculo => {
        const emoji = vehiculo.estadoITV === "Aprobo" ? "✅" : "❌";
        const estado = vehiculo.estadoITV === "Aprobo" ? "Aprobado" : "No Aprobado";
        const clase = vehiculo.estadoITV === "Aprobo" ? "aprobado" : "no-aprobado";

        estadosHTML += `
            <div class="estado-vehiculo ${clase}">
                ${emoji} Vehículo Nº ${vehiculo.numero}: ${estado}
            </div>
        `;
    });

    document.getElementById("raprobado").innerHTML = estadosHTML;
}

Status Styling

Vehicle status items have conditional styling (styles.css:638-656):
styles.css:638-645
.estado-vehiculo {
    padding: 0.75rem;
    margin: 0.5rem 0;
    border-radius: 0.5rem;
    font-weight: 600;
    background: rgba(37, 99, 235, 0.05);
    border-left: 4px solid #2563eb;
}
Color Coding:
  • ✅ Green for approved vehicles
  • ❌ Red for failed vehicles
  • Visual indicators for at-a-glance status recognition

Observations Display

The mostrarObservaciones() function (script.js:244-263) renders vehicle notes:
script.js:244-263
function mostrarObservaciones() {
    let observacionesHTML = "";

    vehiculosData.forEach(vehiculo => {
        if (vehiculo.observaciones) {
            observacionesHTML += `
                <div class="observacion-vehiculo">
                    <strong>🚗 Vehículo Nº ${vehiculo.numero}:</strong><br>
                    <div class="caja-texto">${vehiculo.observaciones}</div>
                </div>
            `;
        }
    });

    if (observacionesHTML === "") {
        observacionesHTML = "<em>Sin observaciones registradas</em>";
    }

    document.getElementById("robservaciones").innerHTML = observacionesHTML;
}
Smart Display Logic:
  • Only vehicles with observations are shown
  • Empty state message displayed if no observations exist
  • Each observation is clearly labeled with vehicle number

Cost Display

See the Cost Calculation page for detailed information about the calcularYMostrarTotal() function.

Animation System

Hide Form, Show Results

The ocultarCaja() function (script.js:339-355) handles the transition:
function ocultarCaja() {
    const formularios = document.getElementById("formularios");
    const formSection = document.querySelector(".form-section");
    const resultados = document.getElementById("muestra");

    // Animación de salida para formularios dinámicos y sección principal
    formularios.style.opacity = "0";
    formularios.style.transform = "translateY(-20px)";
    formSection.style.opacity = "0";
    formSection.style.transform = "translateY(-20px)";

    setTimeout(() => {
        formularios.style.display = "none";
        formSection.style.display = "none";
        mostrarResultados();
    }, 300);
}

Show Results Animation

The mostrarResultados() function (script.js:360-375) animates results in:
script.js:360-375
function mostrarResultados() {
    const resultados = document.getElementById("muestra");
    resultados.classList.add("show");

    // Animación de entrada
    setTimeout(() => {
        resultados.style.opacity = "1";
        resultados.style.transform = "translateY(0)";
    }, 100);

    // Scroll suave hacia los resultados
    resultados.scrollIntoView({
        behavior: "smooth",
        block: "start"
    });
}
Animation Sequence:
  1. Forms fade out and slide up (300ms)
  2. Forms are hidden (display: none)
  3. Results section is revealed
  4. Results fade in and slide down (smooth)
  5. Page scrolls to results section

Action Buttons

The agregarBotonesAccion() function (script.js:578) adds utility buttons to results:
script.js:578-605
function agregarBotonesAccion() {
    const muestra = document.getElementById("muestra");

    if (!document.getElementById("botones-accion")) {
        const botonesHTML = `
            <div id="botones-accion" class="info-card full-width">
                <div style="padding: 1.5rem; text-align: center;">
                    <h3> Acciones Disponibles</h3>
                    <div style="display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; margin-top: 1rem;">
                        <button onclick="imprimirResultados()" class="btn-secondary">
                            🖨️ Imprimir
                        </button>
                        <button onclick="exportarResultados()" class="btn-secondary">
                            📥 Exportar JSON
                        </button>
                        <button onclick="reiniciarFormulario()" class="btn-secondary">
                            🔄 Nuevo Formulario
                        </button>
                    </div>
                </div>
            </div>
        `;
        muestra.innerHTML += botonesHTML;
        agregarEstilosBotonSecundario();
    }
}

Available Actions

Print

🖨️ imprimirResultados()Formats results for printing (script.js:551-573)

Export

📥 exportarResultados()Exports data as JSON file (script.js:529-548)

Reset

🔄 reiniciarFormulario()Reloads page for new inspection (script.js:522-526)

Export Functionality

The export function creates a JSON file with complete inspection data:
script.js:529-548
function exportarResultados() {
    const datosExportacion = {
        cliente: obtenerDatosCliente(),
        vehiculos: vehiculosData,
        fecha: new Date().toLocaleDateString('es-ES'),
        hora: new Date().toLocaleTimeString('es-ES')
    };

    const jsonStr = JSON.stringify(datosExportacion, null, 2);
    const blob = new Blob([jsonStr], { type: 'application/json' });
    const url = URL.createObjectURL(blob);

    const a = document.createElement('a');
    a.href = url;
    a.download = `ITV_${datosExportacion.cliente.apellidos}_${Date.now()}.json`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
}
{
  "cliente": {
    "nombre": "Juan",
    "apellidos": "García",
    "razonSocial": "AutoFleet SL",
    "nAutos": 3
  },
  "vehiculos": [
    {
      "numero": 1,
      "motorizacion": "Diesel",
      "estadoITV": "Aprobo",
      "observaciones": "Vehículo en perfecto estado"
    },
    // ... more vehicles
  ],
  "fecha": "07/03/2026",
  "hora": "14:35:22"
}
The print function (script.js:551-573) formats results for printing:
script.js:551-573
function imprimirResultados() {
    const contenidoOriginal = document.body.innerHTML;
    const resultados = document.getElementById("muestra").outerHTML;
    const informacionCliente = document.getElementById("informacion").outerHTML;

    document.body.innerHTML = `
        <div style="padding: 20px; font-family: Arial, sans-serif;">
            <h1 style="text-align: center; color: #2563eb;">Concesionario de Coches - Resultados ITV</h1>
            <hr style="margin: 20px 0;">
            ${informacionCliente}
            ${resultados}
            <div style="margin-top: 30px; text-align: center; font-size: 12px; color: #666;">
                Impreso el ${new Date().toLocaleDateString('es-ES')} a las ${new Date().toLocaleTimeString('es-ES')}
            </div>
        </div>
    `;

    window.print();
    document.body.innerHTML = contenidoOriginal;
    inicializarEventos();
}
Print Features:
  • Clean, print-optimized layout
  • Includes timestamp footer
  • Restores page after printing
  • Re-initializes events after restoration

Responsive Design

Results section adapts to different screen sizes (styles.css:290-304, 448-456):
styles.css:290-304
.results-section {
    display: none;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 1.5rem;
    margin-top: 2rem;
    padding: 2rem;
    background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
    border-radius: 0.75rem;
    border: 1px solid #e5e7eb;
}

.results-section.show {
    display: grid;
}

Card Styling

Information cards have consistent, elevated styling (styles.css:306-322):
styles.css:306-322
.info-card {
    background: #ffffff;
    border-radius: 0.75rem;
    box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
    border: 1px solid #e5e7eb;
    overflow: hidden;
    transition: all 0.3s ease;
}

.info-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
}

.info-card.full-width {
    grid-column: 1 / -1;
}

Visual Polish

  • Subtle shadows for depth
  • Rounded corners (0.75rem)
  • Smooth hover transitions
  • Gradient backgrounds in headers

Interaction

  • Hover lift effect (-2px translateY)
  • Enhanced shadows on hover
  • 300ms transition timing
  • Smooth, professional animations

Initialization

Results section is prepared on page load (script.js:706-715):
script.js:706-715
document.addEventListener("DOMContentLoaded", function() {
    inicializarEventos();

    // Ocultar resultados inicialmente
    const muestra = document.getElementById("muestra");
    muestra.style.opacity = "0";
    muestra.style.transform = "translateY(20px)";
    muestra.style.transition = "all 0.3s ease";
});
The results section must be hidden on initial page load to enable the slide-in animation when results are calculated.

Next Steps

Dynamic Forms

Learn how forms are generated before results

Data Validation

Understand validation that ensures data quality

Build docs developers (and LLMs) love