Bonjour,

Je souhaiterais faire des requêtes SQL INSERT INTO et UPDATE en utilisant AJAX. Je vous explique : j'ai une page qui affiche l'intégralité du cours. Après chaque question, j'ai mis un <textarea> (avec un compteur qui s'incrémente) pour que l'internaute puisse saisir sa réponse. J'aimerais qu'en quittant un <textarea> (évènement onChange), la réponse de l'internaute s'enregistre dans la base de données (avec bien sûr les bons identifiants de la question et de l'utilisateur). A noter qu'une question est dans uniquement un cours.

Pour cela, j'utilise ces deux fonctions javascript :
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
<script type='text/javascript'>
function init_xhr() {
    if (window.XMLHttpRequest) // Firefox
 
        xhr = new XMLHttpRequest();
 
    else {
 
        if (window.ActiveXObject) // Internet Explorer
 
           xhr = new ActiveXObject("Microsoft.XMLHTTP");
 
        else { // XMLHttpRequest non supporté par le navigateur
 
            alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
 
            return;
        }
    }
    return xhr;
}
</script>
 
<script type='text/javascript'>
function go(tp_rep_id, reponse) {
 
    var xhr = init_xhr();
 
    xhr.onreadystatechange = function () {
 
        if (xhr.readyState == 4 && xhr.status == 200) {
 
            reponse = xhr.responseText;
 
            if (reponse=="0") document.getElementById("image" + tp_rep_id).innerHTML = "<img src=tp_en_attente.png align=left title='En attente de validation' />";
 
            if (reponse=="1") document.getElementById("image" + tp_rep_id).innerHTML = "<img src=en_travaux.png align=left title='Réponse incomplète' />";
 
            if (reponse=="4") document.getElementById("image" + tp_rep_id).innerHTML = "<img src=tp_validee.png align=left title='Réponse OK' />";
 
        }
    }
 
    xhr.open("POST", "fichier_traitement.php", true);
 
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    /* Utilisation des variables PHP (identifiants du cours et de l'utilisateur) - Il détecte les bons identifiants (cours, l'utilisateur connecté) */
    var id_cours_tp = '<?php echo $id_cours_tp; ?>'; /* A mon avis, ce n'est pas la peine de transférer l'identifiant du cours puisqu'une question ne peut pas être dans plusieurs cours ! */
	var id_utilisateur = '<?php echo $query_recuperation_identifiant_connecte; ?>';
	var id_question = ''; 
	// Cette ligne ne va pas (il faut qu'il transfère dans le traitement PHP les identifiants du cours, de l'utilisateur connecté, de l'identifiant de la bonne question et la réponse saisie) pour pouvoir les mettre dans la requête SQL INSERT INTO, de plus il faut voir comment récupérer l'identifiant de la bonne question pour la transférer dans le traitement PHP
	message = "id_cours_tp=" + id_cours_tp + "id_utilisateur=" + id_utilisateur + "tp_rep_id=" + tp_rep_id + encodeURIComponent(reponse); // en faisant un  alert(reponse);, il prend en compte la réponse saisie, en faisant un alert(message); , il prend en compte les identifiants du cours, de l'utilisateur (j'ai ajouté tp_rep_id pour qu'il prenne en compte l'identifiant et le contenu de la réponse) et du contenu de la réponse
 
	document.getElementById("image" + tp_rep_id).innerHTML = "<img src=progressbar.gif align=left title='En attente du serveur' width=24 />";
}
</script>

Voici le code du <textarea> sur l'évènement onChange (il faudra faire en sorte que s'il y a la réponse de l'utilisateur dans la base de données, elle s'affiche dans le <textarea>) :
Code php : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
// Affichage des questions (avec le compteur) du chapitre, s'il y en a
if ($row['contenu_question']) {
	$compteur_question++;
	echo '<div class="exercice"><ul><li>'.$row['contenu_question'].'</li></ul><a name="question'.$compteur_question.'"></a>
        <div class="reponse_cours_tp">Votre réponse <b>n°'.$compteur_question.'</b>
        <div style="position:relative; top:1.5em;left:0em;float:left;" id="image'.$compteur_question.'"></div>:<br /><textarea onkeyup="dynamicHeight(this);" rows="1" style="height: 40px;" cols="80" name="reponse'.$compteur_question.'" onChange="go('.$compteur_question.', this.value);"></textarea>
</div></div>';
}

Avec ce code (les deux fonctions javascript), uniquement l'icône "En attente du serveur" s'affiche quelque soit la réponse saisie. Il utilise le bon identifiant de l'utilisateur. Comme vous pouvez le voir dans les codes, j'ai mis des commentaires.

A mon avis, il faut changer le contenu de la variable "message" puisqu'il faut transmettre les différentes variables (identifiant de la bonne question, identifiant de l'utilisateur connecté et le contenu de la réponse saisie encodé pour gérer les caractères spéciaux) vers le fichier du traitement PHP. Justement, ce fichier doit récupérer l'identifiant de la question, l'identifiant de l'utilisateur, le contenu de la réponse saisie encodée de la zone de texte <textarea> active.

