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.