Saltar al contenido principal

Ejercicio práctico 20: Formularios con Campos de Fecha y Número

Descubre cómo crear formularios HTML que incluyan campos de fecha <input type="date"> y número <input type="number">. Este ejercicio práctico te enseña a implementar controles de entrada modernos, útiles y accesibles para mejorar la experiencia del usuario en formularios web.

Actividad

Crea un formulario HTML que incluya campos de fecha <input type="date"> y número <input type="number">. Añade también un botón para enviar el formulario

Solución interactiva

Logo DivZone de ad link
Plataforma IAConvierte el código en clientes.Pruébalo gratis

Solución con el código HTML completo

HTML
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<title>Formulario con Fecha y Número</title>
</head>
<body>
<h2>Formulario con Fecha y Número</h2>
<form>
<label for="nombre">Nombre:</label>
<input type="text" id="nombre" name="nombre" />
<br />
<label for="fecha-nacimiento">Fecha de Nacimiento:</label>
<input type="date" id="fecha-nacimiento" name="fecha-nacimiento" />
<br />
<label for="edad">Edad:</label>
<input type="number" id="edad" name="edad" min="1" max="120" />
<br />
<label for="email">Correo Electrónico:</label>
<input type="email" id="email" name="email" />
<br />
<button type="submit">Enviar</button>
</form>
</body>
</html>

Variantes del mismo ejercicio

Variante 1: Todos los tipos de fecha y hora

HTML5 ofrece varios tipos de input para fechas y horas, cada uno con un propósito específico. Este ejemplo muestra todos en un mismo formulario.

HTML
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<title>Tipos de Fecha y Hora</title>
<style>
form {
max-width: 500px;
}
label {
display: block;
margin-top: 16px;
font-weight: bold;
color: #333;
}
input {
width: 100%;
padding: 10px;
margin-top: 4px;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 14px;
}
.ayuda {
font-size: 12px;
color: #888;
margin-top: 2px;
}
</style>
</head>
<body>
<h1>Tipos de Input para Fecha y Hora</h1>

<form>
<label for="fecha">📅 date — Fecha (día/mes/año):</label>
<input type="date" id="fecha" name="fecha" />
<p class="ayuda">Ej: 10/06/2026. Ideal para fechas de nacimiento.</p>

<label for="hora">⏰ time — Hora (horas:minutos):</label>
<input type="time" id="hora" name="hora" value="14:30" />
<p class="ayuda">Ej: 14:30. Útil para horarios de turnos o reservas.</p>

<label for="fecha-hora">📆 datetime-local — Fecha y hora juntas:</label>
<input type="datetime-local" id="fecha-hora" name="fecha-hora" />
<p class="ayuda">Ej: 10/06/2026 14:30. Para eventos con fecha y horario preciso.</p>

<label for="mes">🗓️ month — Mes y año:</label>
<input type="month" id="mes" name="mes" />
<p class="ayuda">Ej: Junio 2026. Para seleccionar vencimientos de tarjeta.</p>

<label for="semana">📊 week — Semana del año:</label>
<input type="week" id="semana" name="semana" />
<p class="ayuda">Ej: Semana 24, 2026. Útil en planillas y reportes semanales.</p>

<button type="submit" style="margin-top: 24px; padding: 12px 28px; background: #007bff; color: white; border: none; border-radius: 8px; cursor: pointer; font-size: 16px;">
Enviar
</button>
</form>
</body>
</html>

Compatibilidad: date y time funcionan en todos los navegadores modernos. datetime-local, month y week tienen soporte ligeramente menor en Safari. Siempre probá en múltiples navegadores.

Variante 2: Inputs numéricos avanzados (range, tel, color)

Además de type="number", HTML ofrece otros tipos de entrada para datos numéricos o especializados.