Dans ce fichier, j'ai fait un test pour vérifier l'existence d'une réponse : s'il y en n'a pas, il faut faire la requête SQL d'insertion (INSERT INTO) sinon il ne faut pas en insérer une mais la modifier (UPDATE). Pour ce faire, j'ai mis le code suivant mais lors des essais il n'effectue pas les requêtes SQL (affichage d'une seule icône : "En attente du serveur"). Quand je teste les requêtes SQL dans PHPMyAdmin, elles fonctionnent.

De plus, quand j'accède au fichier en passant par l'adresse URL, ce message s'affiche : "Vous n'avez pas le droit !!!".
La transmission des variables entre la page qui permet d'afficher un cours et le traitement PHP qui permet la requête SQL (soit INSERT INTO soit UPDATE) ne s'effectue pas d'où pourquoi l'icône "En attente du serveur" s'affiche quelque soit la réponse saisie.


Voici le code de traitement 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
39
40
41
42
43
44
45
46
<?php
include('config_bdd.php');
// On ouvre la session pour la transmission des variables
session_start(); // Démarre une nouvelle session ou reprend une session existante
 
// Récupération des variables
//$id_cours_tp = (isset($_POST["id_cours_tp"])) ? $_POST["id_cours_tp"] : NULL; // Ce n'est même pas la peine de transférer l'identifiant du cours puisqu'une question est dans un seul cours !
$id_utilisateur = (isset($_POST["id_utilisateur"])) ? $_POST["id_utilisateur"] : NULL;
$id_question = (isset($_POST["id_question"])) ? $_POST["id_question"] : NULL;
$contenu_reponse = (isset($_POST["contenu_reponse"])) ? $_POST["contenu_reponse"] : NULL; // A voir, il faut récupérer ce que l'utilisateur a écrit comme réponse
// Sélection des réponses pour insérer ou modifier les données dans la base de données
$selection_reponse=mysql_query("
SELECT texte_reponse
FROM reponses
WHERE id_question='".$id_question."'")
or die('Erreur lors de la sélection des réponses d\'un Cours/TP'.mysql_error()); // Envoie une requête à un serveur MySQL
 
// On teste si les valeurs existent - à voir pour $contenu_reponse
if (isset($id_utilisateur)&&(isset($id_question))) {// && $contenu_reponse
	// S'il n'y a aucune réponse dans la base de données, il faut l'insérer
	if(mysql_num_rows($selection_reponse)==0) {
		// Insertion dans la base de données des réponses de l'utilisateur
		$insertion_reponses = "
                INSERT INTO reponses (auteur_reponse,id_question,texte_reponse,date_maj_reponse)
                SELECT auteur_reponse,'$id_question','$contenu_reponse',now()
                FROM reponses, test_site_utilisateur
                WHERE test_site_utilisateur.pseudo_utilisateur=reponses.auteur_reponse";
		$query_insertion_reponses = mysql_query($insertion_reponses)
                or die('Erreur sur la requête SQL qui insère les réponses de l\'utilisateur aux questions.'.mysql_error());
	}
	else
		// S'il y a déjà une réponse dans la base de données, il faut la modifier
		$modification_reponses = "
                UPDATE reponses
                SET auteur_reponse=
                (SELECT pseudo_utilisateur
                FROM test_site_utilisateur
                WHERE pseudo_utilisateur=auteur_reponse),id_question='$id_question',texte_reponse='$contenu_reponse',date_maj_reponse=now()";
		$query_modification_reponses = mysql_query($modification_reponses)
                or die('Erreur sur la requête SQL qui modifie les réponses de l\'utilisateur aux questions.'.mysql_error());
}
else {
	// Message si les variables sont vides, nulles
	echo "Vous n'avez pas le droit !!!";
}
?>

Comment faire pour que quand on poste une réponse, la requête SQL s'exécute (avec le bon identifiant de la question et le contenu de la réponse saisie) puis affiche la bonne icône (c'est-à-dire
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
if (reponse=="0") document.getElementById("image" + tp_rep_id).innerHTML = "<img src=tp_en_attente.png align=left title='En attente de validation' />";
 
if (reponse=="1") document.getElementById("image" + tp_rep_id).innerHTML = "<img src=en_travaux.png align=left title='Réponse incomplète' />";
 
if (reponse=="4") document.getElementById("image" + tp_rep_id).innerHTML = "<img src=tp_validee.png align=left title='Réponse OK' />";
) et si on accède au traitement PHP sans poster de réponse, un message d'erreur s'affiche au lieu de faire la requête SQL ?

Comme je l'ai mis en commentaire dans les codes, je ne pense pas qu'il est nécessaire de transmettre l'identifiant du cours puisqu'une question ne peut pas être dans plusieurs cours mais dans un seul.

Je viens vers vous après avoir essayé.

Cordialement

Note du mercredi 9 avril 2013 : Dans la fonction go, j'ai modifié le contenu de la variable message donc cette ligne : message = "id_cours_tp=" + id_cours_tp + "id_utilisateur=" + id_utilisateur + "tp_rep_id=" + tp_rep_id + encodeURIComponent(reponse);
-En faisant un alert(reponse);, il prend en compte la réponse saisie.
-En faisant un alert(message);, il prend en compte les identifiants du cours, de l'utilisateur (j'ai ajouté tp_rep_id pour qu'il prenne en compte l'identifiant et le contenu de la réponse) et du contenu de la réponse.
-En faisant alert(message);, dans la boite de dialogue il affiche les identifiants de l'utilisateur, du cours et de la réponse.
En ce qui concerne celui de la réponse, il renvoie son identifiant mais par rapport à la page et non à celui de la base de données : il faudra donc trouver un moyen pour qu'il sélectionne et envoie le bon identifiant dans la base de données.