Probleme : innerHTML + DOM + fonctions à paramètre [Résolu]

slifeur22 16 Messages postés mercredi 17 mars 2010Date d'inscription 10 janvier 2012 Dernière intervention - 28 nov. 2010 à 14:00 - Dernière réponse : slifeur22 16 Messages postés mercredi 17 mars 2010Date d'inscription 10 janvier 2012 Dernière intervention
- 28 nov. 2010 à 19:59
Bonjour tou le monde
je fais un programme qui insère des lignes de formulaire en cliquant sur un bouton(Nouveau),


La ligne contient :
zone de texte associé à un calendrier pour saisir les date:
deux liste déroulante
une zone de texte qui change de "value" quand les listes déroulantes changent.

l'insertion se passe à merveille, mais puisque j'ai utilisé innerHTML, il y a une différence entre IE et FF, sur IE ça marche quand j'insère une ligne je la remplie et je clique sur mon Bouton pour insérer une deuxième ligne, j'ai la nouvelle et c'est reparti pour la remplir, je peux à tout moment revenir sur les lignes déjà insérée et les modifier, le malheur c'est avec FireFox, la première ligne s'insère normalement, je la rempli, mais une fois je clique sur le bouton d'insertion pour insérer une nouvelle ligne, il est bien insérée mais toutes les ligne précédente sont réinitialisée, ça veut dire que tout ce que j'ai saisi disparait (les liste déroulante reviennent sur l'option selected parDefaut, les zone de texte sont vide) et le calendrier n'apparait plus quand je clique sur la zone de texte de la date (onfocus engendre l'apparition du calendrier), bref sur FF ça ne marche que sur la dernière ligne insère, les précédentes sont toutes réinitialisées.
Après lecture des tuto j'ai essayé de faire l'insertion par DOM, par contre je rencontre un gros problème :colere: , la majorité de mes fonctions qui sont associées à des évènement des objets insèré contient des paramètred alors que dans ce tuto j'ai que addEventListner(Event,fonction,true) ou addAttachment(onEvent,fonction) SANS PARAMÈTRE, après tout ce long discours ma question est :
Comment associer des fonction qui contient des paramètre à des évènement inséré?



P.S : si besoin du code je peux le copier mais je vous préviens il est troop long (surtout le calendrier)
Afficher la suite 

Votre réponse

11 réponses

Meilleure réponse
PetoleTeam 3435 Messages postés lundi 26 décembre 2005Date d'inscription 14 janvier 2011 Dernière intervention - 28 nov. 2010 à 17:29
3
Merci
HOU LA LA !
pléthore de remarques mais isolons d'abord l'objet de ton problème à savoir innerHTML.
Prenons ta fonction inserer()
function inserer() {
  var m =  document.getElementsByTagName("label").length;
  n = Math.floor(m / 4);
  var contenu = document.getElementById("insertion").innerHTML;
  insertion.innerHTML = contenu + '<div id="ligne ' //et la suite...
}
c'est une utilisation malsaine de innerHTML que tu fais là...ce que l'on peut qualifier d'effet de bord, c'est pour cela qu'il n'est pas conseillé de l'utiliser sauf peut être lors de l'initialisation.

Le plus clean serait de créer via des document.createElement( tag_balise ) puis des oParent.appendChild(new_element) tous tes élément, code lourd mais respectueux du DOM de l'élément modifié.

Une alternative en ce qui te concerne et de créer une nouvelle DIV et de lui inclure tous les éléments via innerHTMl, puis de l'ajouter via un appendChild
cela peut donner
//-----------------
function inserer() {
  var m  = document.getElementsByTagName("label").length;
  n = Math.floor(m / 4);
  //-- Get Element parent
  var oDiv = document.getElementById("insertion");
  //-- Creation de la DIV a ajouter
  var oNew = document.createElement("div");
  //-- Affectation de l'ID
  oNew.id  = "ligne " + n;
  //-- Ajout de l'element
  oDiv.appendChild( oNew)
  //-- Ajout du contenu
  oNew.innerHTML = '<span id="calendrier' //et la suite...
}

