11548 sujets

JavaScript, DOM et API Web HTML5

Pages :
Bonjour !

Je suis entrain de bosser sur un petit module pour effectuer des demandes d'articles.
J'ai permis à l'utilisateur d'ajouter des lignes à la volée pour demander autant d'article qu'il le souhaite.
Lorsque l'utilisateur enregistre sa demande, j'efface les lignes une par une afin qu'il voit que la demande a été prise en compte.
J'utilise donc du JS pour créer et supprimer les lignes.
Sauf que ma fonction pour supprimer les lignes n'en supprime qu'une sur deux et me laisse les lignes paires affichées (sous IE, comme Firefox)...
Ca me laisse perplexe.

Voilà le code JS
function SauveArticles(numero,id_agent,id)
{
	var input=document.getElementById(id).getElementsByTagName('input');
	var recap=document.getElementById('recap_art');
	var liste='action=sauve_art&id_numero='+numero+'&id_agent='+id_agent;
	//Variable pour vérifier que la demande ne soit pas vide
	var flag=0;
	//Variable pour surveiller si des lettres ont été mises
	var ctrl=0;

	for(var i=0;i<input.length;i++){
		if((isNaN(input[i].value))&&(input[i].type=='text')&&(ctrl==0)) {
			alert("Vous ne devez saisir que des chiffres et non des lettres.\nVeuillez corriger l'élément indiqué.");
			input[i].focus();
			ctrl++;
		} else if((input[i].value!='')&&(input[i].type=='text')&&(ctrl==0)){
			liste+='&article[]='+input[i].value;
			flag++;
			} 
		}
	
	if(ctrl>0){
		/*
		Si on a des lettres on arrête là, le temps que l'utilisateur corrige.
		On fait donc une sorte de "catch all" vide pour stopper l'opération
		*/
	} else if(flag==0){
		//Aucun article choisi
		alert("Vous n'avez pas choisi d'article.\nVotre demande n'a pas été prise en compte.");
	} else {
		//On envoie la demande
		xmlhttp.open('POST','user_ajax.php',true);
		xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
		xmlhttp.send(liste);
		xmlhttp.onreadystatechange = function(){
			if(xmlhttp.readyState == 4 && xmlhttp.status == 200){ 
				recap.innerHTML=xmlhttp.responseText;
				alert('Votre demande a été enregistrée.');
				for(var i=0;i<input.length;i++){
					if(input[i].type=='text'){
						EnleveArticle(input[i].name.substr(3,7));
					}
				}
			}
		}
	}
}

[/i][/i][/i][/i][/i][/i][/i][/i][/i]
La boucle posant problème est tout en bas...
Je fais un input[i].name.substr(3,7) pour récupérer une valeur commune à toutes les balises qui doivent être enlevée (input, label et autres).

Edit: j'ai besoin d'une précision... un truc m'échappe.
i++ ça fait bien i+1 ?
J'ai modifié ma boucle for en mettant (i+1) et là ça passe...
Modifié par BruceFeuillette (17 Oct 2007 - 11:44)
Merci !

En fait le problème est différent.
Visiblement d'après les points d'arrêt que j'ai mis, la variable i augmente de 2 à chaque itération.
Ce qui explique que seuls les éléments impairs soient enlevés (sur une base 0).
Lors de la première boucle, il enlève l'élément 0 (donc la première ligne) puis s'incrémente de 2, du coup ôte l'élément 2 (la troisième ligne).
Le problème a disparu en codant explicitement le (i+1) en lieu et place de i++.
Mais ce qui m'échappe c'est pourquoi ce satané i++ fait un +2 au lieu de +1...
je ne vois pas ta fct "EnleveArticle" ...

le bond peut etre du à des retour à la ligne dans le code html...
ou ton 2 eme input n'est pas de type text... fait un alert sur tous pour voir...
boucle...
alert (input[i].type)
if(input[i].type=='text'){}

[/i][/i]
Modifié par gaylover (17 Oct 2007 - 09:51)
Effectivement, j'ai oublié de mettre la fonction EnleveArticle Smiley smile
La voici !

function EnleveArticle(id)
{
	var parent=document.getElementById('ajout_page');
	var postit=document.getElementById('postit');
	var input=document.getElementById('art'+id);
	var label=document.getElementById('label'+id);
	var lien=document.getElementById('lien'+id);
	var image=document.getElementById('img'+id);
	var br=document.getElementById('br'+id);

	parent.removeChild(br);
	lien.removeChild(image);
	parent.removeChild(lien);
	parent.removeChild(input);
	parent.removeChild(label);
	
	/* Petit hack pour que Firefox ajuste la hauteur du postit */
	var style = 'width: '+(postit.style.width)+'; height: '+(postit.offsetHeight-20)+'; top: '+(postit.style.top)+'; left: '+(postit.style.left)+'; z-index: '+(postit.style.zIndex)+'; cursor: move;';
	if (document.all){ 
		postit.style.setAttribute('cssText',style);
	} else {
		postit.setAttribute('style',style);
	}
}


