web-dev-qa-db-fra.com

iOS5 afficher le clavier numérique par défaut sans utiliser type = "numéro" ou type = "tel"

Avec la sortie d'iOS5, Apple a ajouté sa propre validation aux champs de formulaire type = "number". Cela cause quelques problèmes. voir cette question ci-dessous qui résume:

Le type d'entrée = la nouvelle validation 'numéro' supprime les zéros non marqués et le nombre de formats dans Safari pour iPhone iOS5 et le dernier Safari pour Mac

Bien que type d’entrée = "tel" permette d’afficher un clavier numérique sur l’iphone, c’est le clavier phone qui n’a pas de point décimal.

Est-il possible de définir le pavé numérique par défaut à l'aide de HTML/js? Ce n'est pas une application iPhone. Au minimum, j'ai besoin de chiffres et d'un point décimal dans le clavier.

Mettre à jour

Les champs de saisie numérique dans Safari 5.1/iOS 5 n'acceptent que les chiffres et les points décimaux. La valeur par défaut pour l'une de mes entrées est 500 000 $. Safari affiche alors un champ de saisie vide car $,% sont des caractères non valides.

De plus, lorsque j'exécute ma propre validation onblur, Safari efface le champ de saisie car j'ajoute un $ à la valeur.

Ainsi, l'implémentation de type d'entrée = "numéro" par Safari 5.1/iOS5 l'a rendue inutilisable.

jsfiddle

Essayez-le ici - http://jsfiddle.net/mjcookson/4ePeE/ La valeur par défaut de 500 000 $ n'apparaîtra pas dans Safari 5.1, mais si vous supprimez les symboles $ et, ils le seront. Frustrant.

36
marissajmc

Solution de travail: testée sur iPhone 5, Android 2.3, 4

La solution de Tadeck (gagnant de prime) consistant à utiliser un <span> pour contenir les symboles du champ de saisie et placer un <span> formaté au-dessus de l'entrée de la devise est essentiellement ce que j'ai finalement fait.

Mon code final est différent et plus court, donc je le publie ici. Cette solution résout le problème de validation iOS5 des symboles $,% dans les champs de saisie et permet donc à input type="number" d'être utilisé par défaut.

Champ de symbole, par exemple. "xx%" "xx années"

<input name="interest-rate" value="6.4" maxlength="4" min="1" max="20" />
<span class="symbol">%</span>
  • Utilisez simplement un champ de saisie numérique et une plage en dehors de l'entrée pour afficher le symbole.

Champ de devise, par exemple. "$ xxx, xxx"

<span id="formatted-currency">$500,000</span>
<input id="currency-field" type="number" name="loan-amount" value="500000" maxlength="8" min="15000" max="10000000" />
  • Positionnez l'étendue sur l'entrée de devise et réglez l'entrée sur Display: none
  • Lorsqu'un utilisateur clique/appuie sur l'étendue, la masque et affiche l'entrée Si vous positionnez parfaitement la plage, la transition est transparente.
  • Le type de saisie numérique prend en charge la validation.
  • Sur flou et envoi de l’entrée, définissez span html sur la valeur De l’entrée. Formatez la plage. Cachez l'entrée et affichez la plage avec la valeur formatée

$('#formatted-currency').click(function(){
    $(this).hide();
    $('#currency-field').show().focus();
});
$('#currency-field').blur(function(){
    $('#formatted-currency').html(this.value);
    $('#formatted-currency').formatCurrency({
        roundToDecimalPlace : -2
    });
    $(this).hide();
    $('#formatted-currency').show();
});
// on submit
$('#formatted-currency').html($('#currency-field').val());
$('#formatted-currency').formatCurrency({
    roundToDecimalPlace : -2
});
$('#currency-field').hide();
$('#formatted-currency').show();
3
marissajmc

Styliser le champ pour qu'il contienne des symboles

Quand il s'agit d'inclure les symboles dans ce champ number, vous pouvez utiliser un contournement comme celui-ci:

HTML:

<span id="number-container">
    <input type="number" name="number" id="number-field" value="500" />
    <span id="number-container-symbol">$</span>
</span>

CSS:

#number-container {
    position: relative;
}
#number-container-symbol {
    left: 5pt;
    position: absolute;
    top: 0px;
}
#number-field {
    background-color: transparent;
    padding-left: 10pt;
}

Traitez-le comme une preuve de concept. Voir this jsfiddle pour un exemple en direct. Cela ressemble à ça dans Chrome:

