Affichage dans une boucle while

Répondre
coringan
le 26/07/2013 à 23:00
coringan
Bonjour à tous,

je voudrais developer un chat avec une fenêtre de conversation unique pour chaque contact (dans un while en PHP). La gestion des input et out put se faisant en AJAX à l'instar de celui-ci, je l'ai trouvé sur le net.

*** INPUT ***
function sendChatText() {
if(document.getElementById('txt_message').value == '') {
alert("You have not entered a message");
return;
}
if (sendReq.readyState == 4 || sendReq.readyState == 0) {
sendReq.open("POST", 'getChat.php?chat=1&last=' + lastMessage, true);
sendReq.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
sendReq.onreadystatechange = handleSendChat;
var param = 'message=' + document.getElementById('txt_message').value;
param += '&name=Ryan Smith';
param += '&chat=1';
sendReq.send(param);
document.getElementById('txt_message').value = '';
}
}

*** OUT PUT ***
function handleReceiveChat() {
if (receiveReq.readyState == 4) {
var chat_div = document.getElementById('div_chat');
var xmldoc = receiveReq.responseXML;
var message_nodes = xmldoc.getElementsByTagName("message");
var n_messages = message_nodes.length
for (i = 0; i < n_messages; i++) {
var user_node = message_nodes[i].getElementsByTagName("user");
var text_node = message_nodes[i].getElementsByTagName("text");
var time_node = message_nodes[i].getElementsByTagName("time");
chat_div.innerHTML += user_node[0].firstChild.nodeValue + '&nbsp;';
chat_div.innerHTML += '<font class="chat_time">' + time_node[0].firstChild.nodeValue + '</font><br />';
chat_div.innerHTML += text_node[0].firstChild.nodeValue + '<br />';
chat_div.scrollTop = chat_div.scrollHeight;
lastMessage = (message_nodes[i].getAttribute('id'));
}
mTimer = setTimeout('getChatText();',2000); //Refresh our chat in 2 seconds
}
}


AFFICHAGE DANS LE &lt;DIV&gt; SUIVANT
<div id="div_chat"></div>


Je réussi à récupérer et à insérer les données de la manière suivante :
function sendChatText(id) {
if(document.getElementById('txt_message'+id).value == '') {
alert("You have not entered a message"+id);
return;
}
if (sendReq.readyState == 4 || sendReq.readyState == 0) {
sendReq.open("POST", 'getChat.php?chat=1&last=' + lastMessage, true);
sendReq.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
sendReq.onreadystatechange = handleSendChat;
var param = 'message=' + document.getElementById('txt_message'+id).value;
param += '&name='+id;
param += '&chat=1';
sendReq.send(param);
document.getElementById('txt_message'+id).value = '';
}
}

<div id="div_chat+id"></div>

J'aurais pu les afficher autrement, mais le refresh ne fonctionne pas.

Comment afficher les données correspondant à chaque contact ?
Si quelqu'un voit ce que je voudrais dire, votre aide me sera vraiment salvatrice.

Merci.
Je fais ce qui me plaît, et ce que je fais me plaît !
LupusMic
le 26/07/2013 à 23:32
LupusMic
On n'a pas la coloration syntaxique avec JS, mais au moins on a l'indentation, alors utilises la balise code du bbcode du forum ;)

Ça m'a l'air confu. Pourquoi parles-tu d'un while dans ton point d'entrée en PHP ?

Je t'invite à lire la documentation de setTimeout.

De plus, c'est un problème de JS, et tu gagnerais à utiliser Firebug pour tenter de déboguer ton code.

« Ça ne marche pas » n'est pas un constat acceptable. Il faut que tu dises ce que tu veux faire, comment tu le fais, et le résultat obtenu.
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
coringan
le 27/07/2013 à 04:36
coringan
Merci pour la réaction rapide LupusMic.

- Ce que je voudrais faire.
Afficher ma conversation du chat avec un contact vis-à-vis du numéro de ce dernier.

- Voici ce que je fais pour l'enregistrement du message d'une conversation.

Étape No 1
2 petites tables
Une première pour les contacts
CREATE TABLE contact (id_contact INT(5) NOT NULL AUTO_INCREMENT, PRIMARY KEY (id_contact));

