web-dev-qa-db-fra.com

Meilleurs paramètres pour HTML <input type = "number">, pour les appareils mobiles

J'ai lu beaucoup d'autres questions, comme celles-ci [1][2][3] par exemple, mais le problème persiste.

Je dois trouver le moyen le plus "propre" d'avoir un HTML input pour les appareils mobiles et qui respecte ces trois règles: 

  1. convient principalement pour les nombres, entier ou float
  2. affiche le clavier numérique sur les appareils mobiles, sur Chrome pour Android et Safari pour iOS, sans touches supplémentaires étranges

     enter image description here

  3. respecte pleinement les règles HTML5 (testé par le validateur W3)




Qu'ai-je essayé?

J'ai parcouru ces solutions, qui ne respectent ni l'un ni l'autre les trois règles ci-dessus.

Solution 1

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

 enter image description here

Bien que fonctionnant sous iOS et satisfaisant aux règles HTML testées par le validateur w3, présente dans Chrome Android le clavier complet avec le clavier QWERTY.


Solution 2

<input type="number" pattern="\d*" />

Cette solution fonctionne à la fois sur les systèmes iOS et Android Chrome, affichant le pavé numérique sur les deux systèmes, mais génère une erreur de validation HTML.

L'attribut pattern n'est autorisé que lorsque le type d'entrée est email, mot de passe, recherche, tel, texte ou url.


Solution 3

<input type="number" />

Cette solution réussit le test HTML, montre Nice sur Chrome, mais sur le clavier iOS, elle présente plusieurs clés indésirables.

 enter image description here


Solution 4

Je vois que beaucoup de développeurs utilisent cette solution

<input type="tel" />

Mais comme testé avec Android Chrome, il ne permet pas les symboles de points (.), Et les touches ont des lettres, ce qui est superflu. 

 chrome input type="tel"

Pour votre tâche spécifique, j'ai une solution extraordinaire: nous prenons la meilleure solution avec type="text" et pattern, puis ajoutons le JavaScript qui corrige l'attribut type. Nous le faisons pour passer par le validateur W3.

La solution

// iOS detection from: stackoverflow.com/a/9039885 with explanation about MSStream
if(/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream)
{
    var inputs = document.querySelectorAll('input[type="number"]');
    for(var i = inputs.length; i--;)
        inputs[i].setAttribute('pattern', '\\d*');
}
<input type="number" />

Ma solution respecte toutes vos trois règles (validateur W3 inclus).

Mais je dois mentionner que dans ce cas (avec motif) sur iOS, nous n’avons pas la possibilité de mettre des nombres flottants avec un clavier numérique, car sur iOS, nous n’avons aucun clavier avec des chiffres, y compris des points. Sur Android, nous avons cette possibilité. Si vous souhaitez avoir un clavier numérique avec des nombres flottants, vous devez écrire pour la solution supplémentaire iOS comme suit:

 <input type="number" />
3
Bharata

Comme indiqué dans les commentaires, comme il n’existe aucun moyen simple d’y parvenir, il est préférable de toujours utiliser un input type="number" avec une instruction if indiquant que si le périphérique est un périphérique iOS, le code ajoutera le bon attribut type.

1
James

Suivant la suggestion de @Alex Charters, je propose cette solution, utilisant jQuery, qui semble être la solution la plus rapide et la plus élégante. 

Ajouter ce morceau de code au "onload" de la page

//shows numeric keypad on iOS mobile devices
if(getMobileOperatingSystem() === "iOS"){
    $('input[type="number"]').attr("pattern", "\\d*");
}

La fonction de détection du système d’exploitation est la suivante, tirée de l’autre SO réponse :

/**
 * Determine the mobile operating system.
 * This function returns one of 'iOS', 'Android', 'Windows Phone', or 'unknown'.
 *
 * @returns {String}
 */
function getMobileOperatingSystem() {
  var userAgent = navigator.userAgent || navigator.vendor || window.opera;

      // Windows Phone must come first because its UA also contains "Android"
    if (/windows phone/i.test(userAgent)) {
        return "Windows Phone";
    }

    if (/Android/i.test(userAgent)) {
        return "Android";
    }

    // iOS detection from: http://stackoverflow.com/a/9039885/177710
    if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
        return "iOS";
    }

    return "unknown";
}

J'ai testé et il respecte les trois règles. Lorsque le système d'exploitation est iOS, il ajoute l'attribut pattern. Je ne le fais pas par défaut, car je me suis rendu compte que ledit morceau de code prend un certain temps à traiter en fonction du nombre d'entrées, et qu'il s'exécute donc uniquement lorsqu'il suppose un système d'exploitation iOS.