enter image description here

Définir une granularité plus petite

Sur la base de la documentation sur la saisie du nombre (brouillon de l'éditeur) , à définir la granularité vous devez ajouter l'attribut step="<some-floating-point-number>" à la balise <input>:

<input type="number" name="number" value="500.01" step="0.01" />

et cela fonctionnera dans de nombreux navigateurs modernes. Voir ce jsfiddle pour les tests.

Conclusion

Vous devriez pouvoir le personnaliser pour qu'il contienne les symboles dont vous avez besoin. Il existe également une fonctionnalité qui, selon la documentation, permet la prise en charge des nombres à virgule flottante.

Solution alternative - champ vide devant quelque chose d'autre

Vous pouvez également inciter quelqu'un à croire qu'il voit le contenu du champ de saisie}, mais lui montrer autre chose derrière le champ (ceci est une extension de ma solution d'origine). Ensuite, si quelqu'un appuie sur le champ, vous pouvez propager la valeur appropriée, etc., puis revenir à l'état précédent sur flou. Voir ce code ( exemple en direct sur jsfiddle - couleur bleue signifie que vous regardez quelque chose qui n’est pas dans le champ):

// store original value from INPUT tag in jQuery's .data()
var input_field = jQuery('#number-field');
var display_span = jQuery('#number-container-value');
var base_val = parseFloat(input_field.val());
input_field.data('storedVal', base_val);
input_field.val('');
display_span.html(base_val);

// react to field gaining and losing focus
jQuery('#number-field').on('focus', function(event){
    var el = jQuery(this);
    var display = jQuery('#number-container-value');
    if (typeof el.data('storedVal') != 'undefined'){
        el.val(el.data('storedVal'));
    };
    display.html('');
}).on('blur', function(event){
    var el = jQuery(this);
    var display = jQuery('#number-container-value');
    var new_val = parseFloat(el.val());
    el.data('storedVal', new_val);
    display.html(new_val);
    el.val('');
});

(le code complet avec le style est sur le jsfiddle mentionné). Le code doit être raccourci et nettoyé, mais il s’agit d’un preuve de concept. Essayez-le et partagez vos découvertes, s'il vous plaît.

16
Tadeck

Pourquoi ne pas mettre le $ en dehors du champ de saisie (comme une étiquette). Ou le signe de pourcentage à droite du champ de saisie? On dirait que cela résoudrait votre problème et que vous seriez capable d'utiliser input type = "number" et que ça marcherait.

7
Dad

Vous êtes coincé entre le marteau et l'enclume. Tant qu'il n'y aura pas de place dans la spécification HTML pour type="currency" (et cela ne se produira probablement jamais du fait de la façon dont différents pays écrivent de la monnaie), vous devrez utiliser un peu de JS magic pour résoudre le problème. 

Bien sûr, ni le numéro ni le téléphone ne seront pas la meilleure idée. Cependant, en utilisant un peu de ruse JS, je propose cette solution:

var i   = document.getElementById( 'input' );

i.onblur    = function()
{
    i.type  = 'text';

    i.value = number_format( i.value );
}

i.onfocus   = function()
{
    var v   = Number( i.value.replace( /\D/, '' ) );

    i.type  = 'number';

    i.value = v > 0 ? v : '';
}

J'échange simplement le type d'entrée en fonction de la focalisation/du flou. Cela signifie qu'une fois que l'utilisateur a quitté le champ de texte, nous pouvons le formater. Lorsque l'utilisateur revient, nous prenons la valeur, s'il en existe une> 0 et nous la restituons sous forme de nombre. Voici le test de travail, j'espère que cela aide: http://jsfiddle.net/ahmednuaman/uzYQA/

5
Ahmed Nuaman

Ce qui suit fait apparaître le clavier numérique pour iPad avec iOS5, permet de taper tout caractère et permet de définir la valeur de tout:

<input type="text" pattern="\d*">

Cependant, il est moche, fragile (il va probablement se briser à l'avenir ...) et ne fonctionne pas sur iPhone (l'iPhone affiche le pavé numérique qui permet uniquement de 0 à 9). La solution ne semble fonctionner qu'avec le modèle \d* ou son équivalent [0-9]*.

Mieux vaut peut-être utiliser type="tel" qui semble agir de la même manière.

3
robocat

J'ai eu un problème similaire, et est venu avec cette solution JS mort-laide, forçant l'iPad à faire apparaître le pavé numérique.

Mon problème était que safari filtrait tout sauf les chiffres lorsque le formulaire était posté et que j'avais besoin de divers caractères supplémentaires, par exemple "3/7" ou "65 $".

var elem = document.getElementById('MathAnswer');
elem.type = 'number';

elem.onfocus = function() {
  setTimeout(function() {
    elem.type = 'text'; 
  }, 1);
};

Il suffit de redéfinir le type de saisie sur 'text' après que iPad ait affiché le pavé numérique, et le tour est joué, safari ne supprime plus les non-chiffres. 

J'espère que ça aide quelqu'un!

2
Snorvarg

Cette solution fonctionne sur iPad et iPhone, et même sur Next/Previous. Essayez http://fiddle.jshell.net/L77Cq/2/show/ (ou http://jsfiddle.net/L77Cq/ à modifier).

<!DOCTYPE html>
<head>
<style>
    .riggedinput::-webkit-input-placeholder {
    margin: 0em;
    font: -webkit-small-control;
    color: initial;
    letter-spacing: normal;
    Word-spacing: normal;
    line-height: normal;
    text-transform: none;
    text-indent: 0px;
    text-shadow: none;
}
</style>
<script>
    function focused() {
        var test = document.getElementById('test');
        setTimeout(function() { // timeout needed so that keyboard changes to numeric when using Next/Previous keyboard navigation buttons
            if (document.activeElement === test) {
                test.type = 'text';
                test.value = test.placeholder;
                test.placeholder = '';
            }
        }, 1);
    }
    function blurred() {
        var test = document.getElementById('test');
        var value = test.value;
        test.placeholder = value;
        test.value = '';
        test.type = 'number';
    }
    if (!/^(iPhone|iPad|iPod)$/.test(navigator.platform)) alert ('Code specific to Mobile Safari');
</script>
</head>
<body>
    <input>
    <input id="test" type="number" class="riggedinput" placeholder="$100.10USD" onfocus="focused()" onblur="blurred()">
    <input>
</body>

Il a toujours les problèmes suivants: * Si vous utilisez des formulaires, doit copier la valeur dans un champ caché . * Pour une raison quelconque, la page défile de manière amusante (la barre d'adresse de l'iPhone se cache, la console de débogage pour iPad se cache).

PS: J'ai trouvé cette technique indépendamment du commentaire de Ahmed Nuaman ci-dessus (je l'avais essayée dans le passé et j'avais remarqué son commentaire tout à l'heure - arrrgh!).