Une seconde pour les messages de la conversation
CREATE TABLE message (id_message INT(5) NOT NULL AUTO_INCREMENT,
expediteur INT(5),
destinataire INT(5),
message TEXT,
date_post DATETIME DEFAULT NULL,
PRIMARY KEY (id_message));


Étape No 2
Mon fichier central index.php (avec Ajax). À cette étape, tout se passe encore bien jusqu'à l'insertion du message dans la table.
<?php
// Connexion à la base de données
$connexion = mysql_connect ("localhost", "root", "") or die (mysql_error ());
$base = mysql_select_db ("chat") or die (mysql_error ());

// Récupérer mes contacts pour le listage
$req_mes_fav = mysql_query('SELECT * FROM contact ORDER BY id_contact DESC');
$num_fav = mysql_num_rows($req_mes_fav);

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<title>TITRE</title>
<script language="JavaScript" type="text/javascript">

//Gets the browser specific XmlHttpRequest Object
function getXmlHttpRequestObject() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else if(window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
} else {
document.getElementById('p_status').innerHTML = 'Status: Cound not create XmlHttpRequest Object. Consider upgrading your browser.';
}
}

//Add a message to the chat server.
function sendChatText(id) {
if(document.getElementById('txt_message'+id).value == '') {
alert("You have not entered a message"+id);
return;
}
if (sendReq.readyState == 4 || sendReq.readyState == 0) {
sendReq.open("POST", 'Contact.php?destinataire='+id, true);
sendReq.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
var param = 'message=' + document.getElementById('txt_message'+id).value;
sendReq.send(param);
document.getElementById('txt_message'+id).value = '';
}
}

//Send a new message to the server and return false.
function blockSubmit(id) {
sendChatText(id);
return false;
}
</script>

</head>
<body>

<?php
// M'afficher une zone de saisie et d'affichage (DIV) par contact afin de communiquer avec ce dernier
while ($data_fav = mysql_fetch_array($req_mes_fav))
{
// Je voudrais afficher la page Contact.php dans ce div avec rafraichissement toutes les 2 secondes
echo '<div id="div_chat'.$data_fav['id_contact'].'" style="height: 300px; width: 500px; overflow: auto; background-color: #EEEEEE; border: 1px solid #DDDDDD;"> </div>
<form id="frm" name="frm" onsubmit="return blockSubmit('.$data_fav['id_contact'].');"><br />
<input type="text" id="txt_message'.$data_fav['id_contact'].'" style="width: 147px;" />
<input type="button" name="btn_chat" id="btn_chat" value="Envoyer" onclick="javascript:sendChatText('.$data_fav['id_contact'].');" />
</form>';
}

?>
</body>
</html>


Étape No3
Le fichier Contact.php
<?php // Si un message est envoyé, l'enregistrer
if(isset($_POST['message']) && $_POST['message'] != '')
{
$moi = 'expediteur';
$message = mysql_real_escape_string(utf8_decode($_POST['message']));

mysql_query("INSERT INTO message(expediteur, destinataire, message, date_post)
VALUES('$moi', '".$_GET['destinataire']."', '$message', NOW())");
}

// Sélectionner les messages du chat
$req_cht = mysql_query("SELECT * FROM message WHERE
(((expediteur = '".$moi."') AND (destinataire = '".$_GET["destinataire"]."')) OR
((expediteur = '".$_GET["destinataire"]."') AND (destinataire = '".$moi."'))) ORDER BY id_message DESC");

// Listage de la conversation (table message)
while($data = mysql_fetch_array($req_cht))
{
// Affichage formaté de expediteur, destinataire, message et date_post
}
php ?>


- Le résultat est que je ne parviens pas à faire un affichage instantanné avec rafraichissement.

Merci une fois de plus.
Je fais ce qui me plaît, et ce que je fais me plaît !
LupusMic
le 27/07/2013 à 12:33
LupusMic
Il manque encore des morceaux, mais j'y vois un peu plus clair :)
Quelques remarques :
- la construction de tes requêtes est problématique. En effet, elles sont toutes ouvertes à injections SQL.
Par exemple (note que j'utilise sprintf pour améliorer la visiblité, car la concaténation de chaînes, en plus d'être inefficient est illisible) :
$sql = sprintf('insert into poll_votes (choice) values (\'%s\')'
, $db->real_escape_string($choice));

- je vois que tu utilises utf8-decode avant de passer à mysql_real_escape_string. Tu n'as pas besoin de faire ça si tu configure correctement MySQL à l'aide de mysql_set_charset.
- id_contact, id_message : je sais que certaines personnes aiment répéter ce qu'on sait déjà, mais je n'en fait pas parti. Pour moi, l'ID d'une table doit s'appeler 'id', et les références étrangères 'foreign_table_id' (où 'foreign_table' est le nom ou l'alias de la table référencée).
- pourquoi un int(5) ? Si c'est pour optimiser, c'est un peu tôt.
- n'utilises pas d'abréviations. Les abréviations sont quelque chose de personnel, elles sont difficilement partagées.
- l'attribut onclick ne peut contrenir que du JavaScript. Il est inutile, et même illégal, de préciser 'javascript:'.
- lorsque tu fais du templating en PHP, préfère les construction if/endif, ce sera plus lisible. Par exemple :
<?php /* M'afficher une zone de saisie et d'affichage (DIV) par contact afin de
communiquer avec ce dernier */ ?>
<?php while ($data_fav = mysql_fetch_array($req_mes_fav)): ?>
<?php /* Je voudrais afficher la page Contact.php dans ce div avec rafraichissement
toutes les 2 secondes */ ?>
<?php $contact_id = htmlentities($data_fav['id_contact'], ENT_COMPAT, 'UTF-8') ?>
<div id="div_chat<?php echo $contact_id ?>"
style="height: 300px; width: 500px;
overflow: auto; background-color: #EEEEEE; border: 1px solid #DDDDDD;"> </div>
<form id="frm" name="frm" onsubmit="return blockSubmit('<?php echo $contact_id ?>');"><br />
<input type="text" id="txt_message<?php echo $contact_id ?>" style="width: 147px;" />
<input type="button" name="btn_chat" id="btn_chat" value="Envoyer"
onclick="sendChatText('<?php echo $contact_id ?>');" />
</form>
<?php endwhile ?>

- sendReq n'est jamais initialisé (je pense que c'est le nœud de ton problème ici). Quelle est l'URL que le XHR va taper côté serveur pour récupérer les données ?

Je t'invite à lire la réponse rapide que j'avais faite à côté, sur la méthodologie pour employer des requêtes AJAX.
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
coringan
le 27/07/2013 à 14:33
coringan
C'est vrai pour le sendReq.
Il était là au début du JavaScript mais j'ai oublié de le copier.
Je fais ce qui me plaît, et ce que je fais me plaît !
coringan
le 27/07/2013 à 14:37
coringan
var sendReq = getXmlHttpRequestObject();


Merci pour tous ces détails techniques, mais le problème d'affiche n'a pas été résolu.
Je fais ce qui me plaît, et ce que je fais me plaît !
LupusMic
le 27/07/2013 à 15:29
LupusMic
Où est défini handleSendChat ?
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
LupusMic
le 27/07/2013 à 16:23
LupusMic
Forcément, si tu vires la fonction fondamentale qui gère les événements du XHR, ça va beaucoup moins marcher.

xmlHttpRequest, XHR pour les intimes, appelle onreadystatechange sur lui-même lorsque son état change. C'est ce qui permet de gérer l'asynchronicité.

Et c'est là que je comprends ton erreur. En fait, tu as transformé handleSendChat en sendChatText, et tu l'appelle depuis le form.submit.

Ça ne peut pas marcher.

Il faut que tu respecte un certain workflow. L'une des difficulté de JavaScript, c'est son approche fonctionnelle et événementielle.

Je te conseille de tout réécrire depuis zéro, c'est trop compliqué à ton niveau de faire des modifications dans du code mal écrit.

Une autre chose : utilises un Framework JS.
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
Répondre

Ecrire un message

Votre message vient d'être créé avec succès.
LoadingChargement en cours