HTML
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<title>Inputs Numéricos</title>
<style>
form {
max-width: 500px;
}
label {
display: block;
margin-top: 16px;
font-weight: bold;
}
input {
padding: 8px 12px;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 14px;
margin-top: 4px;
}
input[type="range"] {
width: 100%;
padding: 0;
}
.rango-valores {
display: flex;
justify-content: space-between;
font-size: 12px;
color: #888;
margin-top: 2px;
}
.precio-actual {
font-size: 20px;
color: #28a745;
font-weight: bold;
margin-left: 12px;
}
</style>
</head>
<body>
<h1>Tipos de Input Numéricos y Especializados</h1>

<form>
<label for="edad">🔢 number — Edad:</label>
<input type="number" id="edad" name="edad" min="1" max="120" value="25" />

<label for="precio">
📊 range — Precio máximo:
<span class="precio-actual" id="precio-valor">$500</span>
</label>
<input
type="range"
id="precio"
name="precio"
min="0"
max="1000"
step="10"
value="500"
oninput="document.getElementById('precio-valor').textContent = '$' + this.value"
/>
<div class="rango-valores">
<span>$0</span>
<span>$1000</span>
</div>

<label for="telefono">📱 tel — Número de teléfono:</label>
<input type="tel" id="telefono" name="telefono" placeholder="+54 11 1234-5678"
pattern="[+]{0,1}[0-9]{1,4}[ ]{0,1}[0-9]{1,4}[ ]{0,1}[0-9]{1,4}[ ]{0,1}[0-9]{1,4}" />

<label for="color">🎨 color — Color favorito:</label>
<input type="color" id="color" name="color" value="#007bff" />

<label for="url">🔗 url — Sitio web:</label>
<input type="url" id="url" name="url" placeholder="https://tusitio.com" />

<button type="submit" style="margin-top: 24px; padding: 12px 28px; background: #28a745; color: white; border: none; border-radius: 8px; cursor: pointer; font-size: 16px;">
Guardar Preferencias
</button>
</form>
</body>
</html>

El type="range" es ideal para filtros de precio, volumen, brillo o cualquier valor en un espectro. type="color" abre el selector de color nativo del sistema operativo.

Variante 3: Formulario completo con validación HTML5

La validación nativa de HTML5 evita tener que escribir JavaScript para las validaciones más comunes. Con los atributos correctos, el navegador se encarga del resto.

HTML
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<title>Formulario con Validación</title>
<style>
form {
max-width: 520px;
background: #fafafa;
padding: 30px;
border-radius: 12px;
border: 1px solid #e0e0e0;
}
label {
display: block;
margin-top: 18px;
font-weight: 600;
color: #333;
}
label span {
color: #dc3545;
}
input, textarea {
width: 100%;
padding: 10px 12px;
margin-top: 4px;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 14px;
font-family: Arial, sans-serif;
box-sizing: border-box;
}
input:invalid, textarea:invalid {
border-color: #dc3545;
background: #fff5f5;
}
input:valid, textarea:valid {
border-color: #28a745;
background: #f0fff4;
}
.error-msg {
font-size: 12px;
color: #dc3545;
margin-top: 2px;
display: none;
}
input:invalid + .error-msg {
display: block;
}
button {
margin-top: 24px;
width: 100%;
padding: 14px;
background: #007bff;
color: white;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
}
button:hover {
background: #0056b3;
}
</style>
</head>
<body>
<h1>Formulario de Registro</h1>
<p>Los campos con <span style="color: #dc3545;">*</span> son obligatorios.</p>

<form novalidate>
<label for="nombre">Nombre completo <span>*</span></label>
<input
type="text"
id="nombre"
name="nombre"
required
minlength="3"
maxlength="50"
placeholder="Ej: Gabriel Maza"
autocomplete="name"
/>
<p class="error-msg">El nombre debe tener entre 3 y 50 caracteres.</p>

<label for="email">Correo electrónico <span>*</span></label>
<input
type="email"
id="email"
name="email"
required
placeholder="Ej: usuario@dominio.com"
autocomplete="email"
/>
<p class="error-msg">Ingresá un correo electrónico válido.</p>