Les inputs sont tous de type text puisque créés à l'aide d'une fonction JS.
Voilà un exemple de code généré en HTML (Merci Firefox et Firebug).

<div id="postit" style="width: 200px; top: 280px; left: 310px; z-index: 58; cursor: move; height: 415px;">
  <h1>Gazette des communes n°12</h1>
  <h2>Vos pages en cours de demande</h2>
  <p>Si vous désirez supprimer une page de votre demande, cliquez dessus.</p>
  <div id="recap_art">
    <p> <a title="Supprimer la demande pour la page 1" href="javascript:SupprimeArticle('9','1','1','1');">1</a>, <a title="Supprimer la demande pour la page 2" href="javascript:SupprimeArticle('15','2','1','1');">2</a></p>
  </div>
  <h2>Pages souhaitées</h2>
  <p class="ajout_mag"><a href="javascript:AjoutArticle('ajout_page');">Ajouter un article</a></p>
  <div id="ajout_page">
    <label for="art122" id="label122">Page</label>
    <input type="text" size="2" id="art122" alt="article" name="art122"/>
    <a href="javascript:EnleveArticle('122');" id="lien122"><img width="22" height="22" src="images/trashcan_empty.png" alt="Supprimer" id="img122"/></a>    
<br id="br122"/>
    <label for="art573" id="label573">Page</label>
    <input type="text" size="2" id="art573" alt="article" name="art573"/>
    <a href="javascript:EnleveArticle('573');" id="lien573"><img width="22" height="22" src="images/trashcan_empty.png" alt="Supprimer" id="img573"/></a>
   <br id="br573"/>    
<label for="art538" id="label538">Page</label>
     <input type="text" size="2" id="art538" alt="article" name="art538"/>
    <a href="javascript:EnleveArticle('538');" id="lien538"><img width="22" height="22" src="images/trashcan_empty.png" alt="Supprimer" id="img538"/></a>
    <br id="br538"/>    
<label for="art498" id="label498">Page</label>
    <input type="text" size="2" id="art498" alt="article" name="art498"/>
    <a href="javascript:EnleveArticle('498');" id="lien498"><img width="22" height="22" src="images/trashcan_empty.png" alt="Supprimer" id="img498"/></a>
     <br id="br498"/> 
    <a href="javascript:SauveArticles('1','1','ajout_page');"><img width="22" height="22" alt="Sauver" src="images/filesave.png"/></a> Sauver la sélection</div>
</div>


J'ai mis des alert() en place, ce qui m'étonne c'est de voir que mon tableau input[] comprend bien tous mes éléments, mais quand je mets un alert() juste après le for, je n'en ai qu'un sur deux...
Le fait de mettre (i+1) résout le problème alors que i++ et (i+1) font la même chose.
Si ma variable i était altérée au cours des itérations, elle le serait quelque soit le cas de figure.
Modifié par BruceFeuillette (17 Oct 2007 - 10:52)
je comprends pas bien ton prob désolé...

si tu fait
<script>
for(var i=0;i<4;i++){
alert(i)
}

</script>

