Permita 2 decimales en <input type = "number">

221

Tengo un <input type="number">y quiero restringir la entrada de los usuarios a números puramente o números con decimales de hasta 2 decimales.

Básicamente, estoy pidiendo una entrada de precio.

Quería evitar hacer expresiones regulares. ¿Hay una manera de hacerlo?

<input type="number" required name="price" min="0" value="0" step="any">
nubteens
fuente
2
type = "number" no tiene soporte amplio para el navegador. Es mejor usar un cuadro de texto con algunos javascript para asegurarse de obtener la entrada deseada.
www139
66
Sí, pero las entradas type="text"recurren de todos modos, entonces, ¿qué importa?
Ultimater
/^\d+\.\d{2,2}$/ funcionó para mí para requerir 0.00
ZStoneDPM

Respuestas:

334

En lugar de step="any", que permite cualquier número de lugares decimales, use step=".01", que permite hasta dos lugares decimales.

Más detalles en la especificación: https://www.w3.org/TR/html/sec-forms.html#the-step-attribute

Michael Benjamin
fuente
38
Esta no es la respuesta correcta. el paso solo gobierna lo que sucede cuando hace clic o presiona hacia arriba y no restringe nada.
Ini
1
@Michael_B independientemente de lo que espere la especificación, esto es bastante trivial para probar: jsfiddle.net/9hvm0b5u todavía permite la entrada de más de 2 decimales. Los pasos solo gobiernan por qué los botones +/- mueven la cantidad. (Chrome)
Nathan
3
@Michael_B no se impide que el usuario escriba un número como 500.12345en cualquiera de las entradas, quizás nuestra comprensión de los requisitos es diferente.
Nathan
3
Cabe señalar que, si bien el usuario puede escribir cualquier número de dígitos después del lugar decimal, la mayoría de los navegadores no permitirán el envío del formulario con un valor no válido y los selectores CSS :validy :invalidse aplicarán como se espera.
Andrew Dinmore
1
@Nathan, también es trivial probar la validación del navegador. Intente enviar un valor con más de 2 decimales: jsfiddle.net/4yesgn7b
imclean
43

En caso de que alguien esté buscando una expresión regular que permita solo números con 2 decimales opcionales

^\d*(\.\d{0,2})?$

Por ejemplo, he encontrado que la solución a continuación es bastante confiable

HTML:

<input name="my_field" pattern="^\d*(\.\d{0,2})?$" />

JS / JQuery:

$(document).on('keydown', 'input[pattern]', function(e){
  var input = $(this);
  var oldVal = input.val();
  var regex = new RegExp(input.attr('pattern'), 'g');

  setTimeout(function(){
    var newVal = input.val();
    if(!regex.test(newVal)){
      input.val(oldVal); 
    }
  }, 0);
});
Weston Ganger
fuente
2
¿Cuál es el propósito de tener setTimeout ()?
Derek el
2
@Derek. Supongo que es así que regex.test no bloquea el DOM. Busque esto: developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
christo8989
2
@Derek Solo puedo asumir que setTimeout()es esperar keydowna que se complete el evento antes de configurarlo newVal(de lo contrario, será lo mismo que oldVal). Sin embargo, con un tiempo de espera de 0, no tiene sentido y no funciona ya que ambos valores son a menudo los mismos (en Firefox). Si lo establece en 1, por ejemplo, funciona bien.
alstr
Entonces, revertió mi edición en dos publicaciones diferentes con una razón "la edición no aprobada degrada la calidad del formato de la respuesta". ¿Puede explicar cómo no se aprueba mi edición y cómo degrada exactamente la calidad de la respuesta? (OMI, lo mejora, ya que las personas pueden ejecutar el código directamente desde la publicación y no necesitan ir a JSFiddle).
doble pitido
21

Por moneda, sugeriría:

<div><label>Amount $
    <input type="number" placeholder="0.00" required name="price" min="0" value="0" step="0.01" title="Currency" pattern="^\d+(?:\.\d{1,2})?$" onblur="
this.parentNode.parentNode.style.backgroundColor=/^\d+(?:\.\d{1,2})?$/.test(this.value)?'inherit':'red'
"></label></div>

Ver http://jsfiddle.net/vx3axsk5/1/

