11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Je suis actuellement en BTS IG par apprentissage, et je suis en train de developper une sorte d'agenda en ligne en pHp.

Mon appli fonctionne. Afin de la rendre plus interactive j'ai modifié mon code et je suis passé à l'Ajax avec la librairie jQuery.

Mon problème est le suivant :

J'ai un script (affichage.js) qui, lorsque l'on clique sur un des jours du calendrier, affiche la liste des rendez-vous de la journée. Sachant que par défaut à l'ouverture c'est le jours en cours qui s'ouvre.

J'ai un autre script (remove.js) qui, lorsque l'on clique sur la petite corbeille supprime le rendez-vous et rafraichit la div.

Les deux scripts ont l'air fonctionnel, en effet, si je clique sur la corbeille lorsque je viens d'ouvrir l'agenda, le rendez-vous est bien supprimé.

Par contre si je change de jours avec le script affichage.js et que je clique sur la corbeille, le script ne fonctionne plus, il me dirige vers la page php appelée en ajax sans supprimer quoi que ce soit.

Est-ce que les données retournées par la methode $.post de jQuery change les informations ?

Vous pouvez accéder à l'application en ligne à cette adresse : (je vais volontairement creer beaucoup de rendez vous aujourd'hui afin de permettre à ceux qui le voudront de tester donc il a des rendez vous le 19, le 20, le 21, et 26)

http://info-33.fr/~bellonjeanphilippe/agendav2/

Voici les scripts JS :

Affichage.js

$(function() {
	$("#calendrier > ul > li > a").click(function(){
		var day = $(this).text();
		var monthyear = $("#calendrier > h2").attr("title");
		var path = $(this).attr("href");
		$.post(path, { day: day, monthyear: monthyear }, function(data) {
			$("#affichage").empty().html(data);
		});
		$("#calendrier > ul > li").removeAttr("id")
		$(this).parent("li").attr("id","shown");
		return false;
	});
});


remove.js

$(function() {
	$("#affichage > ul > li > .remove").click(function(){
		var id = $(this).attr("alt");
		var path = $(this).attr("href");
		$.post(path, { idrdv: id }, function(data) {
			var day = $("#shown > a").text();
			var monthyear = $("#calendrier > h2").attr("title");
			$.post('affichage.php', { day: day, monthyear: monthyear }, function(data) {
				$("#affichage").empty().html(data);
			});
		});
		return false;
	});
});



En ce qui concerne le php :

affichage.php

	include('function/calendrier.php');
	include('function/aff_rdv.php');
	$jour_fr = array("Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi");
	$date = mktime (0, 0, 0, $mois, $jour, $annee);
	$num_jour = date("w", $date);
	$nom_jour = $jour_fr[$num_jour];
	echo '<h2>'.$nom_jour.' '.$jour.' '.NumEnMot($mois).'</h2>';
	if($num > 0) {
		echo '<ul id="rendezvous">';
		while($data=mysql_fetch_array($res))
		{
			echo '<li>';
			echo '<h3><img src="img/puce-rdv.png" alt="rdv"/>'.substr($data['heure'], 0, -3).'</h3><a href="edit.php" alt="'.$data['idrdv'].'" class="edit">+</a>   <a href="remove.php" alt="'.$data['idrdv'].'" class="remove">-</a></p>';
			echo '<p>Chez : '.$data['nomclient'].' '.$data['prenomclient'].'<br/>'.$data['adresse1client'].'<br/>';
			if(!empty($data['adresse2client'])){echo $data['adresse2client'].'<br/>';}
			echo $data['codepostal'].' '.$data['ville'].'<br/>'.$data['tel1client'].'</p>';
			echo '<p>Motif de l\'intervention : '.$data['motif'].'</p>';
			echo '</li>';
		}
		echo '</ul>';
	}
	else {
		echo "<p class='ras'>Aucun rendez-vous</p>";
	}


aff_rdv.php

	include('database.php');
	if(!isset($_POST['day']) && !isset($_POST['monthyear'])) {
		$jour = $day;
		$mois = getMois($today);
		$annee = getAnnee($today);
	}
	else {
		$jour = $_POST['day'];
		$mois = getMois($_POST['monthyear']);
		$annee = getAnnee($_POST['monthyear']);
	}
	$sql = 'SELECT * FROM rendezvous,client,ville WHERE date = "'.$annee.'-'.$mois.'-'.$jour.'" 
			AND rendezvous.client = client.codeclient
			AND client.codeville = ville.codeville
			ORDER BY heure ASC';
	$res = mysql_query($sql) or die('Erreur de requete dans'.$sql);
	$num = mysql_num_rows($res);


