IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Remplacement d'un event sur <th>


Sujet :

JavaScript

  1. #1
    Membre éclairé
    Avatar de hornetbzz
    Homme Profil pro
    Directeur commercial
    Inscrit en
    Octobre 2009
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Directeur commercial

    Informations forums :
    Inscription : Octobre 2009
    Messages : 482
    Points : 773
    Points
    773
    Par défaut Remplacement d'un event sur <th>
    Bonjour,


    Objectif: Je voudrais remplacer la fonction de callback (VALIDER) d'un event "click" par une autre (GO BACK) sur un même élément <td> avec le même event "click". Seulement ds le contexte Moz & Co (la comptabilité IE viendra plus tard, un jour)


    Problème: je n'arrive pas à tuer le premier event, donc le click sur <td> provoque exécution des 2 fonctions de callback.

    Je sais, ça a vraiment l'air du truc le plus débile de la terre, mais je n'y arrive pas. Donc le problème est surement entre le clavier et la bécane

    Après de nombreuses et vaines tentatives, il semblerait que la seconde fonction soit bien implémentée mais que le premier event listener soit toujours en vie (et je n'arrive pas à le tuer). Donc ça ne donne pas le résultat attendu... double affichage de tables etc... puis des erreurs js en conséquence.

    Quelques unes des recherches en ts genres:
    J'ai bien lu ces forums, tutos articles, et bien sûr tenté un certain nombre de ces méthodes pour tuer le de premier event mais sans succès.
    le meilleur sur le sujet à mon avis
    Un post de 2005...
    quirks
    Le tuto auto-completion (pour l'inspiration)

    Le schéma:
    Je vais essayer de schématiser avant de balancer des paquets de mon code indigeste :
    1) J'affiche une table <table> de 2 colonnes avec un pied de table <tfoot>.
    2) J'attache un event "click" sur une des cellules de <tr>
    3) Le click déclenche une requête ajax avec une fonction de callback F1
    4) Avec F1, quand le retour xhrResponseText est Ok, je change le pied de table pour lui affecter (en tous cas essayer) l'autre fonction de callback F2.
    5) La (tentative de) suppression des events créés précédemment, cette fonction est appelée depuis F1
    6) La fonction F2 qui assure le "go back" vers un tableau de synthèse, est en fait l'émettrice d'une autre requête Ajax.
    Le code:

    1) La Table (j'ai mis tt le code mais ça se passe au point 8), à la fin):
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    function createTable(id_insert_point, table_title, data_title, data_array, with_pic, with_tfoot , input_on_off, callback_on_submit){
    
    	// 1) Creation du noeud <tbody>
    	var tbody = document.createElement("tbody");
    	var nbrows = data_array.length ;
    	var nbcols = data_array[0].length;
    	var count_col = 0;
    	
    	// 2) Remplissage de <tbody>
    	for(var i = 0; i < nbrows; i++){
    	
    		// Création Nouvelle ligne
    		var tr = document.createElement("tr");
    	
    		// Bouclage sur les colonnes de data_array
    		for (var j = 0; j < nbcols; j++){
    		
    			// Creation Nouvelle cellule
    			var td = document.createElement("td");
    			var td_text = false ;
    			
    			// Contenu <text> (1ere colonne, et suivantes si input_on_off = false)
    			if (input_on_off == false) {
    				// Affichage quand j=0 ou j est impair
    				if (j == 0 || j.isMultipleOf(2) == false) {
    					td_text = (undefined != data_array[i][j]) ? data_array[i][j] : '-' ;
    					td_text = document.createTextNode(td_text);
    				}
    				// Cas des IMAGES
    				if (with_pic && i==0 && j==1) {
    					var path_pic = 'images/';
    					//var source = (undefined != data_array['picture']) ? path_pic+data_array['picture'] : '#' ;
    					var source = (undefined != data_array[i][j]) ? path_pic+data_array[i][j] : '#' ;
    					td_text = document.createElement("img");
    					var regex = /jpg|png|gif/ ;
    					if (regex.test(source) == true) td_text.setAttribute("src", source);
    					else td_text.setAttribute("src", "");
    					var new_dim = redimImage(source , 35, 35) ;
    					td_text.setAttribute("width", new_dim['width']);
    					td_text.setAttribute("height", new_dim['height']);
    					td_text.setAttribute("alt", 'no picture available');
    					
    				}
    			}
    
    			// Contenu <input> 
    			if (input_on_off) {
    
    				// 1ere colonne j=0
    				if ( j == 0) {
    					td_text = (undefined != data_array[i][j]) ? data_array[i][j] : '-' ;
    					td_text = document.createTextNode(td_text);
    				}
    				
    				// Colonnes suivantes ssi j impair
    				if (j.isMultipleOf(2) == false ) {
    				
    					// Contenu  Balise <input>
    					//var test = '(' + i + ', ' + j +')' ;
    					var title	= (undefined != data_array[i][0]) ? data_array[i][0] : '-' ;
    					var value	= (undefined != data_array[i][j]) ? data_array[i][j] : '-' ;
    					var id_input= (undefined != data_array[i][j+1]) ? data_array[i][j+1] : '-' ;
    					
    					// Creation Balise <input>
    					td_text = document.createElement("input");
    					td_text.setAttribute("id", id_input);
    					td_text.setAttribute("title", title);
    					td_text.setAttribute("value", value);
    				}
    
    			}
    			
    			// Ajout de la cellule <td> à la ligne <tr> en cours
    				if (td_text) {
    				td.appendChild(td_text);
    				tr.appendChild(td);
    				}
    		}
    		
    		// Ajout de la ligne au tableau <tbody>
    		tbody.appendChild(tr);
    	}
    
    	
    	// 3) thead, tfoot: Creation thead et tfoot par clonage
    	
    		// thead
    		var trTitle = document.createElement("tr"); 
    		var thead   = document.createElement("thead");  
    		
    		// Nbre effectif de colonnes affichées
    		var row = tbody.getElementsByTagName("tr");		// NOTA: compatible IE (c'est getElementsByName qui ne l'est pas)
    		var firstrow = row.item(0) ;
    		var effective_cols = firstrow.children.length;		// NOTA: FF 3.5 only
    		
    		for (var j = 0; j < effective_cols  ; j++){
    			var th = document.createElement("th");
    			var title = (undefined != data_title[j])? data_title[j] : "-" ;
    			th.appendChild(document.createTextNode(title));
    			trTitle.appendChild(th);
    		}
    		thead.appendChild(trTitle.cloneNode(true));
    			
    		// tfoot
    		if (with_tfoot) {
    			var tfoot   = document.createElement("tfoot"); 
    			tfoot.appendChild(trTitle.cloneNode(true));
    			var node_tr = tfoot.firstChild ; // tr
    			var nodes_th = node_tr.childNodes ; // th
    			for (var j=0, c=nodes_th.length; j<c; j++) 
    				nodes_th.item(j).setAttribute("id",'colonne_'+j) ;
    				//if (input_on_off) nodes_th.item(j).setAttribute("value", "VALIDER" ) ;
    		}
    
    	// 4) caption: Creation Titre du tableau 
    		var caption       = document.createElement("caption");
    		var caption_text  = table_title;
    		caption_text = document.createTextNode(caption_text);
    		caption.appendChild(caption_text);
    
    	// 5) <table> Mise En Oeuvre du tableau
    		var table   = document.createElement("table"); 
    		table.appendChild(caption);
    		table.appendChild(thead);
    		if (with_tfoot) table.appendChild(tfoot);
    		table.appendChild(tbody);
    
    	// 6) Ajout du tableau au point d'insertion "id_insert_point"
    		document.getElementById(id_insert_point).appendChild(table);
    
    	// 7) Style des cellules
    		for (i=0; i<row.length; i++) {
    			
    			var cell = row[i].lastElementChild;
    		
    			if (cell.innerHTML == "" || cell.innerHTML.match(/none.+?/) || cell.id.match(/none/) ) {
    				row[i].style.backgroundColor='blue';
    				row[i].firstChild.style.color='white';
    				row[i].lastChild.innerHTML = '';
    			}
    			// Cells with pic
    			else if (cell.lastChild.nodeName == 'IMG') {
    				row[i].style.backgroundColor='white';
    				row[i].style.color='black';
    			}
    			// Other Cells (without pics)
    			else {
    				row[i].style.backgroundColor='gray';
    				row[i].firstChild.style.color='black';
    				with (row[i].firstChild.nextSibling) {
    					style.fontWeight='bold';
    					style.fontSize='small';
    					if (undefined != nextSibling) nextSibling.style.fontWeight='bold';
    					if (undefined != nextSibling) nextSibling.style.fontSize='small';
    				}
    			}
    		}
    		
    	// 8) BOUTON SUBMIT ou GOBACK(tfoot)
    	if (with_tfoot && input_on_off) {
    		addButton("tfoot", "VALIDER", callback_on_submit);
    	}
    	// Bouton de retour à la matrice
    	else if (with_tfoot && !input_on_off) { // redondance de cond°
    		addButton("tfoot", "RETOUR", go_back );
    	}
    	
    }

    2) La fonction d'attachement de l'event
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    function addButton(tag, text, callback) { // FF only
    // Récuperer le tag
    	var tfoot_tr = document.getElementsByTagName(tag).item(0).firstChild;
    	var tfoot_th = tfoot_tr.children; // FF only (permet de ne pas prendre en compte les noeuds texte)
     
    	// Implanter texte et event pour chaque noeud tfoot des colonnes <input> (j>0)
    	for (var j=1, c=tfoot_th.length ; j < c ; j++ ) {
     
    		var current_item = tfoot_th.item(j) ;
     
    		// Texte VALIDER ou GOBACK
    			var text_node = current_item.firstChild ;
    			text_node.nodeValue = text ;
     
    		// Event 'onmouseover'
    			if (document.all) current_item.attachEvent("onmouseover", OnChangeColor);	// IE
    			else current_item.addEventListener("mouseover", OnChangeColor, true);		// Moz&Co
     
    			// Event 'onmouseout'
    			if(document.all) current_item.attachEvent("onmouseout", OffChangeColor);	// IE
    			else current_item.addEventListener("mouseout", OffChangeColor, true);		// Moz&Co
     
    			// Event 'on click' (bouton VALIDER ou GOBACK)
    			if ( undefined != callback || false != callback) {
    				if (document.all) current_item.attachEvent("onclick", callback);	// IE
    				else current_item.addEventListener("click", callback, true);		// Moz&Co
     
    			}
    	}
    	return true;
    }
    3) Requête Ajax, première fonction de callback de la table
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    function update(event) {
    // Callback de <table>
    
    // test arret propagation : ne change rien avec ou sans
    	event.cancelBubble = true;
    	if (event.stopPropagation) event.stopPropagation();
    	
    	// Recup des valeurs des inputs entrées dans la table
    	var specs = GetMyInputs('input', /none.+/) ;
    	
    	// Recuperation de la reference active (3eme <Select>)
    	var selectList	= document.getElementsByTagName("select");
    	var ThirdSelect	= selectList.item(2) ;
    	var product_ref	= ThirdSelect.value;
    		
    	// Xhr des New datas (encodage et filtre réalisés intégralement sous PHP)
    	var parameters	= Serialize(specs) + '&product_ref=' + product_ref + '&update=true' ;
    	var xhr_file	= "spec/local/xhr_create_new_spec.php";
    	//alert('UPDATE SPECS:\nParam sérialisés à envoyer :\n' + parameters) ;
    	request(FirstSelect, xhrReturn, xhr_file, parameters) ;
    
    
    	return true;
    }
    4) Le callback de la requête Ajax (que j'ai appelée "F1")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    function xhrReturn(oText, balise_active) {
    // 4eme fonction de callback de request ajax
     
    	// Virer les espaces ajoutés par le serveur par magie
    	oText = oText.replace(/\s/g, '');
     
    	if (oText == "Ok") {
     
    			removeEvt("tfoot");
     
    			alert('Ok: dB altered properly');
     
    			addButton("tfoot", "RETOUR", go_back );
     
    			return true;
    	}
    	else {
    		alert('Fail: NOT added to dB' + '\nDEBUG:\n' + oText);
    		return false;
    	}
    }
    5) La (tentative de) suppression des event précédents
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function removeEvt(tag) { // test FF only
    	// alert('suppr evt precedents');
    	var tfoot_tr = document.getElementsByTagName(tag).item(0).firstChild;
    	var tfoot_th = tfoot_tr.children;
    	for (var j=0, c=tfoot_th.length ; j < c ; j++ ) {
    		var current_el = tfoot_th.item(j) ;
    		current_el.onclick = null;
    	}
    }
    Nota: j'ai essayé aussi les méthodes du post de 2005, mais pas de changement.

    6) La fonction F2 "go_back" appelée au point 4)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function go_back(event) {
     
    	// Stop propag: ça sert à rien après les tests "avec ou sans"
    	event.cancelBubble = true;
    	if (event.stopPropagation) event.stopPropagation();
     
    	var oSelect = document.getElementsByTagName("select").item(2) ;
    	request(oSelect, checkData, 'spec/local/xhr_check_data_xml.php', false);
     
    }

  2. #2
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut
    Bonjour,
    dans ta fonction removeEvt(), as-tu essayer de tracer via des alert() ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	for (var j=0, c=tfoot_th.length ; j < c ; j++ ) {
    		var current_el = tfoot_th.item(j) ;
                    alert(current_el.onclick);
    		current_el.onclick = null;
                    alert(current_el.onclick);
    	}
    As-tu essayé de cibler différemment les éléments ? Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var tfoot_th = document.getElementsByTagName(tag).item(0).getElementsByTagName("th");
    A+
    Pour tout savoir sur l'utilisation du forum

    En postant votre message, n'oubliez pas les Règles du Club.

  3. #3
    Membre éclairé
    Avatar de hornetbzz
    Homme Profil pro
    Directeur commercial
    Inscrit en
    Octobre 2009
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Directeur commercial

    Informations forums :
    Inscription : Octobre 2009
    Messages : 482
    Points : 773
    Points
    773
    Par défaut
    Bonjour,


    Aucun des essais ci-dessous ne fonctionne. Tout se passe comme s'il n'y avait effectivement pas d'évènement associé à cette balise <th> bien que le click déclenche bien l'évènement souhaité.


    Merci, je n'avais pas pensé à alert(element.onclick);
    - Le premier alert retourne "undefined"
    - Le deuxieme alert retourne "null"
    => "undefined" signifierait qu'il n'y a pas d'évènement onClick sur cet élément... or le click fonctionne. Donc l'élément serait mal sélectionné dans la fonction removeEvt().

    Or la fonction removeEvt() est sensée récupérer l'élément de la même façon qu'il a été créé dans la fonction addButton(). (codes identiques)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var tfoot_tr = document.getElementsByTagName(tag).item(0).firstChild;
    var tfoot_th = tfoot_tr.children; 
    var current_item = tfoot_th.item(j) ;
    current_item.addEventListener("click", callback, true);
    => J'ai ajouté une petite fonction whichElement pour voir quel élément a déclenché l'exécution de la fonction de callback, c'est bien <th> qui est retourné (et non le nœud texte enfant).

    => J'ai essayé de changer le mode de récupération de l'élément mais tous ces tests renvoient "undefined" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    var mon_bouton = document.getElementsByTagName(tag).item(0).getElementsByTagName("th");
    var mon_bouton = document.getElementById('colonne_1');
    var mon_bouton = document.getElementById('colonne_1').firstChild;
    var mon_bouton = document.getElementsByName('bouton_1');
    //var mon_bouton = document.getElementsByName('bouton_1').firstChild;	// undefined
    //var mon_bouton = document.getElementsByName('bouton_1').parentNode; 	// undefined

    => J'ai essayé de changer le mode de sélection, en le conservant identique pour l'affectation de l'event et sa récupération :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // var tfoot_th = tfoot_tr.children; 
    var tfoot_th = tfoot_tr.childNodes;
    Pas de changement, au debuggage sous FireBug, current_item est bien défini mais il n'y a pas d'event affecté.

    => J'ai revérifié le DOM dans firebug et avec le code généré:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <p id="spec">
    <table id="newTable">
    	<caption>MODIFICATIONS</caption>
    	<thead><tr><th>datas prod</th><th>Ref:xxxxx</th></tr></thead>
    	<tfoot>
    		<tr>
    			<th id="colonne_0">datas prod</th>
    			<th style="color: white; background-color: green; cursor: pointer;" name="button_1" id="colonne_1">VALIDER</th>
    		</tr>
    	</tfoot>
     
    	<tbody><tr style="background-color: gray;">
                  <tr><td>truc</td><td>bidule<td>
    	</tbody>
    </table>
    </p>

  4. #4
    Membre éclairé
    Avatar de hornetbzz
    Homme Profil pro
    Directeur commercial
    Inscrit en
    Octobre 2009
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Directeur commercial

    Informations forums :
    Inscription : Octobre 2009
    Messages : 482
    Points : 773
    Points
    773
    Par défaut
    Après qq heures de grosse galère, je suis enfin parvenu à faire fonctionner mes fonctions, mais sans avoir vraiment bien compris comment ni pourquoi ... :

    - j'ai ajouté un return false; à la fin de chaque fonction déclenchée par un évènement,

    - j'ai ajouté un arrêt de la propagation de chaque évènement dans les fonctions de callback appelées :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // Stop la propagation de l'event
    event.cancelBubble = true;
    if (event.stopPropagation) event.stopPropagation();
    et surtout - je pense que ça a été le point décisif- , j'ai modifié la fonction d'affectation des events en lui demandant qu'après le click, l'event soit supprimé de lui-même, et en recalant toutes les phases à false :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    current_item.addEventListener("click", function (event) {
    callback(event);
    this.removeEventListener('click',arguments.callee,false);				}
    , false);
    Nota: FF only, pour IE : employer attachEvent et detachEvent

  5. #5
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut


    Heu ... par contre, il est vraiment comme ça ton tbody ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	<tbody><tr style="background-color: gray;">
                  <tr><td>truc</td><td>bidule<td>
    	</tbody>
    A+
    Pour tout savoir sur l'utilisation du forum

    En postant votre message, n'oubliez pas les Règles du Club.

  6. #6
    Membre éclairé
    Avatar de hornetbzz
    Homme Profil pro
    Directeur commercial
    Inscrit en
    Octobre 2009
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Directeur commercial

    Informations forums :
    Inscription : Octobre 2009
    Messages : 482
    Points : 773
    Points
    773
    Par défaut
    euh non j'ai mal copier/coller, il est correct d'un point de vue DOM.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <tr style="background-color: gray;">
       <td>truc</td>
       <td>bidule</td>
    </tr>

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [C#] Key event sur form
    Par kooljy dans le forum Windows Forms
    Réponses: 4
    Dernier message: 28/06/2006, 13h24
  2. Event sur base de donnée Firebird et programmation delphi
    Par seb8810 dans le forum Connexion aux bases de données
    Réponses: 5
    Dernier message: 16/03/2006, 17h06
  3. remplacement d'un micro sur un reseau
    Par rony dans le forum Développement
    Réponses: 2
    Dernier message: 11/12/2005, 09h34
  4. Event sur le parcours d'un combobox
    Par Psykotik dans le forum MFC
    Réponses: 11
    Dernier message: 25/11/2005, 09h20
  5. window.event sur netscape
    Par edon47 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 24/10/2005, 02h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo