{"id":7481,"date":"2020-06-21T13:14:40","date_gmt":"2020-06-21T11:14:40","guid":{"rendered":"https:\/\/www.creativejuiz.fr\/blog?p=7481"},"modified":"2020-07-07T14:59:39","modified_gmt":"2020-07-07T12:59:39","slug":"code-unique-sms-code-verification-suggestion-clavier-smartphone","status":"publish","type":"post","link":"https:\/\/www.creativejuiz.fr\/blog\/tutoriels\/code-unique-sms-code-verification-suggestion-clavier-smartphone","title":{"rendered":"Code Unique de V\u00e9rification : compatible avec les suggestions du clavier"},"content":{"rendered":"<p>Les exp\u00e9riences les plus douloureuses sur le mobile sont tr\u00e8s certainement celles sur les formulaires en ligne qu&rsquo;il faut remplir ici et l\u00e0. Et si vous optimisiez ces exp\u00e9riences \u00e9tape par \u00e9tape ? Aujourd&rsquo;hui, je vous propose une solution pour la saisie d&rsquo;un code unique temporaire : Vous recevez le SMS avec un code, votre clavier vous le sugg\u00e8re &#8211; un seul tap, c&rsquo;est fait ! Ok, c&rsquo;est parti !<\/p>\n<p><!--more--><\/p>\n<p>G\u00e9n\u00e9ralement, lorsque je propose un formulaire, court ou long, je veux optimiser l&rsquo;exp\u00e9rience pour la rendre la moins douloureuse possible. Pour ce faire, j&rsquo;\u00e9tudie le comportement de mes utilisateurs en testant des solutions et en profitant des fonctionnalit\u00e9s que les terminaux (mobiles notamment) apportent avec les nouvelles versions, d&rsquo;un point de vue mat\u00e9riel et logiciel.<\/p>\n<p>M\u00eame si cet article ressemble \u00e0 un article technique, il est en partie une r\u00e9ponse apr\u00e8s de la recherche utilisateur et de certaines r\u00e8gles d&rsquo;ergonomie :<\/p>\n<ul>\n<li>Le champ correspond \u00e0 la longueur des donn\u00e9es attendues,<\/li>\n<li>La forme du champ aide \u00e0 la d\u00e9couverte et facilite l&rsquo;intention,<\/li>\n<li>Aide \u00e0 la saisie en guidant l&rsquo;utilisateur,<\/li>\n<li>Anticipation des erreurs par la pr\u00e9vention des erreurs de formatage.<\/li>\n<\/ul>\n<h2>La d\u00e9monstration<\/h2>\n<p>\u00ab\u00a0Un clic, c&rsquo;est fait !\u00a0\u00bb, oui, vous avez raison de ne pas me faire confiance, mais voici comment vous pouvez le tester.<\/p>\n<ul>\n<li>Allez sur la page de d\u00e9mo sur CodePen: <a href=\"https:\/\/codepen.io\/GeoffreyCrofte\/full\/zYrxKRe\">One Time Code Demo<\/a>.<\/li>\n<li>Envoyez-vous un SMS avec le texte suivant :<br \/>\n<div class=\"code-embed-wrapper\"> <pre class=\"language-markup code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-markup code-embed-code\">Your verification code is 133-742<\/code><\/pre> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">The SMS text<\/span> <\/div> <\/div><\/li>\n<li>Retournez \u00e0 la page de d\u00e9monstration et touchez l&rsquo;un des champs.<\/li>\n<li>Votre clavier doit vous sugg\u00e9rer le dernier code re\u00e7u.<\/li>\n<\/ul>\n<p class=\"message\"><strong>Note :<\/strong> Parfois, android ne se soucie pas de tout \u00e7a, cela d\u00e9pend de la surcouche de votre fournisseur ou constructeur, ou du clavier que vous avez install\u00e9 et de ses param\u00e8tres. Mais si vous \u00eates sur la derni\u00e8re version d&rsquo;iOS, vous devriez pouvoir g\u00e9rer cela comme un pro.<\/p>\n<h2>Comment le code unique par SMS fonctionne ?<\/h2>\n<p>Pour que la magie op\u00e8re, le syst\u00e8me d&rsquo;exploitation expose le dernier code SMS re\u00e7u pour qu&rsquo;il soit utilis\u00e9 par des applications comme votre clavier. Si le formulaire actuel demande ce code, votre clavier s&rsquo;adapte et propose le code comme suggestion.<\/p>\n<p class=\"center\"><img decoding=\"async\" class=\"alignnone wp-image-7468\" src=\"https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2020\/06\/one-time-code-6-digits-numeric-sms-autocomplete-keyboard-suggestion.jpg\" alt=\"Keyboard Code Suggestion\" width=\"250\" height=\"542\" srcset=\"https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2020\/06\/one-time-code-6-digits-numeric-sms-autocomplete-keyboard-suggestion.jpg 739w, https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2020\/06\/one-time-code-6-digits-numeric-sms-autocomplete-keyboard-suggestion-139x300.jpg 139w, https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2020\/06\/one-time-code-6-digits-numeric-sms-autocomplete-keyboard-suggestion-277x600.jpg 277w, https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2020\/06\/one-time-code-6-digits-numeric-sms-autocomplete-keyboard-suggestion-709x1536.jpg 709w\" sizes=\"(max-width: 250px) 100vw, 250px\" \/> <img decoding=\"async\" class=\"alignnone wp-image-7470\" src=\"https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2020\/06\/one-time-code-6-digits-numeric-sms-autocomplete-keyboard-suggestion-filled.jpg\" alt=\"The autocompleted fields\" width=\"250\" height=\"542\" srcset=\"https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2020\/06\/one-time-code-6-digits-numeric-sms-autocomplete-keyboard-suggestion-filled.jpg 739w, https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2020\/06\/one-time-code-6-digits-numeric-sms-autocomplete-keyboard-suggestion-filled-139x300.jpg 139w, https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2020\/06\/one-time-code-6-digits-numeric-sms-autocomplete-keyboard-suggestion-filled-277x600.jpg 277w, https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2020\/06\/one-time-code-6-digits-numeric-sms-autocomplete-keyboard-suggestion-filled-709x1536.jpg 709w\" sizes=\"(max-width: 250px) 100vw, 250px\" \/><\/p>\n<p>D&rsquo;accord, mais comment demander ce code ? C&rsquo;est assez simple, mais vous ne pouvez pas le deviner si vous ne connaissez pas les possibilit\u00e9s de HTML5. Parmi les nombreuses connaissances peu communes, on trouve les attributs de <code>autocomplete<\/code> et ses nombreuses valeurs. Son utilisation n&rsquo;est pas si difficile, vous devez correspondre \u00e0 la valeur d&rsquo;une <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Attributes\/autocomplete\">liste existante de valeurs<\/a> standard qui ne cesse de s&rsquo;allonger.<\/p>\n<div class=\"code-embed-wrapper\"> <pre class=\"language-markup code-embed-pre line-numbers\"  data-line=\"2\" data-start=\"1\" data-line-offset=\"0\"><code class=\"language-markup code-embed-code\">&lt;label for=&quot;otc&quot;&gt;SMS Code Received&lt;\/label&gt;<br\/>&lt;input type=&quot;text&quot; autocomplete=&quot;one-time-code&quot; id=&quot;otc&quot; name=&quot;otc&quot; aria-label=&quot;Enter the 6 Digits code you received by SMS&quot;&gt;<\/code><\/pre> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">A One Time Code example<\/span> <\/div> <\/div>\n<p>Une fois que vous avez fait cela, votre champ SMS One Time Code est pr\u00eat. Pas besoin d&rsquo;en faire plus ici.<\/p>\n<p>Mais comme je vous l&rsquo;ai dit, j&rsquo;aime \u00eatre complet dans ma proposition d&rsquo;interface, et j&rsquo;ai d\u00e9cid\u00e9 d&rsquo;aller plus loin avec une forme \u00e0 6 entr\u00e9es.<\/p>\n<h2>Formulaire en forme de code SMS \u00e0 6 chiffres<\/h2>\n<p>J&rsquo;ai d\u00e9cid\u00e9 d&rsquo;utiliser un formulaire \u00e0 6 champs, mais avec un formulaire \u00e0 1 entr\u00e9e proposant un design comme si c&rsquo;\u00e9tait 6 champs c\u00f4t\u00e9 ) c\u00f4t\u00e9 aurait aussi pu suffire. Comme je le dis souvent, c&rsquo;est la magie du HTML\/CSS et du JS, 1 solution, plusieurs fa\u00e7ons d&rsquo;y parvenir.<\/p>\n<div style=\"width: 295px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-7481-1\" width=\"295\" height=\"640\" loop autoplay preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2020\/06\/one-time-code-6-digits-sms-autocomplete.mp4?_=1\" \/><a href=\"https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2020\/06\/one-time-code-6-digits-sms-autocomplete.mp4\">https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2020\/06\/one-time-code-6-digits-sms-autocomplete.mp4<\/a><\/video><\/div>\n<p>Pourquoi ferais-je cela ? Parce que lorsque l&rsquo;utilisateur re\u00e7oit son code SMS, le format est assez clair : 3 chiffres, 1 tiret, 3 chiffres. Je veux que mon formulaire ressemble au code re\u00e7u.<\/p>\n<div class=\"code-embed-wrapper\"> <pre class=\"language-markup code-embed-pre line-numbers\"  data-line=\"13\" data-start=\"1\" data-line-offset=\"0\"><code class=\"language-markup code-embed-code\">&lt;form class=&quot;otc&quot; name=&quot;one-time-code&quot; action=&quot;#&quot;&gt;<br\/>\t&lt;fieldset&gt;<br\/>\t\t&lt;legend&gt;Validation Code&lt;\/legend&gt;<br\/>\t\t&lt;label for=&quot;otc-1&quot;&gt;Number 1&lt;\/label&gt;<br\/>\t\t&lt;label for=&quot;otc-2&quot;&gt;Number 2&lt;\/label&gt;<br\/>\t\t&lt;label for=&quot;otc-3&quot;&gt;Number 3&lt;\/label&gt;<br\/>\t\t&lt;label for=&quot;otc-4&quot;&gt;Number 4&lt;\/label&gt;<br\/>\t\t&lt;label for=&quot;otc-5&quot;&gt;Number 5&lt;\/label&gt;<br\/>\t\t&lt;label for=&quot;otc-6&quot;&gt;Number 6&lt;\/label&gt;<br\/><br\/>\t\t&lt;div&gt;<br\/>\t\t\t&lt;!-- https:\/\/developer.apple.com\/documentation\/security\/password_autofill\/enabling_password_autofill_on_an_html_input_element --&gt;<br\/>\t\t\t&lt;input type=&quot;number&quot; pattern=&quot;[0-9]*&quot;  value=&quot;&quot; inputtype=&quot;numeric&quot; autocomplete=&quot;one-time-code&quot; id=&quot;otc-1&quot; required&gt;<br\/><br\/>\t\t\t&lt;!-- Autocomplete not to put on other input --&gt;<br\/>\t\t\t&lt;input type=&quot;number&quot; pattern=&quot;[0-9]*&quot;  value=&quot;&quot; inputtype=&quot;numeric&quot; id=&quot;otc-2&quot; required&gt;<br\/>\t\t\t&lt;input type=&quot;number&quot; pattern=&quot;[0-9]*&quot;  value=&quot;&quot; inputtype=&quot;numeric&quot; id=&quot;otc-3&quot; required&gt;<br\/>\t\t\t&lt;input type=&quot;number&quot; pattern=&quot;[0-9]*&quot;  value=&quot;&quot; inputtype=&quot;numeric&quot; id=&quot;otc-4&quot; required&gt;<br\/>\t\t\t&lt;input type=&quot;number&quot; pattern=&quot;[0-9]*&quot;  value=&quot;&quot; inputtype=&quot;numeric&quot; id=&quot;otc-5&quot; required&gt;<br\/>\t\t\t&lt;input type=&quot;number&quot; pattern=&quot;[0-9]*&quot;  value=&quot;&quot; inputtype=&quot;numeric&quot; id=&quot;otc-6&quot; required&gt;<br\/>\t\t&lt;\/div&gt;<br\/>\t&lt;\/fieldset&gt;<br\/>&lt;\/form&gt;<\/code><\/pre> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">The HTML Form<\/span> <\/div> <\/div>\n<p>Comme vous pouvez le voir, j&rsquo;ai utilis\u00e9 un <code>fieldset<\/code> pour regrouper les champs sous une m\u00eame <code>legend<\/code>. Chaque entr\u00e9e a son propre <code>label<\/code> li\u00e9 gr\u00e2ce aux attributs <code>for<\/code> et <code>id<\/code>, comme il est recommand\u00e9 pour des raisons d&rsquo;accessibilit\u00e9. Malgr\u00e9 toutes ces attentions, je ne suis pas s\u00fbr que la solution soit si bonne pour les lecteurs d&rsquo;\u00e9cran (peut-\u00eatre un peu trop lourde \u00e0 lire), je vais essayer de faire d&rsquo;autres tests apr\u00e8s la publication et je reviendrai vers vous plus tard.<\/p>\n<p>Pour l&rsquo;instant, vous ne devriez pas avoir la forme la plus sexy de votre vie. Les champs num\u00e9riques et toutes ces \u00e9tiquettes&#8230; Mais passons maintenant \u00e0 la partie CSS.<\/p>\n<div class=\"code-embed-wrapper\"> <pre class=\"language-css code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-css code-embed-code\">.otc label {<br\/>\tborder: 0;<br\/>\tclip: rect(1px, 1px, 1px, 1px);<br\/>\t-webkit-clip-path: inset(50%);<br\/>\tclip-path: inset(50%);<br\/>\theight: 1px;<br\/>\tmargin: -1px;<br\/>\toverflow: hidden;<br\/>\tpadding: 0;<br\/>\tposition: absolute;<br\/>\twidth: 1px;<br\/>\twhite-space: nowrap;<br\/>}<\/code><\/pre> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">This hides label visually<\/span> <\/div> <\/div>\n<p>La premi\u00e8re chose que j&rsquo;ai faite est de cacher les <code>label<\/code> visuellement, mais pas pour les lecteurs d&rsquo;\u00e9cran. Code propos\u00e9 par <a href=\"https:\/\/gist.github.com\/ffoodd\/000b59f431e3e64e4ce1a24d5bb36034\">ffoodd<\/a> et utilis\u00e9 dans tous mes projets depuis un certain temps.<\/p>\n<div class=\"code-embed-wrapper\"> <pre class=\"language-css code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-css code-embed-code\">.otc {<br\/>\tposition: relative;<br\/>\twidth: 320px;<br\/>\tmargin: 0 auto;<br\/>\tfont-size: 2.65em;<br\/>}<br\/><br\/>.otc fieldset {<br\/>\tborder: 0;<br\/>\tpadding: 0;<br\/>\tmargin: 0;<br\/>}<br\/><br\/>.otc div {<br\/>\tdisplay: flex;<br\/>\talign-items: center;<br\/>}<br\/><br\/>.otc legend {<br\/>\tmargin: 0 auto 1em;<br\/>\tcolor: #5555FF;<br\/>}<\/code><\/pre> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">Global Form width and fieldset styling<\/span> <\/div> <\/div>\n<p>J&rsquo;ai ensuite donn\u00e9 une dimension \u00e0 mon formulaire pour le centrer, et j&rsquo;ai supprim\u00e9 certains styles par d\u00e9faut des champs et des l\u00e9gendes (principalement les bordures et les espaces), la mise en page flexbox permet d&rsquo;anticiper le petit alignement des tirets entre les champs.<\/p>\n<div class=\"code-embed-wrapper\"> <pre class=\"language-css code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-css code-embed-code\">input[type=&quot;number&quot;] {<br\/>\twidth: .82em;<br\/>\tline-height: 1;<br\/>\tmargin: .1em;<br\/>\tpadding: 8px 0 4px;<br\/>\tfont-size: 2.65em;<br\/>\ttext-align: center;<br\/>\tappearance: textfield;<br\/>\t-webkit-appearance: textfield;<br\/>\tborder: 2px solid #BBBBFF;<br\/>\tcolor: purple;<br\/>\tborder-radius: 4px;<br\/>}<br\/><br\/>input::-webkit-outer-spin-button,<br\/>input::-webkit-inner-spin-button {<br\/>  -webkit-appearance: none;<br\/>  margin: 0;<br\/>}<\/code><\/pre> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">Code to style input number<\/span> <\/div> <\/div>\n<p>Ce code sert \u00e0 styliser nos entr\u00e9es de type <code>number<\/code>, avec une petite astuce pour notre ami Chrome qui doit \u00eatre stylis\u00e9 gr\u00e2ce \u00e0 des pseudo-classes (l.15). De cette fa\u00e7on, vous devriez d\u00e9j\u00e0 avoir quelque chose de plus attrayant : nous avons dimensionn\u00e9 les champs (principalement gr\u00e2ce \u00e0 la taille de la police) et supprim\u00e9 les boutons d&rsquo;incr\u00e9ment. Il ne nous reste plus qu&rsquo;\u00e0 \u00ab\u00a0grouper\u00a0\u00bb les champs 3 par 3. Faisons cela, d&rsquo;accord ?<\/p>\n<div class=\"code-embed-wrapper\"> <pre class=\"language-css code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-css code-embed-code\">input[type=&quot;number&quot;]:nth-of-type(n+4) {<br\/>\torder: 2;<br\/>}<br\/><br\/>.otc div::before {<br\/>\tcontent: &#039;&#039;;<br\/>\theight: 2px;<br\/>\twidth: 24px;<br\/>\tmargin: 0 .25em;<br\/>\torder: 1;<br\/>\tbackground: #BBBBFF;<br\/>}<\/code><\/pre> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">The little dash in between<\/span> <\/div> <\/div>\n<p>Ici j&rsquo;ajoute un tiret gr\u00e2ce \u00e0 un pseudo-\u00e9l\u00e9ment <code>::before<\/code> et je cr\u00e9e visuellement 2 groupes. Le pseudo-\u00e9l\u00e9ment agit comme un autre enfant \u00e0 c\u00f4t\u00e9 de toutes les entr\u00e9es. Si vous ne g\u00e9rez pas l&rsquo;ordre gr\u00e2ce \u00e0 la propri\u00e9t\u00e9 <code>order<\/code>, le tiret est \u00e0 la premi\u00e8re position. Pour le faire appara\u00eetre \u00e0 la quatri\u00e8me place, j&rsquo;ai d\u00fb dire aux 3 derniers champs d&rsquo;\u00eatre \u00e0 la deuxi\u00e8me place (<code>order: 2<\/code>), le tiret \u00e0 la premi\u00e8re (<code>order: 1<\/code>) et les autres sont par d\u00e9faut \u00e0 la place z\u00e9ro (<code>order: 0<\/code>). Ouais, les d\u00e9veloppeurs vous savez\u2026 le 0 est le premier dans cette suite logique \ud83d\ude1c<\/p>\n<p>Et voil\u00e0 !<\/p>\n<h2>Mettons du JavaScript pour am\u00e9liorer l&rsquo;exp\u00e9rience de l&rsquo;utilisateur<\/h2>\n<p>En divisant un champs en 6 champs, nous avons voulu am\u00e9liorer l&rsquo;assistance en guidant l&rsquo;utilisateur pour qu&rsquo;il comprenne plus rapidement le format attendu. Une information plus facile \u00e0 scanner. Mais pour l&rsquo;instant, le formulaire n&rsquo;est pas du tout utilisable, nous l&rsquo;avons rendu pire que mieux si on en reste l\u00e0.<\/p>\n<p>Nous devons couvrir plusieurs choses ici :<\/p>\n<ul>\n<li>Lorsque je remplis un champ, je passe au suivant,<\/li>\n<li>Lorsque je supprime un contenu (backspace), je passe au champ pr\u00e9c\u00e9dent,<\/li>\n<li>Lorsque je clique sur un champ vide, si le champ pr\u00e9c\u00e9dent est vide, je me place dessus,<\/li>\n<li>Lorsque je copie\/colle un code dans le premier champ, je dois couper le code et remplir les autres entr\u00e9es.<\/li>\n<\/ul>\n<p class=\"message important\">Le code JavaScript propos\u00e9 ci-dessous a un peu \u00e9volu\u00e9 si vous le comparez au CodePen. Celui de CodePen est plus avanc\u00e9 et \u00e9galement comment\u00e9. Je mettrai \u00e0 jour l&rsquo;article prochainement.<\/p>\n<p>Allons-y ! Je vous montre le code et vous l&rsquo;explique juste apr\u00e8s.<\/p>\n<div class=\"code-embed-wrapper\"> <pre class=\"language-javascript code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-javascript code-embed-code\">let in1 = document.getElementById(&#039;otc-1&#039;),<br\/>    ins = document.querySelectorAll(&#039;input[type=&quot;number&quot;]&#039;);<br\/><br\/>ins.forEach(function(input) {<br\/>\t\/**<br\/>\t * Control on keyup to catch what the user intent to do.<br\/>\t * I could have check for numeric key only here, but I didn&#039;t.<br\/>\t *\/<br\/>\tinput.addEventListener(&#039;keyup&#039;, function(e){<br\/>\t\t\/\/ Break if Shift, Tab, CMD, Option, Control.<br\/>\t\tif (e.keyCode === 16 || e.keyCode == 9 || e.keyCode == 224 || e.keyCode == 18 || e.keyCode == 17) {<br\/>\t\t\t return;<br\/>\t\t}<br\/>\t\t<br\/>\t\t\/\/ On Backspace or left arrow, go to the previous field.<br\/>\t\tif ( (e.keyCode === 8 || e.keyCode === 37) &amp;&amp; this.previousElementSibling &amp;&amp; this.previousElementSibling.tagName === &quot;INPUT&quot; ) {<br\/>\t\t\tthis.previousElementSibling.select();<br\/>\t\t} else if (e.keyCode !== 8 &amp;&amp; this.nextElementSibling) {<br\/>\t\t\tthis.nextElementSibling.select();<br\/>\t\t}<br\/>\t});<br\/>\t<br\/>\t\/**<br\/>\t * Better control on Focus<br\/>\t * - don&#039;t allow focus on other field if the first one is empty<br\/>\t * - don&#039;t allow focus on field if the previous one if empty (debatable)<br\/>\t * - get the focus on the first empty field<br\/>\t *\/<br\/>\tinput.addEventListener(&#039;focus&#039;, function(e) {<br\/>\t\t\/\/ If the focus element is the first one, do nothing<br\/>\t\tif ( this === in1 ) return;<br\/>\t\t<br\/>\t\t\/\/ If value of input 1 is empty, focus it.<br\/>\t\tif ( in1.value == &#039;&#039; ) {<br\/>\t\t\tin1.focus();<br\/>\t\t}<br\/>\t\t<br\/>\t\t\/\/ If value of a previous input is empty, focus it.<br\/>\t\t\/\/ To remove if you don&#039;t wanna force user respecting the fields order.<br\/>\t\tif ( this.previousElementSibling.value == &#039;&#039; ) {<br\/>\t\t\tthis.previousElementSibling.focus();<br\/>\t\t}<br\/>\t});<br\/>});<br\/><br\/>\/**<br\/> * Handle copy\/paste of a big number.<br\/> * It catches the value pasted on the first field and spread it into the inputs.<br\/> *\/<br\/>in1.addEventListener(&#039;input&#039;, function(e) {<br\/>\tlet data = e.data || this.value; \/\/ Chrome doesn&#039;t get the e.data, it&#039;s always empty, fallback to value then.<br\/>\tif ( ! data ) return; \/\/ Shouldn&#039;t happen, just in case.<br\/>\tif ( data.length === 1 ) return; \/\/ Here is a normal behavior, not a paste action.<br\/>\t<br\/>\tfor (i = 0; i &lt; data.length; i++ ) {<br\/>\t\tins[i].value = data[i];<br\/>\t}<br\/>});<\/code><\/pre> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">The JavaScript to make this form smart<\/span> <\/div> <\/div>\n<p>De la ligne 11 \u00e0 13, je ne fais plus rien avec les touches Shift, Tab, CMD, Option, Control pour \u00e9viter les probl\u00e8mes. De la ligne 16 \u00e0 20, je g\u00e8re les fonctions Pr\u00e9c\u00e9dent\/Suivant. De 29 \u00e0 43, je m&rsquo;occupe du focus sur les champs. L&rsquo;id\u00e9e ici est que si je tape\/clique sur un champ autre que le premier, je force le focus sur le premier champ. C&rsquo;est surtout pour les utilisateurs de smartphones. Mais pour \u00eatre plus intelligent, si certains champs sont d\u00e9j\u00e0 remplis, nous mettons le focus sur le premier champ vide.<\/p>\n<p>Les derni\u00e8res lignes de JavaScript sont l\u00e0 pour g\u00e9rer un copier\/coller, ou l&rsquo;autosuggestion du clavier d&rsquo;un smartphone. Dans ce cas, tout le contenu du code est plac\u00e9 dans ce premier champ. Nous prenons la valeur de ce champ et la divisons pour distribuer les valeurs dans les champs suivants.<\/p>\n<h2>Code Unique : \u00e0 retenir<\/h2>\n<p>Ok, nous l&rsquo;avons fait. Mais n&rsquo;oubliez pas que c&rsquo;est un pattern issu d&rsquo;un de mes besoins, elle n&rsquo;est peut-\u00eatre pas parfaite, mais pour mon cas d&rsquo;utilisation, elle est suffisante. Quelques petites choses \u00e0 rappeler et \u00e0 emporter avec vous.<\/p>\n<ul>\n<li>Utilisez <code>autocomplete=\"one-time-code\"<\/code> pour d\u00e9clencher l&rsquo;autosuggestion de votre smartphone.<\/li>\n<li>Utilisez une combinaison de <code>pattern=\"[0-9]*\"<\/code> et <code>inputtype=\"numeric\"<\/code> pour d\u00e9clencher le clavier num\u00e9rique de votre smartphone.<\/li>\n<li>Lorsque vous cr\u00e9ez des formulaires complexes, essayez de dimensionner\/styliser le champ en fonction des donn\u00e9es attendues.<\/li>\n<li>N&rsquo;oubliez pas de tester vos formulaires en y naviguant avec le clavier uniquement, et avec un lecteur d&rsquo;\u00e9cran.<\/li>\n<\/ul>\n<p>Merci pour votre lecture. Je suis ouvert aux <strong>suggestions les commentaires<\/strong> ou sur <a href=\"https:\/\/twitter.com\/geoffreycrofte\">Twitter<\/a>.<br \/>\nMerci \u00e0 <a href=\"https:\/\/twitter.com\/laurent_vcnt\/\">Laurent<\/a> pour les tests sur iOS.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Les exp\u00e9riences les plus douloureuses sur le mobile sont tr\u00e8s certainement celles sur les formulaires en ligne qu&rsquo;il faut remplir ici et l\u00e0. Et si vous optimisiez ces exp\u00e9riences \u00e9tape par \u00e9tape ? Aujourd&rsquo;hui, je vous propose une solution pour la saisie d&rsquo;un code unique temporaire : Vous recevez le SMS avec un code, votre [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":7479,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_bluesky_dont_syndicate":"","_bluesky_syndication_accounts":"","_bluesky_syndication_text":"","footnotes":""},"categories":[875,610,9],"tags":[432,221,410,578],"coauthors":[597],"class_list":["post-7481","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ux-experience-utilisateur","category-javascript","category-tutoriels","tag-formulaire","tag-ios","tag-smartphone","tag-ux"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/posts\/7481","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/comments?post=7481"}],"version-history":[{"count":2,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/posts\/7481\/revisions"}],"predecessor-version":[{"id":7487,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/posts\/7481\/revisions\/7487"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/media\/7479"}],"wp:attachment":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/media?parent=7481"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/categories?post=7481"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/tags?post=7481"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/coauthors?post=7481"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}