11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Je débute Javascript et ceci est mon premier script alors n'hésitez pas à me dire "les bonnes façon de faire" Smiley biggrin

Donc voila j'ai un formulaire avec en dernier lieu, le moyen d'ajouter des communes. Cela ce fait simplement avec un select et un bouton ajouter.

La fonction associée à ce bouton génère une div avec un textNode contenant l'élément précédemment sélectionné, un bouton supprimer et un textarea.

Le problème est que lorsque j'ajoute plusieurs communes, et que j'en supprime une (autre que la dernière ajoutée) et bien les div suivantes ne se décalent pas vers le haut et restent à leurs positions initiale en recouvrant le reste du contenu... Smiley ohwell

Le plus surprenant c'est que quand je survol le bouton supprimer, tout ce remets correctement.

A noté que le noeud est bien supprimé car quand je vérifie les infos envoyées de mon formulaire, tout correspond.

Ci dessous le code de ma fonction suivi du css associé (ça a peut être un rôle après tout !)

Note importante : je dois dev que pour IE 7


var consigne = "Ajouter des rues.";
var nb_com = 0;

function ajouterCommune(){
	nb_com++;
	
	var liste = document.getElementById('listeCom');
	var indice = liste.selectedIndex;
	var valeur = liste.options[liste.selectedIndex].value;
		
	var cadreDiv = document.createElement("div");	
	cadreDiv.id = nb_com;
	cadreDiv.className = "ajoutCom";
	cadreDiv.name = valeur;
	
	var libDiv = document.createElement("div");	
	libDiv.className = "libDiv";	
	
	var label = document.createTextNode(valeur);		
	
	var bouton = document.createElement("button");
	bouton.className = "bouton";
	bouton.id=nb_com;
	bouton.appendChild(document.createTextNode("Supprimer"));
	bouton.supprimer = 
	function(){
		alert("L'élement "+cadreDiv.id+" "+cadreDiv.name+" va etre supprimé.");
		document.getElementById('divInsert').removeChild(cadreDiv);
		liste.add(new Option(valeur, valeur), 0);		
	}
	bouton.onclick = bouton.supprimer;
	
	var txtDiv = document.createElement("div");
	txtDiv.className = "txtDiv";	
	
	var area = document.createElement("textarea");
	area.rows = 4;
	area.cols = 50;
	area.value = consigne;
	area.name = valeur;	
	area.effacer= 	
	function(){
		if(area.value==consigne)area.value='';
	}
	area.onfocus = area.effacer;		
	
	
	libDiv.appendChild(label);
	libDiv.appendChild(bouton);
	txtDiv.appendChild(area);
	cadreDiv.appendChild(libDiv);
	cadreDiv.appendChild(txtDiv);
	
	document.getElementById('divInsert').appendChild(cadreDiv);
	liste.removeChild( liste.options[indice]);
}



.ajoutCom {
	position: relative;
	overflow: hidden;
	background-color: #505050;
	padding: 10px 0;
	margin: 10px 2%;
}
.libDiv{	
	position:relative;
	width:87%;	
	margin-left: 6.5%;
	padding-bottom: 3%;
}
.txtDiv{
	margin-left: 6.5%;
}
#boutonJS{
	background-color: #363535;
}
#boutonJS:hover{
	background-color: #FF9900;
}


Merci de vos réponses Smiley smile
Modifié par Mc Flurry (30 May 2011 - 09:11)
Bonjour,

Mc Flurry a écrit :
Note importante : je dois dev que pour IE 7
==> Oh, le pauvre! Smiley ohwell

Ton code HTML nous ferait bien plaisir aussi! Merci!

A+
a écrit :
==> Oh, le pauvre!

C'est une vraie galère...


<div class='fieldset'>
<div class='legend'>Créer une nouvelle archive</div>				
	<form method='POST' name='forminsert' action='RootController.php' >
	<div id='divInsert'>
		<p> <label for='id_sit'>Site</label> <select name='id_sit' id='id_sit' style='width: 135px'>".self::siteGenerator()."</select> </p>
		<p>
		<span>Energie : </span>
			<label for='energie_E'>Elec.</label><input class='radio' type=\"radio\" name='energie' id=\"energie_E\" value='E' checked=\"checked\" /> 
			<label for='energie_G'>Gaz</label><input class='radio' type=\"radio\" name='energie' id=\"energie_G\" value='G' />
		</p>
		<p> <label for='num_aff'>N° d'affaire</label> <input class='champs' id='num_aff' name='num_aff' type='text' size='10' tabindex='10' /> </p> 
		<p> <label for='ca'>Chargé d'affaire</label> <input class='champs' id='ca' name='ca' type='text' size='20' tabindex='30'/> </p> 
		<p> <label for='listeCom'>Commune impactée</label> <select name='listeCom' id='listeCom' style='width: 135px'>".self::communeGenerator($communes)."</select> 
		<input class='bouton' type='button' value='Ajouter' onclick=\"ajouterCommune();\"/>
		</p>
	</div>
	<p> <input class='bouton' type='submit' id='valider' value='Valider'/> </p>
	</form>
