Textarea : limiter la largeur et la hauteur du texte saisie

Soyez le premier à donner votre avis sur cette source.

Vue 8 244 fois - Téléchargée 303 fois

Description

La plupart des contrôles de saisie dans un champ textarea se limite à la longueur du texte.

L'intérêt de limiter la largeur et la hauteur peut être simplement cosmétique (je rappèle que l'attribut wrap est à proscrire) : pas de barre de défilement (sauf si vous avez joué avec la feuille de style :-) ).
Il peut aussi s'agir de fournir des données à un vieux programme (genre Cobol) qui veut absolument tant de lignes et tant de colonnes et qui ne plante pas proprement sinon.

Syntaxe :
- memoire(nom_du_textarea);
- texte_limite(nom_du_textarea, largeur_max, hauteur_max);

Le principe est simple :
1. À l'appui d'une touche, on mémorise le contenu actuel du champ. Si on a un copier/coller un peu gros, cela permettra de revenir en arrière.
2. Au relachement de la touche on regarde si le nombre de caractères ne dépasse pas la largeur x la hauteur. Si c'est la cas on arrête tout en pleurant.
3. On compte les lignes en trop. S'il y en a, on les regroupe au début.
4. On vérifie la longueur de chaque ligne une à une. Si ça dépasse, on coupe et on reporte à la ligne suivante.
5. S'il y a eu modification des lignes, on refait une passe (retour au point 2.)

Source / Exemple :


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr">
<head>
	<title>Ne pas dépasser 80 x 6</title>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
	<script type="text/javascript">
function memoire(champ)
{
	avant = champ.value;
}

function texte_limite(champ, largeur, hauteur)
{
	probleme = false;
	apres = champ.value;
	lignes = apres.split(/[\n\r]/);
	// trop de caractères ?
	if (lignes.join('').length > (largeur-1)*hauteur) {
		//alert('largeur x hauteur = '+largeur*hauteur+'\nnombre de lignes : '+lignes.length+'\nnombre de caractères : '+lignes.join('').length);
		champ.value = avant; // marche arrière
		alert('Texte trop long !');
	} else {
		entrop = lignes.length-hauteur;
		// trop de lignes ?
		if (entrop > 0) {
			probleme = true;
			//a=lignes[0];
			detrop = lignes.splice(0,entrop);
			//b=lignes[0];
			lignes[0] = detrop.join(' ')+' '+lignes[0];
			//alert(entrop+' ligne(s) en trop\nligne 1 avant : '+a+'\nligne 1 apres decalage : '+b+'\nnouvelle ligne 1 : '+lignes[0]);
		}
		// ligne(s) trop longue(s) ?
		apartir = Math.min(lignes.length, hauteur);
		for (i = 0 ; i < apartir ; i++)
		{
			entrop = lignes[i].length-largeur;
			if (entrop > 0) {
				probleme = true;
				//a=lignes[i];
				//c=lignes[i+1];
				/*
				coupure = lignes[i].lastIndexOf(' ');
				if (coupure == -1) {

  • /
//b=lignes[i].substr(largeur); if (i+1 == apartir) { lignes[i+1] = lignes[i].substr(largeur); } else { lignes[i+1] = lignes[i].substr(largeur)+' '+lignes[i+1]; } lignes[i] = lignes[i].substr(0, largeur); /* } else { //b=lignes[i].substr(coupure+1); if (i+1 == apartir) { lignes[i+1] = lignes[i].substr(coupure+1); } else { lignes[i+1] = lignes[i].substr(coupure+1)+' '+lignes[i+1]; } lignes[i] = lignes[i].substr(0, coupure); }
  • /
//alert('largeur : '+largeur+' et coupure : '+coupure+'\n'+entrop+' caractère(s) en trop ligne '+(i+1)+'\nligne : '+a+'\npartie en trop : '+b+'\nligne suivante : '+c+'\nnouvelle ligne : '+lignes[i]+'\nnouvelle ligne suivante : '+lignes[i+1]); } } if (probleme) { champ.value = lignes.join('\n'); // concaténation texte_limite(champ, largeur, hauteur); // nouvelle passe } } } </script> </head> <body> <form id="test" method="post" action="#"> <textarea id="texte" name="texte" cols="80" rows="6" style="overflow: auto;" onkeypress="memoire(this);" onkeyup="texte_limite(this, 80, 6);"></textarea> <br /> <input type="submit" value="Zou" /> </form> </body> </html>

Conclusion :


Parmi les modifications possibles (en option par exemple), on peut vouloir :
- Faire une double passe (de bas en haut puis de haut en bas) pour retailler les lignes au mieux,
- Faire du filtrage des espaces en double ou en début de ligne,
- Couper au dernier espace de la ligne pour éviter de tronquer les mots : elle est actuellement commentée (partie utilisant la variable coupure) car il est possible d'avoir une boucle infinie dans certains cas. Le test se fait sur le nombre de caractères mais avec une découpe par mots, il est parfois impossible d'arranger le texte pour qu'il tienne dans le nombre de lignes imparties.
- Ne contrôler que la taille des lignes (nombre de colonnes), à coupler avec l'option précédente dans ce cas.
- etc.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

vilfarfadet
Messages postés
9
Date d'inscription
mardi 19 décembre 2000
Statut
Membre
Dernière intervention
19 février 2009
-
Il me reste un problème de boucle infini à résoudre, mais il faut se mettre dans des conditions particulières pour le déclencher.
jdmcreator
Messages postés
656
Date d'inscription
samedi 30 décembre 2000
Statut
Membre
Dernière intervention
20 juillet 2012
1 -
Je vois que tu as réussi à trouver l'erreur dans ton code, bravo !

A+

JDMCreator
victorcoasne
Messages postés
1100
Date d'inscription
jeudi 24 avril 2003
Statut
Membre
Dernière intervention
17 octobre 2012
2 -
Et avec des attributs rows et cols ça passe pas ?
Vous me direz qu'il y a toujours moyen d'outre-passer, mais le Javascript c'est pareil.
La seule solution : faire une vérif en PHP (mais dans ce cas là on est pas sur le bon site)
Bonne prog,
@++
cs_laservert
Messages postés
3
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
12 juillet 2009
-
Bonjour,

Code intéressant. Dans le cas du copier/coller, j'ai essayé d'introduire aussi les fonctions dans onMouseDown et onMouseUp mais sans succès.
La saisie n'est pas gérée lors de l'appui prolongé sur une touche (tel: **************...) puisque le onKeyUp n'est détecté qu'en fin de saisie, dommage.

Cordialement.
cs_nossoctoruss
Messages postés
126
Date d'inscription
samedi 28 novembre 2009
Statut
Membre
Dernière intervention
9 juin 2013
-
ca va me servir
Commenter la réponse de mickaelpfr

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.