Bonjour,

J'ai un problème avec mon champ téléphone.

<fieldset>
              <label for="Telephone"><span class="underline">Téléphone</span></label>
              <input id="Telephone" name="Phone" type="tel" size="21" maxlength="20" pattern="[+0]{1}[0-9\.]{3,20}" autocomplete="tel" required>      
              </span>
            </fieldset> 


Si le client rentre 11.22.33.44 ça passe par contre si il n'y a pas les points, ça bloque l'envoi du formulaire. Genre 11223344. C'est le navigateur qui exige les points.

Merci de vos retours ?
salut...
c'est ton pattern qui exige les points Smiley cligne
-> \. <-

Très difficile de prévalider un téléphone

ce pattern

0[1-68]([-. ]?[0-9]{2}){4}

valide les modèles suivants

06 01 02 03 04
0601020304
06-01-02-03-04
06.01.02.03.04
Je viens de tester avec le n° du client ça passe. C'était un Suisse, je lui ai fait rajouter les points manuellement et le formulaire est parti. Bref, saloperie de téléphone. Je regarde ton retour.
Merci
pchlj, j'ai viré "\. " et là ça bloque tout. Tu as pas une combine ?

J'ai un JS, qui gère le formant national et inter qui marche nickel. Le truc c'est que des fois, le js ne fonctionne pas coté client ! C'est ce qui m'est arrivé avec mon client Suisse ce matin. Il était énervé, je lui ai dit rajouter des points, et hop ça passe. Je suis toujours ennuyé avec ce foutu JS sur le champ téléphone. Le site à besoin du JS, pour fonctionner donc si il arrive à la page formulaire, c'est que le JS fonctionne autrement il n'aurait pas accès à la page.

Peut-on personnaliser l'alerte Html5 genre merci de rajouter des points au format téléphone par exemple ?

Jencal, avait testé de son coté, et impossible de reproduire le gag. Greg Lumière aussi, c'est un mystère le plus complet Smiley bawling
Modérateur
Le plus simple et le plus propre est de ne pas trop s'embêter à vouloir être trop rigide si tu accepte toute les origines de téléphone.

1) Juste limiter les caractères pour éviter le full bullshit: genre: [0-9\-\+\s\(\)\.]*
2) si tu souhaites un format particulier, genre des points et non des espaces (ou le contraire), il faut l'expliciter clairement, ne pas attendre que l'utilisateur le devine par essai/erreur

Que fais-tu à la fin de ce numéro de téléphone et à quoi sert-il?
Bonjour kustolovic,

Il sert pour le livreur, je suis obliger de l'avoir pour le transporteur.

Ok, je vais expliquer au client qu'il faut des points, si il ne s'affiche pas. Je peux personnaliser mon alerte html5 ?

Merci.
Souvent il est plu simple d'avoir la balise title remplie Smiley cligne

"Format attendu : 00.00.00.00.00"
La personne le verra au survol Smiley smile et sinon l'écrire à côté ou en dessous du champs c'est bien aussi Smiley smile
Meilleure solution
Tintin75 a écrit :
Bonjour,
J'ai un problème avec mon champ téléphone.
&lt;fieldset&gt;
              &lt;label for="Telephone"&gt;&lt;span class="underline"&gt;Téléphone&lt;/span&gt;&lt;/label&gt;
              &lt;input id="Telephone" name="Phone" type="tel" size="21" maxlength="20" pattern="[+0]{1}[0-9\.]{3,20}" autocomplete="tel" required&gt;      
              &lt;/span&gt;
            &lt;/fieldset&gt; 

Si le client rentre 11.22.33.44 ça passe par contre si il n'y a pas les points, ça bloque l'envoi du formulaire. Genre 11223344. C'est le navigateur qui exige les points.
Merci de vos retours ?