remove.php

	include('function/database.php');
	$sql = "DELETE FROM rendezvous WHERE idrdv='".$_POST['idrdv']."'";
	$res = mysql_query($sql);


Merci d'avance à ceux qui se pencheront sur mon problème... Cela fait 2 jours que je bloque sur cette partie sans savoir pourquoi ça ne marche pas.
Modifié par Jipi's (19 Jul 2010 - 11:02)
Je ne suis pas un expert en jQuery (/me aime pas le style de cette librairie) mais le problème me paraît assez clair.

Tu initialise tes évènements au début, tes noeuds DOM ont donc des handlers associés.
Ensuite tu vide ton élément : tout les noeuds DOM descendants et leurs handlers sont détruits.
Tu insère le résultat actualisé dans ta page, tu as de nouveaux noeuds DOM sans aucun handler dessus.

Il faut soit que tu réassocie des handler à ces nouveaux noeuds, soit (et c'est la meilleure solution si tu as beaucoup de handlers à gérer) que tu fasse de la délégation au niveau d'un ancètre qui sera toujours présent dans la page.
Par contre pour faire de la délégation avec jQuery, je laisse la place à un expert (ou google) car perso je ne met pas les doigts dans du jQuery, c'est contraire à ma religion. Smiley langue
Oula, je suis completement largué par ce que tu me racontes. Je ne sais pas ce qu'est un handler, et sur google ce n'est pas trés bien expliqué je trouve.

En fait, si je comprends bien, le problème réside dans le fait que je vide ma div #affichage et que je la remplie sans entete ?

Meme si je ne comprends pas bien ce que tu m'exposes, je pense que c'est evidemment ça le probleme car dans firebug quand je regarde le code source de la page (celle generee avec jQuery) le code est identique à celle de base, donc tu as surement raison, par contre je ne vois pas du tout comment corriger ce probleme.

Peut etre en n'utilisant pas empty(), et en faisant un load()...

Merci en tout cas de ton eclaircissement, j'attends maintenant les conseils de quelqu'un qui se sert de jQuery.
Un handler c'est la fonction qui va gérer (to handle) l'action à entreprendre quand un évènement est déclenché.

En gros quand tu vide ta div, tu remet du contenu avec des nouveaux noeuds vierges de tout handler. Ils n'ont donc pas de comportement spéciaux, et ton lien delete redevient un simple lien.
Ah c'est beaucoup plus clair comme ça, merci pour l'éclaircissement.

Pour verifier ce que tu disais j'ai essayé d'inclure mon script "remove" dans celui "affichage", et en effet lorsque je change de page et que je supprime un element cela fonctionne, par contre si j'en supprime un deuxieme ça ne marche pas.

Le code est trés laid mais il met bien évidence le fait que aies raison :

$(function() {
	$("#calendrier > ul > li > a").click(function(){
		var day = $(this).text();
		var monthyear = $("#calendrier > h2").attr("title");
		var path = $(this).attr("href");
		$.post(path, { day: day, monthyear: monthyear }, function(data) {
				$("#affichage").empty().html(data);
				    //Inclusion du code remove
                                    $("#affichage > ul > li > .remove").click(function(){
					var id = $(this).attr("alt");
					var path = $(this).attr("href");
					$.post(path, { idrdv: id }, function(data) {
						var day = $("#shown > a").text();
						var monthyear = $("#calendrier > h2").attr("title");
						$.post('affichage.php', { day: day, monthyear: monthyear }, function(data) {
							$("#affichage").empty().html(data);
						});
					});
					return false;
				});
		});
		$("#calendrier > ul > li").removeAttr("id")
		$(this).parent("li").attr("id","shown");
		return false;
	});
});
C'est probablement un pb d'"event delegation."
Les évènement comme "click" fonctionne sur le code html qui est présent au moment du chargement de la page. Si tu mets à jour le contenu (via ajax), les évènements ne sont pas attachés au nouveau contenu.

Il y a plusieurs options, la plus simple étant d'utiliser la fonction 'live' de jquery. Cette solution est utiliser avec modération, car gourmande en ressources.
Merci Paolo, mais je ne vois pas bien comment fonctionne cette fonction, j'ai beau regarder je ne vois pas comment la mettre en oeuvre...
Merci beacoup pour votre aide à tous les deux, j'ai résolu mon problème grce à cette fonction.

Juste une derniere question, l'autre methode est elle moins gourmande en ressources ? Car je vais avoir deux live(), un pour le delete, et un pour l'edit... Est-ce grave ?

Merci encore.