Textarea : limiter la largeur et la hauteur du texte saisie

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

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.