--- title: Validación de restricciones slug: Web/Guide/HTML/HTML5/Constraint_validation tags: - CSS - Guía - HTML5 - NecesitaContenido - Selectores translation_of: Web/Guide/HTML/HTML5/Constraint_validation original_slug: HTML/HTML5/Validacion_de_restricciones ---
La creación de formularios web siempre ha sido una tarea compleja. Mientras armar el formulario en sí es fácil, verificar si cada campo tiene un valor que es válido y coherente es aun más difícil, e informar al usuario acerca del problema puede convertirse en un dolor de cabeza. HTML5 introdujo nuevos mecanismos para formularios: añadió nuevos tipos semánticos para el elemento {{ HTMLElement("input") }} y validación de restricciones para facilitar el trabajo de revisar el contenido del formulario de lado del cliente. Se pueden usar restricciones básicas y comunes, sin la necesidad de JavaScript, estableciendo nuevos atributos; para restricciones más complejas se puede usar la API de Validación de Restricciones de HTML.
En HTML5, las restricciones básicas son declaradas de dos formas:
Las restricciones intrínsecas para el atributo {{ htmlattrxref("type", "input") }} son:
Tipo de input | Descripción | Incumplimiento asociado |
---|---|---|
<input type="URL"> | El valor debe ser una URL absoluta, es decir, una de las siguientes:
|
Incumplimiento de restricción por tipo no coincidente (Type mismatch) |
<input type="email"> | El valor debe obedecer a la producción ABNF: 1*( atext / "." ) "@" ldh-str 1*( "." ldh-str ) donde:
Nota: si se estableció el atributo {{ htmlattrxref("multiple", "input") }}, se pueden definir distintas direcciones de correo, separadas por coma, para este control. Si cualquiera de ellas no satisface la condición descrita aquí, se ejecuta el incumplimiento de restricción por tipo no coincidente.
|
Incumplimiento de restricción por tipo no coincidente (Type mismatch) |
Nótese que la mayoría de los tipos de input no tienen restricciones intrínsecas, puesto que algunos simplemente son excluidos de la validación de restricciones, o tienen un algoritmo de sanitización que transforma los valores incorrectos a uno valor correcto predeterminado.
Los siguientes atributos son usados para describir restricciones básicas:
Atributo | Tipos de input que soportan el atributo | Valores posibles | Descripción | Incumplimiento asociado |
---|---|---|---|---|
{{ htmlattrxref("pattern", "input") }} | text, search, url, tel, email, password | Una expresión regular de JavaScript (compilada con las banderas global , ignoreCase , y multiline de ECMAScript 5 desabilitadas) |
El valor debe coincidir con el patrón. | Incumplimiento de restricción por incompatibilidad de patrones (Pattern mismatch) |
{{ htmlattrxref("min", "input") }} | range, number | Un número válido | El valor debe ser mayor o igual al de este atributo. | Incumplimiento de restricción por flujo insuficiente (Underflow) |
date, month, week | Una fecha válida | |||
datetime, datetime-local, time | Una fecha y hora válidos | |||
{{ htmlattrxref("max", "input") }} | range, number | Un número válido | El valor debe ser menor o igual al de este atributo | Incumplimiento de restricción por desborde (Overflow) |
date, month, week | Una fecha válida | |||
datetime, datetime-local, time | Una fecha y hora válidos | |||
{{ htmlattrxref("required", "input") }} | text, search, url, tel, email, password, date, datetime, datetime-local, month, week, time, number, checkbox, radio, file; también en los elementos {{ HTMLElement("select") }} y {{ HTMLElement("textarea") }} | ninguno, pues éste es un atributo de tipo Boolean: su presencia representa true, y su ausencia representa false | Debe tener un valor (si se establece). | Incumplimiento de restricción por ausencia (Missing) |
{{ htmlattrxref("step", "input") }} | date | Un número entero de días | A menos que se establezca el atributo con la literal any, el valor debe ser min + un enter múltiplo del valor de este atributo. | Incumplimiento de restricción por inconsistencia de paso (Step mismatch) |
month | Un número entero de meses | |||
week | Un número entero de semanas | |||
datetime, datetime-local, time | Un número entero de segundos | |||
range, number | Un entero | |||
{{ htmlattrxref("maxlength", "input") }} | text, search, url, tel, email, password; también en el elemento {{ HTMLElement("textarea") }} | Una longitud en enteros | El número de caracteres (puntos de código) no debe exceder el valor del atributo. | Incumplimiento de restricción por ser muy largo (Too long) |
La validación de restricciones se hace a través de la API de Validación de Restricciones, ya sea en un elemento de formulario individual o a nivel de formulario, en el elemento {{ HTMLElement("form") }} mismo. La validación de restricciones se hace de las siguientes maneras:
checkValidity()
de una interfaz DOM relacionada con formas (HTMLInputElement
, HTMLSelectElement
, HTMLButtonElement
o HTMLTextAreaElement
), la cual evalúa las restricciones para este elemento únicamente, permitiendo que un script obtenga esta información. (Esto lo hace comúnmente el agente usuario cuando determina cuál de las pseudo-clases CSS, {{ Cssxref(":valid") }} o {{ Cssxref(":invalid") }}, se aplicará.)checkValidity()
en la interfaz HTMLFormElement
, llamada validación estática de restricciones.send()
en la interfaz HTMLFormElement no invoca a la validación de restricciones. en otras palabras, este método envía los datos del formulario al servidor aunque no se satisfagan las restricciones.
El formato de código postal varía de un país a otro. No sólo la mayoría de los países permiten un prefijo opcional con el código del país (como D-
en Alemania, F-
en Francia o Suiza), sino que algunos países tienen códigos postales con solamente un número fijo de dígitos; otros, como el Reino Unido, tienen estructuras más complejas, permitiendo letras en posiciones específicas.
Nota: Esto no es una guía completa para una biblioteca de validación de código postal, sino más bien una demostración de conceptos clave.
Como un ejemplo, añadiremos un script que verificará la validación de restricciones en este formulario simple:
<form> <label for="ZIP">Código postal : </label> <input type="text" id="ZIP"> <label for="Country">País : </label> <select id="Country"> <option value="ch">Suiza</option> <option value="fr">Francia</option> <option value="de">Alemania</option> <option value="nl">Países Bajos</option> </select> <input type="submit" value="Validar"> </form>
Esto mostrará el siguiente formulario:
Primero, escribimos una función que revisará las restricciones en sí:
function checkZIP() { // Para cada país, se define el patrón para el código postal var constraints = { ch : [ '^(CH-)?\\d{4}$', "El código postal de Suiza debe tener cuatro dígitos: p.ej. CH-1950 o 1950" ], fr : [ '^(F-)?\\d{5}$' , "El código postal de Francia debe tener cinco dígitos: p.ej. F-75012 o 75012" ], de : [ '^(D-)?\\d{5}$' , "El código postal de Alemania debe tener cinco dígitos: p-ej. D-12345 o 12345" ], nl : [ '^(NL-)?\\d{4}\\s*([A-RT-Z][A-Z]|S[BCE-RT-Z])$', "El código postal de Países Bajos debe tener cuatro dígitos, seguidos de dos letras excepto SA, SD y SS" ] }; // Se lee el ID del país var country = document.getElementById("Country").value; // Se obtiene el campo del código postal var ZIPField = document.getElementById("ZIP"); // Se crea el validador de la restricción var constraint = new RegExp(constraints[country][0], ""); console.log(constraint); // ¡Se hace la revisión! if (constraint.test(ZIPField.value)) { // El código postal cumple la restricción, usamos la API de Restricciones para indicarlo ZIPField.setCustomValidity(""); } else { // El código postal no cumple la restricción, usamos la API de Restricciones para // dar un mensaje sobre el formato requerido para este país ZIPField.setCustomValidity(constraints[country][1]); } }
Entonces, enlazamos este código al evento onchange del elemento {{ HTMLElement("select") }} y al evento oninput del elemento {{ HTMLElement("input") }}:
window.onload = function () { document.getElementById("Country").onchange = checkZIP; document.getElementById("ZIP").oninput = checkZIP; }
Puedes ver aquí un ejemplo en vivo de la validación de código postal.
Otra restricción común es limitar el tamaño de un archivo que será subido. Verificar esto de lado del cliente antes de que el archivo sea transmitido al servidor requiere combinar la API de Validación de Restricciones, y especialmente la función field.setCustomValidity(), con otra API de JavaScript, la File API.
Aquí está la parte de HTML:
<label for="FS">Selecciona un archivo menor a 75KB : </label> <input type="file" id="FS">
Esto muestra lo siguiente:
Con JavaScript, leemos el archivo seleccionado, usamos el método File.size() para obtener su tamaño, lo comparamos con el límite fijo (hard coded), y llamamos a la API de Validación de Restricciones para informar al navegador si no se cumple la restricción:
function checkFileSize() { var FS = document.getElementById("FS"); var files = FS.files; // Si hay (por lo menos) un archivo seleccionado if (files.length > 0) { if (files[0].size > 75 * 1024) { // Validar la restricción FS.setCustomValidity("El archivo seleccionado no debe ser mayor a 75KB"); return; } } // No hay incumplimiento de la restricción FS.setCustomValidity(""); }
Finalmente, anclamos el método al evento requerido:
window.onload = function () { document.getElementById("FS").onchange = checkFileSize; }
Puedes ver aquí un ejemplo en vivo de la validación de tamaño de archivos.
Aparte de establecer las restricciones, los desarrolladores web querrán controlar los mensajes que son desplegados al usuario y los estilos de los mismos.
El aspecto de los elementos puede ser controlado por medio de pseudo-clases de CSS.
Las pseudo-clases :required
y :optional
permitene escribir selectores que coincidan con elementos de formulario que tengan el atributo {{ htmlattrxref("required") }} y los que no lo tengan, respectivamente.
Véase ::placeholder (experimental).
Las pseudo-clases :valid e :invalid son usadas para representar elementos <input> cuyo contenido es válido o inválido, respectivamente, acorde a las configuraciones de captura. Estas clases permiten al usuario estilizar elementos de formulario válidos e inválidos, para hacer más fácil el identificar elementos que tienen valores correctos o incorrectos.
El atributo x-moz-errormessage es una extensión de Mozilla que te permite especificar el mensaje de error que se mostrará cuando un campo no es validado exitosamente.
Nota: Esta extensión no es estándar.
El método element.setCustomValidity(error) es usado para establecer un mensaje de error personalizado para mostrar cuando el formulario es enviado. El método toma una cadena de texto como parámetro con el error. Si el error es una cadena no vacía, el método asume que la validación no fue exitosa, y despliega el mensaje con el error indicado. Si el error es una cadena vacía, el elemento es considerado válido, y restablece el mensaje de error.
La interfaz de DOM ValidityState
representa los estados de validez en los que puede estar un elemento, respecto a la validación de restricciones. En conjunto, ayudan a explicar por qué el valor de un elemento falló en la validación, si no es válido.