web-dev-qa-db-fra.com

Type d'entrée HTML5 = la valeur numérique est vide dans Webkit si elle comporte des espaces ou des caractères non numériques?

C'est un comportement étrange pour moi mais sur les navigateurs Webkit (Chrome/Safari, pas Firefox) si j'inclus un espace dans une chaîne de chiffres dans un <input type=number> alors le value de cette entrée est vide.

Voir ce JSFiddle: http://jsfiddle.net/timrpeterson/CZZEX/5/

Voici le code:

<input id='withOutspace' type='number' value='123'>
<input id='with_space' type='number' value='123 123'>
<button>click</button>

$('button').click(function(){ 
    alert("withOut:"+$('#withOutspace').val()+" |||| with:"+$('#with_space').val());
});

Si vous allez à ce JSFiddle , vous remarquerez que le with_space l'entrée est vide. Mais si vous lui mettez un nombre qui a un espace ou des caractères non numériques, l'alerte indiquera que l'entrée est vide.

De toute évidence, il s'agit d'un désastre pour la validation de formulaire avec les numéros de carte de crédit, etc.

26
tim peterson

Le hack consiste à utiliser type="tel" au lieu de type="number".

Cela résout les 2 problèmes principaux:

  1. Il tire un pavé numérique sur les appareils mobiles
  2. Il valide (et n'est pas vide) avec des nombres ou des non-nombres en entrée.

Veuillez consulter ce JSFiddle: http: //jsfiddle.net/timrpeterson/CZZEX/6/

38
tim peterson

Je peux suggérer deux façons. 1. Empêcher les caractères en entrée

# updated to support more numerical characters related
$(window).keydown(function(e) {
  if($('input[type=number]').index($(e.target))!=-1) {
    if(
      ($.inArray(e.keyCode, [48,49,50,51,52,53,54,55,56,57,58,96,97,98,99,100,101,102,103,104,105,8,13,190,189]) == -1) // digits, digits in num pad, 'back', 'enter', '.', '-'
      || (e.keyCode == 190 && $(e.target).val().indexOf(".") != -1) // not allow double dot '.'
      || (e.keyCode == 190 && $(e.target).val().length == 0) // not allow dot '.' at the begining
    ) {
      e.preventDefault();
    }
  }
});

ou 2. Modifiez le type d'entrée à la volée

$('input[type=number]').focus(function() {
    $(this).prop('type', 'text');
});

cela permet de mettre ce que vous voulez et de changer son type en arrière onblur

$(this).blur(function() {
    $(this).prop('type', 'number');
});

Mais quand même vous ne pouvez pas stocker de valeurs non numériques en entrée avec type = nombre , donc val() vous renverra toujours votre chaîne vide si elle rencontre char ou l'espace.

Donc, au moins, vous devez supprimer tous les déchets avec .replace(/[^\d]/g, '') - cela signifie "supprimer tous les numéros sauf" avant de changer de type

Dans mon exemple je montre les deux méthodes + effacer les valeurs d'entrée.

5
vladkras

Un moyen de contrôler le numéro d'entrée est de le laisser vide sur flou lorsque vous ne pouvez pas lire la valeur

static formattedDecimalInput(input, maxScale, allowEmpty = true) {
    input = $(input);

    input.on("blur", function(e) {
        var inputVal = input.val();

        if(inputVal != "" || !allowEmpty) {
            if(inputVal == "") {
                inputVal = "0";
            }
            var number = Number(inputVal);
            input.val(number.toFixed(maxScale));    
        } else {
            input.val("");
        }
    });
}

Vous pouvez le formater en passant, et si vous avez un caractère non valide côté serveur, vous pouvez envoyer une mauvaise réponse à la demande.

Si vous voulez un champ obligatoire, vous pouvez simplement vérifier si l'entrée est vide avec javascript avant votre appel au serveur

Ce n'est pas vraiment la réponse à la question initiale mais je cherchais un contrôle convivial pour ce type d'entrée quand je suis arrivé ici

2
Vincent

Mon hack pour ce problème comprend les éléments suivants (j'utilise des validateurs jQuery):

    $(document).on('keyup', '[type="number"]', function () {
        if (this.validity.badInput) {
            $(this).attr('data-badinput', true);
        }
    });

Plus tard dans la méthode de validation, je fais ceci:

    $.validator.addMethod('isInteger', function (value, element, parameterValue) {
        if ($(element).attr('data-badinput')) {
            //We know nasty browser always clears incorrect input, so empty string will look OK next time
            $(element).removeAttr('data-badinput');
            return false;
        }
        return !value || /^-?\d+$/.test(value);
    });
1
Alexander

Vous définissez un champ de saisie numérique sur une chaîne qui n'est pas un nombre. À quoi vous attendiez-vous? Le fait est que ces champs n'autorisent ni n'acceptent de saisie non numérique. Ils sont documentés comme n'acceptant qu'une valeur virgule flottante .

Il n'y a aucun "hack" disponible ou requis; la solution est d'arrêter d'utiliser un champ de saisie number pour une valeur qui n'est pas un nombre . Cartes de crédit, numéros de téléphone, etc. ces choses sont pas nombres. Ils contiennent des chiffres sous la forme d'un sous-ensemble des caractères valides, mais ils contiennent également des caractères complètement non numériques comme des espaces, des tirets et des parenthèses. Ils doivent être stockés et traités comme des chaînes régulières.

Utilisation <input type="text"/>.

1
meagar