¿Hay alguna manera de evitar que el tipo de entrada = "número" obtenga valores negativos?

Respuestas:

658

Use el minatributo de esta manera:

<input type="number" min="0">
Abrahán
fuente
66
Aquí hay una fuente de referencia más confiable .
Álvaro González
222
Esto bloqueará la entrada de un número negativo usando los botones de flecha / flecha giratoria. Sin embargo, el usuario aún puede ingresar manualmente un número negativo y hacer que el valor de ese campo se lea como un número negativo, evitando así el atributo min.
ecbrodie
52
@demaniak No. Y cómo esta respuesta obtuvo tantos votos positivos cuando la mitad responde que la pregunta es un misterio
GôTô
1
@Abraham ¿Qué pasa si los datos cargados con el valor -ve en el formulario, no lo marca como rojo.
Kamini el
2
Esto no funciona, el usuario aún puede ingresar un número negativo manualmente.
Altef cuatro
129

No estaba satisfecho con la respuesta de @Abhrabm porque:

Solo evitaba que se ingresaran números negativos desde las flechas arriba / abajo, mientras que el usuario puede escribir números negativos desde el teclado.

La solución es prevenir con código clave :

// Select your input element.
var number = document.getElementById('number');

// Listen for input event on numInput.
number.onkeydown = function(e) {
    if(!((e.keyCode > 95 && e.keyCode < 106)
      || (e.keyCode > 47 && e.keyCode < 58) 
      || e.keyCode == 8)) {
        return false;
    }
}
<form action="" method="post">
  <input type="number" id="number" min="0" />
  <input type="submit" value="Click me!"/>
</form>

Aclaración proporcionada por @Hugh Guiney :

Qué códigos clave se verifican:

  • 95, <106 corresponde al teclado numérico del 0 al 9;
  • 47, <58 corresponde de 0 a 9 en la fila de números; y 8 es Retroceso.

Por lo tanto, este script impide que se ingrese una clave no válida en la entrada.

Manwal
fuente
20
Votado pero creo que ayudaría a aclarar qué códigos clave se están verificando:> 95, <106 corresponde a Numpad 0 a 9; > 47, <58 corresponde de 0 a 9 en la fila de números; y 8 es Retroceso. Por lo tanto, este script impide que se ingrese ninguna clave, excepto aquellas. Es exhaustivo, pero creo que podría ser excesivo para los navegadores que admiten entradas numéricas de forma nativa, que ya filtran las teclas alfabéticas (excepto los caracteres como "e" que pueden tener un significado numérico). Probablemente sería suficiente prevenir contra 189 (guión) y 109 (restar). Y luego combinar con min="0".
Hugh Guiney
1
@Manwal Se restringe a copiar y pegar números usando el teclado. Y me permite copiar y pegar números negativos con el mouse.
Beniton
1
@Beniton Gracias por dar este caso de uso. ¿Puedes darme una pequeña idea de lo que estás haciendo? Siempre puedo ayudarte. Proporcione un pequeño código ejecutable o violín. Puede tener el formulario Enviar validación de nivel en su código. Aunque siempre tengo check-in Backend si no permito números negativos.
Manwal
1
Simplemente copie y pegue en el campo básicamente. No es realmente un caso especial ni nada. En lugar de manejar la validación a través del código clave, probablemente sea mejor hacerlo enChange o focusOut y construir una pequeña función de validación para atrapar cualquier número negativo.
ulisesrmzroche
1
La condición para la tecla de flecha (37, 38, 39, 41) también se debe poner. || (e.keyCode>36 && e.keyCode<41)Esto no permite al usuario aumentar / disminuir el número a través de la flecha arriba / abajo e ir a la derecha / izquierda para editar el número.
vusan
86

Para mí la solución fue:

<input type="number" min="0" oninput="this.value = Math.abs(this.value)">
Renato Machado
fuente
1
Realmente la mejor solución una vez que usa pattern y noformvalidate con angular, ya que el modelo no se actualiza si no está dentro del rango. Mi caso:<input ng-model="row.myValue" type="{{row.code == 1 ? 'text' : 'number'}}" min="0" ng-pattern="..." noformvalidate oninput="if (this.type=='text') this.value=Math.abs(this.value) ">
sebius
esto funciona mejor cuando el usuario sabe que el valor predeterminado es 0. Otro usuario sabio se confunde al presionar la tecla de retroceso por qué el campo no se borra. Excepto esto, es la mejor solución. + 1
Deep 3015
1
me salvaste el día
stackmalux
Este funciona mejor, y en caso de usar decimal también. Había usado otra respuesta anterior, dejó de funcionar cuando se permite el decimal. ¿Hay alguna manera de mover esta respuesta hacia arriba para que las personas puedan usar esto principalmente?
Subhan Ahmed
31

Este código funciona bien para mí. Puedes revisar por favor:

