Pregunta

¿Existe una manera rápida de configurar una entrada de texto HTML (<input type=text />) para permitir solo las pulsaciones de teclas numéricas (más '.')?

¿Fue útil?

Solución

Nota: esta es una respuesta actualizada. Los comentarios a continuación se refieren a una versión anterior que se equivocaba con los códigos clave.

JavaScript

La siguiente función setInputFilter le permite utilizar cualquier tipo de filtro de entrada en un texto < input > , incluidos varios filtros numéricos ( ver abajo).

A diferencia de la mayoría de las otras soluciones, esta admite correctamente Copiar + Pegar, Arrastrar + Soltar, todos los atajos de teclado, todas las operaciones del menú contextual, todas las teclas que no se pueden escribir (por ejemplo, cursor y teclas de navegación), el cursor posición, todos los diseños de teclado de todos los idiomas y plataformas, y todos los navegadores desde IE 9 .

Pruébelo usted mismo en JSFiddle .

// Restricts input for the given textbox to the given inputFilter.
function setInputFilter(textbox, inputFilter) {
  ["input", "keydown", "keyup", "mousedown", "mouseup", "select", "contextmenu", "drop"].forEach(function(event) {
    textbox.addEventListener(event, function() {
      if (inputFilter(this.value)) {
        this.oldValue = this.value;
        this.oldSelectionStart = this.selectionStart;
        this.oldSelectionEnd = this.selectionEnd;
      } else if (this.hasOwnProperty("oldValue")) {
        this.value = this.oldValue;
        this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
      }
    });
  });
}

// Restrict input to digits and '.' by using a regular expression filter.
setInputFilter(document.getElementById("myTextBox"), function(value) {
  return /^\d*\.?\d*$/.test(value);
});

