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

AJAX Discussion :

[AJAX] Quelques incompréhensions sur l'envoi de formulaire


Sujet :

AJAX

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 43
    Points : 17
    Points
    17
    Par défaut [AJAX] Quelques incompréhensions sur l'envoi de formulaire
    Bonjour

    En pleine phase de test du concept Ajax, j'essaye comprendre les différentes notions tant bien que mal. Pour cobaye, j'ai pris un formulaire d'envoi de messages instantanés. A l'heure actuelle, le formulaire est basique et recharge l'intégralité de la page web, ce qui peut s'avérer contraignant lorsque des utilisateurs néophytes redondent leur envoi de messages (à cause du cache du navigateur, ils rafraichissent la page et clique sur OK réenvoyant leur message).
    Bref je pense qu'Ajax peut m'aider à éradiquer ce soucis.

    Or donc voici mon code et mes incompréhensions :
    Code Fonction AJAX : 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
     
    var xhr;
    if (window.XMLHttpRequest) { 
      xhr = new XMLHttpRequest(); 
    } else if (window.ActiveXObject) {
      xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }
     
    //AJAX - Shoutbox envoie message
    function AjShoutbox(message) {
    xhr.open('POST',"index.php",true);
    xhr.onreadystatechange = function() {
       if (xhr.readyState == 4 && xhr.status==200) {
         alert('OK'); //Test de résultat OK
       } else {                           
         document.getElementById('msg').innerHTML=message+':NOK'; //Test de résultat NON OK
       }
    } 
    xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
    xhr.send('message='+message);    
    }

    Code Page 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
     
    if (isset($_POST["message"]) && !empty($_POST["message"]) && strstr($_POST["message"], 'Ecrire un message ici...') != true) {
      $updateMessage = "INSERT shoutbox SET s_date = UNIX_TIMESTAMP(now()), s_message ='".$_POST["message"]."', s_mid ='".$info["id"]."' ";
      $resultMessage = mysql_query($updateMessage) or die(mysql_error());	
    }	
     
    echo '<form method="POST" onsubmit="AjShoutbox(this.message.value); return false" action="">';
          echo '<tr>';
    	    echo '<td id="sh_btn"><input type="text" name="message" size="25" maxlength="500" value="Ecrire un message ici..." onFocus="if (this.value==\'Ecrire un message ici...\') {this.value=\'\'}">&nbsp;<input type="submit" value="Envoyer"/></td>';
          echo '</tr>';
          echo '<tr>';
    	    echo '<td id="msg"></td>';
          echo '</tr>';
          echo '<tr>';  
    echo '</form>';

    Alors de mes incompréhensions :
    - Lorsque je clique sur le bouton submit "Envoyer" les deux tests de résultats s'affichent (boite d'alerte -> OK et le td avec id "msg -> message + NOK), avec la condition "if" je ne vois pas pourquoi il m'affiche les deux conditions.
    - Le message est bien envoyé mais je suis obligé de recharger la page intégralement pour afficher le message, est ce à cause du fait que je traite le post directement dans la page index.php ?

    Merci d'avance et bonne journée.

  2. #2
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Salut,
    Citation Envoyé par Beniti Voir le message
    - Lorsque je clique sur le bouton submit "Envoyer" les deux tests de résultats s'affichent (boite d'alerte -> OK et le td avec id "msg -> message + NOK), avec la condition "if" je ne vois pas pourquoi il m'affiche les deux conditions.
    C'est normal, ta fonction est appelée à chaque changement du readyState (d'où son nom ) donc tant qu'il ne vaut pas 4, tu passes dans l'autre condition.
    - Le message est bien envoyé mais je suis obligé de recharger la page intégralement pour afficher le message, est ce à cause du fait que je traite le post directement dans la page index.php ?
    Non, c'est parce qu'à part un alert, tu ne fais rien au retour de ta requête
    Si tu ne demandes pas d'afficher le résultat, JavaScript ne va pas le faire de lui-même.

    De plus, tu sembles récupérer une page complète, ce qui est une erreur !

    Je te conseilles de lire quelques tutos sur Ajax afin de savoir comment ça fonctionne :
    http://gael-donat.developpez.com/web/intro-ajax/
    http://dmouronval.developpez.com/tut...-requete-ajax/
    http://ajax.developpez.com/cours/

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 43
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par Bovino Voir le message
    Salut,

    C'est normal, ta fonction est appelée à chaque changement du readyState (d'où son nom ) donc tant qu'il ne vaut pas 4, tu passes dans l'autre condition.
    Effectivement, donc ces tests de résultats ne servent à rien dans le cas présent.

    Non, c'est parce qu'à part un alert, tu ne fais rien au retour de ta requête
    Si tu ne demandes pas d'afficher le résultat, JavaScript ne va pas le faire de lui-même.
    Et oui ! En continuant les tests je suis arrivé à ceci :
    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
     
    function AjShoutbox(message,idmember) {
            var xhr;
            if (window.XMLHttpRequest) {  
              xhr = new XMLHttpRequest(); 
            } else if (window.ActiveXObject) { 
              xhr = new ActiveXObject("Microsoft.XMLHTTP"); 
            }
     
            xhr.open('POST',"ajaxrequest.php",true);
     
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4 && xhr.status==200) {       
    	          window.location.reload();
                }
            }
     
            xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
            xhr.send('message='+message+'&idmember='+idmember);    
    }
    Ça fonctionne mais j'ai l'impression qu'il s'agit plus d'un bidouillage qu'autre chose. Le window.location.reload() me permet de recharger et afficher le nouveau message et d'empêcher le cache du navigateur de garder les entrées, mais j'ai l'impression de revenir au point de départ -> recharger toute la page. Encore que, j'ai un doute sur le fait qu'il recharge toute la page :
    Lorsque je mets "Hello world" dans le input text et que je clique sur le bouton submit, un chargement s'effectue, le "hello world" s'affiche comme il faut, mais il reste également dans le input text (alors que normalement une fois la page entière rechargée, le input text reprend sa valeur par défaut).

    De plus, tu sembles récupérer une page complète, ce qui est une erreur !
    Effectivement, j'ai fait le nécessaire et mis le traitement du post dans un fichier php propre à lui même

    Je te conseilles de lire quelques tutos sur Ajax afin de savoir comment ça fonctionne :
    http://gael-donat.developpez.com/web/intro-ajax/
    http://dmouronval.developpez.com/tut...-requete-ajax/
    http://ajax.developpez.com/cours/
    Lu et relu mais pas toujours tout compru Plus sérieusement, la compréhension de ces textes évoluent durant les centaines de tests fait au jour le jour, je viens encore d'en apprendre.

    Merci de m'avoir répondu

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 43
    Points : 17
    Points
    17
    Par défaut
    Hello,

    Après plusieurs essais je suis pratiquement arrivé à faire ce que je voulais, cependant il me reste 2 choses gênantes à régler.

    Pour récapituler :
    J'utilise ce formulaire pour une messagerie instantanée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    <form method="POST" onsubmit="AjShoutbox(this.message.value,this.idmember.value,this.name.value,this.time.value); return false" action="">
    <input type="hidden" value="'.$info["id"].'" name="idmember">
    <input type="hidden" value="'.$info["members_display_name"].'" name="name">
    <input type="hidden" value="'.strftime('le %d/%m à %H:%M', time()).'" name="time">
    <input type="text" name="message" size="25" maxlength="500" value="Ecrire un message ici..." onFocus="if (this.value==\'Ecrire un message ici...\') {this.value=\'\'}">
    <input type="submit" value="Envoyer"/> 
    </form>
    Ce formulaire appelle la fonction AjShoutbox() lors du submit, la fonction AjShoutbox() :
    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
    //AJAX - Instance d'objet HTTPRequest
    function createXHR() {
    	var xhr;
    	if(window.XMLHttpRequest) xhr = new XMLHttpRequest();
    	else if(window.ActiveXObject) {
    		try {
    			xhr = new ActiveXObject("Msxml2.XMLHTTP");
          	} catch(e) {
              	xhr = new ActiveXObject("Microsoft.XMLHTTP");
    		}
    	} else xhr = false;
    	return xhr;
    }
     
    //AJAX - Fonction envoie de message Shoutbox
    function AjShoutbox(message,idmember,name,time) {
            xhr = createXHR();
     
            xhr.open('POST',"ajaxrequest.php",true);
     
    		xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
            xhr.send('message='+message+'&idmember='+idmember);	
     
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4 && xhr.status == 200) {              
    			  if(message == "" || message == "Ecrire un message ici...") {
                    alert("Si tu vois ce message, "+name+", il s'agit sans nul doute d'une mauvaise utilisation de la shoutbox. Réessaie d'écrire un message.");
                  } else {		
    			    var myRowText;
    			    if (window.XMLHttpRequest) {
                      var myRowText = document.getElementById('shTable').insertRow(0);
                    } else if (window.ActiveXObject) {				
                      var myRowText = document.all.shTable.insertRow(0);
    			    }
                    var myCellText = myRowText.insertCell(0);
    			    myCellText.className = 'shout_row1';
                    myCellText.innerHTML = message;			  
     
    			    var myRowTitle;
    			    if (window.XMLHttpRequest) {
                      var myRowTitle = document.getElementById('shTable').insertRow(0);
                    } else if (window.ActiveXObject) {				
                      var myRowTitle = document.all.shTable.insertRow(0);
    			    }
                    var myCellTitle = myRowTitle.insertCell(0);
    			    myCellTitle.className = 'shout_row1 shouttitle';			  
    			    myCellTitle.innerHTML = '<a href="/forum/index.php?showuser='+idmember+'">'+name+'</a> '+time;				
                  }				
                }           			
            }					
    }
    Tout ceci fonctionne très bien, sauf qu'il y a deux points que je n'arrive pas à résoudre.
    - Le premier point, lorsque je clique sur le bouton submit j'aimerais que le input text reprenne sa valeur par défaut ou devienne vide. Or, à l'heure actuelle, lorsque j'envoie un message, il s'affiche bien au onreadystatechange mais ce même message reste dans l'encadré du input texte.
    - Le deuxième point concerne l'encodage des caractères spéciaux. Je ne comprend pas pourquoi depuis que j'utilise cette fonction les caractères de type "é à ù ï î, etc..." se transforment en caractères exotiques incompréhensibles.

    Auriez vous une piste ?

    Cordialement.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 43
    Points : 17
    Points
    17
    Par défaut
    MAJ :
    Citation Envoyé par Beniti Voir le message
    - Le deuxième point concerne l'encodage des caractères spéciaux. Je ne comprend pas pourquoi depuis que j'utilise cette fonction les caractères de type "é à ù ï î, etc..." se transforment en caractères exotiques incompréhensibles.
    Trouvé : le script xhr.send renvoie le message encodé en UTF8 à cause du xhr.setRequestHeader qui applique un encode utf8 (application/x-www-form-urlencoded). Donc il faut recoder le message en ISO-8859-1 avant que la requête php ne l'envoie dans la base de données, grâce à utf8_decode($string) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $updateMessage = "INSERT shoutbox SET s_message ='".utf8_decode($_POST["message"])."', s_mid ='".$_POST["idmember"]."' ";

  6. #6
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    - Le premier point, lorsque je clique sur le bouton submit j'aimerais que le input text reprenne sa valeur par défaut ou devienne vide. Or, à l'heure actuelle, lorsque j'envoie un message, il s'affiche bien au onreadystatechange mais ce même message reste dans l'encadré du input texte.
    Pour ça, tu peux utiliser la propriété defaultValue de ton input :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (xhr.readyState == 4 && xhr.status == 200) {              
        if(message == "" || message == "Ecrire un message ici...") {
            alert("Si tu vois ce message, "+name+", il s'agit sans nul doute d'une mauvaise utilisation de la shoutbox. Réessaie d'écrire un message.");
        } else {
            document.forms[0].elements['message'].value = document.forms[0].elements['message'].defaultValue;
    ...

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 43
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par Bovino Voir le message
    Pour ça, tu peux utiliser la propriété defaultValue de ton input :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    document.forms[0].elements['message'].value = document.forms[0].elements['message'].defaultValue;
    ...
    Salut,

    Merci pour la réponse
    J'ai testé cette ligne mais ça n'a pas l'air de fonctionner.
    Par manque de nouvelles idées, j'ai décidé de changer le "input text" par un textarea et utilisé cette instruction : document.getElementById('styled').innerHTML = ''; (en mettant id="styled" dans le tag textarea). Alors une fois n'est pas coutume, cela fonctionne sur ie uniquement et pas sur firefox, safari, chrome et opéra


  8. #8
    Membre expérimenté Avatar de DoubleU
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 106
    Points : 1 388
    Points
    1 388
    Par défaut
    Pour l'input text, tu peux vider sa propriété .value pour enlever le texte.

  9. #9
    Rédacteur/Modérateur
    Avatar de andry.aime
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    8 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations forums :
    Inscription : Septembre 2007
    Messages : 8 391
    Points : 15 059
    Points
    15 059
    Par défaut
    Bonjour,
    document.getElementById('styled').innerHTML = ''; (en mettant id="styled" dans le tag textarea). Alors une fois n'est pas coutume, cela fonctionne sur ie uniquement et pas sur firefox, safari, chrome et opéra
    Ce problème était déjà posé sur le forum javascript.
    Pour le textarea, utilise les attributs innerHTML et value à la fois.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    document.getElementById('styled').innerHTML = '';
    document.getElementById('styled').value = '';

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 43
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par andry.aime Voir le message
    Bonjour,

    Ce problème était déjà posé sur le forum javascript.
    Pour le textarea, utilise les attributs innerHTML et value à la fois.
    Yes ! Parfait merci bien

    Je pense que mon affaire se présente très bien, les finitions n'étant plus que cosmétiques.
    Merci à tous en tout cas

    Cordialement,

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 43
    Points : 17
    Points
    17
    Par défaut
    Salut,

    Juste pour finir avec ce code, et pour ceux qui débute dans Ajax, il faut savoir que l'instruction xhr.send() avec l'option "POST" (indiqué dans le xhr.open) encode mal les caractères "&", "+" ou encore "?" parce que par défaut ce sont des caractères utilisés dans les adresses (se référer au "GET"). Il faut donc ajouter le paramètre encodeURIComponent(element) lorsque vous utilisez le XMLHttprequest en mode POST

    soit dans mon exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xhr.send('message='+encodeURIComponent(message)+'&idmember='+idmember);
    Voilà, si ça peut éviter des prises de têtes aux novices

    A+

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

Discussions similaires

  1. Action est tronqué sur l'envoi du formulaire
    Par philou029 dans le forum Langage
    Réponses: 2
    Dernier message: 26/08/2010, 22h53
  2. soucis sur l'envoi de formulaire
    Par ChronosXIII dans le forum XMLRAD
    Réponses: 3
    Dernier message: 11/03/2009, 11h41
  3. Controle de formulaire sur l'envoi
    Par navis84 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 18/08/2005, 17h23
  4. Réponses: 4
    Dernier message: 10/07/2005, 20h53

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