ton i doit s'incrementer de 1
Sur ce point on est d'accord Smiley smile
Sauf que dans ma fonction, le i augmente de 2... et ce pour une raison inconnue !
C'est comme si le
for(var i=0;i<input.length;i++){

					if(input[i].type=='text'){

						EnleveArticle(input[i].name.substr(3,7));

					}
[/i]
ne tournait pas rond...[/i]
Hello,

a écrit :
Le fait de mettre (i+1) résout le problème alors que i++ et (i+1) font la même chose.


i++ et i+1 ne font pas la même chose.
i++ et i=i+1 oui par contre.

C'est à dire que
for(var i=0;i<input.length;i++) { }

et
for(var i=0;i<input.length;i+1) { }


Ne font absolument pas la même chose, la deuxieme boucle tournera de façon infinie, vu que la valeur de i n'est pas changée.

Je parierai plutot sur ta fonction EnleveArticle() qui modifie la valeur de i et l'incrémente "par erreur", faisant sauter les pas deux par deux quand tu mets i++ et un par un quand tu mets i+1 dans ta boucle for
Tymlis a écrit :
i++ et i+1 ne font pas la même chose.
i++ et i=i+1 oui par contre.

En fait, pour être précis, (++i) et (i = i +1) sont équivalents.
(i++) est équivalent à (i = i +1, i - 1).

Oui, je sais, je chipote. Smiley confused
Modifié par Julien Royer (17 Oct 2007 - 13:36)
Oh,

Effectivement, i++ "retourne" i avant incrémentation, ++i le "retourne" après incrémentation.

Par contre je ne connaissais pas cette syntaxe pour attribuer une valeur à une variable mais définir une autre valeur de retour à l'attribution elle même, merci Smiley smile


var i = 0;
alert( (i=i+1, "Hoho !"));
alert(i);


Je ne vois pas (encore) réellement à quoi la connaissance de cette syntaxe va me servir, mais qui sait... Smiley lol
Modifié par Tymlis (17 Oct 2007 - 14:08)
Tymlis a écrit :
Je ne vois pas (encore) réellement à quoi la connaissance de cette syntaxe va me servir, mais qui sait... Smiley lol

L'opérateur "," est en effet très rarement utile. Le seul cas pratique que j'imagine est la boucle "for" :
for (var i = 0, j = 1; i < 50; ++i, j *= 2) {
[...]
Modérateur
Une petite remarque...

Dans le cadre d'un script qui se situe directement dans la page et où se trouve une décrémentation du type i-- ou --i, c'est quand même bon de savoir faire le remplacement par i = i -1 afin de rendre le site valide. Smiley murf
koala64 a écrit :
Dans le cadre d'un script qui se situe directement dans la page et où se trouve une décrémentation du type i-- ou --i, c'est quand même bon de savoir faire le remplacement par i = i -1 afin de rendre le site valide. Smiley murf

Oui, en effet (à condition que le script soit encadré par des commentaires).
koala64 a écrit :
Une petite remarque...

Dans le cadre d'un script qui se situe directement dans la page et où se trouve une décrémentation du type i-- ou --i, c'est quand même bon de savoir faire le remplacement par i = i -1 afin de rendre le site valide. Smiley murf


Hmm, désolé mais là je ne vous suis plus du tout. Script dans la page, site valide, entre commentaires, pardon? J'ai l'impression d'avoir raté un épisode ^^
Modérateur
ben, la page suivante est invalide à cause du -- derrière le i (interdit dans un commentaire Smiley cligne ) :
<!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" xml:lang="fr" lang="fr">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8" />

		<title>Exemple</title>

	</head>
	<body>

		<script type="text/javascript"><!--

var i = 2;
i--;
alert(i);

		//--></script>

	</body>
</html>

Modifié par koala64 (17 Oct 2007 - 14:44)
koala64 a écrit :
ben, la page suivante est invalide à cause du -- derrière le i (interdit dans un commentaire Smiley cligne )

C'est surtout cette méthode de mise en commentaire de scripts qui est invalide en xhtml.

En xhtml normal, ça metterais pour de vrai le contenu du script en commentaires (l'intérieur de script est du PCDATA en xhtml, au lieu de CDATA en html). Donc le script ne serait pas executé, vu qu'il n'y a plus de script (juste un gros commentaire)...

En Xhtml, il faudrait déclarer le contenu en CDATA alors :
<script type="text/javascript"><![CDATA[

  ... contenu

//]]></script>

Sauf que maintenant c'est invalide en html (il nous faudrait les bon vieux commentaires). Certains dingues ont donc trouvé la solution ultime :
<script type="text/javascript"><!--//--><![CDATA[//><!--

    ... contenu

//--><!]]></script>



Moralité, toujours externaliser les scripts dans un fichier, ça évite énormément de problèmes Smiley smile
Modifié par FlorentG (17 Oct 2007 - 14:57)
Ah ok, je vois oui, j'avais pas pensé au -- dans un commentaire Smiley cligne

(On a un peu pourri le sujet initial avec nos discussions, ahem)
FlorentG a écrit :
C'est surtout cette méthode de mise en commentaire de scripts qui est invalide en xhtml.

Ca ne pose aucun problème tant que le document est servi en tant que "text/html".
Tymlis a écrit :
(On a un peu pourri le sujet initial avec nos discussions, ahem)

Oui... Smiley confused
Ouh là que de posts Smiley smile
Merci pour toutes ces réponses !

Effectivement, j'ai oublié de réaffecté le i+1 à i !
Mais bizarrement, ça fonctionne. Smiley eek

Je vais faire des tests aujourd'hui histoire d'avoir le fin mot de l'histoire, parce que je ne comprend pas pourquoi ce i s'incrémenterait dans une fonction qui ne l'utilise pas...

Tymlis a écrit :
(On a un peu pourri le sujet initial avec nos discussions, ahem)

Toute information est bonne à prendre Smiley cligne
Modifié par BruceFeuillette (18 Oct 2007 - 09:54)
ok, j'ai éclairci mon problème.
Tout vient de input.length.
En fait i est bien géré sauf que input.length se vide au fur et à mesure de l'exécution de la fonction !
Ce qui est logique dans un sens.
input.length contient le nombre d'éléments input dans ma page. Or ma fonction EnleveArticle enlève un élément input à chaque passage.
input.length se voyait donc décrémenté de 1 à chaque passage pendant que i était incrémenté lui aussi de 1.
Et finalement le jeu de la pile length qui se vide et de i qui augmente aboutissait à une égalité à mi-chemin.

J'ai donc modifié ma fonction pour ne pas mettre de condition d'itération. Et j'en ai profité pour travailler sur un input[0]...
for(var i=0;i<input.length;){
 if(input[0].type=='text'){
 EnleveArticle(input[0].name.substr(3,7));
 }
}
Pages :