<label for="password">Contraseña <span>*</span></label>
<input
type="password"
id="password"
name="password"
required
minlength="8"
pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}"
placeholder="Mínimo 8 caracteres, 1 mayúscula, 1 minúscula, 1 número"
autocomplete="new-password"
/>
<p class="error-msg">
La contraseña debe tener al menos 8 caracteres, una mayúscula, una minúscula y un número.
</p>

<label for="fecha-nacimiento">Fecha de nacimiento <span>*</span></label>
<input
type="date"
id="fecha-nacimiento"
name="fecha-nacimiento"
required
max="2010-12-31"
/>
<p class="error-msg">Debés ser mayor de 16 años (fecha anterior a 2010).</p>

<label for="telefono">Teléfono</label>
<input
type="tel"
id="telefono"
name="telefono"
pattern="[+]{0,1}[0-9]{7,15}"
placeholder="+541112345678"
autocomplete="tel"
/>
<p class="error-msg">Ingresá un número de teléfono válido (7 a 15 dígitos).</p>

<label for="url">URL de portfolio</label>
<input
type="url"
id="url"
name="url"
placeholder="https://tuportfolio.com"
autocomplete="url"
/>
<p class="error-msg">Ingresá una URL válida que comience con http:// o https://.</p>

<label for="comentarios">Comentarios adicionales</label>
<textarea
id="comentarios"
name="comentarios"
rows="4"
maxlength="500"
placeholder="Escribí tus comentarios acá (máximo 500 caracteres)..."
></textarea>

<button type="submit">✅ Registrarse</button>
</form>
</body>
</html>

Atributos de validación clave:

  • required — campo obligatorio
  • minlength / maxlength — largo mínimo/máximo de texto
  • min / max — valor numérico mínimo/máximo
  • pattern — expresión regular para validar el formato
  • autocomplete — sugiere al navegador qué tipo de dato autocompletar

Variante 4: Formulario con fieldset, legend y datalist

Los formularios largos se benefician de estar organizados en grupos lógicos con <fieldset> y <legend>. Además, <datalist> ofrece sugerencias mientras el usuario escribe.

HTML
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<title>Formulario con Fieldset</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
fieldset {
border: 2px solid #e0e0e0;
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
}
legend {
font-weight: bold;
font-size: 18px;
color: #333;
padding: 0 10px;
}
label {
display: block;
margin-top: 12px;
font-weight: 600;
}
input, select {
width: 100%;
padding: 8px 12px;
margin-top: 4px;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 14px;
box-sizing: border-box;
}
button {
padding: 12px 32px;
background: #007bff;
color: white;
border: none;
border-radius: 8px;
font-size: 16px;
cursor: pointer;
}
button[type="reset"] {
background: #6c757d;
}
</style>
</head>
<body>
<h1>Reserva de Viaje</h1>

<form>
<fieldset>
<legend>👤 Datos Personales</legend>
<label for="nombre">Nombre completo</label>
<input type="text" id="nombre" name="nombre" required />

<label for="email">Correo electrónico</label>
<input type="email" id="email" name="email" required />

<label for="pais">País de residencia</label>
<input
type="text"
id="pais"
name="pais"
list="lista-paises"
placeholder="Escribí tu país..."
/>
<datalist id="lista-paises">
<option value="Argentina" />
<option value="Brasil" />
<option value="Chile" />
<option value="Colombia" />
<option value="España" />
<option value="México" />
<option value="Perú" />
<option value="Uruguay" />
<option value="Venezuela" />
<option value="Estados Unidos" />
</datalist>
<p style="font-size:12px; color:#888; margin-top: 4px;">
Escribí las primeras letras y seleccioná de la lista.
</p>
</fieldset>