Algunos filtros de entrada que puede utilizar:

  • Valores enteros (solo positivos):
    /^\d*$/.test(value)
  • Valores enteros (positivo y hasta un límite particular):
    /^\d*$/.test(value) & amp; & amp; (value === " " || parseInt (value) < = 500)
  • Valores enteros (tanto positivos como negativos):
    /^-?\d*$/.test(value)
  • valores de punto flotante (permitiendo tanto . como , como separador decimal):
    /^-?\d*[.,font>?\d*$/.test(value)
  • Valores de
  • Moneda (es decir, como máximo dos decimales):
    /^-?\d*[.,font>?\d{0,2}$/.test(value)
  • A-Z solamente (es decir, letras latinas básicas):
    /^[a-zfont>*$/i.test(value)
  • letras latinas solamente (es decir, inglés y la mayoría de los idiomas europeos, consulte https: // unicode-table .com para obtener detalles sobre los rangos de caracteres Unicode):
    /^[a-z\u00c0-\u024ffont>*$/i.test(value)
  • Valores
  • Hexadecimales :
    /^[0-9a-ffont>*$/i.test(value)

¡Tenga en cuenta que todavía debe hacer la validación del lado del servidor!

jQuery

También hay una versión jQuery de esto. Consulte esta respuesta o pruébelo usted mismo en JSFiddle .

HTML 5

HTML 5 tiene una solución nativa con < input type = " number " > (consulte especificación ), pero tenga en cuenta que la compatibilidad del navegador varía:

  • La mayoría de los navegadores solo validarán la entrada al enviar el formulario, y no al escribir.
  • La mayoría de los navegadores móviles no admiten el paso , min y max atributos.
  • Chrome (versión 71.0.3578.98) aún permite al usuario ingresar los caracteres e y E en el campo. Consulte también esta pregunta .
  • Firefox (versión 64.0) y Edge (EdgeHTML versión 17.17134) aún permiten al usuario ingresar cualquier texto en el campo.

Pruébelo usted mismo en w3schools.com .

Otros consejos

Usa este DOM

<input type='text' onkeypress='validate(event)' />

Y este script

function validate(evt) {
  var theEvent = evt || window.event;

  // Handle paste
  if (theEvent.type === 'paste') {
      key = event.clipboardData.getData('text/plain');
  } else {
  // Handle key press
      var key = theEvent.keyCode || theEvent.which;
      key = String.fromCharCode(key);
  }
  var regex = /[0-9]|\./;
  if( !regex.test(key) ) {
    theEvent.returnValue = false;
    if(theEvent.preventDefault) theEvent.preventDefault();
  }
}

He buscado mucho para encontrar una buena respuesta a esto, y necesitamos desesperadamente < input type = " number " , pero en resumen, estas 2 son las formas más concisas Podría idear:

<input type="text" 
       onkeyup="this.value=this.value.replace(/[^\d]/,'')">

Si no le gusta el carácter no aceptado que se muestra durante una fracción de segundo antes de ser borrado, el método a continuación es mi solución. Tenga en cuenta las numerosas condiciones adicionales, esto es para evitar deshabilitar todo tipo de navegación y teclas rápidas. Si alguien sabe cómo compactar esto, ¡háganoslo saber!

<input type="text" 
onkeydown="return ( event.ctrlKey || event.altKey 
                    || (47<event.keyCode && event.keyCode<58 && event.shiftKey==false) 
                    || (95<event.keyCode && event.keyCode<106)
                    || (event.keyCode==8) || (event.keyCode==9) 
                    || (event.keyCode>34 && event.keyCode<40) 
                    || (event.keyCode==46) )">

Aquí hay uno simple que permite exactamente un decimal, pero no más:

<input type="text" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');" />

Y un ejemplo más, que funciona muy bien para mí:

function validateNumber(event) {
    var key = window.event ? event.keyCode : event.which;
    if (event.keyCode === 8 || event.keyCode === 46) {
        return true;
    } else if ( key < 48 || key > 57 ) {
        return false;
    } else {
        return true;
    }
};

Adjuntar también al evento de pulsación de tecla

$(document).ready(function(){
    $('[id^=edit]').keypress(validateNumber);
});

Y HTML:

<input type="input" id="edit1" value="0" size="5" maxlength="5" />

Aquí hay un ejemplo de jsFiddle

HTML5 tiene < input type = number > , que suena bien para usted. Actualmente, solo Opera lo admite de forma nativa, pero hay un proyecto que tiene una implementación de JavaScript.

La mayoría de las respuestas aquí tienen la debilidad de usar eventos clave .

Muchas de las respuestas limitarían su capacidad de seleccionar texto con macros de teclado, copiar + pegar y más comportamientos no deseados, otros parecen depender de complementos específicos de jQuery, lo que está matando moscas con ametralladoras.

Esta solución simple parece funcionar mejor para mí multiplataforma, independientemente del mecanismo de entrada (pulsación de tecla, copiar + pegar, hacer clic con el botón derecho copiar + pegar, voz a texto, etc.). Todas las macros de teclado de selección de texto seguirían funcionando, e incluso limitarían la capacidad de establecer un valor no numérico por script.

function forceNumeric(){
    this.value(this.value.replace(/[^\d]+/g,''));
}
$('body').on('propertychange input', 'input.numeric-text', forceNumeric);

Opté por usar una combinación de las dos respuestas mencionadas aquí, es decir,

< input type = " number " / >

y

function isNumberKey(evt){
    var charCode = (evt.which) ? evt.which : evt.keyCode
    return !(charCode > 31 && (charCode < 48 || charCode > 57));
}

< input type = " text " onkeypress = " return isNumberKey (event); " >

HTML5 admite expresiones regulares, por lo que puede usar esto:

<input id="numbersOnly" pattern="[0-9.]+" type="text">

Advertencia: algunos navegadores aún no admiten esto.

JavaScript

function validateNumber(evt) {
    var e = evt || window.event;
    var key = e.keyCode || e.which;

    if (!e.shiftKey && !e.altKey && !e.ctrlKey &&
    // numbers   
    key >= 48 && key <= 57 ||
    // Numeric keypad
    key >= 96 && key <= 105 ||
    // Backspace and Tab and Enter
    key == 8 || key == 9 || key == 13 ||
    // Home and End
    key == 35 || key == 36 ||
    // left and right arrows
    key == 37 || key == 39 ||
    // Del and Ins
    key == 46 || key == 45) {
        // input is VALID
    }
    else {
        // input is INVALID
        e.returnValue = false;
        if (e.preventDefault) e.preventDefault();
    }
}

adicional podría agregar coma, punto y menos (, .-)

  // comma, period and minus, . on keypad
  key == 190 || key == 188 || key == 109 || key == 110 ||

HTML

<input type="text" onkeydown="validateNumber(event);"/ >

2 soluciones:

Utilice un validador de formularios (por ejemplo, con complemento de validación jQuery )

Realice una comprobación durante el evento onblur (es decir, cuando el usuario abandona el campo) del campo de entrada, con la expresión regular:

<script type="text/javascript">
function testField(field) {
    var regExpr = new RegExp("^\d*\.?\d*<*>quot;);
    if (!regExpr.test(field.value)) {
      // Case of error
      field.value = "";
    }
}

</script>

<input type="text" ... onblur="testField(this);"/>

Tan simple ...

// En una función de JavaScript (puede usar HTML o PHP).

function isNumberKey(evt){
    var charCode = (evt.which) ? evt.which : evt.keyCode;
    if (charCode > 31 && (charCode < 48 || charCode > 57))
        return false;
    return true;
}

En su entrada de formulario:

<input type=text name=form_number size=20 maxlength=12 onkeypress='return isNumberKey(event)'>

Con entrada máx. (Estos anteriores permiten un número de 12 dígitos)

Un enfoque más seguro es verificar el valor de la entrada, en lugar de secuestrar las pulsaciones de teclas y tratar de filtrar códigos de teclas.

De esta forma, el usuario puede usar flechas de teclado, teclas modificadoras, retroceso, eliminar, usar teclados no estándar, usar el mouse para pegar, usar arrastrar y soltar texto, incluso usar entradas de accesibilidad.

El siguiente script permite números positivos y negativos

1
10
100.0
100.01
-1
-1.0
-10.00
1.0.0 //not allowed

var input = document.getElementById('number');
input.onkeyup = input.onchange = enforceFloat;

//enforce that only a float can be inputed
function enforceFloat() {
  var valid = /^\-?\d+\.\d*$|^\-?[\d]*$/;
  var number = /\-\d+\.\d*|\-[\d]*|[\d]+\.[\d]*|[\d]+/;
  if (!valid.test(this.value)) {
    var n = this.value.match(number);
    this.value = n ? n[0] : '';
  }
}
<input id="number" value="-3.1415" placeholder="Type a number" autofocus>

EDITAR: eliminé mi respuesta anterior porque creo que ahora es anticuada.

Encuentre la solución mencionada a continuación. En este usuario solo se puede ingresar el valor numérico , tampoco se puede copiar , pegar , arrastrar y drop en la entrada.

  

Caracteres permitidos

0,1,2,3,4,5,6,7,8,9
  

Personajes no permitidos y Personajes a través de eventos

  • Valor alfabético
  • Caracteres especiales
  • Copiar
  • Pegar
  • Drag
  • Drop

$(document).ready(function() {
  $('#number').bind("cut copy paste drag drop", function(e) {
      e.preventDefault();
  });     
});
function isNumberKey(evt) {
    var charCode = (evt.which) ? evt.which : evt.keyCode;
    if (charCode > 31 && (charCode < 48 || charCode > 57))
        return false;
    return true;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="text" class="form-control" name="number" id="number" onkeypress="return isNumberKey(event)" placeholder="Enter Numeric value only">

Avísame si no funciona.

Puede usar un patrón para esto:

<input id="numbers" pattern="[0-9.]+" type="number">

Aquí puede ver el consejos completos sobre la interfaz del sitio web móvil .

Si desea sugerir al dispositivo (tal vez un teléfono móvil) entre alfa o numérico, puede usar < input type = " number " > .

Una implementación breve y dulce usando jQuery y replace () en lugar de mirar event.keyCode o event.which:

$('input.numeric').live('keyup', function(e) {
  $(this).val($(this).val().replace(/[^0-9]/g, ''));
});

Solo un pequeño efecto secundario es que la letra escrita aparece momentáneamente y CTRL / CMD + A parece comportarse un poco extraño.

Código JavaScript:

function validate(evt)
{
    if(evt.keyCode!=8)
    {
        var theEvent = evt || window.event;
        var key = theEvent.keyCode || theEvent.which;
        key = String.fromCharCode(key);
        var regex = /[0-9]|\./;
        if (!regex.test(key))
        {
            theEvent.returnValue = false;

            if (theEvent.preventDefault)
                theEvent.preventDefault();
            }
        }
    }

Código HTML:

<input type='text' name='price' value='0' onkeypress='validate(event)'/>

funciona perfectamente porque el código de retroceso es 8 y una expresión regex no lo permite, por lo que es una forma fácil de evitar el error :)

Solo otra variante con jQuery usando

$(".numeric").keypress(function() {
    return (/\d/.test(String.fromCharCode(event.which) ))
});

input type = " number " es un atributo HTML5.

En el otro caso, esto te ayudará:

function isNumberKey(evt){
    var charCode = (evt.which) ? evt.which : evt.keyCode
    if (charCode > 31 && (charCode < 48 || charCode > 57))
        return false;
    return true;
}

<input type="number" name="somecode" onkeypress="return isNumberKey(event)"/>

Un ejemplo más donde puede agregar solo números en el campo de entrada, no puede letras

<input type="text" class="form-control" id="phone" name="phone" placeholder="PHONE" spellcheck="false" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');">

simplemente use type = " number " ahora este atributo es compatible con la mayoría de los navegadores

<input type="number" maxlength="3" ng-bind="first">

También puede comparar el valor de entrada (que se trata como una cadena por defecto) a sí mismo forzado como numérico, como:

if(event.target.value == event.target.value * 1) {
    // returns true if input value is numeric string
}

Sin embargo, debe vincularlo a un evento como keyup, etc.

<input name="amount" type="text" value="Only number in here"/> 

<script>
    $('input[name=amount]').keyup(function(){
        $(this).val($(this).val().replace(/[^\d]/,''));
    });
</script>

Utiliza este DOM:

<input type = "text" onkeydown = "validate(event)"/>

Y este script:

validate = function(evt)
{
    if ([8, 46, 37, 39, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 35, 36].indexOf(evt.keyCode || evt.which) == -1)
    {
        evt.returnValue = false;
        if(evt.preventDefault){evt.preventDefault();}
    }
}

... O este script, sin indexOf, usando dos para 's ...

validate = function(evt)
{
    var CharValidate = new Array("08", "046", "039", "948", "235");
    var number_pressed = false;
    for (i = 0; i < 5; i++)
    {
        for (Ncount = 0; Ncount < parseInt(CharValidate[i].substring(0, 1)) + 1; Ncount++)
        {
            if ((evt.keyCode || evt.which) == parseInt(CharValidate[i].substring(1, CharValidate[i].lenght)) + Ncount)
            {
                number_pressed = true;
            }
        }
    }
    if (number_pressed == false)
    {
        evt.returnValue = false;
        if(evt.preventDefault){evt.preventDefault();}
    }
}

Utilicé el atributo onkeydown en lugar de onkeypress, porque el atributo onkeydown se verifica antes que el atributo onkeypress. El problema estaría en el navegador Google Chrome.

Con el atributo " onkeypress " ;, TAB sería incontrolable con " preventDefault " en google chrome, sin embargo, con el atributo "onkeydown", ¡TAB se vuelve controlable!

Código ASCII para TAB = > 9

El primer script tiene menos código que el segundo, sin embargo, la matriz de caracteres ASCII debe tener todas las claves.

El segundo script es mucho más grande que el primero, pero la matriz no necesita todas las claves. El primer dígito en cada posición de la matriz es el número de veces que se leerá cada posición. Para cada lectura, se incrementará 1 a la siguiente. Por ejemplo:




NCount = 0

48 + NCount = 48

NCount + +

48 + NCount = 49

NCount + +

...

48 + NCount = 57




En el caso de las teclas numéricas son solo 10 (0 - 9), pero si fueran 1 millón, no tendría sentido crear una matriz con todas estas teclas.

Códigos ASCII:

  • 8 == > (Retroceso);
  • 46 = > (Eliminar);
  • 37 = > (flecha izquierda);
  • 39 = > (flecha derecha);
  • 48 - 57 = > (números);
  • 36 = > (hogar);
  • 35 = > (fin);

Esta es una función mejorada:

function validateNumber(evt) {
  var theEvent = evt || window.event;
  var key = theEvent.keyCode || theEvent.which;
  if ((key < 48 || key > 57) && !(key == 8 || key == 9 || key == 13 || key == 37 || key == 39 || key == 46) ){
    theEvent.returnValue = false;
    if (theEvent.preventDefault) theEvent.preventDefault();
  }
}

La mejor manera (permitir TODOS los tipos de números: negativo real, positivo real, entero negativo, entero positivo) es:

$(input).keypress(function (evt){
    var theEvent = evt || window.event;
    var key = theEvent.keyCode || theEvent.which;
    key = String.fromCharCode( key );
    var regex = /[-\d\.]/; // dowolna liczba (+- ,.) :)
    var objRegex = /^-?\d*[\.]?\d*$/;
    var val = $(evt.target).val();
    if(!regex.test(key) || !objRegex.test(val+key) || 
            !theEvent.keyCode == 46 || !theEvent.keyCode == 8) {
        theEvent.returnValue = false;
        if(theEvent.preventDefault) theEvent.preventDefault();
    };
}); 

Esta es la versión extendida de la solución de geowa4 . Admite los atributos min y max . Si el número está fuera de rango, se mostrará el valor anterior.

Puede probarlo aquí.

Uso: < input type = text class = 'number' maxlength = 3 min = 1 max = 500 >

function number(e) {
var theEvent = e || window.event;
var key = theEvent.keyCode || theEvent.which;
if(key!=13&&key!=9){//allow enter and tab
  key = String.fromCharCode( key );
  var regex = /[0-9]|\./;
  if( !regex.test(key)) {
    theEvent.returnValue = false;
    if(theEvent.preventDefault) theEvent.preventDefault();
    }   
  }
}

$(document).ready(function(){
    $("input[type=text]").filter(".number,.NUMBER").on({
        "focus":function(e){
         $(e.target).data('oldValue',$(e.target).val());
            },
        "keypress":function(e){
                e.target.oldvalue = e.target.value;
                number(e);
            },
        "change":function(e){
            var t = e.target;
            var min = $(t).attr("min");
            var max = $(t).attr("max");
            var val = parseInt($(t).val(),10);          
            if( val<min || max<val)
                {
                    alert("Error!");
                    $(t).val($(t).data('oldValue'));
                }

            }       
    });     
});

Si las entradas son dinámicas, use esto:

$(document).ready(function(){
    $("body").on("focus","input[type=text].number,.NUMBER",function(e){
        $(e.target).data('oldValue',$(e.target).val());
    }); 
    $("body").on("keypress","input[type=text].number,.NUMBER",function(e){
        e.target.oldvalue = e.target.value;
        number(e);
    }); 
    $("body").on("change","input[type=text].number,.NUMBER",function(e){
        var t = e.target
        var min = $(t).attr("min");
        var max = $(t).attr("max");
        var val = parseInt($(t).val());         
        if( val<min || max<val)
            {
                alert("Error!");
                $(t).val($(t).data('oldValue'));
            }
    }); 
});

Mi solución para una mejor experiencia de usuario:

  

HTML

<input type="tel">
  

jQuery

$('[type=tel]').on('change', function(e) {
  $(e.target).val($(e.target).val().replace(/[^\d\.]/g, ''))
})
$('[type=tel]').on('keypress', function(e) {
  keys = ['0','1','2','3','4','5','6','7','8','9','.']
  return keys.indexOf(event.key) > -1
})

Detalles :

En primer lugar, tipos de entrada :

number muestra flechas arriba / abajo que reducen el espacio de entrada real, las encuentro feas y solo son útiles si el número representa una cantidad (cosas como teléfonos, códigos de área, ID ... no ' no los necesito) tel proporciona validaciones similares de número de navegador sin flechas

El uso de [número / tel] también ayuda a mostrar el teclado numérico en dispositivos móviles.

Para la validación de JS terminé necesitando 2 funciones, una para la entrada normal del usuario (pulsación de tecla) y la otra para una corrección de copiar + pegar (cambiar), otras combinaciones me darían una experiencia de usuario terrible.

Uso el más confiable KeyboardEvent.key en lugar del ahora obsoleto KeyboardEvent.charCode

Y dependiendo del soporte de su navegador puede considerar usar Array.prototype.includes () en lugar del mal llamado Array.prototype.indexOf () (para resultados verdaderos / falsos)

Una manera fácil de resolver este problema es implementar una función jQuery para validar con regex los caracteres escritos en el cuadro de texto, por ejemplo:

Su código html:

<input class="integerInput" type="text">

Y la función js usando jQuery

$(function() {
    $('.integerInput').on('input', function() {
      this.value = this.value
        .replace(/[^\d]/g, '');// numbers and decimals only

    });
});

$(function() {
        $('.integerInput').on('input', function() {
          this.value = this.value
            .replace(/[^\d]/g, '');// numbers and decimals only
            
        });
    });
<script
			  src="https://code.jquery.com/jquery-2.2.4.min.js"
			  integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
			  crossorigin="anonymous">
</script>

<input type="text" class="integerInput"/>


		

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top