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.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.