{"id":1058,"date":"2023-01-06T13:47:32","date_gmt":"2023-01-06T12:47:32","guid":{"rendered":"https:\/\/geekcommunicant.com\/blog\/?p=1058"},"modified":"2023-01-06T13:47:33","modified_gmt":"2023-01-06T12:47:33","slug":"retour-compteur-caracteres","status":"publish","type":"post","link":"https:\/\/geekcommunicant.com\/blog\/2023\/01\/06\/retour-compteur-caracteres\/","title":{"rendered":"Le retour du compteur de caract\u00e8res"},"content":{"rendered":"\n<p>Apr\u00e8s \u00eatre revenu derni\u00e8rement sur ma s\u00e9rie de tutos d\u2019<a href=\"https:\/\/geekcommunicant.com\/blog\/2022\/12\/16\/amusons-nous-avec-canvas-retour\/\" data-type=\"post\" data-id=\"1000\">introduction aux canvas<\/a>, j\u2019ai d\u00e9cid\u00e9 de m\u2019attaquer \u00e0 l\u2019un de mes anciens articles me valant le plus d\u2019affichage sur le moteur de recherche d\u2019Alphabet&nbsp;: le <a href=\"https:\/\/geekcommunicant.com\/blog\/2012\/09\/12\/un-compteur-de-caracteres-en-jquery\/\" data-type=\"post\" data-id=\"25\">compteur de caract\u00e8res<\/a>.<\/p>\n\n\n\n<p>Comme pour mes derniers articles traitant de JavaScript, une fois de plus je n\u2019utiliserai que des fonctions natives, sans aucune librairie.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Organisation du nouveau code<\/h2>\n\n\n\n<p>Le nouveau code sera r\u00e9parti dans deux fonctions&nbsp;: une fonction d\u2019initialisation, et la fonction en charge du compte des caract\u00e8res. Cette derni\u00e8re fonction \u00e9tant appel\u00e9e une fois \u00e0 l\u2019initialisation, pour pouvoir \u00eatre utilisable sur une page o\u00f9 les champs de formulaire contiennent d\u00e9j\u00e0 du texte (une am\u00e9lioration par rapport \u00e0 l\u2019ancien code), et ensuite attach\u00e9e \u00e0 un \u00e9v\u00e9nement sur les champs.<\/p>\n\n\n\n<p>Un des gros changement est la mani\u00e8re dont on va passer les param\u00e8tres \u00e0 notre champ compteur de caract\u00e8res&nbsp;: au lieu de passer ces param\u00e8tres \u00e0 notre fonction d\u2019initialisation, on va utiliser des attributs HTML.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Ces attributs HTML sont au nombre de 5&nbsp;:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>pour la longueur maximale de notre champ, on va utiliser l\u2019attribut <code><a rel=\"noreferrer noopener\" href=\"https:\/\/developer.mozilla.org\/fr\/docs\/Web\/HTML\/Attributes\/maxlength\" target=\"_blank\">maxlength<\/a><\/code>, qui en plus permet d\u2019emp\u00eacher l\u2019ajout de caract\u00e8res au-del\u00e0 de la limite, ce que l\u2019ancienne version de faisait pas (cet attribut existait d\u00e9j\u00e0 \u00e0 l\u2019\u00e9poque de la r\u00e9daction du premier article)<\/li>\n\n\n\n<li>pour la valeur de seuil, on va utiliser un attribut de donn\u00e9es (<a href=\"https:\/\/developer.mozilla.org\/fr\/docs\/Web\/HTML\/Global_attributes\/data-*\" target=\"_blank\" rel=\"noreferrer noopener\">data-*<\/a>) <code>data-threshold<\/code><\/li>\n\n\n\n<li>pour la couleur \u00ab&nbsp;normale&nbsp;\u00bb, on utilisera un attribut <code>data-normal<\/code><\/li>\n\n\n\n<li>pour la couleur \u00e0 utiliser quand la valeur de seuil est atteinte, ce sera l\u2019attribut <code>data-alert<\/code><\/li>\n\n\n\n<li>pour la couleur utilis\u00e9e quand plus aucun caract\u00e8re ne peut \u00eatre rajout\u00e9, on utilisera un attribut <code>data-reached<\/code><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">La fonction d\u2019initialisation<\/h2>\n\n\n\n<p>Cette fonction prend un seul param\u00e8tre d\u2019entr\u00e9e&nbsp;: l\u2019objet \u00e0 utiliser par la suite.<\/p>\n\n\n\n<p>Premier truc \u00e0 faire, stocker les r\u00e9glages de notre compteur. Pour cela on utilise un objet settings, dans lequel on stocke les valeurs des diff\u00e9rents data-attributes, r\u00e9cup\u00e9r\u00e9es via la propri\u00e9t\u00e9 <code><a href=\"https:\/\/developer.mozilla.org\/fr\/docs\/Web\/API\/HTMLElement\/dataset\" target=\"_blank\" rel=\"noreferrer noopener\">dataset<\/a><\/code> de notre objet. Si les attributs n\u2019ont pas \u00e9t\u00e9 d\u00e9finis, une valeur par d\u00e9faut est utilis\u00e9e.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nconst settings = {\n    &#039;threshold&#039; : (t.dataset.threshold?parseInt(t.dataset.threshold): Math.floor(t.maxLength\/2)),\n    &#039;normalColor&#039; : (t.dataset.normal?t.dataset.normal: &#039;#000000&#039;),\n    &#039;alertColor&#039; : (t.dataset.alert?t.dataset.alert: &#039;#FFA500&#039;),\n    &#039;reachedColor&#039; : (t.dataset.reached?t.dataset.reached: &#039;#FF0000&#039;)\n};\n<\/pre><\/div>\n\n\n<p>Viens ensuite le moment de cr\u00e9er l\u2019\u00e9l\u00e9ment HTML \u00e0 utiliser pour afficher l\u2019\u00e9tat du compteur.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nconst countSpan = document.createElement(&#039;span&#039;); \/\/ cr\u00e9ation d\u02bcun nouvel \u00e9l\u00e9ment HTML\ncountSpan.style.setProperty(&#039;margin-left&#039;, &#039;8px&#039;); \/\/ on lui ajoute une propri\u00e9t\u00e9 de style\n                \nt.after(countSpan); \/\/ on l\u02bcinjecte dans le DOM apr\u00e8s la cible du script\n<\/pre><\/div>\n\n\n<p>Puis on appelle une premi\u00e8re fois la fonction en charge du d\u00e9compte, et on l\u2019attache \u00e0 l\u2019\u00e9v\u00e9nement &lsquo;<a rel=\"noreferrer noopener\" href=\"https:\/\/developer.mozilla.org\/fr\/docs\/Web\/API\/HTMLElement\/input_event\" target=\"_blank\">input<\/a>&lsquo;.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\ncharCount(t, settings);\n\nt.addEventListener(&#039;input&#039;, (e) =&gt; { charCount(e.target, settings) });\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">La fonction de d\u00e9compte<\/h2>\n\n\n\n<p>La fonction de d\u00e9compte prend deux param\u00e8tres d\u2019entr\u00e9e&nbsp;: l\u2019objet cible et un objet contenant les param\u00e8tres \u00e0 utiliser.<\/p>\n\n\n\n<p>Premi\u00e8re \u00e9tape, on r\u00e9cup\u00e8re le nombre de caract\u00e8res dans le champ, puis, on calcule le nombre de caract\u00e8res restants.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nlet nbChars = t.value.length;\nlet remChars = t.maxLength - nbChars;\n<\/pre><\/div>\n\n\n<p>Viens ensuite le changement de l\u2019affichage.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nconst countSpan = t.nextElementSibling; \/\/ s\u00e9lectionne le &lt;span&gt;\n                \nlet color = s.normalColor;\n\nlet text = remChars + &#039; caract\u00e8res restants&#039;; \n\n\/\/ Change la couleur et le texte selon la situation\nif (remChars &lt;= s.threshold &amp;&amp; remChars &gt; 0) {\n    color = s.alertColor;\n} else if(remChars == 0) {\n    color = s.reachedColor;\n    text = &#039;Maximum atteint&#039;;\n}\n\ncountSpan.style.setProperty(&#039;color&#039;, color); \/\/ couleur du texte\ncountSpan.innerText = text; \/\/ contenu du &lt;span&gt;\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Utilisation du code<\/h2>\n\n\n\n<p>Ce code est utilisable de mani\u00e8re tr\u00e8s simple&nbsp;: on s\u00e9lectionne le\/les champ(s) auquel\/auxquels on veut rattacher un compteur via <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.mozilla.org\/fr\/docs\/Web\/API\/Document\/getElementById\" target=\"_blank\"><code>document.getElementById()<\/code><\/a> ou <code><a href=\"https:\/\/developer.mozilla.org\/fr\/docs\/Web\/API\/Document\/querySelectorAll\" target=\"_blank\" rel=\"noreferrer noopener\">document.querySelectorAll()<\/a><\/code>, et ensuite on lance la fonction d\u2019initialisation sur chaque champ s\u00e9lectionn\u00e9.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\ndocument.querySelectorAll(&#039;.charcount&#039;).forEach((t) =&gt; {\n    initCount(t);\n});\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Autre utilisation possible<\/h2>\n\n\n\n<p>Derni\u00e8rement j&rsquo;ai commenc\u00e9 \u00e0 m&rsquo;int\u00e9resser aux <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.mozilla.org\/fr\/docs\/Web\/Web_Components\" target=\"_blank\">web components<\/a>, et c\u2019est ce qui m\u2019a donn\u00e9 envie de revenir sur cette histoire de compteur de caract\u00e8res.<\/p>\n\n\n\n<p>Dans notre cas, pas besoin de cr\u00e9er un \u00e9l\u00e9ment 100&nbsp;% personnalis\u00e9. On va se contenter de simplement \u00e9tendre les classes des <code>&lt;input&gt;<\/code> (<a href=\"https:\/\/developer.mozilla.org\/fr\/docs\/Web\/API\/HTMLInputElementhttps:\/\/developer.mozilla.org\/fr\/docs\/Web\/API\/HTMLInputElement\" target=\"_blank\" rel=\"noreferrer noopener\">HTMLInputElement<\/a>) et des <code>&lt;textarea&gt;<\/code> (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/HTMLTextAreaElement\" target=\"_blank\" rel=\"noreferrer noopener\">HTMLTextAreaElement<\/a>).<\/p>\n\n\n\n<p>Ces classes \u00e9tendues ne contiennent que un constructeur, qui apr\u00e8s l\u2019appel obligatoire \u00e0 super() lance la fonction d\u2019initialisation sur l\u2019objet lui-m\u00eame.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nclass CharCountInput extends HTMLInputElement {\n    constructor() {\n        super();\n        \n        initCount(this);\n    }\n}\n\nclass CharCountTextArea extends HTMLTextAreaElement {\n    constructor() {\n        super();\n\n        initCount(this);\n    }\n} \n<\/pre><\/div>\n\n\n<p>Viens ensuite la \u00ab&nbsp;cr\u00e9ation&nbsp;\u00bb de ces nouveaux objets via <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/CustomElementRegistry\/define\" target=\"_blank\" rel=\"noreferrer noopener\">customElements.define()<\/a>&nbsp;:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\ncustomElements.define(&#039;charcount-input&#039;, CharCountInput, { extends: &#039;input&#039; });\ncustomElements.define(&#039;charcount-textarea&#039;, CharCountTextArea, { extends: &#039;textarea&#039; });\n<\/pre><\/div>\n\n\n<p>Pour utiliser ces nouveaux types d\u2019objet, il suffit de rajouter un attribut <code><a href=\"https:\/\/developer.mozilla.org\/fr\/docs\/Web\/HTML\/Global_attributes\/is\" target=\"_blank\" rel=\"noreferrer noopener\">is<\/a><\/code> aux champs devant \u00eatre de ce nouveau type.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Pour conclure<\/h2>\n\n\n\n<p>J\u2019esp\u00e8re une fois de plus vous avoir appris quelque chose ou que cet article vous aura permis de r\u00e9soudre un probl\u00e8me dans votre code.<\/p>\n\n\n\n<p>Le <a href=\"https:\/\/geekcommunicant.com\/demos\/compteur-caracteres.html\" target=\"_blank\" rel=\"noreferrer noopener\">r\u00e9sultat final<\/a> est visible dans la partie d\u00e9monstration de mon site.<\/p>\n\n\n\n<p>\u00c0 bient\u00f4t pour d\u2019autres aventures codistiques&nbsp;!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Apr\u00e8s \u00eatre revenu derni\u00e8rement sur ma s\u00e9rie de tutos d\u2019introduction aux canvas, j\u2019ai d\u00e9cid\u00e9 de m\u2019attaquer \u00e0 l\u2019un de mes anciens articles me valant le plus d\u2019affichage sur le moteur de recherche d\u2019Alphabet&nbsp;: le compteur de caract\u00e8res. Comme pour mes &hellip; <a href=\"https:\/\/geekcommunicant.com\/blog\/2023\/01\/06\/retour-compteur-caracteres\/\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[19],"tags":[8,31,55],"class_list":["post-1058","post","type-post","status-publish","format-standard","hentry","category-javascript","tag-compteur-de-caracteres","tag-javascript","tag-webcomponent"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p2IoOb-h4","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":25,"url":"https:\/\/geekcommunicant.com\/blog\/2012\/09\/12\/un-compteur-de-caracteres-en-jquery\/","url_meta":{"origin":1058,"position":0},"title":"Un compteur de caract\u00e8res en jQuery","author":"geekc","date":"12\/09\/2012","format":false,"excerpt":"Aujourd'hui nous allons voir comment faire un plugin jQuery, qui permet de compter le nombre de caract\u00e8res pouvant encore \u00eatre accept\u00e9 dans des champs de texte. Pour commencer, il faut d\u00e9cider du nombre de variables utiles \u00e0 ce genre de r\u00e9alisation. Une longueur maximale autoris\u00e9e est un minimum. Ensuite, comme\u2026","rel":"","context":"Dans &quot;jQuery&quot;","block_context":{"text":"jQuery","link":"https:\/\/geekcommunicant.com\/blog\/category\/jquery\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1133,"url":"https:\/\/geekcommunicant.com\/blog\/2023\/03\/10\/gloubi-script-un-systeme-de-tooltip\/","url_meta":{"origin":1058,"position":1},"title":"Gloubi script &#8211; un syst\u00e8me de tooltip","author":"geekc","date":"10\/03\/2023","format":false,"excerpt":"J\u2019ai d\u00e9cid\u00e9 cette semaine de me pencher sur le script de tooltip pr\u00e9sent\u00e9 sur le site de gloubiweb. Dans une premi\u00e8re partie je pr\u00e9senterai rapidement le fonctionnement du script actuel, et dans une deuxi\u00e8me, je vous indiquerai comment recr\u00e9er (quasi) \u00e0 l\u2019identique cet ancien script. Pr\u00e9sentation de du code existant\u2026","rel":"","context":"Dans &quot;JavaScript&quot;","block_context":{"text":"JavaScript","link":"https:\/\/geekcommunicant.com\/blog\/category\/javascript\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1108,"url":"https:\/\/geekcommunicant.com\/blog\/2023\/02\/10\/gloubi-tuto-menu-avec-description-du-lien\/","url_meta":{"origin":1058,"position":2},"title":"Gloubi tuto &#8211; menu avec description du lien","author":"geekc","date":"10\/02\/2023","format":false,"excerpt":"Voici venu le temps d\u2019un nouveau gloubi tuto sur un autre script de menu. Aujourd\u2019hui, nous allons nous attaquer au menu interactif avec description du lien. Fonctionnement du script Le menu est mis en forme avec un simple tableau \u00e0 une seule colonne, avec un case vide en pied de\u2026","rel":"","context":"Dans &quot;JavaScript&quot;","block_context":{"text":"JavaScript","link":"https:\/\/geekcommunicant.com\/blog\/category\/javascript\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":991,"url":"https:\/\/geekcommunicant.com\/blog\/2022\/12\/09\/gloubi-tuto-texte-degrade\/","url_meta":{"origin":1058,"position":3},"title":"Gloubi tuto &#8211; un texte en d\u00e9grad\u00e9","author":"geekc","date":"09\/12\/2022","format":false,"excerpt":"Pour ce deuxi\u00e8me gloubi tuto, on s\u2019attaque \u00e0 un script qui a eu son petit succ\u00e8s sur Skyblog\u00a0: le texte \u00ab\u00a0arc-en-ciel\u00a0\u00bb (en d\u00e9grad\u00e9s). Script original et explication Pour voir le script original, qui fonctionne encore dans les navigateurs modernes, rendez-vous ici sur le site de notre N\u00e9m\u00e9sis dans la deuxi\u00e8me\u2026","rel":"","context":"Dans &quot;JavaScript&quot;","block_context":{"text":"JavaScript","link":"https:\/\/geekcommunicant.com\/blog\/category\/javascript\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1096,"url":"https:\/\/geekcommunicant.com\/blog\/2023\/02\/03\/fenetre-modale-javascript-natif\/","url_meta":{"origin":1058,"position":4},"title":"Une fen\u00eatre modale en JavaScript natif","author":"geekc","date":"03\/02\/2023","format":false,"excerpt":"Aujourd\u2019hui, nouveau retour sur un de mes anciens tutoriels qui a rencontr\u00e9 un certain succ\u00e8s, mon tutoriel sur comment faire une fen\u00eatre modale avec jQuery. Depuis maintenant \u00e0 peu pr\u00e8s un an, tous les navigateurs majeurs supportent la balise <dialog> qui permet de cr\u00e9er des fen\u00eatres modales (\u00e7a \u00e7a tombe\u2026","rel":"","context":"Dans &quot;JavaScript&quot;","block_context":{"text":"JavaScript","link":"https:\/\/geekcommunicant.com\/blog\/category\/javascript\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":808,"url":"https:\/\/geekcommunicant.com\/blog\/2019\/06\/11\/carte-interactive-metro-paris-leaflet\/","url_meta":{"origin":1058,"position":5},"title":"Carte interactive du m\u00e9tro de Paris avec Leaflet","author":"geekc","date":"11\/06\/2019","format":false,"excerpt":"Si on vous parle de solution pour int\u00e9grer une carte sur votre site, la premi\u00e8re qui vous vient \u00e0 l\u2019esprit est surement Google Maps. Mais il existe plusieurs solutions open-source et gratuites. Je vous ai d\u00e9j\u00e0 parl\u00e9 d\u2019OpenLayers, avec laquelle j\u2019ai d\u00e9j\u00e0 refait une carte r\u00e9alis\u00e9e pr\u00e9c\u00e9demment avec jQuery. Mais\u2026","rel":"","context":"Dans &quot;JavaScript&quot;","block_context":{"text":"JavaScript","link":"https:\/\/geekcommunicant.com\/blog\/category\/javascript\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/geekcommunicant.com\/blog\/wp-json\/wp\/v2\/posts\/1058","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/geekcommunicant.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/geekcommunicant.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/geekcommunicant.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/geekcommunicant.com\/blog\/wp-json\/wp\/v2\/comments?post=1058"}],"version-history":[{"count":0,"href":"https:\/\/geekcommunicant.com\/blog\/wp-json\/wp\/v2\/posts\/1058\/revisions"}],"wp:attachment":[{"href":"https:\/\/geekcommunicant.com\/blog\/wp-json\/wp\/v2\/media?parent=1058"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/geekcommunicant.com\/blog\/wp-json\/wp\/v2\/categories?post=1058"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/geekcommunicant.com\/blog\/wp-json\/wp\/v2\/tags?post=1058"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}