</div>


les méthodes "Generator" récupère un tableau de données de la db et servent à créer mes <option>.

Edit1 : Depuis que j'ai lu l'article sur display: inline-block je me sens con avec mon tableau !
Edit2 : Changement de code html, ça simplifie la vie !
Modifié par Mc Flurry (30 May 2011 - 15:45)
Bonjour,

As tu essayé avec une id unique pour les boutons ? Si je ne me trompe pas tout tes boutons supprimer se retrouve avec le même id #boutonJs .
Merci de ta réponse rs459, oui c'est effectivement le cas. J'ai changé en donnant un id unique mais ça na pas résolu le problème.

Après des tests plus poussés j'ai réussi à déterminer le comportement du bug :

* c'est à partir de 3 ajouts de div qu'il y a le problème à la suppression.

* à 3 ajouts, pour la suppression de la div de début, l'emplacement numéro 2 devient invisible comme si on lui appliquait visibility:hidden mais le survol du bouton supprimer de la dernière div lui permet de revenir à sa place.

* dès 4 ajouts, pour la suppression de la div de début, l'emplacement numéro 2 devient invisible.

* dès 4 ajouts, à part pour les div de début et de fin, lors d'une suppression de div son emplacement devient invisible

* après une suppression, lorsque je relance un ajout, l'emplacement invisible redevient visible avec les valeur qu'il contenait et la div s'ajoute à la fin.

Je ne sais pas si mon explication est compréhensible mais en tout cas le bug lui, ne l'est pas !
Modifié par Mc Flurry (27 May 2011 - 08:58)
Bonjour,
Cela ne resoudra peut-être pas ton problème, mais j'ai remarqué quelques erreurs dans ton code html.
- il y a 2 fois l'id 'sit'.
<select name='listeCom' id='sit' style='width: 135px'>
devrait devenir
<select name='listeCom' [b]id='listeCom'[/b] style='width: 135px'>
car sinon le script js ne retrouve pas l'élément.
- label for="..." ne pointe pas toujours vers un ID.
- au lieu de l'attribut "checked" tout court, mettre checked="checked",
- je te conseille, pour un même élément, de donner (quand c'est possible) une valeur identique à l'attribut "name" qu'à l'attribut "id" (par exemple : ... name="sit_com" id="sit_com" ... )
- tu utilises 2 fois la variable "nb_com" pour désigner des choses différentes (une fois comme id d'un élément, et 1 fois comme variable dans le code js)
- cette ligne n'est pas correcte, tu dois créer 2 labels différents pointant vers des id différentes.
<p> <label for='energie'> Energie </label> E <input class='radio' type=radio name='energie' value='E' checked/> G <input class='radio' type=radio name='energie' value='G'/> </p>


- dans le js, tu devrais remplacer "bouton.value = 'Supprimer';" par
bouton.appendChild(document.createTextNode("Supprimer"));

Modifié par lddsoft (28 May 2011 - 09:54)
Bonjour,
merci de tes corrections pour mon code html, j'avais pas fais attention au double id... par contre je ne comprend pas le double label pour les radio, je leur ai mi le meme nom pour pouvoir ensuite les récupérer via $_POST['energie'] et ce indépendamment de la valeur cochée.

Je mets à jour mon code html et mon code js des précédent posts.
Bonjour,
Pour les labels, voici la correction à apporter :
          
<p>
<span>Energie : </span>
<label for='energie_E'>Elec.</label><input class='radio' type="radio" name='energie' id="energie_E" value='E' checked="checked" /> 
 <label for='energie_G'>Gaz</label><input class='radio' type="radio" name='energie' id="energie_G" value='G' />
</p>

Ceci te permet de récupérer la valeur cochée pour 'energie' de la même façon, mais en respectant l'utilisation de 'label for=....' Smiley cligne
Merci pour la solution Smiley smile

Petite question, l'utilisation des double quotes sur le type et l'ID est obligatoire ?

Mon site est en PHP et génère du code HTML sous forme de longe chaine de caractère et je sais que si je ne met pas \" avant l'intitulé des fonctions js par exemple, ça ne marchera pas.
Excuse-moi de répondre si tardivement.
Il est évident que tu peux remplacer les " par des ' dans le code de mon post précédent si cela te convient mieux. Smiley cligne
Surtout bien veiller aux échappements, sinon ça foire!
Modifié par lddsoft (30 May 2011 - 17:54)