Voila pour commencer, les autres remarques on verra après...

;O)

Merci PetoleTeam 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 84 internautes ce mois-ci

Commenter la réponse de PetoleTeam
Meilleure réponse
PetoleTeam 3435 Messages postés lundi 26 décembre 2005Date d'inscription 14 janvier 2011 Dernière intervention - 28 nov. 2010 à 19:48
3
Merci
j'ai oublié tu peux rajouter à la panoplie
document.getElementsByTagName(nom_balise) qui te renvoie les éléments correspondant à nom_balise
var oParent = document.getElementById("ligne " + numb);
var oSelect = oParent.getElementsByTagName("SELECT");
alert(oSelect[0].innerHTML);


Bien plus d'info sur https://developer.mozilla.org/fr/JavaScript, entre autres...

;O)

Merci PetoleTeam 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 84 internautes ce mois-ci

Commenter la réponse de PetoleTeam
PetoleTeam 3435 Messages postés lundi 26 décembre 2005Date d'inscription 14 janvier 2011 Dernière intervention - 28 nov. 2010 à 14:10
0
Merci
Bonjour,
si besoin du code je peux le copier mais je vous préviens il est troop long (surtout le calendrier)
plutôt que le calendrier, au moins la fonction d'insertion de ta ligne et la façon dont elle est appelée, pas plus dans un premier temps.

;O)
Commenter la réponse de PetoleTeam
slifeur22 16 Messages postés mercredi 17 mars 2010Date d'inscription 10 janvier 2012 Dernière intervention - 28 nov. 2010 à 16:18
0
Merci
plutôt que le calendrier, au moins la fonction d'insertion de ta ligne et la façon dont elle est appelée, pas plus dans un premier temps.


je vais le coper(le calendrier inclus) car elle présente aussi les même symptômes dans FireFox pour l'utiliser suffit de cliquer sur la zone de texte

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
  
<style>
body{
background-image : url("bg-logo.jpg");
background-attachment: fixed;
}
</style>
<script language="javascript">
moisX=["","Janvier","Fevrier","Mars","Avril","Mai","Juin","Juillet","Aout","Septembre","Octobre","Novembre","Decembre"];
JourM=["Di","Lu","Ma","Me","Je","Ve","Sa"];

var fermable_microcal=true;
var select_old= null;

var startWeek=0;//debut de la semaine 0=dim,1=lun,...
var jourPause={0:true,6:true}; //jour de pause de la semaine
var jourFeriee={"1-1":"jour an","1-5":"fête du travail","8-5":"armistice","14-7":"fête nationale","15-8":"ascencion","1-11":"armistice","11-11":"toussain","25-12":"noel"};

//structure la date 
function strucDate(dateX) 
{return {"pos":dateX.getDay(),"jour":dateX.getDate(),"mois":dateX.getMonth()+1,"annee":dateX.getFullYear()};}


var dateS= strucDate(new Date());//date Selectionné
var dnow= strucDate(new Date());//date actuelle


//retourne le ième jour du 1er du mois
function premJourMois(mois,annee) 
{return (new Date(annee,mois-1,1).getDay());}
//retourne le jour max du mois
function JmaxMois(mois,annee) 
{return (new Date(annee,mois,0).getDate());}


/* Test une date si elle est correct...spécial killer*/
function testTypeDate(dateEntree)
{
tst=false;
try
{rc=dateEntree.split("/");nd=new Date(rc[2],(rc[1]-1),rc[0]);
tst=(rc[2]>1800&&rc[2]<2200&&rc[2]==nd.getFullYear()&&rc[1]==(nd.getMonth()+1)&&rc[0]==nd.getDate());
} catch(e) {}
return tst;
}

//selection de la zone avec la souris
function choix(koi,code)
{
if (code) 
{  select_old= koi.style.background;
   koi.style.background ='#c0c0FF';
}
else 
{
koi.style.background =select_old;
}
}


