Contrôle du nombre de caractères dans un champs textarea

Soyez le premier à donner votre avis sur cette source.

Snippet vu 28 187 fois - Téléchargée 23 fois

Contenu du snippet

Nouvelle version beaucoup plus performante que l'ancienne. La mise en place de la demande de contrôle d'un textarea ne se fait plus du tout de la même manière.

/*Compatible avec firefox et IE*/

Avant, il fallait mettre les attibuts onkeypress, etc... directement dans le textarea concerné, mais celà alourdissait le code et ne simplifiait pas les choses en cas de modifs.

Maintenant, c'est l'objet document qui est détourné et ensuite, quand nous sommes dans la procédure de contrôle, on vérifie que la cible est bien à contrôler (cf. function verif_textarea_length()). Sinon, on sort directement.

Tout se passe dans le <TEXTAREA>:
<TEXTAREA id="rappel" rows="4" cols="80" maxlength="200" control_length="1" id_control_cell="counter"></TEXTAREA>

En fait, chose que je ne savait il y a 3 ans, c'est que l'on peut mettre des attributs personnalisés sur les éléments HTML. C'est super pratique pour passer des arguments d'appels à une procédure.

Ici, je renseigne la l'attribut maxlength qui represente la taille maxi et qui sera traitée dans le script.
l'attribut control_length est un booléen qui set a savoir si l'on veux controler ou pas sa taille. Celà peut par exemple être utilise si dans un cas vous voulez inicialement mettre un contrôl de taille sur le champs puis l'enlever en cour de route, il suffira juste de changer la valeur de l'attibut de 1 à 0.

L'attribut id_cell_control est la valeur de l'attibut 'id' de la div de control ou va apparaître la taille du texte:
<div id="counter" style="display:inline">0</div>/ 200 max.

Merci.

Source / Exemple :


<head>
<script type="text/javascript">

//Nicolas LE DREFF  2009
//Version 2
//ce code est visible à l'adresse suivante:
//http://www.javascriptfr.com/code.aspx?ID=38494

// cette fonction est appelée à chaque fois que l'on tape sur une touche (onkeypress,onkeyup), que l'on quite un champ(onblur).
// l'aiguillage se fait à l'intérieur.
// A savoir: si l'élément d'éclencheur de l'évenemment a un attibut nomé 'control_length' et qu'il est mis à 1, alors on traite l'évenement,
// sinon, on passe la main
function verif_textarea_length(e)
{
        var target = e.target || e.srcElement;  // récupération de la cible
        var is_something_wrong = false;         // initialisation variable

        if ((target.attributes) && (target.attributes['control_length']) && (target.attributes['control_length'].value = '1'))   // 'control_length'?
        {
	        max = target.attributes['maxlength'].value;           //récupération de la valeur maxlength de la cible
                id_textarea = target.attributes['id'].value;          //récupération de la valeur id de la cible
                id_control_cell = target.attributes['id_control_cell'].value;      //récupération de la valeur id de la div pour le compteur

                textarea = document.getElementById(id_textarea);      //assignation du textarea dans un objet plus accessible
                if (textarea.value.length > max)                      //est-ce que la taille du texte est trop grande?
	        {
	            //oui, on affiche un message et on découpe ce qui traine après la limite
            	    alert('Vous ne pouvez rentrer que '+ max +' caractères maximum pour ce champs');
		    textarea.value=textarea.value.substring(0,max);
                    is_something_wrong = true;     // on prévient à la sortie que qque chose ne s'est pas bien passé
	        }
                show_counter_value(id_control_cell,textarea.value.length);  //on affiche la taille du texte
        }
	return (!is_something_wrong);     //retour à l'envoyeur
}

// affiche le nombre de caractères du textarea
//rien de bien compliqué
function show_counter_value(id_control_cell,counter_value)
{
                control_cell_div = document.getElementById(id_control_cell);
		control_cell_div.innerHTML = counter_value ;    // on met à jour le champs de contrôle.
		return true;
}

//mise en place des gachettes (triggers en anglais)
function set_callback_events()
{
	if (document.addEventListener){
	//      alert('FF');
	        document.addEventListener('keypress', verif_textarea_length, false);
	        document.addEventListener('keyup', verif_textarea_length, false);
	        document.addEventListener('blur', verif_textarea_length, false);
	} else if (document.attachEvent){
	//      alert('IE');
	        document.attachEvent('onkeypress', verif_textarea_length);
	        document.attachEvent('onkeyup', verif_textarea_length);
	        document.attachEvent('onblur', verif_textarea_length);
	}
}

</script>

</head>
<body onload="set_callback_events()">
<form name="text"  method="POST" action="">
<span class="BlancLarge">Début de votre texte : </span><br>
<TEXTAREA id="rappel" rows="4" cols="80" maxlength="200" control_length="1" id_control_cell="counter"></TEXTAREA><br>
<span class="VertSmall">Nombre de caractères de ce champs : <div id="counter" style="display:inline">0</div>/ 200 max.</span><br><br>
<input type="hidden" name="mode" value="submit"><br>
<span class="BlancMedium">Pour valider et enregistrer votre texte : </span><input type="submit" value="Cliquez ici">
</form>
</body>

