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

Discussion: DIV cliquable après requête [AJAX]

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    septembre 2018
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : septembre 2018
    Messages : 5
    Points : 2
    Points
    2

    Par défaut DIV cliquable après requête

    Bonjour à tous !
    J'ai un soucis un peu embêtant : un div cliquable contient le résultat d'une requête SQL. Elle est mise à jour par ajax toutes les secondes. Quand je clique dessus, je veux récupérer une valeur de ma requête :
    Code php : 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
    /* page php : */
    foreach($posteur as $p) {
    	if (!$p['lu']) {
    		echo '<div class="clientMessage recent">';
    	}
    	else {
    		echo '<div class="clientMessage">';
    	}
    		echo '<time>'.$p['datetime_message'].'</time>';
    		echo '<h4>'.$p['nom_posteur'].' : </h4>';
    		echo '<p>'.substr($p['texte'], 0, 140).'</p>';
    	echo '</div>';
    }
    /* fonctions js : */
    // pour récupérer ma valeur en cliquant sur la div
    $('.clientMessage').on('click', function() {
    	var $text = $(this).children("h4").text();
    	var $pseudo = $text.indexOf(":", 0);
    	$pseudo = $text.substring(0, $pseudo-1);
    	alert($pseudo);
    });
    // pour mettre à jour via ajax :
    function load(callback) {
    	var xhr = new XMLHttpRequest();
    	xhr.onreadystatechange = function() {
    		if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
    			callback(xhr.responseText);
    		}
    	};
    	xhr.open('GET', 'http://localhost/tests/siteComportementaliste/php/chats.php', true);
    	xhr.send(null);
    }
    function readData(sData) {
    	$("#jajax").html(sData);
    }
    setInterval(function() {
    	load(readData);
    }, 1000);

    Si je mets juste la première fonction, quand je clique je récupère ma valeur, c'est magnifique. Quand je mets ma fonction pour mettre à jour, tout va pour le mieux dans le meilleur des mondes. Par contre, quand je mets les 2 ensembles, la fonction qui clique boude et je ne peux plus récupérer ma valeur

    Quelqu'un saurait remédier à ce problème ? (Je précise, je suis débutant, peut être que je fais quelque chose de stupide ou que la solution est évidente... n'hésitez pas à me dire s'il y a autre chose qui ne va pas d'ailleurs).

    Merci d'avance de votre aide !

  2. #2
    Membre émérite Avatar de CosmoKnacki
    Homme Profil pro
    Inscrit en
    mars 2009
    Messages
    1 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : mars 2009
    Messages : 1 442
    Points : 2 803
    Points
    2 803

    Par défaut

    J'ai l'impression de ne pas avoir toutes les données pour évaluer et résoudre ton problème. Le mieux serait que tu postes le code nécessaire et suffisant (donc fonctionnel et le plus court possible) pour reproduire le problème, ce qui évitera un jeu de piste potentiellement interminable à tout ceux qui souhaiteraient te répondre.
    Pour l'instant on a dans une seule et même balise code du php(*) qui ne semble absolument pas lié au problème, suivi d'un code javascript avec un mélange de jquery et de vanilla javascript dont on se demande la raison et qui fait référence à un élément dont l'id est jajax absent de ton exemple. Dans ces conditions, il est difficile de t'aider.

    (*) En ce qui concerne l'affichage de code html par php, il est préférable d'utiliser cette syntaxe qui permet de conserver l'indentation et d'éviter des echo voire des échappements à n'en plus finir et autres points-virgules:
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php foreach($posteur as $p): ?>
        <?php if ( !$p['lu'] ): ?>
    <div class="clientMessage recent">
        <?php else: ?>
    <div class="clientMessage">
        <?php endif; ?>
        <time><?=$p['datetime_message']?></time>
        <h4><?=$p['nom_posteur']?> : </h4>
        <p><?=substr($p['texte'], 0, 140)?></p>
    </div>
    <?php endforeach; ?>

    Voir la syntaxe alternative.

    Maître Pangloss n'aurait pas dit mieux.
    3615 JEXISTE

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    septembre 2018
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : septembre 2018
    Messages : 5
    Points : 2
    Points
    2

    Par défaut

    Merci de ton aide @CosmoKnacki et merci pour cette syntaxe que je ne connaissais pas
    Pour le code, bein... j'ai dû un peu trop écourter justement le php est ce qui est dans la balise "jajax".

    Sinon le "vanilla javascript" c'est le javascript "normal", donc pas jquery c'est ça ? (je pars de loin je sais ) Si oui, c'est parce que je n'ai pas réussi à faire du code ajax fonctionnel avec jquery.

    page "accueil" :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ...
    <div id="jajax">
    	<?php include ("chats.php"); ?>
    </div>
    ...
    page chats.php
    Code php : 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
    <?php
    if (!isset($bdd)) {
    	try {
    		$bdd = new PDO('mysql:host=localhost; dbname=maDB; charset=utf8', 'root', 'root');
    		date_default_timezone_set('CET');
    	} catch (Exception $e) {
    		die('Erreur' . $e->getMessage());
    	}
    }
    $req = $bdd->prepare('SELECT nom_posteur as n FROM chat WHERE nom_destinataire IS NULL GROUP BY n');
    $req->execute();
    $nom = [];
    while($n = $req->fetch()) {
    	$nom[] = $n['n'];
    }
    $posteur = [];
    foreach($nom as $n) {
    		$req = $bdd->prepare('SELECT nom_posteur, texte, datetime_message, lu FROM chat WHERE nom_posteur = :nom ORDER BY datetime_message DESC LIMIT 1');	
    		$req->execute(array('nom' => $n));
    		$posteur[] = $req->fetch();
    }
    $sort = array_column($posteur, "datetime_message");
    array_multisort($sort, SORT_DESC, $posteur);
    echo '<div id="chats">'; 
    foreach($posteur as $p) {
    	if (!$p['lu']) {
    		echo '<div class="clientMessage recent">';
    	}
    	else {
    		echo '<div class="clientMessage">';
    	}
    		echo '<time>'.$p['datetime_message'].'</time>';
    		echo '<h4>'.$p['nom_posteur'].' : </h4>';
    		echo '<p>'.substr($p['texte'], 0, 140).'</p>';
    	echo '</div>';
    }
    echo '</div>';
    ?>
    et page javascript :
    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
    $('.clientMessage').on('click', function() {
    	var $text = $(this).children("h4").text();
    	var $pseudo = $text.indexOf(":", 0);
    	$pseudo = $text.substring(0, $pseudo-1);
    	alert($pseudo);
    });
    function load(callback) {
    	var xhr = new XMLHttpRequest();
    	xhr.onreadystatechange = function() {
    		if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
    			callback(xhr.responseText);
    		}
    	};
    	xhr.open('GET', 'http://localhost/tests/siteComportementaliste/php/chats.php', true);
    	xhr.send(null);
    }
     
    function readData(sData) {
    	$("#jajax").html(sData);
    }
     
    setInterval(function() {
    	load(readData);
    }, 1000);
    Merci encore pour l'aide.

  4. #4
    Membre émérite Avatar de CosmoKnacki
    Homme Profil pro
    Inscrit en
    mars 2009
    Messages
    1 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : mars 2009
    Messages : 1 442
    Points : 2 803
    Points
    2 803

    Par défaut

    D'après moi, le problème est qu'au premier appel ajax, les éléments auxquels les gestionnaires d'événements sont attachés, donc ceux avec la classe clientMessage, sont détruits puis remplacés par les autres mis à jour. Ces nouveaux éléments n'ont quant à eux aucun gestionnaire d'événement click.

    Basiquement, tu dois pouvoir t'en tirer en rajoutant le gestionnaire d'événement click après chaque appel ajax. Mais il y a peut-être mieux à faire en utilisant la délégation d'évènement qui consiste à attacher le gestionnaire d'événement au parent (soit le div#jajax) qui recevra l'évènement click par propagation (bubbling) de ses enfants. Comme cet élément parent n'est pas effacé ou remplacé, le gestionnaire d'évènement sera toujours là même après un appel ajax. Quelque chose comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $('#jajax').on('click', '.clientMessage', function(e) {
        // e.target représente alors l'élément d'où le click est parti.
        // e.currentTarget représente l'élément avec la classe .clientMessage
    });
    3615 JEXISTE

  5. #5
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    septembre 2018
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : septembre 2018
    Messages : 5
    Points : 2
    Points
    2

    Par défaut

    Merci pour ton aide

    Je peux recevoir "quelque chose" à chaque fois maintenant. Par contre, je n'arrive pas à sélectionner le morceau que je veux récupérer.

    J'ai donc :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $('#jajax').on('click', function(e) {
    	/* Je veux récupérer le texte du h4 correspondant au div cliqué où est présent le pseudo :
            var $text = e.+++quelque chose+++("h4").text();
            var $pseudo = $text.indexOf(":", 0);
    	$pseudo = $text.substring(0, $pseudo-1);*/
    	alert($pseudo);
    });
    Quand j'essaie mon code en faisant un alert avec e.target, j'obtiens un résultat.
    Par contre, dès que je cherche autre chose (genre e.parent().x, e.siblings().x, etc) le clic ne marche plus.

    Je creuse, mais je ne comprends pas pourquoi si e.target fonctionne, les autres ne fonctionnent pas

    (et merci NoSmoking pour la coloration des balises).

  6. #6
    Membre émérite Avatar de CosmoKnacki
    Homme Profil pro
    Inscrit en
    mars 2009
    Messages
    1 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : mars 2009
    Messages : 1 442
    Points : 2 803
    Points
    2 803

    Par défaut

    dès que je cherche autre chose (genre e.parent().x, e.siblings().x, etc) le clic ne marche plus.
    Le paramètre e dans la fonction anonyme désigne l'événement, pas l'élément. Par contre cet évènement a une propriété target qui elle renvoie l'élément. Donc si tu veux atteindre un parent, Il faut partir de e.target, pas de e.

    Très important: débugguer du code à coup de alert() ne t'apportera rien, remplace le par console.log() qui est beaucoup plus riche en information et utilise les outils développeurs de ton navigateur pour voir les messages (ctrl + shift + i dans firefox). La console te permettra en plus l'affichage des erreurs.
    3615 JEXISTE

  7. #7
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    septembre 2018
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : septembre 2018
    Messages : 5
    Points : 2
    Points
    2

    Par défaut

    Merci encore CosmoKnacki, t'es de l'or !!

    Ma fonction marche à présent

    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
    $('#jajax').on('click', '.clientMessage', function(e) {
    	var event = e.target;
    	var text;
    	if($(event).is('div')) {
    		text = $(event).children("h4").text();
    	}
    	else if($(event).is('h4')) {
    		text = $(event).text();
    	}
    	else {
    		text = $(event).siblings("h4").text();
    	}
    	event = text.substring(0, text.length-2);
    	console.log(event);
    });

    Du coup, on arrive au moment où on peut dire deux choses : "c'est marche donc c'est bien" ou "c'est marche mais c'est sans doute moche"...

    J'ai l'impression que cette fonction est pas trop moche, mais comme je ne suis pas un expert, je veux bien une confirmation :p

    Pour mon autre fonction, je crois savoir... qu'elle est moche ! Je la remets au cas où :

    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
    function load(callback) {
    	var xhr = new XMLHttpRequest();
    	xhr.onreadystatechange = function() {
    		if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
    			callback(xhr.responseText);
    		}
    	};
    	xhr.open('GET', 'http://localhost/tests/siteComportementaliste/php/chats.php', true);
    	xhr.send(null);
    }
     
    function readData(sData) {
    	$("#jajax").html(sData);
    }
     
    setInterval(function() {
    	load(readData);
    }, 1000);

    En essayant de faire propre, j'ai remplacé par :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function load() {
    	$.ajax({
    		url: 'http://localhost/tests/siteComportementaliste/php/chats.php',
    		success: function(result) {
    			$("#jajax").html(result);
    		}
    	}).then(function() {
    		setTimeout(load, 1000);
    	});
    };
    load();

    ça passe ?

  8. #8
    Membre émérite Avatar de CosmoKnacki
    Homme Profil pro
    Inscrit en
    mars 2009
    Messages
    1 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : mars 2009
    Messages : 1 442
    Points : 2 803
    Points
    2 803

    Par défaut

    Je me suis emmêlé les pinceaux dans un précédent post: e.currentTarget renvoie l'élément dont la classe est .clientMessage.

    Ce qui simplifie grandement la récupération du contenu du h4:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $('#jajax').on('click', '.clientMessage', function (e) {
        console.log($(e.currentTarget).children('h4').text().slice(0, -2));
    });
    Par contre, choisis tes noms de variable en fonction de ce qu'ils représentent: n'appelle pas quelque chose 'event' lorsqu'il s'agit d'un élément ou d'une chaîne.
    3615 JEXISTE

  9. #9
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    septembre 2018
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : septembre 2018
    Messages : 5
    Points : 2
    Points
    2

    Par défaut

    Merci mille fois de ton aide !

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

Discussions similaires

  1. [AJAX] Rafraîchir une DIV après requête AJAX
    Par TheBleedz dans le forum jQuery
    Réponses: 6
    Dernier message: 05/12/2013, 20h10
  2. Affichage du menu en boucle après requête effectuer
    Par leloup84 dans le forum PHP & MySQL
    Réponses: 14
    Dernier message: 08/02/2006, 15h44
  3. changer de style une fois sur 2 après requête
    Par mussara dans le forum PHP & MySQL
    Réponses: 2
    Dernier message: 14/12/2005, 22h55
  4. Mise en page après requête MySql
    Par php_de_travers dans le forum Requêtes
    Réponses: 5
    Dernier message: 23/11/2005, 10h25
  5. Mise à jour de table impossible après requête avec jointure
    Par sto dans le forum Bases de données
    Réponses: 5
    Dernier message: 17/03/2004, 14h24

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