11545 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Je viens cette fois vers vous, afin de vous demander de l'aide. Les utilisateurs ont le droit de n'écrire que 5 lignes, à partir de là leur saisie doit être bloquée. J'ai énormément de mal à appréhender le problème sachant qu'il faut prendre en compte le fait qu'il puisse revenir à la ligne de son plein gré ainsi que le fait qu'il fasse des copier/coller avec sa souris seulement.

Merci d'avance pour toute aide/remarque que vous me suggérerez !

PS : Mon textarea fait 233px de large (avec un police à 11px), j'espère que ça vous aidera !
Je connaissais ces attributs, mais si je dépasse les 5 lignes, je ne suis pas bloqué ! Un scroll apparaît et je peux continuer à écrire. Or j'aimerais que l'utilisateur ne puisse pas continuer à écrire.
Après des recherches et des modifications de scripts se balladant sur la toile, je suis arrivé à ça :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<script language="javascript" type="text/javascript">
			
			function getPosition () {
				if ( typeof document.getElementById('txt').selectionStart != 'undefined' )
					return document.getElementById('txt').selectionStart;
				// IE Support
				document.getElementById('txt').focus();
				var range = document.getElementById('txt').createTextRange();
				range.moveToBookmark(document.selection.createRange().getBookmark());
				range.moveEnd('character', document.getElementById('txt').value.length);
				return this.value.length - range.text.length;
			}

			function setCursor(pos_){
				//-- Recup l'Objet
				var Obj = document.getElementById('txt');
				if(Obj){
					Obj.focus();
					if( typeof Obj.selectionStart != "undefined"){
						Obj.setSelectionRange( pos_, pos_);
					}
					else{ // IE and consort
						var Chaine = Obj.createTextRange();
						Chaine.moveStart('character', pos_);
						//-- Deplace le curseur
						Chaine.collapse();
						Chaine.select();
					}
					return true;
				}
			} 

			function checkValide() {
				var textarea = document.getElementById('txt');
				var text = textarea.value;
				var max = text.length;
				// alert(typeof max);
				var cpt_nl = 0;
				var cpt_ligne = 0;
				for (i=0;i<max;i++)
				{
					if (text.charAt(i) == '\n')
					{
						cpt_nl++;
						cpt_ligne = 0;
					}
					else
					{
						if (cpt_ligne == 30)
						{
							cpt_nl++;
							cpt_ligne = 0;
						}
						else
						{
							cpt_ligne++;
						}
					}
					if (cpt_nl >= 5)
					{
						var position = getPosition();
						// alert(position);
						// On efface ce que l'utilisateur vient de taper ! >:D MOUHAHHAHA !
						document.getElementById('txt').value = text.substring(0, i);
						setCursor(position);
						// On sort de la boucle
						document.getElementById('txt').style.background = 'red';
						document.getElementById('msg').innerHTML = "Vous ne pouvez pas taper un texte de plus de 5 lignes !" ;
						setTimeout("document.getElementById('msg').innerHTML = ''", 3000);
						max = i;
					}
				}
				setTimeout("document.getElementById('txt').style.background='white'", 1000);

				return cpt_nl+1;
			}

		</script>
	</head>
	<body>
		<table cellpadding=0 cellspacing=0>
			<form name="frm">
				<tr>
					<td>
						<textarea style="overflow:hidden" nowrap="nowrap" id="txt" cols="33" rows="5" onKeyUp="checkValide()" onChange="checkValide()"></textarea>
					</td>
				</tr>
			</form>
		</table>
		<div id="msg" style="color:red;"></div>
	</body>
</html>


Mais celà ne me satisfait pas complètement, en effet, dans le cas ou l'utilisateur tape des mots assez long, il y a un décalage et il peut arriver sur la 6eme ligne ! Voilà pourquoi j'ai baissé la valeur de comptage à 30, au lieu de 33 !

D'autres idées ?
Modifié par Aerandir (09 Mar 2009 - 11:48)
Bon... Je vois que mon sujet ne passionne pas les foules...

Question : Personne ne sait comment faire ? ou personne n'a essayé ? (ceci n'est pas du tout une question agressive)
Si j'agrandis mes tailles de texte je fais comment pour remplir 5 lignes en essayant d'en mettre autant que les autres ? Plutôt que réfléchir en terme de lignes, essaie plutôt de penser ton truc en terme de nombres de caractères autorisés. Tu trouveras des JS qui font ça très bien (annonce dynamique du nombre de car. restants, etc).
Le problème vient du fait que si l'utilisateur revient à la ligne, nous devions lui compter non pas un caractère, mais une ligne ! Beaucoup d'autre petite problèmatique se posent alors...
Modifié par Aerandir (10 Mar 2009 - 16:10)
Administrateur
Bonjour,

Aerandir a écrit :
PS : Mon textarea fait 233px de large (avec un police à 11px), j'espère que ça vous aidera !

c'est une police monospace j'espère? Smiley cligne
Et toutes les polices "à 11px" n'occupent pas la même place Smiley cligne Mais je suppose que la largeur de ton textarea convient exactement à la police que tu as choisie pour le nombre de caractères prévus?
Oui bien sur Smiley cligne Enfin il n'empêche que cette problèmatique est vraiment complexe a résoudre, j'y ai passé 1 jour et demi sans solution viable !

