Limitar los caracteres permitidos en un control de formulario con Javascript
En este ejemplo limitamos tanto el número de carácteres permitido, como el conjunto de carácteres a utilizar usando una expresión regular:
var caracteresPermitidos = /^[A-Za-z0-9 .,;]$/;
Donde dejaremos las letras mayúsculas y minúsculas, los números, el espacio en blanco, el punto, la coma y el punto y coma. Podéis ampliar el patrón a vuestro gusto, por ejemplo para validar un email.
El código del ejemplo completo es este:
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <title>Textarea limitado - Usando ER</title> <script type="text/javascript"> /* Global con ER de carácteres permitidos */ var caracteresPermitidos = /^[A-Za-z0-9 .,;]$/; var gTeclasEdicion = [8, 37, 39, 46]; // array de teclas edicion permitidas var globalEsTeclaEspecial = false; // Global que se pone a true en function comprobarNumeroCaracteres(tipo, maximoCaracteres, id) { var control = document.getElementById(id); var info = document.getElementById("info" + control.name); //display var caracteresConsumidos = control.value.length; if (!globalEsTeclaEspecial) caracteresConsumidos++; var caracteresQuedan = maximoCaracteres - caracteresConsumidos; var boolQuedanCaracteres = (caracteresConsumidos < maximoCaracteres); var textoSalida = tipo; if (boolQuedanCaracteres) textoSalida += "Puedes escribir aun " + caracteresQuedan + " caracteres adicionales.<br>"; else textoSalida += "Has alcanzado el máximo de " + maximoCaracteres + " caracteres"; info.innerHTML = textoSalida; return boolQuedanCaracteres; } function manejadorTeclasASCII(infoEvento, maximoCaracteres, id) { var boolPermitidos = false; var boolQuedanCaracteres = false; var codigoCaracter = 0; /* ¿tecla ASCII imprimible? Comprobar si se encuentra en los caracteres permitidos */ codigoCaracter = infoEvento.charCode; if (codigoCaracter > 0) { var caracterAscii = String.fromCharCode(codigoCaracter); boolPermitidos = caracteresPermitidos.test(caracterAscii); } // Se comprueba si quedan caracteres disponibles y se actualiza interfaz boolQuedanCaracteres = comprobarNumeroCaracteres("[ASCII__]", maximoCaracteres, id); /* Se construye una respuesta con dos comprobaciones hechas aqui: boolPermitidos y boolQuedanCaracteres y una externa del gestor de teclas edicion: globalEsTeclaEspecial */ return ((boolPermitidos || globalEsTeclaEspecial) && boolQuedanCaracteres); } function manejadorTeclasEdicion(infoEvento, maximoCaracteres, id) { var codigoCaracter = 0; codigoCaracter = infoEvento.keyCode; globalEsTeclaEspecial = false; // Comprobar si la tecla pulsada es alguna de las teclas especiales for (var i in gTeclasEdicion) { if (codigoCaracter == gTeclasEdicion[i]) { globalEsTeclaEspecial = true; break; } } return comprobarNumeroCaracteres("[EDICION]", maximoCaracteres, id) || globalEsTeclaEspecial; } function onKeyPress(infoEvento) { var e = infoEvento || window.event; // para salvar las deficiencias de IE=window.event return manejadorTeclasASCII(e, "200", "texto"); // de esta forma le paso más parámetros } function onKeyDown(infoEvento) { var e = infoEvento || window.event; // para salvar las deficiencias de IE=window.event return manejadorTeclasEdicion(e, "200", "texto"); } function manejadores() { document.getElementById('texto').onkeypress = onKeyPress; document.getElementById('texto').onkeydown = onKeyDown; } </script> </head> <body onload="manejadores();"> <form> <fieldset> <legend>Textarea limitado (200 car + signos puntuación) - Usando ER</legend> <label for="texto">Comentarios</label> <textarea rows="5" cols="80" name="Texto" id="texto"></textarea> <br> <label for="infoTexto">Información del texto:</label> <br> <div id="infoTexto"></div> </fieldset> </form> </body> </html>
Explicación del código
Como siempre en el onload de la pagina se cargan los manejadores de eventos:
<body onload="manejadores();">
En esta ocasion pincharemos 2 eventos: onkeydown para la gestión de teclas especiales, y onkeypress para las ASCII imprimibles.
function manejadores() { document.getElementById('texto').onkeypress = onKeyPress; document.getElementById('texto').onkeydown = onKeyDown; }
Los respectivos manejadores son estas otras funciones que siguen a continuación, que por un lado aseguran el evento, y por otro lado llaman al correspondiente manejador personalizado de ambos, que además recibe más parámetros además del propio evento, como es el límite de caracteres permitidos en el control, y el id del mismo en el html:
function onKeyPress(infoEvento) { var e = infoEvento || window.event; // para salvar las deficiencias de IE=window.event return manejadorTeclasASCII(e, "200", "texto"); // de esta forma le paso más parámetros } function onKeyDown(infoEvento) { var e = infoEvento || window.event; // para salvar las deficiencias de IE=window.event return manejadorTeclasEdicion(e, "200", "texto"); }
Nota: A lo largo del script se utilizan 3 globales:
/* Global con ER de carácteres permitidos */ var caracteresPermitidos = /^[A-Za-z0-9 .,;]$/; var gTeclasEdicion = [8, 37, 39, 46]; // array de teclas edicion permitidas var globalEsTeclaEspecial = false; // Global que se pone a true en
Por un lado el evento KeyPress que gestiona las teclas ASCII imprimibles, limitadas a 200 en número y permitidas según una expresión regular, se apoya en la función manejadorTeclasASCII:
function manejadorTeclasASCII(infoEvento, maximoCaracteres, id) { var boolPermitidos = false; var boolQuedanCaracteres = false; var codigoCaracter = 0; /* ¿tecla ASCII imprimible? Comprobar si se encuentra en los caracteres permitidos */ codigoCaracter = infoEvento.charCode; if (codigoCaracter > 0) { var caracterAscii = String.fromCharCode(codigoCaracter); boolPermitidos = caracteresPermitidos.test(caracterAscii); } // Se comprueba si quedan caracteres disponibles y se actualiza interfaz boolQuedanCaracteres = comprobarNumeroCaracteres("[ASCII__]", maximoCaracteres, id); /* Se construye una respuesta con dos comprobaciones hechas aqui: boolPermitidos y boolQuedanCaracteres y una externa del gestor de teclas edicion: globalEsTeclaEspecial */ return ((boolPermitidos || globalEsTeclaEspecial) && boolQuedanCaracteres); }
Por otro lado el evento KeyDown se encarga de la gestión de teclas de edición, para ello dispone del array:
var gTeclasEdicion = [8, 37, 39, 46]; // array de teclas edicion permitidas
Y realiza su magia con este código de la función manejadorTeclasEdicion:
function manejadorTeclasEdicion(infoEvento, maximoCaracteres, id) { var codigoCaracter = 0; codigoCaracter = infoEvento.keyCode; globalEsTeclaEspecial = false; // Comprobar si la tecla pulsada es alguna de las teclas especiales for (var i in gTeclasEdicion) { if (codigoCaracter == gTeclasEdicion[i]) { globalEsTeclaEspecial = true; break; } } return comprobarNumeroCaracteres("[EDICION]", maximoCaracteres, id) || globalEsTeclaEspecial; }
Desde ambos manejadores se llama a una función comprobarNumeroCaracteres, que cuenta los caracteres usados, y actualiza la interfaz:
function comprobarNumeroCaracteres(tipo, maximoCaracteres, id) { var control = document.getElementById(id); var info = document.getElementById("info" + control.name); //display var caracteresConsumidos = control.value.length; if (!globalEsTeclaEspecial) caracteresConsumidos++; var caracteresQuedan = maximoCaracteres - caracteresConsumidos; var boolQuedanCaracteres = (caracteresConsumidos < maximoCaracteres); var textoSalida = tipo; if (boolQuedanCaracteres) textoSalida += "Puedes escribir aun " + caracteresQuedan + " caracteres adicionales.<br>"; else textoSalida += "Has alcanzado el máximo de " + maximoCaracteres + " caracteres"; info.innerHTML = textoSalida; return boolQuedanCaracteres; }
Podéis ver el código en acción pinchando aquí: http://www.sospedia.net/limitar-los-caracteres-permitidos-en-un-control-de-formulario/
Espero que os sirva y hasta pronto.