0
robocat

Votre problème serait résolu si Safari prend en charge l'attribut HTML5 'inputmode' pour les éléments d'entrée. Personne ne sait si ou quand cela se produira ..__ Entre-temps ce lien fournit une lecture intéressante.

0
rakensi

Il existe potentiellement un autre moyen de contourner le problème pour l'iPhone:

<input id="test" TYPE="text" value="5.50" ontouchstart="this.type='number'" onfocus="this.type='text'" />

Cela change le type en nombre avant l'entrée est activée lorsque vous la touchez (pour que le clavier numérique apparaisse), puis change le type en texte afin que la valeur correcte puisse être modifiée.

Il peut être difficile de le faire fonctionner de manière fiable, par exemple. touchez le contrôle en laissant le type = numéro, et je ne vois pas comment détecter le bouton Suivant du clavier, entre autres problèmes.

0
robocat

Nous avons fini par utiliser une solution bidirectionnelle pour permettre au clavier des chiffres et des ponctuations de montrer le focus sur celui qui fonctionne sur un iPhone: nous enregistrons les pressions de touche et simulons la valeur.

https://output.jsbin.com/necuzoj/quiet

Nous avons essayé de changer le type d'entrée de type = nombre en type = texte mis en évidence, mais ce n'était pas fiable: (1) le clavier numérique ne s'affiche pas à 100%, écran puis le défilement automatique pour montrer que l’entrée focalisée était complètement encombrée (l’entrée focalisée se trouvait parfois hors écran ou sous le clavier virtuel).

L'affichage du clavier numérique (par exemple type=tel) n'autorisait pas la saisie d'un signe décimal ou de deux points.

Sur un iPad, vous pouvez simplement utiliser <input type=text pattern=[0-9]*> pour afficher les chiffres et le clavier de ponctuation, mais cette solution ne fonctionne pas pour un iPhone (un iPhone affiche le pavé numérique sans décimale).

0
robocat