function testTravail(oldX,xx,jj,mm,aa)
{
styleX="font-family:Tahoma;font-size:10px;text-align:center;";
styleX+=(oldX)?"":"color:#e0e0e0;";
styleX+="cursor:hand;border-right:1px #e0e0e0 solid;border-bottom:1px #e0e0e0 solid;";
if (jourPause[xx]||jourFeriee[jj+"-"+mm]!=null) styleX+="background:#f0f0f0;";
if (jj==dnow.jour&&mm==dnow.mois&&aa==dnow.annee) styleX+="border:2px red solid;";
return styleX;
}

//test si année bissextile
function bissextile(annee) {
return (annee%4==0 && annee %100!=0 || annee%400==0);
}

//Retourne le nombre de jour depuis le 1er janvier (num de semaine)
function nbJAnnee(dateX){
var nb_mois=[,0,31,59,90,120,151,181,212,243,273,304,334];
j=dateX.jour ; m=dateX.mois ; a=dateX.annee;
nb=nb_mois[m]+j-1 ;
if (bissextile(a) && m>2) nb++;
return nb;
}

//affiche le calendrier
function view_microcal(actif,ki,source,mxS,axS)
{
if (actif)
{
//decalage du mois su on clique sur -/+
if (mxS!=-1) 
{
clearTimeout(cc);
ki.focus();
fermable_microcal=true;
dateS.mois=mxS;
dateS.annee=axS;
if (dateS.mois<1) {dateS.annee--;dateS.mois+=12;}
if (dateS.mois>12) {dateS.annee++;dateS.mois-=12;}
}
//init
Dstart=(premJourMois(dateS.mois,dateS.annee)+7-startWeek)%7;
jmaxi=JmaxMois(dateS.mois,dateS.annee);
jmaxiAvant=JmaxMois((dateS.mois-1),dateS.annee);
//si on veux ajouter le numero de la semaine ...
//idxWeek=parseInt(nbJAnnee(strucDate(new Date(dateS.mois+'-01-'+dateS.annee)))/7,10)+1;

ymaxi=parseInt((jmaxi+Dstart+1)/7,10);

//generation du tableau
//--entête
htm="\";
htm+=\"-, \";
htm+=\" "+moisX[dateS.mois]+" "+dateS.annee+", \";
htm+=\"+, \";
//--corps
htm+=\"----
\";
//affichage des jours DLMMJVS
for (x=0;x<7;x++)
htm+=\""+JourM[(x+startWeek)%7]+", \";
htm+=\"\"

//------------------------
for (y=0;y<=ymaxi;y++)
{
htm+=\"----
\";
for (x=0;x<7;x++)
{
idxP=y*7+x-Dstart+1;   //numero du jour
aa=dateS.annee;
xx=(x+startWeek)%7;
//jour du mois précedent
if (idxP<=0)
{
jj=idxP+jmaxiAvant;mm=dateS.mois-1;
if (mm==0)
{mm=12;aa--;}
htm+=\""+jj+", \";
}
else if (idxP>jmaxi) //jour du mois suivant
{
jj=idxP-jmaxi;mm=dateS.mois+1;
if (mm==13)
{mm=1;aa++;}

htm+=\""+jj+", \";}
else //jour du mois en cours
{
jj=idxP;mm=dateS.mois;
htm+=\""+jj+", \";}
}
htm+=\"\"
}//-------------------------
htm+="
"
//affiche le tableau
source.innerHTML=htm;
source.style.visibility="";
} else
{
//ferme le calendrier
if (fermable_microcal) 
   cc=setTimeout(source.id+".style.visibility='hidden'",500);
}
}

</script>
<SCRIPT LANGUAGE="JavaScript">
<!--

var i=0,j=0;
function compZero(nombre) {
    return nombre < 10 ? '0' + nombre : nombre;
}

function date() {
    var infos = new Date();
var str;
str='['+compZero(infos.getDay())+' - '+compZero(infos.getMonth())+' - '+compZero(infos.getFullYear())+']';
return str;
}


var marge = 445;
function inserer(){
var m = document.getElementsByTagName("label").length;
n = Math.floor(m/4);


var contenu = document.getElementById("insertion").innerHTML;
insertion.innerHTML = contenu+'
                                     <label>ALLEE    </label>    <select id="listeD '+n+'" onchange="afficher('+n+');" >	<option value="agadir">Agadir</option><option value="hoceima">Al Hoceima</option>		<option value="casa" selected>Casablanca</option><option value="dakhla">Dakhla</option><option value="jdida">El Jadida</option>		<option value="rachidiya">Errachidia</option>	</select>     <select id="listeA '+n+'" onchange="afficher('+n+');"><option value="agadir">Agadir</option><option value="hoceima">Al Hoceima</option><option value="casa" selected>Casablanca</option><option value="dakhla">Dakhla</option>	<option value="jdida">El Jadida</option><option value="rachidiya">Errachidia</option></select>                                                                     Supprimer
                                    <label>RETOUR</label>        <label>Casablanca</label>             <label>Casablanca</label><hr />
 ';
 

}
function afficher(numb){
var D = document.getElementById("ligne "+numb);
var i = D.childNodes[5].selectedIndex;
var j = D.childNodes[7].selectedIndex;
if(isNaN(parseInt(distance[i][j])))
D.childNodes[9].setAttribute("value","------");
else
D.childNodes[9].setAttribute("value",2*parseInt(distance[i][j])+" Km");
D.childNodes[20].innerHTML = D.childNodes[5].options[i].innerHTML;
D.childNodes[18].innerHTML = D.childNodes[7].options[j].innerHTML;


}

var distance = new Array(
new Array("----","1091 Km","511 Km","1173 Km","417 Km","661 Km"),
new Array("1091 Km","----","539 Km","2264 Km","632 Km","616 Km"),
new Array("511 Km","539 Km","----","1173 Km","417 Km","545 Km"),
new Array("1173 Km","2264 Km","1684 Km","----","1590 Km","1954 Km"),
new Array("417 Km","632 Km","417 Km","1590 Km","----","506 Km"),
new Array("661 Km","616 Km","545 Km","1954 Km","506 Km","----"));
//-->
</SCRIPT>
</HEAD>

,

----

Espace agent comptable
,

----
Nom : XXXXX, ----

----
Prénom : XXXXX, ----

----
Tél : XXXXX, ----

----
Voiture : XXXXX, ----

----
Type : XXXXX, ----

----
CV : XXXXX, ----

----

Date,
Type,
Depart,
Arrivée,
Distance,
Indemnité,
---------,

----

<form id="formulaire" name="formulaire" action="" method="get">

</form>



</HTML>
Commenter la réponse de slifeur22
slifeur22 16 Messages postés mercredi 17 mars 2010Date d'inscription 10 janvier 2012 Dernière intervention - 28 nov. 2010 à 17:53
0
Merci
MAIS t'es un genie !!!!!!!!!!!!!! vraiment j'ai jamais pensé a mélanger entre DOM et innerHTML, pour moi je les considère comme ennemie ces deux là, mais vraiment je viens de tester sur ça marche sur FF et IE, tous mes respect, si tu as d'autre remarques ça me sera d'une grande utilité d'un génie comme vous, encore merci

PS: j'étais entrain de créer toute la ligne via DOM et comme tu le sait déjà c'est pas facile surtout que les deux listes déroulantes que j'ai mis sont juste a titre d'exemple, mes deux vraie liste sont assez long^^

ENCORE MERCI
Commenter la réponse de slifeur22
PetoleTeam 3435 Messages postés lundi 26 décembre 2005Date d'inscription 14 janvier 2011 Dernière intervention - 28 nov. 2010 à 18:08
0
Merci
...surtout que les deux listes déroulantes que j'ai mis sont juste a titre d'exemple, mes deux vraie liste sont assez long^^...
dans ces cas il ne faut pas hésiter à créer une fonction, voir le créer en PHP, si BdD par exemple, et le cloner ensuite puis l'ajouter.

Cela vaut pour la ligne entière d'ailleurs, une ligne type masquée à l'affichage puis clonée direct et dont on modifie ensuite les IDs et/ou NAMEs si l'on doit les envoyer.
Cette solution présente l'avantage de la maintenance si une modification doit intervenir dans la ligne à ajouter.

Une autre remarque pendant que l'on y est, dans la fonction afficher(numb) il faut se méfier de l'accés aux différents éléments par D.childNodes[5], les navigateurs n'ayant pas tous la même façon de hiérarchiser le DOM, mets un espace entre deux éléments de ta ligne et tu verras que cela va planter sous FireFox
;O)
Commenter la réponse de PetoleTeam
slifeur22 16 Messages postés mercredi 17 mars 2010Date d'inscription 10 janvier 2012 Dernière intervention - 28 nov. 2010 à 18:20
0
Merci
oui j'y avait pensé dès le début, mais le prof a exigé que ça soit en JS pour éviter le rechargement de la page, par contre le dernier point me rend perplexe car je suis déjà tombé sur problème et pour être franc les indice que j'ai mis dans childNodes[i] sont mis après parcours indice par indice jusqu'à ce que je tombe sur les objet que je cherche (j(utilise alert(Objet.childNodes[i].innerHTML), je ne sais pas comment passer d'un composant aux suivant, j'ai utilisé Noeud.nextSibiling qui donne le noeud suivant de Noeud mais elle ne fait que childNodes[i+1]. si tu as une idée comment passer d'un composant à un autre sans passer par les espacement fait moi part :)
Commenter la réponse de slifeur22
PetoleTeam 3435 Messages postés lundi 26 décembre 2005Date d'inscription 14 janvier 2011 Dernière intervention - 28 nov. 2010 à 18:43
0
Merci
glisse ce petit morceau de code en début de fonction afficher(numb)
var oParent = document.getElementById("ligne " + numb);
var oChild = oParent.childNodes; // liste de tous les enfants
var szTmp = "";
for( var i 0, nb oChild.length; i < nb; i++){
  szTmp += i + '->' +oChild[i].nodeName +'->' +oChild[i].nodeType +'\n';
}
alert( szTmp);
et observes, tu peux bien sur afficher ce que bon te semble

