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

JavaScript Discussion :

[AJAX] autocomplétion avec Ajax


Sujet :

JavaScript

  1. #1
    Expert éminent

    Avatar de mlny84
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    4 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 4 023
    Points : 8 107
    Points
    8 107
    Par défaut [AJAX] autocomplétion avec Ajax
    Bonjour,

    J'effectue un module de recherche avancée pour mon site.
    Je gère 3 types de documents : notices, brèves et illustrations.
    L'interface "d'accueil" est donnée sur l'image1 donnée en PJ.
    L'utilisateur peut ajouter les critères qu'il souhaite par le menu déroulant.

    Je gère les champs ajoutés selon 2 méthodes : une avec une liste directe des champs obtenu (méthode addSelection), et une autre avec l'autocomplétion (méthode addAutocompletion).

    Je voudrais gérer la recherche par commune par l'autocomplétion.
    Mon problème : ma méthode fonctionne pour les notices, mais pas pour les brèves ou les illustrations (j'expose ici surtout le problème avec les brèves).
    Cf image2 et image2bis.

    J'ai installé Firedebug, et on voit bien que dans le cas des brèves, la requête Ajax est vide.

    J'ai essayé de tester la recherche par commune avec mon autre méthode : addSelection (Cf image3) et là pas de problèmes, ça marche avec les notices, les brèves et les illustrations. C'est pourquoi je pense que le problème vient d'Ajax.

    Je ne comprends pas pourquoi mon autocomplétion ne fonctionne pas avec mes brèves. Quelqu'un a une idée ?

    Mon code Javascript (version simplifiée):
    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
    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
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
     
    //J'attends que la page soit chargée
    var n=0;
    Event.observe(window,'load', initEventListener);
     
    // initialisation : on surveille les clic de l'utilisateur
    function initEventListener() {
    	Event.observe('add_button', 'click', addField);
    	Event.observe('valid', 'click', validForm);
    }
     
    //J'ai simplifié ma fonction, mais je n'ai pas que les communes dans ma liste.
    function addField() {
    	var champ = $F("add_field");
     
            if (champ == 'fcommune') { //Champ commun : selon les cases cochées, on rajoute les choix (c'est là que si je fais AddSelection aulieu de addAutocompletion, ça marche...
    		box = document.getElementById('notices');
    		if(box.checked){
    			addAutocompletion('fcommune', "Commune (notices)");
    		}
    		box = document.getElementById('breves');
    		if(box.checked){
    			addAutocompletion('fbrcommune', "Commune (brèves)");
    		}
    		box = document.getElementById('illus');
    		if(box.checked){
    			addAutocompletion('ficommune', "Commune (illustrations)");
    		}
    	}
     
     
     
    // ajout d'un champ d'autocomplétion : d'abord je rajoute mes champs pour le "graphique" ensuite je fais ma requête Ajax
    function addAutocompletion (champ, intitule) {
    	tbody = $('ajout');
    	tr = Builder.node('tr', {id: n+'_tr'}, [
    			addBoolean(champ),
    			Builder.node('td',[intitule]),
    			Builder.node('td',[
    				Builder.node('input', {id: n+'_'+champ+'-choice', name: n+'_'+champ+'-choice', type: 'text', value: '', size: '50'}),
    				Builder.node('div', {id:'suggestion', className: 'autocompletion recherche_champ', style:'display:none'})
    			]),
    			Builder.node('td',[
    				Builder.node('select', {
    					className: 'choix',
    					name: n + '_' + champ + '-chosen', 
    					id:n + '_' + champ + '-chosen', 
    					style: 'width: 100%; max-width: 100%;',
    					size: 5,
    					multiple: 'true',
    					className: 'recherche_liste',
    					onclick: 'delOption('+n+',\''+champ+'\',0)'
    				})
    			]),
    			Builder.node('td', [
    				Builder.node('input', {className: 'bouton', type: 'button', value: '-', onclick: 'removeElement('+n+')'})
    			])
    		]);
    	tbody.appendChild(tr);
    	var params = 'field='+champ+'&id='+n+'_'+champ+"-choice";
    	autocompletion = new Ajax.Autocompleter(n+'_'+champ+'-choice',
    						'suggestion',
    						'autocompletion',
    						{updateElement: updateList,
    						parameters: params});	
    }
     
     
     
    // mise à jour de la liste li
    function updateList(li) {
    	var id = li.up('div').previous().id;
    	Field.clear(id);
    	var select = $(id.replace("-choice", "-chosen"));
    	var text = li.down("span.value").innerHTML;
    	addOption(select,text);
    }
     
     
    // Ajout d'une option
    function addOption(select, text) {
    	var suivant = null;
    	var optionExist = false;
    	for(var i=0; i<select.options.length; i++) {
    		if(select.options[i].value == text) {
    			optionExist = true;
    			break;
    		} else if(select.options[i].value.toLowerCase() > text.toLowerCase()) {
    			suivant = select.options[i];
    			break;
    		}
    	}
    	if(!optionExist) {
    		option = Builder.node('option', {value: text, selected: 'selected'},[text]);
    		if(suivant !== null) {
    			select.insertBefore(option,suivant);
    		} else {
    			select.appendChild(option);
    		}
    	}
    }
     
     
    //Pour info, ma méthode addSelection : 
    // ajout une liste à sélection
    function addSelection (champ, intitule) {
    	tbody = $('ajout');
    	tr = Builder.node('tr', {id: n+'_tr'}, [
    			addBoolean(champ),
    			Builder.node('td',[intitule]),
    			Builder.node('td', [
    				Builder.node('select', {
    					name: n + '_' + champ + '-choice', 
    					id:n + '_' + champ + '-choice', 
    					style: 'width: 100%; max-width: 100%;',
    					size: 5,
    					multiple: 'true',
    					onclick: 'swap('+n+',\''+champ+'\',0)'
    				})
    			]),
    			Builder.node('td', [
    				Builder.node('select', {
    					name: n + '_' + champ + '-chosen', 
    					id:n + '_' + champ + '-chosen', 
    					style: 'width: 100%; max-width: 100%;',
    					size: 5,
    					multiple: 'true',
    					className: 'recherche_liste',
    					onclick: 'swap('+n+',\''+champ+'\',1)'
    				})				
    			]),
    			Builder.node('td', [
    				Builder.node('input', {className: 'bouton', type: 'button', value: '-', onclick: 'removeElement('+n+')'})
    			])
    		]);
      	tbody.appendChild(tr);
      	var num = n; /* afin d'éviter le décalage entre la variable global n et le temps de réponse d'ajax */
     
    	ajax = new Ajax.Request('listTerms.ajax', 
    		{
    			method: 'post',
    			parameters: $H({'field': champ}).toQueryString(),
    			onSuccess: function(request) {
    				options = request.responseText.substring(request.responseText.indexOf("<select>")+8,request.responseText.indexOf("</select>")-1);
    				$(num + '_' + champ + '-choice').update(options);
     
    			},
    		}
    	);
     
    }
    S'il vous faut d'autres renseignements, n'hésitez pas .
    Merci d'avance à ceux qui réfléchiront à mon problème.
    Fichiers attachés Fichiers attachés

  2. #2
    Expert éminent

    Avatar de mlny84
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    4 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 4 023
    Points : 8 107
    Points
    8 107
    Par défaut
    Petit up car je suis toujours bloquée sur ce problème, et je suis toujours à court d'idée...
    La moindre piste ou petite idée pourrait m'aider, svp, n'hésitez pas à intervenir !

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 130
    Points : 127
    Points
    127
    Par défaut
    Salut, question qui a l'air idiote mais ne l'est p-e pas tant que ça :
    es-tu sure de ton code serveur et/ou des paramètres que tu lui envoies ?

    Si tu n'as aucune réponse dans un cas mais des réponses dans d'autres, le problème vient p-e de là.

    Bonne chance.

  4. #4
    Expert éminent

    Avatar de mlny84
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    4 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 4 023
    Points : 8 107
    Points
    8 107
    Par défaut
    Merci pour ta réponse !
    Et non ce n'est pas une question idiote, mais j'y avais déjà réfléchi

    Concernant les paramètres que j'envoie (dans le cas présent des communes), les différentes valeurs de 'champ' sont :
    - fcommune si c'est une notice
    - ficommune si c'est une illustration
    - fbrcommune si c'est une brève

    Si j'utilise ma méthode addSelection : la requête Ajax trouve des résultats pour fcommune, ficommune et fbrcommune.
    Ma requête en post pour les notices (merci Firebug) :
    ça marche

    Ma requête en post pour les brèves :
    ça marche (Montbazin, Nancy comme résultat)

    Si j'utilise ma méthode addAutocomplétion : la requête Ajax trouve des résultats pour fcommune uniquement.
    Ma requête en post si je tape 'A' pour les notices :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    0_fcommune-choice=A&field=fcommune&id=0_fcommune-choice&_=
    ça marche

    Ma requête en post si je tape 'M' pour les brèves :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    0_fbrcommune-choice=M&field=fbrcommune&id=0_fbrcommune-choice&_=
    les résultats ne sont pas trouvés, alors que j'ai une commune 'Montbazin' pour les brèves.

    Ce qui me surprend le plus, c'est que les paramètres ne changent pas entre les 2 méthodes, et que ça ne marche qu'avec addSelection.
    De plus, addAutocomplétion n'est pas forcément fausse, puisqu'elle marche bien avec les brèves...

    Bref, je suis perdue...

    EDIT : Pour info, mes fichiers autocompletion.xsl (utilisé dans addAutocomplétion)

    Code XML : 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
    <?xml version="1.0" encoding="UTF-8"?><!-- 
        Description :
            Transformation XSL pour l'autocomplétion
    -->
    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx"
    	xmlns:snd="http://sinedie.inist.fr/snd"
        xmlns:adfi="http://www.culture.gouv.fr/ns/dapa/1.0"
        exclude-result-prefixes="xsl sdx snd adfi">
     
        <xsl:template match="/">	
        	<ul>
        		<xsl:for-each select="/sdx:document/sdx:terms/sdx:term">
        			<li>
    			<span class="value"><xsl:value-of select="@value"/></span>
    			</li>
        		</xsl:for-each>
        	</ul>
    	</xsl:template>
     
    </xsl:stylesheet>

    Et mon fichier listTerms_ajax.xsl (utilisé dans addSelection)

    Code XML : 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
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- 
        Description :
            Transformation XSL pour la réponse de la requête AJAX pour obtenir les 
            enfants d'un terme dans un thésaurus
    -->
    <xsl:stylesheet version="1.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
      xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx" 
      exclude-result-prefixes="xsl sdx">  
    	<xsl:output method="text"/>	
        <xsl:template match="/">
        	<select>
    	    	<xsl:for-each select="sdx:document/sdx:terms/sdx:term">
        			<option>
        				<xsl:attribute name="value"><xsl:value-of select="@value"/></xsl:attribute>
        				<xsl:value-of select="@value"/>
    	    		</option>
        		</xsl:for-each>
        	</select>
    	</xsl:template>	
    </xsl:stylesheet>

    Qu'on ne me dise pas que le code est trop différent entre les 2 fichiers...

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 130
    Points : 127
    Points
    127
    Par défaut
    Vu que ton auto-complétion, fonctionne dans un cas et pas dans l'autre et que le symptôme principal est un retour de requête vide, je continue à croire que c'est un problème de code serveur.

    Je pense à un truc du genre faute de frappe dans un switch par exemple ou autre bêtise qu'on a toujours beaucoup de mal à localiser quand on a le nez dans le code.

    Ça m'est arrivé plus d'une fois, et un œil extérieur trouve toujours la solution assez vite p/r à celui qui "vit" dans son code depuis un moment.

    Je peux toujours essayer ta fonction d'auto-complétion de mon côté, mais je ne suis pas sur que ce soit utile vu qu'elle fonctionne bien dans certains cas chez toi.

    J'aurai du mal à t'aider plus pour le moment désolé

    Bonne chance.

  6. #6
    Expert éminent

    Avatar de mlny84
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    4 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 4 023
    Points : 8 107
    Points
    8 107
    Par défaut
    Merci encore pour ton aide.
    Mais je ne comprends pas ce que tu appelles "code serveur", peux-tu m'éclairer un peu plus là-dessus ?

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 130
    Points : 127
    Points
    127
    Par défaut
    Quand tu fais un traitement AJAX, tu appelles forcément une autre "page" qui te renvoie les infos demandées, depuis une base de données ou autre.

    Chez moi, ça a toujours été un script PHP qui me renvoyait des infos d'une base de donnée.

    C'est ça que j'appelle un "code serveur".

    Tu n'utilises pas de base de données pour stocker tes infos ni de langage serveur (PHP, ASP, JSP ou autre) pour interroger cette base ?

    Tu appelles directement des fichiers XML ?

  8. #8
    Expert éminent

    Avatar de mlny84
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    4 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 4 023
    Points : 8 107
    Points
    8 107
    Par défaut
    Oui, j'utilise une base de donnée pour stocker mes fichiers.
    Cette base est incluse dans le logiciel que j'utilise, SDX (une usine à gaz très peu connue que je suis malheureusement obligée d'utiliser).
    Si j'ai bien compris, les fichiers "code serveur" que j'utilise sont les fichiers XSL que j'ai fourni dans mon post précédent : ils vont chercher dans les bases de données les infos que je veux.

    EDIT : Tu pourra remarquer qu'il y a très peu de différence entre les 2 fichiers, pourtant, l'un marche avec les brèves et l'autre non... Si tu arrives à voir le problème...

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 130
    Points : 127
    Points
    127
    Par défaut
    Effectivement, ce sont bien ces fichiers qui sont ton "code serveur" dans le sens où je l'entendais.

    Et oui, je ne connais pas SDX :p
    Mais je compatis, je suis "obligé" de faire du WebDev au boulot, et ce n'est pas drôle tous les jours (jamais drôle en fait mais bref).

    Ces fichiers sont générés automatiquement ou c'est toi qui les écrit ?

    Remarque de profane donc: je vois deux différences en fait dans ces fichiers.

    1. listTerms_ajax.xsl comporte une mention
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:output method="text"/>
    que n'a pas l'autre fichier.

    2. il y a une légère différence dans le "foreach" dans deux fichiers:
    dans autocompletion.xsl =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:for-each select="/sdx:document/sdx:terms/sdx:term">
    dans listTerms_ajax.xsl =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:for-each select="sdx:document/sdx:terms/sdx:term">
    (il n'y a pas de "/" au début de l'attribut select)


    Si par miracle ça peut t'aider :p

    Bonne chance.

  10. #10
    Expert éminent

    Avatar de mlny84
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    4 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 4 023
    Points : 8 107
    Points
    8 107
    Par défaut
    Dur dur de travailler avec les outils imposés...

    Ces fichiers ne sont pas générés automatiquement. Je me suis grandement "inspiré" d'une version précédente du site que mon prédécesseur (parti bien loin maintenant) avait réalisé.

    Tout comme Ajax, je suis en apprentissage du XSL, mais merci pour les remarques, j'ai pu effectuer d'autres tests.

    Pour le '/' devant le chemin, je t'avoue que je n'y avais jamais vraiment prêté attention : ça marche avec et ça marche sans.
    Après quelques recherches sur le site, il semblerait que la différence entre ces 2 chemins soient une histoire de chemin relatif ou absolu.
    Comme dans mon cas, mon "sdx:document" est à la racine, et que je me place à la racine au début (<xsl:template match="/">), il n'y a pas de différences.

    Bref, avec ou sans / au début, mes résultats sont toujours les même.

    Pour le <xsl:output method="text"/>, il permet de définir le type de sortie qui sera produit. J'ai essayé avec et sans cette ligne dans mes 2 fichiers, cela ne change rien, même résultats.

    J'ai pourtant redémarrer Tomcat et vidé le cache du navigateur pour être sûre que les modifications étaient bien prises en compte, mais rien n'y fait, ma requête Ajax est toujours vide pour les brèves...

    __________________________________________________________________________________________________________________




    Bon, après d'autres tests et trifouillage dans mes fichiers, je me suis souvenue que mon fichier XSL fonctionnait toujours avec un fichier XSP et que je n'avais jamais fait attention à son contenu...

    Mon fichier autocompletion.xsp :

    Code XML : 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
     
    <?xml version="1.0"?>
    <!-- 
        Description :
            Page XSP retournant les possibilités d'autocomplétion
    -->
    <xsp:page xmlns:xsp="http://apache.org/xsp" 
    	xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx"
        xmlns:snd="http://sinedie.inist.fr/snd">
    	<sdx:page show="user get post headers">
            <sdx:logout/>
           	<xsp:logic>
    	       	request.setCharacterEncoding("iso-8859-1");
            	String id = request.getParameter("id");
            	String start = request.getParameter(id);
                String reqMin = start.substring(0,1).toLowerCase() + start.substring(1) + "*";  
                String reqMaj = start.substring(0,1).toUpperCase() + start.substring(1) + "*";            
           	</xsp:logic>
            <sdx:terms base="base_notices" hpp="20" fieldParam="field" valueString="reqMin"/>
            <sdx:terms base="base_notices" hpp="20" fieldParam="field" valueString="reqMaj"/>
    	</sdx:page>
    </xsp:page>

    Et nous voyons un magnifique "base_notices" : les termes ne sont cherchés que dans cette base, c'est pourquoi cela fonctionne avec les notices et pas avec les autres types de documents... Si je remplace par "base_illus" ou "base_breves" : alors ça marche pour les illustrations ou les brèves...

    Je suis un boulet...

    J'ai plus qu'à revoir un peu ce code pour prendre mes 3 bases en considérations, mais j'ai fini par voir d'où venait le problème !!!

    Merci à toi jojosbiz pour ton aide, comme tu l'as dit :
    un œil extérieur trouve toujours la solution assez vite p/r à celui qui "vit" dans son code depuis un moment.

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 130
    Points : 127
    Points
    127
    Par défaut
    Heureux d'avoir pu t'aider, même un petit peu

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

Discussions similaires

  1. [AJAX] Autocomplétion avec ajax et C#
    Par Kira77 dans le forum AJAX
    Réponses: 5
    Dernier message: 06/12/2012, 11h11
  2. [AJAX] autocomplétion avec ajax et php
    Par timmy1 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 07/06/2007, 16h28
  3. [AJAX] PHP avec ajax(makerequest)
    Par Benjiijneb dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 11/04/2006, 16h53
  4. [AJAX] Modifier avec AJAX une image générée avec GD
    Par thsantac dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 27/03/2006, 19h34
  5. [AJAX] Autocomplétion + méthode Ajax
    Par seblo_scoqi dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 26/10/2005, 16h24

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