<input type="number" name="test" min="0" oninput="validity.valid||(value='');">
Chinmay235
fuente
2
Esto funciona, pero vaciar toda la entrada después de intentar escribir -no es realmente una buena idea.
extempl
99
@extempl Suena como un castigo justo para el usuario que intenta ingresar un negativo en un campo donde el sentido común indica que no hay negativos.
KhoPhi
3
<input type="number" name="test" min="0" oninput="validity.valid||(value=value.replace(/\D+/g, ''))">- esto eliminará todos los símbolos que no sean dígitos
Oleh Melnyk
@Rexford Estoy de acuerdo, pero lo he configurado min="0"para que no haya nada negativo. Si desea un valor negativo, elimine este atributo.
Chinmay235
1
Intenté esto pero también evitó que se ingresaran números con puntos decimales.
klent
21

Método fácil:

<input min='0' type="number" onkeypress="return (event.charCode == 8 || event.charCode == 0) ? null : event.charCode >= 48 && event.charCode <= 57">

Rouvé
fuente
Agradable y fácil ... pero aún así, se pueden pegar números negativos.
Ralf
10

Quería permitir números decimales y no borrar toda la entrada si se ingresó un negativo. Esto funciona bien en Chrome al menos:

<input type="number" min="0" onkeypress="return event.charCode != 45">
ykay dice reinstalar a Mónica
fuente
¿Cómo puedo agregar más números ASCII aquí? por ej. con 45, quiero agregar 46 también. ¿Cómo se puede hacer?
Pradeep Singh
3
@PradeepSingh "return [45, 46] .indexOf (event.charCode) == -1"
ykay dice Reinstate Monica el
Por favor piense fuera de la caja. ¿Está realmente seguro de que a keypresses la única forma de ingresar un número negativo en una entrada ...
Roko C. Buljan,
6

La respuesta @Manwal es buena, pero me gusta el código con menos líneas de código para una mejor legibilidad. También me gusta usar onclick / onkeypress en html.

Mi solución sugerida hace lo mismo: Agregar

min="0" onkeypress="return isNumberKey(event)"

a la entrada html y

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

como una función de javascript.

Como se dijo, hace lo mismo. Es solo una preferencia personal sobre cómo resolver el problema.

Chris H.
fuente
5

Solo como referencia: con jQuery puede sobrescribir valores negativos en focusout con el siguiente código:

$(document).ready(function(){
    $("body").delegate('#myInputNumber', 'focusout', function(){
        if($(this).val() < 0){
            $(this).val('0');
        }
    });
});

¡Esto no reemplaza la validación del lado del servidor!

Hafenkranich
fuente
Esto funciona bien SI el usuario se enfoca fuera del campo de entrada, sin embargo, si presiona inmediatamente enter mientras aún está en el campo; aún pueden ingresar un número negativo.
NemyaNation
3

Aquí hay una solución angular 2:

crear una clase OnlyNumber

import {Directive, ElementRef, HostListener} from '@angular/core';

@Directive({
  selector: '[OnlyNumber]'
})
export class OnlyNumber {

  // Allow decimal numbers. The \. is only allowed once to occur
  private regex: RegExp = new RegExp(/^[0-9]+(\.[0-9]*){0,1}$/g);

  // Allow key codes for special events. Reflect :
  // Backspace, tab, end, home
  private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home'];

  constructor(private el: ElementRef) {
  }

  @HostListener('keydown', ['$event'])
  onKeyDown(event: KeyboardEvent) {
    // Allow Backspace, tab, end, and home keys
    if (this.specialKeys.indexOf(event.key) !== -1) {
      return;
    }

    // Do not use event.keycode this is deprecated.
    // See: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
    let current: string = this.el.nativeElement.value;
    // We need this because the current value on the DOM element
    // is not yet updated with the value from this event
    let next: string = current.concat(event.key);
    if (next && !String(next).match(this.regex)) {
      event.preventDefault();
    }
  }
}

agregue OnlyNumber a las declaraciones en app.module.ts y utilícelo así en cualquier lugar de su aplicación

