IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bibliothèques & Frameworks Discussion :

Compteur de caractères


Sujet :

Bibliothèques & Frameworks

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2006
    Messages : 89
    Par défaut Compteur de caractères
    Bonjour,

    J'aimerais mettre au point le script Prototype suivant:
    affichage "en direct" dans un div du nombre de caractères saisi dans un textarea hors espace et retour chariot + blocage automatique au maximum autorisé

    Comme j'ai bcp de mal avec le JS en général et Prototype en particulier, je soumet ici l'algo général, si qq pouvait me le "traduire" en code ou m'y aider, je lui en serai très reconnaissant!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    évènement déclencheur: onKeyUp dans element_id 'textPerso'
     
    entrée:
    - texte saisie t
    - nombre max de caractères autorisé nbMax
     
    algo:
     
    begin
     
    nbCar = 0;
    pour chaque lettre l de t {
    	si (nbCar > nbMax) exit boucle;
    	si (l != ' ' && l != '\n') {
    		nbCar++;
    	}
    }
    si (nbCar > nbMax) {
    	t = fonctionQuiDecoupeLeTexte(t, 0, nbMax -1);
    	affiche t dans element_id = 'textPerso'
    }
    affiche nbCar dans element_id = 'displayNbCar';
     
    end
    Merci pour votre aide!

  2. #2
    Membre Expert
    Avatar de gwyohm
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2007
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 925
    Par défaut
    Bonjour,

    Il me semble que dans ton algo, tu oublies un point important :
    Quand tu appelles fonctionQuiDecoupeLeTexte, tu découpes sans tenir compte du nombre de caractère ' ' et '\n' que tu aurais pu rencontrer et qui ne doivent pas influencer le comptage des caractères.

    Pour répondre un eu sur les méthodes de prototype dont tu as besoin (ou plutôt les raccourcis qu'introduit prototype) :

    Récupérer la valeur d'un champ :
    Observer l'evenement keyup sur un element:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $(id_element).observe("keyup", function(){
      // ton code
    });
    ou bien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    function maFonction() {
     
    }
    //...
    $(id_element).observe("keyup", maFonction);

  3. #3
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 104
    Par défaut
    Un problème bien barbare. Et j’en sais quelque chose, je suis dessus depuis bientôt deux mois pour un projet personnel… Mon objectif étant d’éviter d’avoir à recompter le nombre de caractères total à chaque keyup, mais plutôt de le mettre à jour « en relatif », en ajoutant ou soustrayant de petits nombres.

    Le cœur du problème c’est la diversité des actions que peut faire l’utilisateur. Par exemple s’il utilise la commande « coller », comment savoir combien de caractères viennent d’atterir ? S’il fait une séléction à la souris ou avec Maj+flèche et qu’il appuie sur effacer ?

    Mais je pense que tu n’auras pas besoin de te poser toutes ces questions. Je te propose la version « comptage absolu » bien plus simple. Et comme je suis d’humeur taquine je vais seulement te donner des indices ^^

    Voici un premier outil qui te sera utile : la méthode replace() des chaînes de caractères. Elle fonctionne comme ceci :
    Code console : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> 'saumon'.replace('au', 'i')
    "simon"
    >>> 'poulet'.replace('et', 'iche')
    "pouliche"
     
    // remplacer par une chaîne vide
    >>> 'café crème'.replace(' crème', '')
    "café"

    Note le support de l’unicode, tu n’as pas de soucis à te faire avec les caractères spéciaux.

    Le second outil qui t’aidera, tu le connais sans doute déjà : l’expression régulière. La classe \s te sera sans doute utile car elle permet de matcher n’importe quel caractère d’espacement : sauts de ligne, tabulations, espaces insécables.

    Le troisième outil… est un mélange des deux : tu peux utiliser les regexp dans la méthode replace() !
    Code console : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> ' En \t été, les ibères\r\n sont\v rudes \xA0 \u00A0 '.replace(/\s+/g, ' ')
    " En été, les ibères sont rudes "
     
    // inutile à première vue, mais…
    >>> 'Je vais me chercher un chinois.'.replace(/\s+/g, '')
    "Jevaismechercherunchinois."
    Et je terminerais en disant que tu n’as pas pensé à utiliser une propriété très connue des chaînes, qu’on retrouve sur les tableaux également…


    À propos de l’évènement :
    à chaud, j’aurais choisi d’observer l’évènement keypress plutôt que keyup, car keypress ne réagit qu’aux caractères réellement saisis (il ne catche pas Maj, Ctrl, etc.). Cependant, comme je l’ai dit plus haut, l’utilisateur peut utiliser des raccourcis comme Ctrl+V, donc keyup se révèle plus pertinent. Reste le cas où il va passer par les menus… Selon le navigateur, ça peut déclencher un change ou pas. Morale : on ne peut pas vraiment réagir immédiatement.
    Libre à toi de choisir cette solution ou une autre. Un setInterval ? Hmm peut-être. S’il est trop rapide, il risque de surcharger les vieux ordinateurs, s’il est trop lent l’utilisateur risque de ne pas comprendre pourquoi des bouts de son texte disparaissent de temps en temps. En même temps il peut se révéler moins lourd que surveiller le keyup si on a affaire à un virtuose du clavier ^^

    À toi de voir. Bon courage !

    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2006
    Messages : 89
    Par défaut
    Salut,

    Merci pour ces indices, j'ai mélangé le tout et j'ai réussi à préparer une drôle de formule, mais je parviens au résultat escompté...

    Comme je suis sûr que c'est loin d'être optimal et que le code doit être rempli d'horreurs pour les puristes, le voilà sous le feu des projecteurs:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    countChar = function(idTextarea, idSpan, max) {
      var cptCar=0;
      var nbEsp=0;
       for(var nbCar=0; nbCar<$(idTextarea).value.length; nbCar++){
       if (!($F(idTextarea)[nbCar] == ' ' || $F(idTextarea)[nbCar] == '\n')) {
         cptCar++;
       } else {
         nbEsp++;
       }
     }
     
     $(idSpan).update(cptCar);
     
    // var txt = $F(idTextarea).replace(/\s+/g, '');
    // $(idSpan).update(txt.valueOf().length);
     
       var maxPlusNbEsp = eval(max) + eval(nbEsp);
     
       $(idTextarea).value = $F(idTextarea).substr(0, maxPlusNbEsp);
    }
    Je suis resté sur une boucle pour pouvoir récupérer le nombre d'espaces et de RC, mais la méthode replace+regex marche bien et semble plus propre. En résumé, si une méthode existe pour récupérer le nombre de caractères ' ' et '\n' présent dans la chaine...

    Merci bcp en tout cas!

  5. #5
    Membre Expert
    Avatar de gwyohm
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2007
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 925
    Par défaut
    Bonjour,

    Quelques commentaires sur le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    countChar = function(idTextarea, idSpan, max) {
      var cptCar=0;
      var nbEsp=0;
      // Dans un souci de performance, mieux vaut variabiliser 
      // la valeur et sa taille pour ne pas refaire les calculs à chaque fois
      var textValue = $F(idTextarea);
       for(var nbCar=0, len=textValue.length; nbCar<len; nbCar++){
       if (!(textValue[nbCar] == ' ' || textValue[nbCar] == '\n')) {
         cptCar++;
       } else {
         nbEsp++;
       }
     }
     
     $(idSpan).update(cptCar);
     
    // var txt = $F(idTextarea).replace(/\s+/g, '');
    // $(idSpan).update(txt.valueOf().length);
     
       // pas besoin d'eval ici (d'autant que eval is evil)
       var maxPlusNbEsp = max + nbEsp;
     
       $(idTextarea).value = textValue.substr(0, maxPlusNbEsp);
    }

  6. #6
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 104
    Par défaut
    Salut,
    tu fais des trucs bizarres
    Je pensais que la solution était évidente, mais sans doute ne l’est-elle pas pour tout le monde. Voici une petite session qui montre une solution possible :
    Code console : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> var pangramme, compact, nCars
    >>> pangramme = 'Voyez ce bon fakir moqueur\r\npousser un wagon en jouant du xylophone\xA0!'
    "Voyez ce bon fakir moqueur
    pousser un wagon en jouant du xylophone !"
    >>> compact = pangramme.replace(/\s+/g, '')
    "Voyezcebonfakirmoqueurpousserunwagonenjouantduxylophone!"
    >>> nCars = compact.length
    56

    Pour compter le nombres de blancs, il y a une subtilité : le cas Windows, avec ses doubles retours chariots \r\n. Sous Unix on a seulement \n et sous Mac seulement \r, donc pas de problème, mais pour Windows il faudra diviser par deux. Je propose cette RegExp un peu complexe :
    Code regexp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    /(\S+)|((?:\r\n)+)|\s/g
    // 1  |     2     | 3
    Le but est de capturer trois groupes différents : le premier matche tout ce qui n’est pas blanc (\S). Si on tombe sur du blanc, on regarde le deuxième groupe, qui matche les paires \r\n, toujours ensemble. Et si on n’a pas une paire, on va dans le troisième groupe. Dans ce cas, il faut compter les blancs un par un car sinon il partirait sur sa lancée et engloberait des éventuels \r\n qui suivent un blanc. Du coup on n’a pas besoin de capturer ce dernier groupe, car on sait que sa longueur sera toujours 1.
    J’espère que je suis assez clair :$

    Avec la méthode exec() des RegExp, on récupère les différents groupes dans un tableau, ce qui nous permet de les compter séparément. On obtient le nombre de caractères non-blancs avec le premier groupe ; pour le deuxième, il faut diviser par 2, puis on ajoute le nombre de blancs du troisième.

    Voici le code :
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function count( str ) {
    	var rx = /(\S+)|((?:\r\n)+)|\s/g;
    	var nCars = 0, nBlanks = 0;
    	var match;
    	while (match = rx.exec(str)) {
    		if (match[1]) {
    			nCars += match[1].length;
    		} else if (match[2]) {
    			nBlanks += match[2].length / 2;
    		} else {
    			nBlanks++;
    		};
    	};
    	return [nCars, nBlanks];
    };
    La boucle while utilise le même principe que mysql_fetch_array de PHP (si tu connais) : exec() avance dans la chaîne à chaque étape, et finit par renvoyer null, ce qui nous fait sortir de la boucle.

    Le résultat est un tableau qui donne le nombre de caractères non blancs en 0 et le nombre de blancs en 1.


    Edit: Pour rester dans l’esprit du Framework Prototype, je propose cette version :
    Code Prototype : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    String.prototype.count = function() {
    	var rx = /(\S+)|((?:\r\n)+)|\s/g;
    	var nCars = 0, nBlanks = 0;
    	var match;
    	while (match = rx.exec(this)) {
    		if (match[1]) {
    			nCars += match[1].length;
    		} else if (match[2]) {
    			nBlanks += match[2].length / 2;
    		} else {
    			nBlanks++;
    		};
    	};
    	return [nCars, nBlanks];
    };

    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

Discussions similaires

  1. Compteur de caractères
    Par Marc_27 dans le forum ASP.NET
    Réponses: 18
    Dernier message: 22/01/2010, 17h32
  2. compteur de caractère pour 5 textaera
    Par anca2 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 29/06/2009, 21h36
  3. Compteur de caractères petit blocage.
    Par fx_web dans le forum Général JavaScript
    Réponses: 0
    Dernier message: 17/01/2009, 13h32
  4. Compteur de caractères lors d'un saut de ligne
    Par blueman dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 22/06/2006, 11h08
  5. Compteur de caractères dans textarea en temps réél
    Par Jherek dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 22/03/2006, 19h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo