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 avec J2EE et Javascript XMLHttpRequest


Sujet :

AJAX

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2015
    Messages : 8
    Par défaut Ajax avec J2EE et Javascript XMLHttpRequest
    J'essaye de faire un système d'autocomplétion sur une input.

    J'ai déjà fait la fonction qui gère le surlignement des éléments, et je m'attaque à la partie Ajax.

    Voici ma servlet:

    Code java : 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
    package com.autocompl.servlets;
     
    import java.io.IOException;
     
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    /**
     * Servlet implementation class Base
     */
    @WebServlet("/Base")
    public class Base extends HttpServlet {
    	private static final long serialVersionUID = 1L;
     
        /**
         * @see HttpServlet#HttpServlet()
         */
        public Base() {
            super();
            // TODO Auto-generated constructor stub
        }
     
    	/**
             * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
             */
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    			System.out.println(request.getParameter("param1"));
    			response.setContentType("text/xml");
    			response.getWriter().write("<message>"+"<span>pilou</span><span>toto</span><span>mouais</span>"+"</message>");
     
    	}
     
    	/**
             * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
             */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// TODO Auto-generated method stub
    	}
     
    }
    Pour l'instant je cherche juste à réussir à communiqué en direct avec la page, sans chercher dans la base de donnée encore.



    Voici ma jsp avec le script (j'ai un problème qui fait qu eje n'arrive pas encore à l'externalisé, si des gens s'y connaissent en javaee, je veut bien de l'aide ici



    Code html : 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
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
    <%@ page pageEncoding="UTF-8" %>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    	<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/styles/style.css" />
    <title>AutoCompl</title>
    </head>
    <body>
    	<form method="post" action="">
            <input type="search" name="searchbar" id="searchbar" />
        </form>
        <div id="autoZone"></div>
     
     
     
     
    	<script>
                    (function() {
                            var input = document.getElementById("searchbar");
                            
                            input.addEventListener("keyup",function(e) {
                                            var xhr = new XMLHttpRequest();
                                            xhr.open('GET', 'base?param1='+e.currentTarget.value,true);
                                            xhr.send(null);
            
                                            
                                            
                                            xhr.addEventListener('readystatechange', function() {
                                                if (xhr.readyState === xhr.DONE) { 
                                                    var spans = xhr.responseXML.getElementsByTagName('span');
                                                    document.getElementById('autoZone').innerHTML="";
                                                    for(var i =0, l=spans.length; i<l; i++){
                                                            console.log(xhr.responseText);
                                                            spans[i].setAttribute("class", "propos");
                                                            document.getElementById('autoZone').appendChild(spans[i]); 
                                                            document.getElementById('autoZone').appendChild(document.createElement('br'));
                                                    }
                                                    addListen();            
                                                }
                                            }, false);
                                    
                                    })
                            
                    })();
            
            
    //gère le surlignement
                    function addListen() { // Utilisation d une IIFE pour éviter les variables globales.
                    
                    var propos = document.querySelectorAll('.propos');
                    console.log(propos);
                    propos[0].setAttribute('style',"color:white;background:blue;");
                    var current = propos[0];
                    var indCur=0;
                    var nbPro = propos.length;
                    for(i=0;i<nbPro;i++){
                            (function(i){
                            propos[i].addEventListener('mouseover',function(e){
                                    current.setAttribute('style', "");
                                    e.currentTarget.setAttribute('style',"color:white;background:blue;");
                                    current=e.currentTarget;
                                    indCur=i;
                            });
                            })(i);
                    };
                    
                    document.addEventListener('keyup',function(e){
                            var code= e.keyCode;
                            if(code==38){
                                    indCur--;
                                    if(indCur<0){
                                            indCur=nbPro-1;
                                    }
                                    current.setAttribute('style', "");
                                    propos[indCur].setAttribute('style',"color:white;background:blue;");
                                    current=propos[indCur];
                            }
                            if(code==40){
                                    indCur++;
                                    if(indCur>nbPro-1){
                                            indCur=0;
                                    }
                                    current.setAttribute('style', "");
                                    propos[indCur].setAttribute('style',"color:white;background:blue;");
                                    current=propos[indCur];
                            }
                            
                    });
                    
                    }
            </script>
     
     
    </body>
    </html>


    Le problème que j'ai c'est que la seconde balise span (<span>toto</span>) est considéré comme un undefined par le code derriere; donc il ne veut pas utilisé les fonctions spécifique aux Node. (alors qu'il l'a reconnais bien comme balise span comme il fait 3 tours de boucles)



    *Merci d'avance si vous avez des idées de solutions

  2. #2
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 198
    Par défaut
    Bonjour,
    considérons ton bout de code suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var spans = xhr.responseXML.getElementsByTagName('span');
    document.getElementById('autoZone').innerHTML = "";
    for (var i = 0, l = spans.length; i < l; i++) {
        console.log(xhr.responseText);
        spans[i].setAttribute("class", "propos");
        document.getElementById('autoZone').appendChild(spans[i]);
        document.getElementById('autoZone').appendChild(document.createElement('br'));
    }
    1. getElementsByTagName retourne une NodeList "live", elle se remet à jour si un changement dans le DOM se réalise
    2. spans.length effectue une lecture à chaque itération de ta boucle de la longueur de spans
    3. appendChild(spans[i]) déplace l'élément et donc par ce fait modifie le DOM


    Maintenant on voit qu'à chaque boucle spans.length diminue de 1, à cause du point 3 alors que dans le même temps tu incrémentes ton compteur, en gros tu ne vise plus l’élément que tu crois.
    quand i = 0  => tu as spans = [<span>#1</span>, <span>#2</span>, <span>#3</span>, <span>#4</span>]
    quand i = 1  => tu as spans = [<span>#2</span>, <span>#3</span>, <span>#4</span>
    quand i = 2  => tu as spans = [<span>#3</span>, <span>#4</span>]
    quand i = 3  => tu as spans = [<span>#4</span>]
    
    Il te faut prendre le problème différemment, je te propose cette solution sur base de ton code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var oSpans = xhr.responseXML.getElementsByTagName('SPAN'),
        oDest = document.getElementById('autoZone'),
        i, nb = oSpans.length;
    // parcours des datas
    while( oSpans[0]){
        oDest.appendChild( oSpans[0]);
        oDest.appendChild( document.createElement('BR'));
    }
    A noter que la méthode querySelectorAll() ne retourne pas une NodeList "live" et pourrait donc être utilisé avec ta boucle for.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var oSpans = xhr.responseXML.querySelectorAll('SPAN'),
        oDest = document.getElementById('autoZone'),
        i, nb = oSpans.length;
    // parcours des datas
    for( var i = 0; i<nb; i++){
        oDest.appendChild( oSpans[i]);
        oDest.appendChild( document.createElement('BR'));
    }
    enfin une autre solution consisterait à ajouter non pas l'élément mais son clone et ce en utilisant la méthode getElementsByTagName
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var oSpans = xhr.responseXML.getElementsByTagName('SPAN'),
        oDest = document.getElementById('autoZone'),
        i, nb = oSpans.length;
    // parcours des datas
    for( var i = 0; i<nb; i++){
        oDest.appendChild( oSpans[i].cloneNode(true));
        oDest.appendChild( document.createElement('BR'));
    }

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2015
    Messages : 8
    Par défaut
    Woh, merci beaucoup
    Je ne connaissais pas du tout ce concept de live, tout est clair pour ça du coup


    Un truc marche pas derrière, c'est plus trop le sujet du topic du coup, mais est ce que les node ainsi ajouter au DOM sont spéciaux? Car quand je atttribue un style autre que par un css, il ne s'applique pas, j'imagine que c'est une erreur toute bête ><

    ma méthode est assez mauvaise et passer par des classes selected ou non serais plus pratique, mais ça me dérange quand même le fait que ça fonctionne pas là. De plus elle fonctionnais avant que j'insere les spans via l'ajax (j'en mettais directement dans le html)
    Nom : stylezarb.PNG
Affichages : 594
Taille : 46,9 Ko

    Voilà à quoi ressemble mon script désormais, j'ai juste externalisé l'ajout des spans car sinon ça commençais avant que le serveur ai fini sa requête j'avais l'impression des fois:

    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
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    		get(change);
     
     
    		function get(callback) {
    			var input = document.getElementById("searchbar");
     
    			input.addEventListener("keyup",function(e) {
    					var xhr = new XMLHttpRequest();
     
    					xhr.addEventListener('readystatechange', function() {
    					    if (xhr.readyState === 4 && (xhr.status == 200 || xhr.status == 0)) { 
    					    	var spans = xhr.responseXML.getElementsByTagName('span');
    					    	document.getElementById('autoZone').innerHTML="";
    					    	callback(spans);
    					    	addListen();	    	
    					    }
    					}, false);
     
     
    					xhr.open('GET', 'base?param1='+e.currentTarget.value,true);
    					xhr.send(null);
     
     
     
     
    				})
     
    		}
     
    		function change(spans){
     
    		    var oDest = document.getElementById('autoZone'),
    		    i, nb = spans.length;
    		// parcours des datas
    			while( spans[0]){
    				 spans[0].setAttribute("class", "propos");
     
    				oDest.appendChild( spans[0]);
    				oDest.appendChild( document.createElement('BR'));
    			}
    		}
     
    		function addListen() { 		
    		var propos = document.querySelectorAll('.propos');
    		propos[0].setAttribute('style',"color:white;background:blue;");
    		var current = propos[0];
    		var indCur=0;
    		var nbPro = propos.length;
    		for(i=0;i<nbPro;i++){
    			(function(i){
    			propos[i].addEventListener('mouseover',function(e){
    				current.setAttribute('style', "");
    				e.currentTarget.setAttribute('style',"color:white;background:blue;");
    				current=e.currentTarget;
    				indCur=i;
    			});
    			})(i);
    		};
     
    		document.addEventListener('keyup',function(e){
    			var code= e.keyCode;
    			if(code==38){
    				indCur--;
    				if(indCur<0){
    					indCur=nbPro-1;
    				}
    				current.setAttribute('style', "");
    				propos[indCur].setAttribute('style',"color:white;background:blue;");
    				current=propos[indCur];
    			}
    			if(code==40){
    				indCur++;
    				if(indCur>nbPro-1){
    					indCur=0;
    				}
    				current.setAttribute('style', "");
    				propos[indCur].setAttribute('style',"color:white;background:blue;");
    				current=propos[indCur];
    			}
     
    		});
     
    		}

  4. #4
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 198
    Par défaut
    mais est ce que les node ainsi ajouter au DOM sont spéciaux?
    je n’irais pas jusqu'à dire spéciaux mais il ne sont effectivement pas pris en compte comme de "vrai" noeuds du DOM, ils proviennent d'une structure XML au départ.
    Si tu fais un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    alert(oDest.getElementsByTagName('span').length)
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    alert(oDest.getElementsByTagName('SPAN').length)
    le résultat ne sera pas le même !

    Je dirais que pour être plus conforme à la tradition je ferais plutôt une récupération/création comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for( var i = 0; i<nb; i++){
        oSpan = oDest.appendChild(document.createElement('SPAN'));
        oSpan.setAttribute("class", "propos");
        oSpan.appendChild(document.createTextNode( oSpans[i].firstChild.data));
    }
    et là tu auras des bons vieux noeuds DOM

    j'ai juste externalisé l'ajout des spans car sinon ça commençais avant que le serveur ai fini sa requête
    là j'en doute, et créer une fonction juste pour en créer une n'est pas forcément un bon choix.


    J'ai regardé un peu plus avant ton script e je dois admettre que la gestion mouseover/mouseout peut directement se faire en CSS, par exemple
    Code css : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #autoZone span{
      color:blue;
    }
    #autoZone span:hover{
      color:white;
      background:blue;
    }
    de plus il aurait été sémantiquement plus judicieux de créer une liste <ul><li>...</li></ul> par exemple.

    J'en profite pour te mettre le lien vers un tuto qui te correspond complétement Ajax - une autocomplétion pas à pas .

  5. #5
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2015
    Messages : 8
    Par défaut
    Eh bien merci beaucoup pour toutes tes réponses très complètes et j'ai tout compris
    Je vais suivre le tuto sur l'autocomplétion

    Bonne soirée!

    Je passe le sujet en résolu

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

Discussions similaires

  1. [AJAX] AJAX avec J2EE
    Par coolmomodu31 dans le forum AJAX
    Réponses: 1
    Dernier message: 31/12/2011, 06h19
  2. Formulaire avec champ dynamique javascript/ajax
    Par Louka-65 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 24/07/2009, 16h34
  3. Javascript + XMLHttpRequest + Lightbox avec IE
    Par Invité dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 28/03/2009, 13h54
  4. Erreur Javascript Ajax avec Map Suite
    Par Cartman.inc dans le forum C#
    Réponses: 0
    Dernier message: 13/01/2009, 18h07
  5. [AJAX] Acces aux données avec ajax dans une fonction javascript
    Par Sidi-Bou dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 03/03/2008, 12h04

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