Pourquoi t'embêter avec une expression régulière ?
Je suis plutôt dans le monde Java et pour ce type de problème je préfère, de loin, récupérer un à un les chiffres depuis le tampon en entrée, exclure les autres caractères et tester la longueur de la chaîne en sortie pour la valider ou non.
C'est bourrin, mais au moins on maîtrise ce qu'on veut récupérer au fur et à mesure où il se présente.
Une suggestion :
function getNumber($tel)
{
	$buffer = "";
	$length = strlen($tel);
	// Boucle sur tampon en entrée (optimiser le cas échéant
	// avec un for each...)
	for ($index = 0 ; $index < $length ; $index++)
	{
		// Récupération du caractère courant
		$char = $tel[$index];
		// Test si chiffre
		if (is_numeric($char))
		{
			// Insertion du séparateur "." si nécessaire et ajout
			// du caractère valide
			$buffer .= (strlen($buffer) % 3 == 2 ? "." : "") . $char;
		}
	}
	// Format OK = XX.XX.XX.XX.XX = longueur 14
	// Toute autre chaîne est rejetée
	return strlen($buffer) == 14 ? $buffer : "";
}

echo "processing<br>";
echo "phone [" . getNumber("01.02---03/04____05") . "]<br>";
echo "phone [" . getNumber("0102030405") . "]<br>";
echo "phone [" . getNumber("01.02.03.04.05") . "]<br>";
echo "Completed<br>";

Quelle que soit la chaîne reçue en paramètre, elle n'est acceptée que si on peut en extraire une séquence de type XX.XX.XX.XX.XX
Testé OK sur phptester.net.
processing
phone [01.02.03.04.05]
phone [01.02.03.04.05]
phone [01.02.03.04.05]
Completed

Ceci dit, je ne maîtrise pas, pour l'instant, PHP, donc code ci-dessus restant à vérifier et valider par les cadors du PHP écumant le présent forum.
Je te laisse par contre le soin d'adapter le code si tu veux gérer l'indicatif international...
Modifié par sepecat (03 Mar 2018 - 00:00)
Bonjour sepecat,

Le code coté client est en js naturellement mais par sécurité, je l'ai doublé en php, pour êtres sur de l'avoir au bon format à la réception.

Ce que l'on explique pas, c'est que des fois, le js, ne s'active pas pour le format du téléphone alors que j'ai une autre fonction js sur le formulaire qui fonctionne.

Je te donne le code en question :

'use-strict';

document.addEventListener('DOMContentLoaded', function() {
    let phoneFields = document.querySelectorAll('[type="tel"]');
    let phoneFieldsLength = phoneFields.length;
    if (phoneFieldsLength <= 0) {
        return;
    }
    for (let i = 0; i < phoneFieldsLength; ++i) phoneFields[i].addEventListener('keyup', function () {
        let phoneNumber = phoneFields[i].value;
        if (phoneNumber.substr(0, 2) === '00') {
            phoneNumber = phoneNumber.substr(0, 2).replace('00', '+');
        }
        phoneNumber = phoneNumber.replace(/[-./ ,()]/g, '');
        if (phoneNumber.substr(0, 1) === '+') {
            if (phoneNumber >= 4) {
                phoneNumber = phoneNumber.split(/^(.{4})(.+)/);
                if (typeof phoneNumber[1] !== 'undefined') {
                    phoneNumber[1] = phoneNumber[1].replace(/^(.{3})(.{1})/, "$1.$2.");
                }
                if (typeof phoneNumber[1] !== 'undefined') {
                    phoneNumber[2] = phoneNumber[2].replace(/(.{2})(?=.)/g, "$1.");
                }
                phoneNumber = phoneNumber.join('');
            }
        } else {
            /** Numéro national **/
            phoneNumber = phoneNumber.replace(/(.{2})(?=.)/g, "$1.");
        }
        phoneFields[i].value = phoneNumber;
    }, false);
}, false);


Réalisation Greg Lumière, ça fonctionne super bien. Greg est pas spécialiste du JS, et il a codé comme il a pu. Il y a peut être des améliorations dans le code à produire ? Quoi qu'il en soit, mon problème vient de ce code qui fait quelques fois des caprices. Smiley decu

Merci par avance pour ton avis. Smiley smile
Modifié par Tintin75 (03 Mar 2018 - 10:47)
Tintin75 a écrit :
Bonjour sepecat,