<input OnlyNumber="true">
Sarath Nagesh
fuente
¿Hay alguna manera de permitir Pegar para esto? También cambié la expresión regular a: /^-?[0-9font>+(\.[0-9font>*){0,1}$/g para permitir números negativos, pero parece que no funciona.
Dave Nottage
2
oninput="this.value=(this.value   < Number(this.min) || this.value   > Number(this.max))  ? '' : this.value;"
usuario9276950
fuente
2
Si bien este fragmento de código puede resolver la pregunta, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y que esas personas podrían no saber los motivos de su sugerencia de código.
Sudheesh Singanamalla
Si bien esta puede ser la respuesta correcta, carece de suficientes detalles. Por favor explique por qué esto funciona. Cuando use Stack Overflow, considere que esta es una base de conocimiento viva , las respuestas que no comparten conocimiento son mucho menos útiles.
Marc LaFleur
2

Simplemente agregue otra forma de hacer esto (usando Angular) si no quiere ensuciar el HTML con aún más código:

Solo tiene que suscribirse al campo valueChanges y establecer el Value como un valor absoluto (teniendo cuidado de no emitir un nuevo evento porque eso causará otro valueChange, por lo tanto, una llamada recursiva y desencadenará un error de Tamaño de llamada máximo excedido)

CÓDIGO HTML

<form [formGroup]="myForm">
    <input type="number" formControlName="myInput"/>
</form>

CÓDIGO TypeScript (dentro de su componente)

formGroup: FormGroup;

ngOnInit() { 
    this.myInput.valueChanges 
    .subscribe(() => {
        this.myInput.setValue(Math.abs(this.myInput.value), {emitEvent: false});
    });
}

get myInput(): AbstractControl {
    return this.myForm.controls['myInput'];
}
Pedro B.
fuente
1

<input type="number" name="credit_days" pattern="[^\-]+" 
    #credit_days="ngModel" class="form-control" 
    placeholder="{{ 'Enter credit days' | translate }}" min="0" 
    [(ngModel)]="provider.credit_days"
    onkeypress="return (event.charCode == 8 || event.charCode == 0 || 
    event.charCode == 13) ? null : event.charCode >= 48 && event.charCode <= 
    57" onpaste="return false">

Hui Lin
fuente
1

La respuesta a esto no es útil. ya que solo funciona cuando usas las teclas arriba / abajo, pero si escribes -11 no funcionará. Así que aquí hay una pequeña solución que uso

este para enteros

  $(".integer").live("keypress keyup", function (event) {
    //    console.log('int = '+$(this).val());
    $(this).val($(this).val().replace(/[^\d].+/, ""));
    if (event.which != 8 && (event.which < 48 || event.which > 57))
    {
        event.preventDefault();
    }
   });

este cuando tienes números de precio

        $(".numeric, .price").live("keypress keyup", function (event) {
     //    console.log('numeric = '+$(this).val());
    $(this).val($(this).val().replace(/[^0-9\,\.]/g, ''));

    if (event.which != 8 && (event.which != 44 || $(this).val().indexOf(',') != -1) && (event.which < 48 || event.which > 57)) {
        event.preventDefault();
    }
   });
Ahmed Sunny
fuente
0

Esta solución permite todas las funciones del teclado, incluyendo copiar y pegar con teclado. Evita pegar números negativos con el mouse. Funciona con todos los navegadores y la demostración en codepen usa bootstrap y jQuery. Esto debería funcionar con configuraciones y teclados que no estén en inglés. Si el navegador no admite la captura de eventos de pegado (IE), eliminará el signo negativo después de enfocarse. Esta solución se comporta como debería hacerlo el navegador nativo con min = 0 type = number.

Margen:

<form>
  <input class="form-control positive-numeric-only" id="id-blah1" min="0" name="nm1" type="number" value="0" />
  <input class="form-control positive-numeric-only" id="id-blah2" min="0" name="nm2" type="number" value="0" />
</form>

Javascript

$(document).ready(function() {
  $("input.positive-numeric-only").on("keydown", function(e) {
    var char = e.originalEvent.key.replace(/[^0-9^.^,]/, "");
    if (char.length == 0 && !(e.originalEvent.ctrlKey || e.originalEvent.metaKey)) {
      e.preventDefault();
    }
  });

  $("input.positive-numeric-only").bind("paste", function(e) {
    var numbers = e.originalEvent.clipboardData
      .getData("text")
      .replace(/[^0-9^.^,]/g, "");
    e.preventDefault();
    var the_val = parseFloat(numbers);
    if (the_val > 0) {
      $(this).val(the_val.toFixed(2));
    }
  });

  $("input.positive-numeric-only").focusout(function(e) {
    if (!isNaN(this.value) && this.value.length != 0) {
      this.value = Math.abs(parseFloat(this.value)).toFixed(2);
    } else {
      this.value = 0;
    }
  });
});
wilsotc
fuente
0

Aquí hay una solución que funcionó mejor para un campo QTY que solo permite números.

// Only allow numbers, backspace and left/right direction on QTY input
    if(!((e.keyCode > 95 && e.keyCode < 106) // numpad numbers
        || (e.keyCode > 47 && e.keyCode < 58) // numbers
        || [8, 9, 35, 36, 37, 39].indexOf(e.keyCode) >= 0 // backspace, tab, home, end, left arrow, right arrow
        || (e.keyCode == 65 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + A
        || (e.keyCode == 67 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + C
        || (e.keyCode == 88 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + X
        || (e.keyCode == 86 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + V
    )) {
        return false;
    }
TheRealJAG
fuente
0

If Number is Negative or Positive Using ES6s Math.Sign

const num = -8;
// Old Way
num === 0 ? num : (num > 0 ? 1 : -1); // -1

// ES6 Way
Math.sign(num); // -1

Israt Jahan Simu
fuente