J'ai tenté l'approche par comptage des lettres (et des retours chariots), mais un décalage flagrant apparaît (notamment du au fait qu'un user peut saisir un grand mot en fin de ligne, ce qui aura pour effet de 'pousser' le texte de la ligne d'après, donc créé un décalage à la fin !

J'ai donc tenté une approche en comptage par mot, mais malheureusement manque de temps je me suis noyé !

Donc si quelqu'un a une idée ou se sent de tenter un truc je serais intéressé et curieux de voir comment il a réussi à faire !

PS : ce qu'il est important de noter, c'est que l'utilisateur a le droit à 33 caractères par lignes, et à 5 lignes. Donc à 165 caractères max et 5 lignes max (sachant que 165 caractères peuvent mais ne doivent pas dépasser les 5 lignes et inversement !) [Aerandir ne se sent pas clair Smiley lol ]
Modifié par Aerandir (10 Mar 2009 - 18:35)
Salut,

C'est le genre de cas où je suis fainéant du javascript, je place un message qui explique la règle et je vérifie la saisie après coup. (un split sur \n, puis comptage du nombre d'éléments (5 max) et de leurs longueurs (33 max).
Je précise "après coup" (sur onsubmit) parce que c'est plus simple à gérer, il n'y a qu'à voir le script que tu proposes et qui ne gère pas tous les cas de figure, il devient agaçant lorsqu'on a fait par exemple un coller avec la souris et que l'on se retrouve dans une situation non-acceptée : impossible alors de sélectionner du texte au clavier pour le supprimer.

Tu laisses également entendre qu'un mot long prend 2 lignes :
- C'est faux techniquement parlant (pas de \n);
- C'est vrai visuellement avec IE (avec Opera et FF, le mot reste sur sa ligne, avec un scroll horizontal sur le textarea). Ceci ne devrait pas entrer en considération.

a écrit :
sachant que 165 caractères peuvent mais ne doivent pas dépasser les 5 lignes

"peuvent" ? Comment ça, si tu limites justement à 5 lignes ?
Quand je dis peuvent, j'entends que si sur la fin de ma première ligne j'écris un mot un peu long ce dernier va revenir à la ligne et 'prendre de la place' sur le début de la seconde ligne. Ce qui va créer un décalage, et permettre à l'utilisateur avec le bon nombre de caractères, de faire 1 ligne de plus.
Or je dois exclure ce cas !

Il est clair qu'un check à la fin serait plus simple, mais pas forcément très agréable pour un utilisateur.

PS : Quand je parle de ligne je parle de lignes visuelles
Salut,
Aerandir a écrit :
PS : Quand je parle de ligne je parle de lignes visuelles

Ah ben dans ce cas, il ne me reste qu'à te souhaiter bon courage, je ne me risquerai pas sur un tel script. Trop de contraintes, pas de garantie de réussite.
J'avoue également ne pas comprendre la finalité d'un tel mécanisme, mais bon...

Bonne continuation tout de même !
J.
Merci... ^_^

En fait c'est pour un journal, chaque utilisateur n'a que 5 lignes maximum, et dans un journal la ligne visuelle est primordiale ! Le script est faisable, mais comme tu dis, très long avec beaucoup de cas différent.

Donc voilà il est clair que si quelqu'un a une idée de génie, et se sent de faire un script très pointu, il arriverait à calculer la ligne visuelle et bien il (ou elle) est et restera le (ou la) bienvenu(e) !

Merci à tous de votre attention !
Salut,
Une saloperie que j'ai tenté aussi mais je n,ai jamais réussi a avoir un compte juste de caractères par ligne.
Maintenant je me sert de la fonction php Wordwrap.


string wordwrap( string $str [, int $width= 75 [, string $break= "\n"  [, bool $cut= false  ]]] )

$str ==> La chaîne d'entrée.
$Width ==> La largeur de la colonne. Par défaut, 75.
$break ==> La ligne est rompue en utilisant ce paramètre optionnel. Par défaut, il vaut '\n'.
$cut ==>Si le paramètre cut vaut TRUE, la césure de la chaîne sera toujours à la taille width plus petit. Si vous avez un mot qui est plus long que la taille de césure, il sera coupé en morceaux.


$text = "Portez ce vieux whisky au juge blond qui fume.";
$newtext = wordwrap($text, 20, "<br />\n");
echo $newtext;


Portez ce vieux<br />
whisky au juge<br />
blond qui fume.

Avec le $cut a True


$text = "Un mot très très loooooooooooooooooong.";
$newtext = wordwrap($text, 8, "\n", true);
echo "$newtext\n";


Un mot
très
très
looooooo
oooooooo
ooong.

Peut-être un début de solution pour toi.

Bonne journée
Modifié par BartoLoco (21 Aug 2009 - 14:51)
Bonjour BartoLoco et bienvenue parmi nous Smiley smile

En tant que modérateur, je me dois de te faire remarquer que tu n'as malheureusement pas respecté l'une des Règles de base du forum qui est d'afficher les codes et exemples proprement à l'aide des boutons [ code]... ici ton code HTML, CSS, PHP, etc.[ /code] (sans espace).

Je te remercie par avance de bien vouloir éditer ton message afin de le rendre conforme à cette règle. Smiley cligne

upload/1-code.gif