si tu as une idée comment passer d'un composant à un autre sans passer par les espacement fait moi part
comme indiqué ci dessus avec un test sur le nodeType, si 1 on prend en compte SiNON on fait rien, par exemple.

le mieux, me semble t-il, reste une ID et/ou NAME, si transmit, et la récupération traditionnelle.
;O)
Commenter la réponse de PetoleTeam
slifeur22 16 Messages postés mercredi 17 mars 2010Date d'inscription 10 janvier 2012 Dernière intervention - 28 nov. 2010 à 19:03
0
Merci
très bonne méthode, j'ai fait la connaissance de nodeType qui retourne soit 1 soit 3 (dans mon cas) merci , il reste plus que faire une fonction qui peut même me retourner si je suis un input ou un select, merci énormément tu me sauve la vie.
Commenter la réponse de slifeur22
PetoleTeam 3435 Messages postés lundi 26 décembre 2005Date d'inscription 14 janvier 2011 Dernière intervention - 28 nov. 2010 à 19:35
0
Merci
nodeType peut prendre les valeurs de 1 à 12.

...et observes, tu peux bien sur afficher ce que bon te semble ...
tu peux mettre oChild[ i].tagName

penses à mettre en Réponse acceptées !certains point pouvant aider d'autres personnes.

;O)
Commenter la réponse de PetoleTeam
slifeur22 16 Messages postés mercredi 17 mars 2010Date d'inscription 10 janvier 2012 Dernière intervention - 28 nov. 2010 à 19:59
0
Merci
Merci enormément encore, je vais mettre resolu, passe une superbe soirée
Commenter la réponse de slifeur22

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.