Le code coté client est en js naturellement mais par sécurité, je l'ai doublé en php, pour êtres sur de l'avoir au bon format à la réception.

Ce que l'on explique pas, c'est que des fois, le js, ne s'active pas pour le format du téléphone alors que j'ai une autre fonction js sur le formulaire qui fonctionne.

Je te donne le code en question :

'use-strict';

document.addEventListener('DOMContentLoaded', function() {
    let phoneFields = document.querySelectorAll('[type="tel"]');
    let phoneFieldsLength = phoneFields.length;
    if (phoneFieldsLength &lt;= 0) {
        return;
    }
    for (let i = 0; i &lt; phoneFieldsLength; ++i) phoneFields[i].addEventListener('keyup', function () {
        let phoneNumber = phoneFields[i].value;
        if (phoneNumber.substr(0, 2) === '00') {
            phoneNumber = phoneNumber.substr(0, 2).replace('00', '+');
        }
        phoneNumber = phoneNumber.replace(/[-./ ,()]/g, '');
        if (phoneNumber.substr(0, 1) === '+') {
            if (phoneNumber &gt;= 4) {
                phoneNumber = phoneNumber.split(/^(.{4})(.+)/);
                if (typeof phoneNumber[1] !== 'undefined') {
                    phoneNumber[1] = phoneNumber[1].replace(/^(.{3})(.{1})/, "$1.$2.");
                }
                if (typeof phoneNumber[1] !== 'undefined') {
                    phoneNumber[2] = phoneNumber[2].replace(/(.{2})(?=.)/g, "$1.");
                }
                phoneNumber = phoneNumber.join('');
            }
        } else {
            /** Numéro national **/
            phoneNumber = phoneNumber.replace(/(.{2})(?=.)/g, "$1.");
        }
        phoneFields[i].value = phoneNumber;
    }, false);
}, false);


Réalisation Greg Lumière, ça fonctionne super bien. Greg est pas spécialiste du JS, et il a codé comme il a pu. Il y a peut être des améliorations dans le code à produire ? Quoi qu'il en soit, mon problème vient de ce code qui fait quelques fois des caprices. Smiley decu

Merci par avance pour ton avis. Smiley smile

Perso, je crois que je n'utiliserais pas l'événement "keyup" mais plutôt "blur", afin de ne tester la validité du texte saisi que lors de la perte de focalisation clavier du champ.
Si j'ai bien compris et sous sa forme présente, le code effectue, à mon sens, trop de traitements dès lors qu'une touche a été relâchée par l'utilisateur, sans que cela n'apporte un réel plus.
En utilisant plutôt la perte de focus "blur" : si la valeur entrée est correcte, aucune action particulière - a contrario si la valeur ne satisfait pas le contrôle, alors affichage d'un message ou style de la balise INPUT avec une bordure du rouge, par exemple.
Ce qui me gène un peu dans la version actuelle, c'est qu'un "keyup" va pour chaque touche frappée récupérer la valeur (let phoneNumber = phoneFields.value;), déclencher un contrôle et la réécrire dans le champ (phoneFields[i].value = phoneNumber;), éventuellement modifiée.
Je reste un brin dubitatif Smiley smile mais bon, JS n'est pas non plus le langage que j'utilise au quotidien et j'essaie au maximum de minimiser son usage dans mes pages HTML.
[/i]
Je vais transmettre à Greg pour qu'il jette un oeil, vue que c'est lui qui a codé.

Merci pour ton retour, c'est sympa.

Bon week-end. Smiley cligne
Modifié par Tintin75 (03 Mar 2018 - 17:29)
Modérateur
Bonjour,

Il est des sujets qui ont tendance à faire couler de l'encre et celui-ci en fait définitivement partie.

Je suis maintenant en mesure de pouvoir vous apporter des précisions mais avant j'aimerai revenir sur vos réponses.