Las propiedades HTML5 "step", "min" y "pattern" se validarán cuando se envíe el formulario, no onblur. No necesita el stepsi tiene un patterny no necesita un patternsi tiene un step. Entonces podría volver a step="any"mi código ya que el patrón lo validará de todos modos.

Si desea validar onblur, creo que darle al usuario una señal visual también es útil, como colorear el fondo de rojo. Si el navegador del usuario no es compatibletype="number" , recurrirá a type="text". Si el navegador del usuario no admite la validación de patrones HTML5, mi fragmento de JavaScript no impide que el formulario se envíe, pero da una señal visual. Por lo tanto, para las personas con poco soporte de HTML5 y para las personas que intentan piratear la base de datos con JavaScript deshabilitado o falsificar solicitudes HTTP, de todos modos debe validar en el servidor. El punto con la validación en el front-end es para una mejor experiencia de usuario. Por lo tanto, siempre que la mayoría de sus usuarios tengan una buena experiencia, está bien confiar en las características de HTML5, siempre que el código siga funcionando y pueda validarlo en el back-end.

Ultimater
fuente
2
Según MDN , patternno funciona para input type=number:<input type="number"> elements do not support use of the pattern attribute for making entered values conform to a specific regex pattern. The rationale for this is that number inputs can't contain anything except numbers, and you can constrain the minimum and maximum number of valid digits using the min and max attributes, as explained above.
izogfif
@izogfif Buena nota. También tenga en cuenta que en realidad noté que no necesita ambos y proporcioné tres formas: Paso, patrón y onblur. Mi razonamiento en ese momento era si un navegador se ahoga en uno por alguna razón que tiene el otro. Probablemente sea seguro confiar en el paso en estos días para la validación de la interfaz.
Ultimater
16

Paso 1: conecta el cuadro de entrada de tu número HTML a un evento onchange

myHTMLNumberInput.onchange = setTwoNumberDecimal;

o en el código HTML

<input type="number" onchange="setTwoNumberDecimal" min="0" max="10" step="0.25" value="0.00" />

Paso 2: escribe el setTwoDecimalPlacemétodo

function setTwoNumberDecimal(event) {
    this.value = parseFloat(this.value).toFixed(2);
}

Puede alterar el número de decimales variando el valor pasado al toFixed()método. Ver documentos de MDN .

toFixed(2); // 2 decimal places
toFixed(4); // 4 decimal places
toFixed(0); // integer
Sachin Sudhakar Sonawane
fuente
3
parseFloat (parseFloat (this.value) .toFixed (2)); Si desea un tipo decimal o numérico, puede envolver todo en parseFloat () ya que, de forma predeterminada, el método toFixed () devuelve una cadena.
spacedev
6

Descubrí que usar jQuery era mi mejor solución.

$( "#my_number_field" ).blur(function() {
    this.value = parseFloat(this.value).toFixed(2);
});
SamohtVII
fuente
6

Pruebe esto para permitir solo 2 decimales en el tipo de entrada

<input type="number" step="0.01" class="form-control"  />

O use jQuery como lo sugiere @SamohtVII

$( "#ELEMENTID" ).blur(function() {
    this.value = parseFloat(this.value).toFixed(2);
});
Nilesh Gajare
fuente
21
Esto no limita los decimales a 2 lugares en Chrome 57
mintedsky
1
Esto no es correcto. el paso solo gobierna lo que sucede cuando hace clic o presiona hacia arriba y no restringe nada.
Ini
este paso también evita que se ingrese un número como 1,000.
Zapnologica
-2

Usa este código

<input type="number" step="0.01" name="amount" placeholder="0.00">

Por defecto, el valor de Paso para los elementos de entrada HTML5 es step = "1".

Obaidul Haque
fuente
-4

solo escribe

<input type="number" step="0.1" lang="nb">

lang = 'nb "te permite escribir tus números decimales con coma o punto

REY ILUSTRATIVO
fuente
"lang = 'nb' te permite escribir tus números decimales con coma o punto" No puedo hablar por nada más, pero eso no funciona en Chrome para mí.
Andrew Dinmore
-9

En entrada:

step="any"
class="two-decimals"

En guión:

$(".two-decimals").change(function(){
  this.value = parseFloat(this.value).toFixed(2);
});
xemasiv
fuente
55
Evita usar insultos en tu publicación. Y recuerda ser amable
James