Conclusion :


Je pense qu'avec cette nouvelle version, je rends plus ouvert l'intégration du script dans d'autres application.
J'ai aussi trouvé d'autre solution sur le net, mais j'aime bien la mienne :D

A voir également

Ajouter un commentaire

Commentaires

masternico
Messages postés
494
Date d'inscription
dimanche 5 octobre 2003
Statut
Membre
Dernière intervention
1 septembre 2011

Cool,
Je suis content que tu ai finalement pu régler ton problème... et aussi de savoir que mon script fonctionne bien en fait... ;)

Une petite (grande) note?

A+ et bon code
Mabikas
Messages postés
8
Date d'inscription
mardi 4 novembre 2008
Statut
Membre
Dernière intervention
2 avril 2010

Ok je reconnais mon erreur :D

J'ai fais un petit bout de script histoire de l'illustrer au cas où y'aurai des gens que ça intéresse :)
<?php
header("Content-Type:text/html;");
header("Content-Type:charset=ISO-8859-1;");
$sValue = "Jé souis fatigué";
echo utf8_decode($sValue) . '
'; //Affiche : Jé souis fatigué
echo mb_detect_encoding($sValue) . '
'; // Affiche: UTF-8
echo mb_strlen($sValue, mb_detect_encoding($sValue)) . '
'; //Affiche bien 16

/**
* CREATE TABLE `ec_test` (
* `champ` varchar(16) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL
* ) ENGINE=MyISAM DEFAULT CHARSET=latin1
*/

$rConnexion = mysql_connect('server', 'user', 'pass');
if(mysql_select_db('test', $rConnexion) !== false){
mysql_query("SET NAMES 'utf8'"); //Nécessaire car les !!!données!!! envoyées au serveur sont en UTF-8
mysql_query("INSERT INTO ec_test (champ) VALUES ('" . $sValue . "')");//Le charset de la table n'est pas important
//parce que notre ami Mysql se débrouille bien en fait et du coup on a bien toute la chaine 'Jé souis fatigué'
//stocké dans le champ, l'essentiel est d'indiqué que les informations envoyées sont UTF-8
}
else{
echo 'pb de connexion';
}
?>
masternico
Messages postés
494
Date d'inscription
dimanche 5 octobre 2003
Statut
Membre
Dernière intervention
1 septembre 2011

Salut,
Je pense que tu prends le problème à l'envers, sans vouloir être têtu...
Voila comment je vois les choses:
Coté javascript, on comptabilise bien le nombre de caractères. puis quand on appuis sur le bouton de validation du formulaire, les données sont transmises à un srcipt PHP qui les interprètes.
Lors de la réception, on compte le nombre de bytes et non plus le nombre de caractères (dixit:"puisque je ne compte plus les caractères mais bien les bytes").
Ce qui ammène comme conclusion que le problème ne vient pas de mon script... mais plutôt de ce qui est fait des données reçues.

Si ton script PHP te dis que la taille de ta chaine est 18 alors que en vrais elle est de 16, c'est que PHP se trompe ou que tu n'utilise pas la fonction de comptage correctement.

////////////////////////////////////////////////////////
Doc PHP:
int mb_strlen ( string $str [, string $encoding] )
mb_strlen() retourne le nombre de caractères dans la chaîne $str, avec l'encodage $encoding.
Un caractère multi-octets est alors compté pour 1.

!!!!!! => $encoding est l'encodage de $str. Si $encoding est omis, l'encodage **interne** sera utilisé.

La fonction mb_strlen a besoin de savoir en quel charset se trouve la chaine que tu veux analyser

/////////////////////////////////////////////////////////////

string mb_detect_encoding ( string $str [, mixed $encoding_list [, bool $strict]] )

mb_detect_encoding() détecte l'encodage utilisé par la chaîne str. mb_detect_encoding() retourne le nom de l'encodage détecté

///////////////////////////////////////////////////////////////

Donc en combinant les deux on obtient ceci:

$nb_cars = mb_strlen($textarea_value,mb_detect_encoding($textarea_value));

Et là, php doit t'afficher 16 caractères et non 18...
Mabikas
Messages postés
8
Date d'inscription
mardi 4 novembre 2008
Statut
Membre
Dernière intervention
2 avril 2010

Hello,

Je me suis mal exprimé.
Imagine je suis dans un formulaire avec encodage UTF-8. Je vais dans mon textarea et je saisi : "Jé souis fatigué"
Là ton script va compter : 16
Je valide mon formulaire en appuyant sur bouton prévu à cet effet et passe à la vérification coté serveur:
PHP lui va compter (avec mb_strlen()) : 18

=> Le texte fais bien 16 caractères, mais 18 octets en somme

Du coup l'utilisateur se prends un message d'erreur parce que son texte est trop long pour être inséré en BDD alors que le JS lui disait que c'était bon.
masternico
Messages postés
494
Date d'inscription
dimanche 5 octobre 2003
Statut
Membre
Dernière intervention
1 septembre 2011

et puis avec ça aussi...
header("Content-Type:text/html;");
header("Content-Type:charset=ISO-8859-1;");

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.