Existe alguma maneira de impedir que o tipo de entrada = "número" obtenha valores negativos?

302

Quero obter apenas valores positivos, existe alguma maneira de evitá-lo usando apenas html?
Por favor, não sugira método de validação

Captura de tela do controle de entrada

Tural Ali
fonte
3
Esta discussão responde à mesma pergunta em uma extensão muito melhor: stackoverflow.com/questions/31575496/…
PiotrWolkowski

Respostas:

658

Use o minatributo assim:

<input type="number" min="0">
Abraão
fonte
6
Aqui está uma fonte de referência mais confiável .
Álvaro González
222
Isso impedirá que um número negativo seja inserido usando os botões de seta / giratório. No entanto, o usuário ainda pode inserir manualmente um número negativo e fazer com que o valor desse campo seja lido como um número negativo, ignorando o atributo min.
Ecclodie
52
@demaniak Não. E como esta resposta obter tantos upvotes quando metade responde à pergunta é um mistério
Ir à
1
@Abraham E se os dados carregados com o valor -ve no formulário, eles não o marcarem como vermelho.
Kamini
2
Isso não funciona, o usuário ainda pode inserir um número negativo manualmente.
Altef four
129

Não fiquei satisfeito com a resposta da @Abhrabm porque:

Isso impedia que números negativos fossem inseridos nas setas para cima / para baixo, enquanto o usuário pode digitar um número negativo no teclado.

A solução é evitar com o código da chave :

// 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>

Esclarecimentos fornecidos por @Hugh Guiney :

Quais códigos de chave estão sendo verificados:

  • 95, <106 corresponde ao Numpad 0 a 9;
  • 47, <58 corresponde de 0 a 9 na linha de números; e 8 é Backspace.

Portanto, este script está impedindo que uma chave inválida seja inserida na entrada.

Manwal
fonte
20
Voto positivo, mas acho que ajudaria a esclarecer quais códigos-chave estão sendo verificados:> 95, <106 corresponde ao Numpad de 0 a 9; > 47, <58 corresponde de 0 a 9 na linha do número; e 8 é Backspace. Portanto, este script está impedindo a inserção de qualquer chave, exceto aquelas. É completo, mas acho que pode ser um exagero para navegadores que suportam nativamente entradas numéricas, que já filtram as teclas alfabéticas (exceto caracteres como "e" que podem ter um significado numérico). Provavelmente seria suficiente prevenir contra 189 (traço) e 109 (subtrair). E depois combine com min="0".
Hugh Guiney
1
@Manwal Restringe a copiar e colar números usando o teclado. E permite copiar e colar números negativos usando o mouse.
Beniton 5/07
1
@ Beniton Obrigado por fornecer este caso de uso. Você pode me dar uma pequena idéia do que está fazendo? Sempre posso ajudá-lo. Forneça pouco código ou violão executável. Você pode ter o formulário Enviar validação de nível para no seu código. Embora eu sempre tenha o check-in no Backend se não permitir números negativos.
Manwal 5/07
1
Basta copiar e colar no campo basicamente. Não é realmente um caso especial nem nada. Em vez de manipular a validação via keycode, provavelmente é melhor fazê-lo em Change ou focusOut e criar uma pequena função de validação para capturar qualquer número negativo.
21816 ulisesrmzroche
1
Também deve ser colocada a condição da tecla de seta (37, 38, 39, 41). || (e.keyCode>36 && e.keyCode<41)Isso não permite que o usuário aumente / diminua o número pela seta para cima / para baixo e vá para a direita / esquerda para editar o número.
vusan
86

Para mim, a solução foi:

<input type="number" min="0" oninput="this.value = Math.abs(this.value)">
Renato Machado
fonte
1
Realmente a melhor solução depois de usar o pattern e o noformvalidate com angular, já que o modelo não é atualizado se não estiver dentro do intervalo. Meu 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
isso funciona melhor quando o usuário sabe que o valor padrão é 0. Outro usuário sábio fica confuso ao pressionar backspace por que o campo não está sendo limpo. Exceto isso, é a melhor solução. + 1
Deep 3015 25/01
1
você salvou meu dia
stackmalux 27/09/18
Este funciona melhor, e no caso de usar decimal também. Eu tinha usado outra resposta acima, ela parou de funcionar quando o decimal é permitido. Existe alguma maneira de elevarmos essa resposta para que as pessoas possam usá-la principalmente.
Subhan Ahmed 06/03
31

Este código está funcionando bem para mim. Você pode verificar:

<input type="number" name="test" min="0" oninput="validity.valid||(value='');">
Chinmay235
fonte
2
Isso funciona, mas esvaziar toda a entrada depois que você tenta digitar -não é realmente uma boa ideia.
extempl
9
@extempl Parece uma punição justa para o usuário que tenta inserir um negativo em um campo em que o senso comum indica que não há negativos.
KhoPhi
3
<input type="number" name="test" min="0" oninput="validity.valid||(value=value.replace(/\D+/g, ''))">- isso removerá todos os símbolos que não sejam dígitos
Oleh Melnyk 18/02
@Rexford Eu concordo, mas eu configurei min="0"para que não haja nagativos. Se você deseja um valor negativo, remova esse atributo.
precisa saber é o seguinte
1
Eu tentei isso, mas também impediu que números com pontos decimais fossem inseridos.
Klent 16/05/19
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é
fonte
Agradável e fácil ... mas ainda assim, números negativos podem ser colados.
Ralf
10

Eu queria permitir números decimais e não limpar toda a entrada se um negativo fosse inserido. Isso funciona bem no chrome, pelo menos:

<input type="number" min="0" onkeypress="return event.charCode != 45">
ykay diz Restabelecer Monica
fonte
Como pode adicionar mais número ASCII aqui. por exemplo. com 45 eu adiciono 46 também. Como pode ser feito?
Pradeep Singh
3
@PradeepSingh "return [45, 46] .indexOf (event.charCode) == -1"
ykay diz Restabelecer Monica em
Por favor, pense fora da caixa. Tem a certeza de um keypressé a única maneira pode-se inserir um número negativo a uma entrada ...
Roko C. Buljan
6

A resposta @Manwal é boa, mas eu gosto de código com menos linhas de código para melhor legibilidade. Também eu gosto de usar o uso onclick / onkeypress em html.

Minha solução sugerida faz o mesmo: Adicionar

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

para a entrada html e

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

como uma função javascript.

Como dito, faz o mesmo. É apenas uma preferência pessoal sobre como resolver o problema.

Chris H.
fonte
5

Apenas para referência: com o jQuery, você pode sobrescrever valores negativos no focusout com o seguinte código:

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

Isso não substitui a validação do lado do servidor!

Hafenkranich
fonte
Isso funciona bem se o usuário se concentrar fora do campo de entrada, no entanto, se pressionar imediatamente enter enquanto ainda estiver no campo; eles ainda podem inserir um número negativo.
NemyaNation
3

Aqui está uma solução angular 2:

criar uma classe 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();
    }
  }
}

adicione OnlyNumber às declarações em app.module.ts e use desta forma em qualquer lugar do seu aplicativo

<input OnlyNumber="true">
Sarath Nagesh
fonte
Existe uma maneira de permitir colar para isso? Também mudei o regex para: /^-?[0-9,95+(\.[0-9,95*){0,1}$/g para permitir números negativos, mas parece que não funciona?
precisa saber é o seguinte
2
oninput="this.value=(this.value   < Number(this.min) || this.value   > Number(this.max))  ? '' : this.value;"
user9276950
fonte
2
Embora esse trecho de código possa resolver a questão, incluir uma explicação realmente ajuda a melhorar a qualidade da sua postagem. Lembre-se de que você está respondendo à pergunta dos leitores no futuro e essas pessoas podem não saber os motivos da sua sugestão de código.
Sudheesh Singanamalla
Embora essa seja a resposta correta, faltam detalhes suficientes. Por favor, explique por que isso funciona. Ao usar o Stack Overflow, considere que essa é uma base de conhecimento viva , respostas que não compartilham conhecimento são muito menos úteis.
Marc LaFleur
2

Apenas adicionando outra maneira de fazer isso (usando Angular) se você não quiser sujar o HTML com ainda mais código:

Você só precisa se inscrever no campo valueChanges e definir o Valor como um valor absoluto (cuidando para não emitir um novo evento, pois isso causará outro valueChange, portanto, uma chamada recursiva e acionará um erro de tamanho máximo de chamada excedido)

CÓDIGO HTML

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

CÓDIGO TypeScript (dentro do seu 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.
fonte
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
fonte
1

A resposta para isso não é útil. pois só funciona quando você usa as teclas para cima / para baixo, mas se você digitar -11, não funcionará. Então, aqui está uma pequena correção que eu uso

este para números inteiros

  $(".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 quando você tem números de preço

        $(".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
fonte
0

Esta solução permite todas as funcionalidades do teclado, incluindo copiar e colar com o teclado. Impede a colagem de números negativos com o mouse. Funciona com todos os navegadores e a demo no codepen usa bootstrap e jQuery. Isso deve funcionar com configurações e teclados que não sejam do inglês. Se o navegador não suportar a captura de eventos de colagem (IE), removerá o sinal negativo após o foco. Essa solução se comporta como o navegador nativo deve com min = 0 type = number.

Marcação:

<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
fonte
0

Aqui está uma solução que funcionou melhor para mim em um campo QTY que permite apenas 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
fonte
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
fonte