@Sepecat: Je suis tout à fait de ton avis quand à l'utilisation de JS. En effet, je préfère ne lui attribuer que des missions de confort non indispensables aux pages mais là, le demandeur l'exige. Je m'y plie.
J'ai bien noté ta suggestion sur le type d'évènement à mettre en surveillance et j’admets que la charge serait moindre avec un évènement de type blur.
L'idée aussi selon laquelle tu découpe la chaîne en caractères individuels me reste dans un coin de l'esprit. Je pense implémenter cette méthode dans la validation côté serveur. En effet pour l'heure je traite la chaîne dans son intégrité et la rend invalide si elle ne contient pas que les caractères autorisé - ce qui implique de faire une liste des caractères interdits. Ta méthode permet de prendre la chose par son envers et de ne valider que les caractères autorisés.

@pchlj: l'usage de l'attribut title comme aide à la saisie n'est pas judicieuse. Un seul mot: tactile. En effet, comment fais-tu pour faire afficher le title sur ce type de périphérique de saisie ? L'aide à la saisie apparaîtra via une balise adjacente ; j'ai ma petite idée sur la question.

@kustolovic: Certes, nous souhaitons éviter le "full bullshit" comme tu dis. Chose faite par l'utilisation d'un pattern (plus souple) et de l'attribut maxlength mais surtout d'une validation côté serveur imperméable. Nous n'utiliserons pas JS pour la validation, juste pour la mise en forme.

Merci à tous pour votre participation qui, comme toujours, est fort instructive et mérite réflexion.


Maintenant, pour en revenir au vif du sujet, grâce à la journalisation des visites de Tintin, nous avons pus cerner le cas de figure où le script JS ne fonctionnait pas.
L'agent utilisateur révèle que l'utilisateur était sur Internet Explorer 11 (ou un ersatz). Je n'ai pas encore mis le doigt sur le pourquoi la validation du formulaire était impossible sans les points (j'ai besoin du concours de Tintin qui est indisponible pour le moment) mais je sais avec exactitude pourquoi le script ne fonctionne pas.

En effet cette ligne renvoi un message d'erreur:
let phoneNumber = phoneFields[i].value;

Le message retourné à la saisie est : Impossible d’obtenir la propriété « value » d’une référence null ou non définie
Chose incompréhensible car querySelectorAll() fonctionne depuis IE9 et si phoneFields se révélait être vide, le script n'exécuterait pas jusqu'à ce point. De plus, .value semble lui aussi compatible IE11 donc mystère et boule de gomme.

Hormis le fait qu'il me faille faire en sorte que la validation du formulaire soit possible même si le script JS n'est pas actif (chose simple au demeurant). Je ne comprends pas comment rendre ce dernier compatible IE11.
Modifié par Greg_Lumiere (11 Mar 2018 - 17:46)
Modérateur
Bon en fait c'est pire que ce que je croyais. Ce n'est pas seulement .value qui pose problème mais la syntaxe générale du script.

Le moteur JS de IE11 ne tolère pas mon écriture: il rejette let en indiquant une erreur de syntaxe, n'admet pas le coup de la fonction anonyme pendant la déclaration d'évènement en me réclamant un point-virgule là où il n'y a pas lieu d'être etc...

Sans trop être sûr je pense que mes leçons portaient sur ES6 alors que lui ne comprend pas plus loin que ES5.

Hésitant certes, mais j'ai tout de même trouvé une solution que je vais de ce pas vous expliciter.

Tout d'abord je me suis servis de BabelJS afin de convertir mon script en ES5 et l'ai testé sur IE 11. Ouf, il fonctionne.
J'aurais aimé le faire par moi même mais mes compétences en ce domaine sont insuffisantes.

Ensuite je place cette copie dans un fichier à part. Ce sera mon polyfill.

Enfin, dans mon fichier originel j'ai rajouté 2 choses:
- une fonction qui vérifie que des instructions propres à ES 6 sont reconnues
- une condition sur la fonction précédente. Si le résultat est négatif, on crée un élément script qui charge le polyfill sinon on exécute le code qui vous a été présenté.


Pas sûr que ce puisse être le meilleur moyen mais il a le mérite de fonctionner. Ce qui reste déplaisant est de se retrouver ainsi avec 2 versions d'un même code à maintenir pour encore quelques années.
Modifié par Greg_Lumiere (12 Mar 2018 - 14:15)