<fieldset>
<legend>✈️ Detalles del Viaje</legend>
<label for="destino">Destino (escribí tu ciudad)</label>
<input type="text" id="destino" name="destino" list="lista-destinos" placeholder="Escribí tu destino..." />
<datalist id="lista-destinos">
<option value="Buenos Aires" />
<option value="Cancún" />
<option value="Madrid" />
<option value="Nueva York" />
<option value="París" />
<option value="Río de Janeiro" />
<option value="Roma" />
<option value="Tokio" />
</datalist>

<label for="fecha-ida">Fecha de ida</label>
<input type="date" id="fecha-ida" name="fecha-ida" required />

<label for="fecha-vuelta">Fecha de vuelta</label>
<input type="date" id="fecha-vuelta" name="fecha-vuelta" required />

<label for="pasajeros">Cantidad de pasajeros</label>
<input type="number" id="pasajeros" name="pasajeros" min="1" max="10" value="1" />

<label for="clase">Clase</label>
<select id="clase" name="clase">
<option value="economy">Económica</option>
<option value="premium">Premium Economy</option>
<option value="business">Business</option>
<option value="first">Primera Clase</option>
</select>
</fieldset>

<div style="display: flex; gap: 12px;">
<button type="submit">🔍 Buscar Vuelos</button>
<button type="reset">🗑️ Limpiar</button>
</div>
</form>
</body>
</html>

<datalist> es una funcionalidad subestimada de HTML5. Proporciona sugerencias de autocompletado sin JavaScript, combinando lo mejor de un <input> libre y un <select>.


Buenas y Malas Prácticas

✅ Buena práctica❌ Mala práctica
Siempre vincular <label for="..."> con el id del inputUsar solo placeholder como etiqueta (desaparece al escribir)
Usar type="email", type="tel", type="url" según correspondaUsar type="text" para todo (perdés validación y teclados táctiles)
Agregar required y min/max para validación nativaDepender solo de JavaScript para validaciones básicas
Organizar formularios largos con <fieldset> y <legend>Dejar todos los campos en un solo bloque sin agrupación lógica
Usar autocomplete para mejorar la experiencia del usuarioDejar autocomplete="off" en campos donde el navegador puede ayudar
Usar pattern con expresiones regulares clarasCrear patterns demasiado restrictivos que rechazan datos válidos

Preguntas Frecuentes (FAQ)

¿Los inputs de tipo date, time y number funcionan en todos los navegadores?

Sí, en todos los navegadores modernos (Chrome, Firefox, Safari, Edge desde 2020). En navegadores muy antiguos (IE11), estos inputs se degradan a type="text". Para proyectos que deban soportar IE11, necesitás un polyfill o usar una biblioteca de componentes (React Datepicker, Flatpickr).

¿Qué diferencia hay entre type="number" y type="tel"?

type="number" muestra teclado numérico con decimales y acepta los atributos min, max y step. type="tel" muestra un teclado telefónico (ideal para móviles) y no fuerza restricciones numéricas, lo que permite caracteres como +, (, ), - y espacios. Usá number para cantidades y tel para números de teléfono.

¿Es suficiente la validación HTML5 o necesito JavaScript?

La validación HTML5 cubre el 80% de los casos (campos requeridos, formato de email, rangos numéricos). Para validaciones más complejas (ej: "la fecha de vuelta debe ser posterior a la de ida", "el nombre de usuario no debe estar en uso"), necesitás JavaScript. La mejor estrategia es combinar validación HTML5 (primera línea) + JavaScript (validaciones personalizadas) + validación del lado del servidor (seguridad).

¿<datalist> reemplaza a <select>?

No. <select> fuerza al usuario a elegir una opción de una lista cerrada. <datalist> solo sugiere opciones; el usuario puede escribir cualquier valor. Usá <select> cuando las opciones son fijas (ej: país, mes, categoría) y <datalist> cuando querés sugerir pero permitir libertad (ej: buscador de ciudades, tags).

info

📘 Conocé más a fondo este tema acá 👉 Creación de formularios con HTML.