entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

4votos

¿Como hacer para que solo se puedan picar ciertos caracteres?

Con este código consigo que no se puedan introducir más de 2 caracteres en el input, pero si yo quiero ademas que solo ciertos caracteres se puedan picar ¿Como lo hago?

$(document).ready(function() {
        $("body").on("click", "form", function( event ) {          
            var caracteres = 1;
            var elementopresionado = ".camponumerico";

            function limitarcaracteres() {
                                if($(this).val().length > caracteres) {                 
                        $(this).val($(this).val().substr(0, caracteres));
                }
            }           
            $(elementopresionado).keydown(limitarcaracteres);
        });

bichomen comentado Nov 11, 2016

Te pego el codigo tal y como lo tengo ahora mismo con keypress, yo ya me conformo con el funcionamiento actual, seguramente tendrás razón pero desconozco porque, también es verdad que solo estoy probando con Firefox

function limitarcaracteres(event) {         
                var MAX_CARACTERES = 2;
                var elementopresionado = ".camponumerico";
                var keyCode = event.which || event.keyCode;             
                if (keyCode == 8 || keyCode == 46 || keyCode == 37 || keyCode == 39) {
                    return true;
                }
                var newVal = $(elementopresionado).val() + String.fromCharCode(keyCode);

                if(keyCode < 48 || keyCode > 57) 
                {
                    return false;
                }           
                else if(newVal.length > MAX_CARACTERES) {                          
                    return false;
                }
                else if(parseInt(newVal) < 1 || parseInt(newVal)  > 20) {     
                    $("#submit").prop( "disabled", true );
                    return false;
                }                   
                else {
                    $("#submit").prop( "disabled", false );
                }
            }
            $("body").on("keypress", ".camponumerico", function( event ) {
                return limitarcaracteres(event);        
            });

jrgm0005 comentado Nov 11, 2016

Hola @bichomen @magarzon,

Me alegro que hayas resuelto tu problema.

Te dejo aquí una solución al mismo, que creo que hace lo que buscas, de una manera más sencilla y fácil de entender.

Link al ejemplo

Espero tu comentario a ver si lo que hace es lo que esperabas.

Un saludo.

bichomen comentado Nov 11, 2016

Hola @jrgm0005, tu codigo esta bien y funcionan las teclas de control, yo prefiero tener todo agrupado en una función ya que el archivo jquery tiene muchas más funciones que esta y así queda todo más ordenado por funciones, solo un detalle, tu código no acepta el 20 y en cambio acepta el 0.

Saludos

jrgm0005 comentado Nov 11, 2016

Ah sí, jaja lo hice así rápido para mostrar, eso sólo es cambiar el if de la función de si es menor que 20, pero era así para mostrarte.

Mi consejo es que separes lo máximo posible, porque aunque sean más funciones, siempre vas a poder reutilizar al máximo y eso es fundamental en proyectos grandes.

Me alegro que ya tengas solucionada tu duda.

Un saludo.

jrgm0005 comentado Nov 11, 2016

Te he actualizado el código, por si quieres echarle un vistazo, para que veas qué tal se queda tal cual como quieres.

¿Qué te parece el código? ¿Es fácil de entender y de leer?

Un saludo.

3 Respuestas

3votos

magarzon Puntos16300

Modifica tu función limitarCaracteres así:

function limitarcaracteres(event) {
  if($(this).val().length > caracteres) {                
      return false; //No hace falta hacer un substr, con que devuelvas false ya no te añade el último caracter introducido
  }   

   var keyCode = event.which || event.keyCode;
   //En keyCode tienes el código ASCII de la tecla presionada, por ejemplo para permitir sólo números:
   return keyCode >= 48 && keyCode <= 57;
}  

Por cierto, me acabo de dar cuenta. ¿Por qué estableces el keydown cada vez que haces click en el form? De esta forma, vas a añadir N controladores, uno por cada vez que el usuario haga click en el formulario, que luego se van a ejecutar N veces cada vez que el usuario entre algún carácter en el campo (y además si el usuario accede al input pulsando tabulador, en lugar de hacer click en el form, no te va a funcionar). Deberías establecerlo fuera del formulario, aplicado al elemento input concreto.

bichomen comentado Nov 4, 2016

Por cierto, me acabo de dar cuenta. ¿Por qué estableces el keydown cada vez que haces click en el form? De esta forma, vas a añadir N controladores, uno por cada vez que el usuario haga click en el formulario, que luego se van a ejecutar N veces cada vez que el usuario entre algún carácter en el campo (y además si el usuario accede al input pulsando tabulador, en lugar de hacer click en el form, no te va a funcionar). Deberías establecerlo fuera del formulario, aplicado al elemento input concreto.

Porque no me gustaba el efecto del keyup, el keydown evita que directamente escribas, con el keyup, escribes y luego se borra, no me había fijado en lo del tabulador

He modificado el código, para que solo pueda meter números del 1 al 20, pero no me funciona:

$("body").on("click", "form", function( event ) {          
            var caracteres = 1;
            var elementopresionado = ".camponumerico";
            var suma = 0;

            function limitarcaracteres(event) {
                if($(this).val().length > caracteres) {                 
                        return false;
                }
                var keyCode = event.which || event.keyCode;
                suma += keyCode.value;
                if (suma > 0 && suma <= 20 && keyCode >= 48 && keyCode <= 57) {
                    return keyCode;
                }
            }           
            $(elementopresionado).keydown(limitarcaracteres);           
        });

magarzon comentado Nov 4, 2016

No te funciona por varios motivos:

  1. keyCode es un entero, no es un objeto, con lo que keyCode.value te va a dar como valor undefined
  2. La función tiene que devolver true o false, devolver keyCode te puede funcionar, porque cualquier valor entero positivo es equivalente a true, pero no estoy seguro que el no devolver nada en caso de no cumplirse la condición sea equivalente a devolver false
  3. Estás inicializando el valor de suma dentro del evento click del form. Si yo entro en el campo, meto un 3, hago click en otro lado, y vuelvo a entrar en el campo y meto un 0, con lo que el valor sería 30, me va a dejar, porque al hacer el segundo click va a inicializar la suma a 0.

Te doy el mismo consejo que antes, saca el keydown del evento click, y por otro lado si quieres limitar el valor, comprueba contra el valor del input (por ejemplo $(this).val(), no contra una suma que, como ya te he dicho, puede tener cualquier valor

Leonardo-Tadei comentado Nov 5, 2016

Hola @bichomen,

lo que @magarzon quiere decirte no es que cambies el evento keydown por otro, si no que no le asignes el evento dentro del evento click, porque de esta forma le estás asignado el evento cada vez que el usuario clickea.

Asigna el manejador de evento fuera del click!

Saludos cordiales

2votos

jrgm0005 Puntos2920

Hola @bichomen,

Esto es un MUST para crecer como developer, DIVIDE Y VENCERAS, tienes que aprender a estudiar tu situación, estudiarla y ver lo que quieres obtener.

Haz las cosas por pasos, y que cada parte de código se encargue de una sola cosa.

Aquí te voy a dejar un ejemplo de como sería una solución aproximada, no sé si el código será el correcto ni será lo que estás buscando exactamente, pero échale un vistazo a cómo he ido solucionando y el proceso seguido, y así tú mismo pensaras la solución más limpia y clara posible a tu problema.

// Función que comprueba si el valor introducido es númerico
function entradaEsNumero(event){
var keyCode = event.which || event.keyCode;
   return keyCode >= 48 && keyCode <= 57;
}

// Función que comprueba si es menor que 20, que creo que no necesitas un acumulado
function valorMenorQue20(campoNumerico) {
return parseInt(campoNumerico.val()) < 20;
            }

// Una vez que tenemos nuestras funciones para lo que queremos, añadimos el evento, donde validamos, primero que sea númerico lo introducido, y después que su valor no es superior a 20.
$(".camponumerico").onkeydown = function(){
return entradaEsNumero(event) && valorMenorQue20($(".camponumerico"));
}

Si tienes más dudas no dudes en preguntar.

Un saludo.

Juan Ramón González Morales. UX Designer

bichomen comentado Nov 8, 2016

Gracias @magarzon @Leonardo-Tadei @jrgm0005

La verdad me esta costando, he intentado aplicar lo que me habeis comentado, pero si no hago un $("body").on("click", ".camponumerico", function( ) { no consigo que funcione en parte, entiendo lo que comentaba @magarzon, pero no se como aplicarlo y luego enlazarlo con la función de delimitar el numero de caracteres del 1 al 20, he probado con este código pero no funciona:

$(".camponumerico").keydown(function() {

            var caracteres = 1;
            var elementopresionado = ".camponumerico";

            function limitarcaracteres(event) {
                if($(this).val().length > caracteres) {                 
                        return false;
                }
                var keyCode = event.which || event.keyCode;

                return keyCode >= 48 && keyCode <= 57;
            }

            function veinte(elementopresionado) {

                if(!parseInt(elementopresionado.val()) > 20 && !parseInt(elementopresionado.val()) <= 0) {
                    return false;   
                }
                else
                    return elementopresionado;
                }
            }   

            limitarcaracteres(event);           
            veinte(elementopresionado);

            if(limitarcaracteres(event) == false || veinte(elementopresionado) == false ) {
                return  false;
            }                   
        });  

magarzon comentado Nov 8, 2016

No te funciona por varios motivos:

  • Cuando llamas a la función limitarcaracteres, le estás pasando un parámetro event que en realidad no está definido. Ese parámetro event es el evento "producido" por el keydown, por tanto debes definirlo en la función del keydown, algo así:
$(".camponumerico").keydown(function(event) {
///Aquí el resto
}
  • Estás llamando a la función veinte con un string ('.camponumerico'), no con un objeto jQuery.

  • Tu intención inicial era limitar el número de caracteres a 2, sin embargo lo estás limitando a 1, porque la variable caracteres se pone a 1 cada vez que introduces algo.

Por otro lado, ¿por qué llamas dos veces a limitarcaracteres y veinte, una por sí solos, y luego otra en el if?

Deberías guardar el resultado de las llamadas. Además, deberías sacar esas funciones fuera de la función del keydown, para una mejor organización y reutilización del código.Para ello debes cambiarlo un poco el código, porque el this ya no se referirá al input

Algo así te debería funcionar:

var MAX_CARACTERES = 2;

$(".camponumerico").keydown(function(event) {

    var elementopresionado = $(this);

    return limitarcaracteres(event) && veinte(elementopresionado);           
});

function limitarcaracteres(event) {
   var elementopresionado = event.currentTarget;
   if(elementopresionado.val().length > MAX_CARACTERES) {                 
      return false;
   }

   var keyCode = event.which || event.keyCode;

   return keyCode >= 48 && keyCode <= 57;
}

function veinte(elementopresionado) {
   return parseInt(elementopresionado.val()) >= 0 && parseInt(elementopresionado.val()) < 20) 
}   

bichomen comentado Nov 8, 2016

Hola @magarzon, gracias por la ayuda he tenido que modificar un poco tu código por porque la función de veinte daba un error tal cual la ponías, aun así cuando presiono en .camponumerico, no salta el evento, no hace nada, he mirado en el depurador de Mozilla y esta todo correcto, pero el alert que he puesto no salta, eso es que no esta identificando el evento.

No se donde esta el error, por cierto he buscado event.currentTarget porque no sabía que hacía esta propiedad y lo que hace es devolver true o false un booleano ¿es correcto?, porque entonces elementopresionado.val().length fallaría, ya que no devolvería un int, así lo entiendo yo.

var MAX_CARACTERES = 2;

        $(".camponumerico").keydown(function(event) {
            alert('Entro?')
                var elementopresionado = $(this);   

                return limitarcaracteres(event) && veinte(elementopresionado);           
        });

        function limitarcaracteres(event) {
            var elementopresionado = event.currentTarget;
            if(elementopresionado.val().length > MAX_CARACTERES) {                 
                    return false;
            }

            var keyCode = event.which || event.keyCode;

            return keyCode >= 48 && keyCode <= 57;
        }

        function veinte(elementopresionado) {
            var numero = parseInt(elementopresionado.val());
            if(numero <= 0 && numero > 20) {
                return false;       
            }
            return numero;
        }

magarzon comentado Nov 8, 2016

No sé dónde has mirado lo del currentTarget, pero lo que te devuelve es el elemento que ha lanzado el evento.

Y si ni siquiera te salta el alert, puede ser por dos motivos:

  1. Tu input no tiene la clase camponumerico o tienes algún typo (has puesto por ejemplo camponumerrico)
  2. No estás llamando a esta parte del código en el onReady, y por tanto nunca se asocia el evento a los elementos con la clase camponumerico.

bichomen comentado Nov 8, 2016

No estás llamando a esta parte del código en el onReady, y por tanto nunca se asocia el evento a los elementos con la clase camponumerico.

No, si que lo estoy poniendo, no lo puse aquí porque lo vi obvio:

$(document).ready(function() {

...

});

1voto

jrgm0005 Puntos2920

Hola @bichomen ,

En ese código, las funciones tienes que declararlas fuera del evento, y en el evento llamarlas.Aún así échale un vistazo a mi código, que creo que te soluciona tu problema, o te deja en una aproximación bastante cercana.

magarzon comentado Nov 8, 2016

Es mejor partir siempre de su código, y que sea lo más aproximado a su estructura y nomenclatura, para que asimile mejor los cambios y en qué se ha equivocado

jrgm0005 comentado Nov 8, 2016

Puede ser, a veces me pongo así en plan por reducir y hacerlo lo más simple posible, que a lo mejor, se puede perder con cierta refactorización del código.

Por favor, accede o regístrate para responder a esta pregunta.

¿Conoces alguien que puede responder?
¡Comparte esta pregunta!


Actividad Reciente

¿Eres Usuario Apple?

...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta