Textarea : limiter la largeur et la hauteur du texte saisie

Soyez le premier à donner votre avis sur cette source.

Vue 8 284 fois - Téléchargée 306 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

mickaelpfr
Messages postés
197
Date d'inscription
mardi 18 février 2003
Statut
Membre
Dernière intervention
29 avril 2009
2 -
Juste une question , ( je n'ai pas recherché l'info sur le net ... )
est ce que cols , prend en compte le nombre de caractère ou s'adapte t-il a la taille / police définit ?
jdmcreator
Messages postés
656
Date d'inscription
samedi 30 décembre 2000
Statut
Membre
Dernière intervention
20 juillet 2012
3 -
Petite remarque

Après un certainn nombre de caractère mis dans une ligne, lorsqu'on tape sur CTRL + A pour surligner, il ajoute "undefined" au texte.
vilfarfadet
Messages postés
9
Date d'inscription
mardi 19 décembre 2000
Statut
Membre
Dernière intervention
19 février 2009
-
L'attribut 'cols' (obligatoire) correspond au nombre de caractères visiblent sur une ligne. Autrement dit, la largeur du 'textarea' en nombre de caractères. À condition bien sûr de ne pas dire autre chose avec la feuille de style.

Essayez par exemple en ajoutant "width: 100%;" ou "width: 10em;" dans l'attribut 'style' du 'textarea'. L'attribut 'cols' ne sert plus à rien dans ce cas...
vilfarfadet
Messages postés
9
Date d'inscription
mardi 19 décembre 2000
Statut
Membre
Dernière intervention
19 février 2009
-
C'est étrange cette histoire de "undefined", je n'arrive pas à la reproduire quelque soit la combinaison de touches utilisées.

Avez-vous modifié le source pour faire des essais ?

En effet, j'ai eu ce problème en cours de développement parce qu'un substr() coupait un caractère de plus que la ligne en contenait. Le javascript retourne "undefined" pour ce caractère inexistant.
vilfarfadet
Messages postés
9
Date d'inscription
mardi 19 décembre 2000
Statut
Membre
Dernière intervention
19 février 2009
-
Petites précisions :

* Dans mon exemple, les lignes sont limités à 80 caractères, mais j'enlève le caractère retour-charriot avant traitement des lignes (avec split()) et je le remet ensuite (avec join()), les lignes font donc 81 caractères.

* Cette source a été écrite pour du texte tapé au fur et à mesure. Elle gère malgré tout les copier/coller.

Mais elle n'est pas optimale pour des copier/coller de plusieurs lignes en milieu de texte. Il peut arriver que le texte dépasse temporairement du cadre, cela se règle tout seul si l'on se déplace dans le texte avec les touches fléchées par exemple.

Une source multipasse serait mieux mais plus complexe. Il faut bien vous laisser un peu de travail :-)

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.