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] Plusieurs autocomplétion sur la même page


Sujet :

JavaScript

  1. #1
    Membre éclairé Avatar de Death83
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 667
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 667
    Points : 878
    Points
    878
    Par défaut [AJAX] Plusieurs autocomplétion sur la même page
    Salut à tous,

    j'ai rajouter le système d'autocomplétion sur un de mes formulaire en m'inspirant du super tutoriel de Denis Cabasson (http://dcabasson.developpez.com/arti...ion-pas-a-pas/)

    Le problème c'est que je souhaite en mettre plusieur sur la même page, et je ne vois pas comment procéder (au mieux).

    Je pourrais le faire à la barbare en recopiant les fonction en changent le nom pour chaque nouveau champ autocompléter mais la c'est vraiment pas propre.

    Je veut donc utiliser les même fonction pour tous les champs.

    Mais je ne vois pas comment faire

    Si quelqu'un a une idée ou une piste, je suis preneur!!

    Merci d'avance.
    manganimes (en construction) -
    zemanga

  2. #2
    Membre éclairé Avatar de Death83
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 667
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 667
    Points : 878
    Points
    878
    Par défaut
    Bon j'ai éssayé de me débrouiller et de tout passer en objet, mais comme il fallait s'y attendre, ca ne marche pas . Pourtant je n'ai pas d'erreur javascript.

    Je vais vous montrer le code (désolé il est long) mais si jamais vous en avez le courage (ca pourra toujours vous servir plus tard ).

    Donc la parties HTML:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    <link rel="stylesheet" href="styles/temp.css" type="text/css"/>
    <script type="text/javascript" src="script.js"></script>
    <script type="text/javascript">
         window.onload=function()
         {
    	   autocomplete1 = new autocomplete('complete1');
     initAutoComplete.call(autocomplete1,document.getElementById('ajouteref'),document.getElementById('Genre'),document.getElementById('valideref'),'genre','../AJAX/cherche_genre.php');
           }
    </script>

    et la page script.js (qui merde):
    (apparement le problème est au niveau des "event", mais je sais pas trop comment les géré en objet, j'ai jamais fait ca auparavant en js.

    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
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
     
    function autocomplete(name)
    {
    	this.name=name;
    }
     
     
     
    // retourne un objet xmlHttpRequest.
    // méthode compatible entre tous les navigateurs (IE/Firefox/Opera)
    function getXMLHTTP(){
      var xhr=null;
      if(window.XMLHttpRequest) // Firefox et autres
      xhr = new XMLHttpRequest();
      else if(window.ActiveXObject){ // Internet Explorer
        try {
          xhr = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
          try {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
          } catch (e1) {
            xhr = null;
          }
        }
      }
      else { // XMLHttpRequest non supporté par le navigateur
        alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
      }
      return xhr;
    }
     
    var _documentForm=null; // le formulaire contenant notre champ texte
    var _inputField=null; // le champ texte lui-même
    var _submitButton=null; // le bouton submit de notre formulaire
    var _tag=null;
    var _page=null;
     
     
    function initAutoComplete(form,field,submit,tag,page)
    {
    	this._tag=tag;
    	this._page=page;
    	this._documentForm=form;
    	this._inputField=field;
    	this._submitButton=submit;
    	this._inputField.autocomplete="off";
    	creeAutocompletionDiv.call(this);
    	this._currentInputFieldValue=this._inputField.value;
    	this._oldInputFieldValue=this._currentInputFieldValue;
    	cacheResults.call(this,"",new Array())
    	document.onkeydown=onKeyDownHandler;
    	this._inputField.onkeyup=this.onKeyUpHandler;
    	this._inputField.onblur=this.onBlurHandler;
    	window.onresize=onResizeHandler;
    	// Premier déclenchement de la fonction dans 200 millisecondes
    	setTimeout("mainLoop()",200);
    }
     
     
    var _oldInputFieldValue=""; // valeur précédente du champ texte
    var _currentInputFieldValue=""; // valeur actuelle du champ texte
    var _resultCache=new Object(); // mécanisme de cache des requetes
     
    // tourne en permanence pour suggerer suite à un changement du champ texte
    function mainLoop(){
      if(_oldInputFieldValue!=_currentInputFieldValue){
        var valeur=escapeURI(_currentInputFieldValue);
        var suggestions=_resultCache[_currentInputFieldValue];
        if(suggestions){ // la réponse était encore dans le cache
          metsEnPlace(valeur,suggestions)
        }else{
          callSuggestions(valeur) // appel distant
        }
        _inputField.focus()
      }
      _oldInputFieldValue=_currentInputFieldValue;
      setTimeout("mainLoop()",200); // la fonction se redéclenchera dans 200 ms
      return true
    }
     
    // echappe les caractère spéciaux
    function escapeURI(La){
      if(encodeURIComponent) {
        return encodeURIComponent(La);
      }
      if(escape) {
        return escape(La)
      }
    }
     
    var _xmlHttp = null; //l'objet xmlHttpRequest utilisé pour contacter le serveur
    var _adresseRecherche = null; //l'adresse à interroger pour trouver les suggestions
     
    function callSuggestions(valeur)
    {
    	_adresseRecherche = _page;
      if(_xmlHttp&&_xmlHttp.readyState!=0){
        _xmlHttp.abort()
      }
      _xmlHttp=getXMLHTTP();
      if(_xmlHttp){
        //appel à l'url distante
        _xmlHttp.open("GET",_adresseRecherche+"?debut="+valeur,true);
        _xmlHttp.onreadystatechange=function() {
          if(_xmlHttp.readyState==4&&_xmlHttp.responseXML) {
            var liste = traiteXmlSuggestions(_xmlHttp.responseXML)
            cacheResults(valeur,liste)
            metsEnPlace(valeur,liste)
          }
        };
        // envoi de la requete
        _xmlHttp.send(null)
      }
    }
     
    // Mecanisme de caching des réponses
    function cacheResults(debut,suggestions){
      _resultCache[debut]=suggestions
    }
     
     
     
    // Transformation XML en tableau
    function traiteXmlSuggestions(xmlDoc) {
      var options = xmlDoc.getElementsByTagName(_tag);
      var optionsListe = new Array();
      for (var i=0; i < options.length; ++i) {
        optionsListe.push(options[i].firstChild.data);
      }
      return optionsListe;
    }
     
    //insère une règle avec son nom
    function insereCSS(nom,regle){
      if (document.styleSheets) {
        var I=document.styleSheets[0];
        if(I.addRule){ // méthode IE
          I.addRule(nom,regle)
        }else if(I.insertRule){ // méthode DOM
          I.insertRule(nom+" { "+regle+" }",I.cssRules.length)
        }
      }
    }
     
    function initStyle(){
      var AutoCompleteDivListeStyle="font-size: 13px; font-family: arial,sans-serif; word-wrap:break-word; cursor:pointer;";
      var AutoCompleteDivStyle="display: block; padding-left: 3; padding-right: 3; height: 16px; overflow: hidden; background-color: white;";
      var AutoCompleteDivActStyle="background-color: #3366cc; color: white ! important; ";
      insereCSS(".AutoCompleteDivListeStyle",AutoCompleteDivListeStyle);
      insereCSS(".AutoCompleteDiv",AutoCompleteDivStyle);
      insereCSS(".AutoCompleteDivAct",AutoCompleteDivActStyle);
    }
     
    function setStylePourElement(c,name){
      c.className=name;
    }
     
    // calcule le décalage à gauche
    function calculateOffsetLeft(r){
      return calculateOffset(r,"offsetLeft")
    }
     
    // calcule le décalage vertical
    function calculateOffsetTop(r){
      return calculateOffset(r,"offsetTop")
    }
     
    function calculateOffset(r,attr){
      var kb=0;
      while(r){
        kb+=r[attr];
        r=r.offsetParent
      }
      return kb
    }
     
    // calcule la largeur du champ
    function calculateWidth(){
      return this._inputField.offsetWidth-2*1
    }
     
    function setCompleteDivSize(){
      if(this._completeDiv){
        this._completeDiv.style.left=calculateOffsetLeft(this._inputField)+"px";
        this._completeDiv.style.top=calculateOffsetTop(this._inputField)+this._inputField.offsetHeight-1+"px";
        this._completeDiv.style.width=calculateWidth.call(this)+"px"
      }
    }
     
    function creeAutocompletionDiv() {
      initStyle.call(this);
      this._completeDiv=document.createElement("DIV");
      this._completeDiv.id=this.name+"Div";
      var borderLeftRight=1;
      var borderTopBottom=1;
      this._completeDiv.style.borderRight="black "+borderLeftRight+"px solid";
      this._completeDiv.style.borderLeft="black "+borderLeftRight+"px solid";
      this._completeDiv.style.borderTop="black "+borderTopBottom+"px solid";
      this._completeDiv.style.borderBottom="black "+borderTopBottom+"px solid";
      this._completeDiv.style.zIndex="1";
      this._completeDiv.style.paddingRight="0";
      this._completeDiv.style.paddingLeft="0";
      this._completeDiv.style.paddingTop="0";
      this._completeDiv.style.paddingBottom="0";
      setCompleteDivSize.call(this);
      this._completeDiv.style.visibility="hidden";
      this._completeDiv.style.position="absolute";
      this._completeDiv.style.backgroundColor="white";
      document.body.appendChild(this._completeDiv);
      setStylePourElement.call(this,this._completeDiv,"AutoCompleteDivListeStyle");
    }
     
    function metsEnPlace(valeur, liste){
      while(this._completeDiv.childNodes.length>0) {
        this._completeDiv.removeChild(this._completeDiv.childNodes[0]);
      }
      // mise en place des suggestions
      for(var f=0; f<this.liste.length; ++f){
        this.nouveauDiv=document.createElement("DIV");
        this.nouveauDiv.onmousedown=divOnMouseDown;
        this.nouveauDiv.onmouseover=divOnMouseOver;
        this.nouveauDiv.onmouseout=divOnMouseOut;
        setStylePourElement.call(this,this.nouveauDiv,"AutoCompleteDiv");
        this.nouveauSpan=document.createElement("SPAN");
        this.nouveauSpan.innerHTML=this.liste[f]; // le texte de la suggestion
        this.nouveauDiv.appendChild(this.nouveauSpan);
        this._completeDiv.appendChild(this.nouveauDiv)
      }
      PressAction.call(this);
      if(this._completeDivRows>0) {
        this._completeDiv.height=16*this._completeDivRows+4;
      } else 
      {
     
        hideCompleteDiv.call(this);
      }
     
    }
     
    var _lastKeyCode=null;
     
    // Handler pour le keydown du document
    function onKeyDownHandler(event){
      // accès evenement compatible IE/Firefox
      if(!event&&window.event) {
        event=window.event;
      }
      // on enregistre la touche ayant déclenché l'evenement
      if(event) {
        _lastKeyCode=event.keyCode;
      }
    }
     
    var _eventKeycode = null;
     
    // Handler pour le keyup de lu champ texte
    function onKeyUpHandler(event)
    {
      // accès evenement compatible IE/Firefox
      if(!event&&window.event) {
        event=window.event;
      }
      this._eventKeycode=event.keyCode;
      // Dans les cas touches touche haute(38) ou touche basse (40)
      if(this._eventKeycode==40||this._eventKeycode==38) {
        // on autorise le blur du champ (traitement dans onblur)
        blurThenGetFocus.call(this);
      }
      // taille de la selection
      this.N=rangeSize.call(this,this._inputField);
      // taille du texte avant la selection (selection = suggestion d'autocomplétion)
      this.v=beforeRangeSize(this._inputField);
      // contenu du champ texte
      this.V=this._inputField.value;
      if(this._eventKeycode!=0){
        if(this.N>0&&this.v!=-1) {
          // on recupere uniquement le champ texte tapé par l'utilisateur
          this.V=this.V.substring(0,v);
        }
        // 13 = touche entrée
        if(this._eventKeycode==13||this._eventKeycode==3){
          this.d=this._inputField;
          // on mets en place l'ensemble du champ texte en repoussant la selection
          if(this._inputField.createTextRange){
            this.t=this._inputField.createTextRange();
            this.t.moveStart("character",this._inputField.value.length);
            this._inputField.select()
          } else if (this.d.setSelectionRange){
            this._inputField.setSelectionRange(this._inputField.value.length,this._inputField.value.length)
          }
        } else {
          // si on a pas pu agrandir le champ non selectionné, on le mets en place violemment.
          if(this._inputField.value!=this.V) {
            this._inputField.value=this.V
          }
        }
      }
      // si la touche n'est ni haut, ni bas, on stocke la valeur utilisateur du champ
      if(this._eventKeycode!=40&&this._eventKeycode!=38) {
        // le champ courant n est pas change si key Up ou key Down
      	this._currentInputFieldValue=V;
      }
      if(handleCursorUpDownEnter(this._eventKeycode)&&this._eventKeycode!=0) {
        // si on a préssé une touche autre que haut/bas/enter
        PressAction.call(this);
      }
    }
     
    // Change la suggestion selectionné.
    // cette méthode traite les touches haut, bas et enter
    function handleCursorUpDownEnter(eventCode){
      if(eventCode==40){
        highlightNewValue(_highlightedSuggestionIndex+1);
        return false
      }else if(eventCode==38){
        highlightNewValue(_highlightedSuggestionIndex-1);
        return false
      }else if(eventCode==13||eventCode==3){
        return false
      }
      return true
    }
     
    var _completeDivRows = 0;
    var _completeDivDivList = null;
    var _highlightedSuggestionIndex = -1;
    var _highlightedSuggestionDiv = null;
     
    // gère une touche pressée autre que haut/bas/enter
    function PressAction(){
      this._highlightedSuggestionIndex=-1;
      this.suggestionList=this._completeDiv.getElementsByTagName("div");
      this.suggestionLongueur=this.suggestionList.length;
      // on stocke les valeurs précédentes
      // nombre de possibilités de complétion
      this._completeDivRows=this.suggestionLongueur;
      // possiblités de complétion
      this._completeDivDivList=this.suggestionList;
      // si le champ est vide, on cache les propositions de complétion
      if(this._currentInputFieldValue==""||this.suggestionLongueur==0){
     
        hideCompleteDiv.call(this)
      }else{
        showCompleteDiv.call(this)
      }
      this.trouve=false;
      // si on a du texte sur lequel travailler
      if(this._currentInputFieldValue.length>0){
     
        // T vaut true si on a dans la liste de suggestions un mot commencant comme l'entrée utilisateur
        for(this.indice=0; this.indice<this.suggestionLongueur; this.indice++){
          if(getSuggestion.call(this,suggestionList.item(indice)).toUpperCase().indexOf(_currentInputFieldValue.toUpperCase())==0) {
            this.trouve=true;
            break
          }
        }
      }
      // on désélectionne toutes les suggestions
      for(var i=0; i<this.suggestionLongueur; i++) {
        setStylePourElement.call(this,this.suggestionList.item(i),"AutoCompleteDiv");
      }
      // si l'entrée utilisateur (n) est le début d'une suggestion (n-1) on sélectionne cette suggestion avant de continuer
      if(this.trouve){
        this._highlightedSuggestionIndex=this.indice;
        this._highlightedSuggestionDiv=suggestionList.item.call(this,this._highlightedSuggestionIndex);
      }else{
        this._highlightedSuggestionIndex=-1;
        this._highlightedSuggestionDiv=null
      }
      this.supprSelection=false;
      switch(_eventKeycode){
        // cursor left, cursor right, page up, page down, others??
        case 8:
        case 33:
        case 34:
        case 35:
        case 35:
        case 36:
        case 37:
        case 39:
        case 45:
        case 46:
          // on supprime la suggestion du texte utilisateur
          this.supprSelection=true;
          break;
        default:
          break
      }
      // si on a une suggestion (n-1) sélectionnée
      if(!this.supprSelection&&this._highlightedSuggestionDiv){
        setStylePourElement.call(this,this._highlightedSuggestionDiv,"AutoCompleteDivAct");
        var z;
        if(this.trouve) {
          z=getSuggestion.call(this._highlightedSuggestionDiv).substr(0);
        } else {
          z=this._currentInputFieldValue;
        }
        if(z!=this._inputField.value){
          if(this._inputField.value!=this._currentInputFieldValue) {
            return;
          }
          // si on peut créer des range dans le document
          if(this._inputField.createTextRange||this._inputField.setSelectionRange) {
            this._inputField.value=z;
          }
          // on sélectionne la fin de la suggestion
          if(this._inputField.createTextRange){
            var t=this._inputField.createTextRange();
            t.moveStart.call(this,"character",this._currentInputFieldValue.length);
            t.select()
          }else if(this._inputField.setSelectionRange){
            this._inputField.setSelectionRange(this._currentInputFieldValue.length,this._inputField.value.length)
          }
        }
      }else{
        // sinon, plus aucune suggestion de sélectionnée
        this._highlightedSuggestionIndex=-1;
      }
    }
     
    var _cursorUpDownPressed = null;
     
    // permet le blur du champ texte après que la touche haut/bas ai été pressé.
    // le focus est récupéré après traitement (via le timeout).
    function blurThenGetFocus(){
      _cursorUpDownPressed=true;
      _inputField.blur();
      setTimeout("_inputField.focus();",10);
      return
    }
     
    // taille de la selection dans le champ input
    function rangeSize(n){
      var N=-1;
      if(this.n.createTextRange){
        var fa=document.selection.createRange().duplicate();
        N=fa.text.length
      }else if(n.setSelectionRange){
        N=n.selectionEnd-n.selectionStart
      }
      return N
    }
     
    // taille du champ input non selectionne
    function beforeRangeSize(n){
      var v=0;
      if(n.createTextRange){
        var fa=document.selection.createRange().duplicate();
        fa.moveEnd("textedit",1);
        v=n.value.length-fa.text.length
      }else if(n.setSelectionRange){
        v=n.selectionStart
      }else{
        v=-1
      }
      return v
    }
     
    // Place le curseur à la fin du champ
    function cursorAfterValue(n){
      if(n.createTextRange){
        var t=n.createTextRange();
        t.moveStart("character",n.value.length);
        t.select()
      } else if(n.setSelectionRange) {
        n.setSelectionRange(n.value.length,n.value.length)
      }
    }
     
     
    // Retourne la valeur de la possibilite (texte) contenu dans une div de possibilite
    function getSuggestion(uneDiv){
      if(!uneDiv) {
        return null;
      }
      return trimCR(uneDiv.getElementsByTagName('span')[0].firstChild.data)
    }
     
    // supprime les caractères retour chariot et line feed d'une chaine de caractères
    function trimCR(chaine){
      for(var f=0,nChaine="",zb="\n\r"; f<chaine.length; f++) {
        if (zb.indexOf(chaine.charAt(f))==-1) {
          nChaine+=chaine.charAt(f);
        }
      }
      return nChaine
    }
     
    // Cache completement les choix de completion
    function hideCompleteDiv(){
      this._completeDiv.style.visibility="hidden"
    }
     
    // Rends les choix de completion visibles
    function showCompleteDiv(){
      this._completeDiv.style.visibility="visible";
      setCompleteDivSize.call(this)
    }
     
    // Change la suggestion en surbrillance
    function highlightNewValue(C){
      if(!_completeDivDivList||_completeDivRows<=0) {
        return;
      }
      showCompleteDiv();
      if(C>=_completeDivRows){
        C=_completeDivRows-1
      }
      if(_highlightedSuggestionIndex!=-1&&C!=_highlightedSuggestionIndex){
        setStylePourElement(_highlightedSuggestionDiv,"AutoCompleteDiv");
        _highlightedSuggestionIndex=-1
      }
      if(C<0){
        _highlightedSuggestionIndex=-1;
        _inputField.focus();
        return
      }
      _highlightedSuggestionIndex=C;
      _highlightedSuggestionDiv=_completeDivDivList.item(C);
      setStylePourElement(_highlightedSuggestionDiv,"AutoCompleteDivAct");
      _inputField.value=getSuggestion(_highlightedSuggestionDiv);
    }
     
    // Handler de resize de la fenetre
    onResizeHandler=function(event){
      // recalcule la taille des suggestions
      setCompleteDivSize.call(this);
    }
     
    // Handler de blur sur le champ texte
    onBlurHandler=function(event){
      if(!this._cursorUpDownPressed){
        // si le blur n'est pas causé par la touche haut/bas
    	 alert(this.name);
        hideCompleteDiv.call(this);
     
        // Si la dernière touche préssé est tab, on passe au bouton de validation
        if(this._lastKeyCode==9){
          this._submitButton.focus();
          this._lastKeyCode=-1
        }
      }
      this._cursorUpDownPressed=false
    };
     
    // declenchee quand on clique sur une div contenant une possibilite
    var divOnMouseDown=function(){
      _inputField.value=getSuggestion(this);
      //_documentForm.submit()
    };
     
    // declenchee quand on passe sur une div de possibilite. La div précédente est passee en style normal
    var divOnMouseOver=function(){
      if(_highlightedSuggestionDiv) {
        setStylePourElement(_highlightedSuggestionDiv,"AutoCompleteDiv");
      }
      setStylePourElement(this,"AutoCompleteDivAct")
    };
     
    // declenchee quand la sourie quitte une div de possiblite. La div repasse a l'etat normal
    var divOnMouseOut = function(){
      setStylePourElement(this,"AutoCompleteDiv");
    };



    manganimes (en construction) -
    zemanga

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 19
    Points : 11
    Points
    11
    Par défaut
    Je rencontre exactement le même problème ! Comme tu le disais dans ton premier post, j'ai commencé par renommer toutes les variables, toutes les fonctions ... Et puis pfou ... lol

    Je pense que la solution de passer en objet est bonne. Je vais essayer de débugguer ton code.

    J'ai écrit à D. Cabasson, auteur de l'artibcle sur l'auto-complétion, pour lui demander des conseils.

    Je t'aviserai de sa réponse si j'en ai une !

    Bon courage, A bientot !

  4. #4
    Candidat au Club
    Inscrit en
    Juin 2007
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Bonjour,
    J'avais lancé un meme sujet sur ce forum il y a bientot 3 mois, sans réponse... Je me suis donc plongé dans le code.
    ATTENTION! Ce sont mes premiers pas en javascript et j'ai supprimé l'une ou l'autre option qui ne m'intéressait pas (mise en surbrillance dans le champ texte, recalculer la position des suggestions quand on redimmensionne la fenetre, gestion du cache,...).
    J'ai 2 fichiers:
    - le premier sert à initialiser le processus. J'y définis qques variables pour chaque champ.
    - le second est celui qui va tout gérer
    Je fais appel à un script php distant qui me renvoie la réponse de la requete.
    Ca fonctionne sous FF et IE.
    Je vous livre le code tel que je l'ai écrit, il y a peut-être des commentaires qui n'ont rien à voir... et c'est surement pas optimisé!!!!!!
    Par contre, tout est commenté puisque je découvre javascript, je veux pouvoir m'y retrouver dans ce que j'ai codé ;-)

    Premier fichier:
    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
    window.onload = function(){
      // Je dois préciser le fichier *.php5 qui va gérer la requete pour chaque champ
      document.getElementById('prenom').champBDD = 'prenom';
      document.getElementById('nom').champBDD = 'nom';
      document.getElementById('nomSupplementaire').champBDD = 'nom';
      // J'initialise le processus
      initAutoComplete(
        document.getElementById('formContact'),
        new Array(
          document.getElementById('prenom'), 
          document.getElementById('nom'), 
          document.getElementById('nomSupplementaire')
        )
      );
    }
    Second fichier:
    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
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    /*
    Toutes les 200 milisecondes, s'il y a un champs à autocompléter dans lequel il y a des lettres,
    alors rechercher les possibilités.
    */
     
    // retourne un objet xmlHttpRequest.
    // méthode compatible entre tous les navigateurs (IE/Firefox/Opera)
    function get_Xhr(){
      var xhr=null;
      if(window.XMLHttpRequest) // Firefox et autres
      xhr = new XMLHttpRequest();
      else if(window.ActiveXObject){ // Internet Explorer
        try {
          xhr = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
          try {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
          } catch (e1) {
            xhr = null;
          }
        }
      }
      else { // XMLHttpRequest non supporté par le navigateur
        alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
      }
      return xhr;
    }
     
    var _form = null; // Variable qui permettra (une fois affectée) d'accéder directement au fromulaire (ça donnera: _form au lieu de faire par exemple: document.forms["nouveauContact"] ou document.getElementById('nouveauContact'))
    var _tabInputFields = new Array(); // Tableau qui contient des objets qui permettront d'accéder directement aux champs à autocompléter (ça donne: _tabInputFields[0] au lieu de faire par exemple: document.getElementById('prenom'))
    var _selectedSugg = -1; // Variable qui retient quel était la dernière suggestion que l'internaute a sélectionnée quand il a touché aux flèches haut ou bas pour choisir une suggestion
    var _xmlHttp = null; // L'objet xmlHttpRequest utilisé pour contacter le serveur
    var _adresseRecherche = "../AutoCompletion/AC_Fonctions.php5" // L'adresse à interroger pour trouver les suggestions
    var _eventKeycode = null;
    var _champsCaches = new Array(); // Tableau contenant tous les champs cachés créés automatiquement (par exemple quand je tape le nom d'un pays et que je le sélectionne via autocomplétion, je dois renvoyer son id via un champ caché)
     
    function initAutoComplete(form,tabFields){
      _form = form; // Je stocke l'objet form[] dans une variable globale
      _tabInputFields = tabFields;
      for (var i=0; i < _tabInputFields.length; i++) { // J'initialise chaque champ qui attend une auto-complétion
        _tabInputFields[i].oldValue = _tabInputFields[i].value; // Pour ne pas faire de requete AJAX tant que je n'ai rien inscrit dans ce champs
        _tabInputFields[i].stopReq = null; // Cette variable sert à ne plus effectuer de requete si l'internaute continue de taper un mot dont le début ne renvoie déjà pas de suggestions (par exemple: à partir de la 3eme lettre, la requete ne retourne rien. Si l'internaute a un mot de 10 lettres, alors il ne faut plus faire de requete à chaque fois que l'internaute écrit une des 7 lettres restantes)
        _tabInputFields[i].setAttribute("autocomplete", "off"); // Pour éviter l'autocompletion des champs input automatique des navigateurs (quand le navigateur propose les entrées précédentes par défaut)
        _tabInputFields[i].onkeydown = onKeyDownFunction; // Pour détecter certaines actions du clavier qui nous intéressent (flèches haut et bas, tab, enter) quand la touche est ENFONCEE
        _tabInputFields[i].onkeyup = onKeyUpFunction; // Pour détecter certaines actions du clavier qui nous intéressent (flèches haut et bas, tab, enter) quand la touche est RELACHEE
        _tabInputFields[i].onblur = onBlurFunction; // Quand on quitte ce champ qui attend l'auto-completion, je fais tout disparaitre et je réinitialise certaines variables
     }
      window.onresize = onResizeFunction; // Si l'internaute resize la fenetre, je fais tout disparaitre
      // Premier déclenchement de la fonction dans 200 millisecondes
      setTimeout("mainLoop()",200)
    }
     
    // Fonction qui tourne en permanence et qui vérifie si un des champs à autocompléter a été modifié par l'internaute. Si c'est le cas, on déclenche le processus de recherche
    function mainLoop(){
      for (var i=0; i < _tabInputFields.length; i++) { // Je vérifie chaque champ qui attend une auto-complétion
        // Si l'internaute a tapé une nouvelle lettre dans ce champ (ou s'il en a supprimé) depuis la dernière boucle,...
        // ... ET SI la partie présente dans le champ ne contient pas une suite de lettres qui n'ont plus aucune correspondance dans la BDD
        if(_tabInputFields[i].value != _tabInputFields[i].oldValue && (_tabInputFields[i].value.indexOf(_tabInputFields[i].stopReq) == -1)){
          if(_champsCaches[_tabInputFields[i].id]){ // S'il y a un champ caché pour l'ancienne valeur de ce champ,...
            _form.removeChild(_champsCaches[_tabInputFields[i].id]); // ... il faut l'effacer dans le code html ...
            delete _champsCaches[_tabInputFields[i].id]; // ... et effacer la variable qui contient ce champ dans mon code javascript
          }
          var valeur = escapeURI(_tabInputFields[i].value); // Fonction qui échappe les caractères spéciaux avant la requete
    //      var valeur = _tabInputFields[i].value;
          callSuggestions(valeur, _tabInputFields[i]); // Fonction qui fait la requete et interprète le résultat obtenu
          _tabInputFields[i].oldValue = _tabInputFields[i].value; // Je réinitialise oldValue pour stopper la recherche lors de la prochaine boucle
        }
      }
      setTimeout("mainLoop()",200); // la fonction se redéclenchera dans 200 ms
      return true
    }
     
    function callSuggestions(valeur, inputField){
      _xmlHttp = null;
      if(_xmlHttp && _xmlHttp.readyState != 0){
        _xmlHttp.abort()
      }
      _xmlHttp = get_Xhr();
      if(_xmlHttp){
        // Création de la requete
        // Je dois d'abord vérifier s'il y a d'autres infos à envoyer en plus pour la requete (c'est précisé dans le fichier qui initialise l'autocomplete AC_FORM_???.js)
        var champsSupp = '';
        if(inputField.champsSupp){ // S'il y a des valeurs en plus à joindre dans la requete
          for(var i=0; i<inputField.champsSupp.length; i++){ // Pour chaque valeur je complète la requete
            if(document.getElementById(inputField.champsSupp[i])){ // S'il y a déjà un pays mentionné dans le champ pays
      //        champsSupp = '&id'+inputField.champsSupp[i].id+'='+inputField.champsSupp[i].value;
              champsSupp = '&'+inputField.champsSupp[i]+'='+document.getElementById(inputField.champsSupp[i]).value;
            }
          }
        }
        // J'envoie la requete
        _xmlHttp.open("GET",_adresseRecherche+"?debut="+valeur+"&champ="+inputField.champBDD+champsSupp,true);
     
        _xmlHttp.onreadystatechange = function() {
          if(_xmlHttp.readyState==4 && _xmlHttp.status == 200 && _xmlHttp.responseText != 'false') { // Si je reçois des données, autres que 'false'
            inputField.stopReq = null; // Si la requete retourne une réponse, alors il n'y a pas encore de raisons de bloquer les requetes suivantes si l'internaute continue à taper la suite de son mot
            if(document.getElementById("autoComplete_"+inputField.id)){ // Si j'ai déjà un div "autocomplete" pour ce champ
              var _divListe = document.getElementById("autoComplete_"+inputField.id); // j'initialise la var _divListe (plus facile pour la suite)
              if(_divListe.hasChildNodes()){ // Si _divListe a déjà un noeud enfant (s'il y a déjà des suggestions qui sont faites)
                _divListe.removeChild(_divListe.firstChild); // Je supprime les dernières suggestions en vue de les remplacer par celles qui arrivnet
              }
            }else{ // Si je n'ai pas encore de div "autocomplete" pour ce champ, alors je le crée
              // Calcul du décalage en haut
              var parent = inputField.offsetParent;
              var top = inputField.offsetTop;
              while (parent) {
                top += parent.offsetTop;
                parent=parent.offsetParent;
              }
     
              // Calcul du décalage à gauche
              var parent = inputField.offsetParent;
              var left = inputField.offsetLeft;
              while (parent) {
                left += parent.offsetLeft;
                parent=parent.offsetParent;
              }
     
              // Calcul de la largeur          
              var width = (inputField.offsetWidth);
     
              // On crée un nouvel élément          
              var _divListe = document.createElement("DIV"); // création d'un nouvel élément
     
              _divListe.style.top = (top+inputField.offsetHeight)+"px"; // je le positionne par rapport à mon champ de formulaire
              _divListe.style.left = left+"px";
              _divListe.style.width = width+"px";
              _divListe.id = "autoComplete_"+inputField.id; // je lui donne un id
              _divListe.className = "listeAutoCompletion"; // je l'attribue à une classe de mise en page
     
              document.body.appendChild(_divListe); // je l'attache à body, j'en fait un enfant de body
            }
            _divListe.innerHTML = _xmlHttp.responseText; // J'insère la réponse qui m'arrive dans le div créé auparavant
            for(var i = 0; i < _divListe.getElementsByTagName("li").length; i++){
              _divListe.getElementsByTagName("li")[i].numSugg = i; // J'attibue un numéro à chaque suggestion, pour pouvoir identifier laquelle est sélectionnée ou doit être sélectionnée
              _divListe.getElementsByTagName("li")[i].onmouseover = function(){
                // Je désélectionne la sélection active (s'il y en a une)
                if(_selectedSugg >= 0){ // S'il y a déjà une suggestion sélectionnée, alors je la désélectionne
                  // Je change l'atribut class="" de cette suggestion (de sugg à selectedSugg)
                  document.getElementById("autoComplete_"+inputField.id).getElementsByTagName("li")[_selectedSugg].className = "sugg";
                }
                // La suggestion sélectionnée change de numéro
                _selectedSugg = this.numSugg;
                // Je change l'atribut class="" de cette suggestion (de sugg à selectedSugg)
                document.getElementById("autoComplete_"+inputField.id).getElementsByTagName("li")[_selectedSugg].className = "selectedSugg";
              }
              _divListe.getElementsByTagName("li")[i].onmouseout = function(){
                // Je change l'atribut class="" de cette suggestion (de sugg à selectedSugg)
                document.getElementById("autoComplete_"+inputField.id).getElementsByTagName("li")[_selectedSugg].className = "sugg";
                _selectedSugg = -1;
     
              }
              _divListe.getElementsByTagName("li")[i].onmousedown = function(){
                inputField.value = this.getAttribute("valeur"); // J'attribue la valeur au champ texte
                inputField.oldValue = inputField.value; // J'attribue la valeur que l'internaute vient de sélectionner comme ancienne valeur, pour éviter de faire encore une requete AJAX qui retournera la même suggestion lors de la prochaine boucle
                hiddenUniqueId(inputField); // Je crée un champ caché contenant l'id de la proposition sélectionnée
              }
            }
    //        _divListe.appendChild(document.getElementById("liste_"+inputField.id)); // J'attache la liste au div "autocomplete" de ce champ
          }else if(_xmlHttp.readyState == 4 && _xmlHttp.responseText == 'false'){ // Si je n'ai pas de réponse, ou une réponse vide (false renvoyé par autocompletion.php5)
            if(document.getElementById("autoComplete_"+inputField.id)){ // S'il y a un div "autocomplete" pour ce champ
              document.body.removeChild(document.getElementById("autoComplete_"+inputField.id)); // Alors je le supprime
            }
            if(inputField.value != ""){
              inputField.stopReq = inputField.value;
            }else{
              inputField.stopReq = null;
            }
            _selectedSugg = -1; // Pour que le premier element sélectionné avec le clavier soit bien le premier ou le dernier de la liste, et pas le troisième par exemple
          }
        }
        // envoi de la requete
        _xmlHttp.send(null);
      }
    }
     
    // Fonction pour le keydown du champ texte
    var onKeyDownFunction = function(event){
      // accès evenement compatible IE/Firefox
      if(!event&&window.event) {
        event=window.event;
      }
      _eventKeycode=event.keyCode;
    //  alert(_eventKeycode);
      // Dans les cas touches touche haute(38) ou touche basse (40)
      if(_eventKeycode == 40 || _eventKeycode == 38) {
        // S'il n'y a pas de suggestion affichée, si on appuye sur fleche haut ou bas, on force une recherche AJAX. C'est utile si l'internaute tape une lettre, puis perd le focus, puis reprend le focus et veut à nouveau avoir la lsite des suggestions pour ce qu'il avait déjà tapé
        if(!document.getElementById("autoComplete_"+this.id)){
          this.oldValue = ""; // Je réinitialise cette vairable qui va alors déclencher la requete AJAX lors de la prochaine boucle
          return;
        }
        var nbSugg = document.getElementById("autoComplete_"+this.id).getElementsByTagName("li").length; // Je calcule le nombre de suggestions renvoyées par le serveur
        if(_selectedSugg >= 0 && _selectedSugg < nbSugg){ // S'il y a déjà une suggestion sélectionnée, alors je la désélectionne
        // Je change l'atribut class="" de cette suggestion (de sugg à selectedSugg)
          document.getElementById("autoComplete_"+this.id).getElementsByTagName("li")[_selectedSugg].className = "sugg";
        }
        if(_eventKeycode == 40) { // Fleche bas
          if(_selectedSugg >= nbSugg-1){ // Si la suggestion sélectionnée avant que l'internaute n'appuye sur une flèche était la dernière suggestion, alors on sélectionne la première suggestion
            _selectedSugg = -1;
          }
          _selectedSugg++; // On sélectionne la suggestion suivante
        }
        if(_eventKeycode == 38) { // Fleche haut
          if(_selectedSugg <= 0){ // Si la suggestion sélectionnée avant que l'internaute n'appuye sur une flèche était la première suggestion, alors on sélectionne la dernière suggestion
            _selectedSugg = nbSugg;
          }
          _selectedSugg--; // On sélectionne la suggestion précédente
        }
        // Je change l'atribut class="" de cette suggestion (de selectedSugg à sugg)
        document.getElementById("autoComplete_"+this.id).getElementsByTagName("li")[_selectedSugg].className = "selectedSugg";
        // J'inscris la valeur sélectionnée dans le champs
        this.value = document.getElementById("autoComplete_"+this.id).getElementsByTagName("li")[_selectedSugg].getAttribute("valeur");
        // Il faut éviter de refaire une requete, pcq sinon on perd les sélections. Il ne faudra le faire que si l'internaute valide son choix
        this.oldValue = this.value;
      }
     
      // Dans le cas de la touche enter (3 ou 13) ou tab (9)
      if(_eventKeycode==13 || _eventKeycode==3 || _eventKeycode == 9){
        if(document.getElementById("autoComplete_"+this.id) && document.getElementById("autoComplete_"+this.id).getElementsByTagName("li")[_selectedSugg].getAttribute("valeur") != ""){ // S'il y a une suggestion sélectionnée,...
     
          hiddenUniqueId(this); // Je crée un champ caché contenant l'id de la proposition sélectionnée
     
          this.value = document.getElementById("autoComplete_"+this.id).getElementsByTagName("li")[_selectedSugg].getAttribute("valeur"); // ... on l'insère dans le champs texte
          this.oldValue = this.value; // Pour éviter de faire une requete lors de la prochaine boucle
          if(_eventKeycode==13 || _eventKeycode==3){ // Si l'internaute a appuyé sur une touche "enter"
            this.blur(); // C'est pour supprimer la listes des suggestions (valable seulement pour les touches enter, car la touche tab fait un blur d'office en passant au champs suivant)
     
            // Ici je vais simuler un appui sur la touche tab pour passer au tabindex suivant
            var tab = parseInt(this.getAttribute("tabindex")); // Je récupère le numéro du tabindex du champ actuel
            tab++; // J'incrémente le tabindex pour passer au suivant
            var allFields = _form.elements; // Je récupère un tableau avec tous les éléments de ce formulaire-ci
            for(var i=0; i!=allFields.length; i++) { // Je vérifie le tabindex de chaque élément de formulaire
              if(parseInt(allFields[i].getAttribute("tabindex")) == tab) { // Si c'est celui-ci le suivant,...
                allFields[i].focus(); // ... alors je lui donne le focus
                break
              }
            }
            return false // Pour que la touche enter ne valide pas le formulaire maintenant
          }
        }
      }
    }
     
    // Fonction pour le keyup du champ texte
    var onKeyUpFunction = function(event){
      // accès evenement compatible IE/Firefox
      if(!event&&window.event) {
        event=window.event;
      }
      _eventKeycode=event.keyCode;
      // Dans le cas de la touche fleche vers le haut (38)
      if(_eventKeycode == 38) {
        // Je dois remettre le curseur en fin de texte dans le champ texte (pcq avec les flèches haut et bas, on fait bouger aussi le curseur dans le champ texte)
        // NOTE: J'aurais préféré mettre cette fonction dans le keyDown, mais le curseur ne bouge que sur le keyUp. Donc si je le met en fin de keyDown, il se met à la fin puis quand on relache la touche, il revient de 1 caractère en arrière
        setCursorToEnd(this); // La fonction setCursorToEnd() est définie plus bas et je ne l'ai pas pondue moi-même
      }
    }
     
    // Fonction qui fait tout disparaitre et qui réinitialise certaines variables lorsqu'on quitte le champ
    var onBlurFunction = function() { // Quand on quitte ce champ qui attend l'auto-completion
      if(document.getElementById("autoComplete_"+this.id)){ // S'il y a un div "autocomplete" pour ce champ avec des suggestions
        document.body.removeChild(document.getElementById("autoComplete_"+this.id)); // Alors je le supprime
      }
      _selectedSugg = -1; // Je réinitialise cette variable
    }
     
    // Fonction qui supprime toutes les suggestions affichées lors du resize de la fenetre.
    // NOTE: plutot que de tout supprimer, je pourrais replcer les suggestions au bon endroit et tout recalculer...
    var onResizeFunction = function(){ // Si l'internaute resize la fenetre,...
      for (var i=0; i < _tabInputFields.length; i++) { // ... pour chaque champ à autocompléter...
        _tabInputFields[i].blur(); // ... je lui fais perdre le focus, comme ça je fais disparaitre les suggestions qui étaient éventuellemt affichées.
      }
    }
     
    // Fonction qui sert à la fonction setCursorToEnd(), et peut-être à autre chose, mais je ne sais pas, ce n'est pas moi qui l'ai écrite
    function setSelectionRange(input, selectionStart, selectionEnd) {
      if (input.setSelectionRange) {
        input.focus();
        input.setSelectionRange(selectionStart, selectionEnd);
      }else if (input.createTextRange) {
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', selectionEnd);
        range.moveStart('character', selectionStart);
        range.select();
      }
      return false
    }
     
    // Fonction qui sert à mettre le pointeur en fin de champ texte (je n'ai pas écrit cett fonction moi-même)
    function setCursorToEnd (input) {
      setSelectionRange(input, input.value.length, input.value.length);
    }
     
    // Fonction qui échappe les caractère spéciaux (en fonction des navigateurs)
    function escapeURI(valeur){
      if(encodeURIComponent) {
        return encodeURIComponent(valeur);
      }
      if(escape) {
        return escape(valeur)
      }
    }
     
    // Fonction qui génère un champ hidden avec le uniqueId correspondant au choix de l'internaute pour un champ
    function hiddenUniqueId(champInput){
    //  alert("toto");
      // S'il y a un uniqueId qui correspond à la proposition sélectionnée, je dois rajouter un champ hidden qui contient ce uniqueId
      if(document.getElementById("autoComplete_"+champInput.id).getElementsByTagName("li")[_selectedSugg].getAttribute("uniqueid")){
        _champsCaches[champInput.id] = document.createElement('input'); // création d'un nouvel élément
        var champ = _champsCaches[champInput.id];
        champ.id = "id"+champInput.id; // je lui donne un id
        champ.setAttribute('type','hidden');
        champ.setAttribute('name','parametres[Champs][id'+champInput.id+']');
        champ.value = document.getElementById("autoComplete_"+champInput.id).getElementsByTagName("li")[_selectedSugg].getAttribute("uniqueid");
        _form.appendChild(champ); // je l'attache au formulaire, j'en fait un enfant du formulaire
        return true
      }
    }
     
    ////////////////////////////////////////////////////////////////////////////////////////////
    // TOUT CE QUI SE TROUVE EN DESSOUS DE CETTE LIGNE N EST PAS EMPLOYE
    // calcule le décalage à gauche
    function calculateOffsetLeft(r){
      return calculateOffset(r,"offsetLeft")
    }
     
    // calcule le décalage vertical
    function calculateOffsetTop(r){
      return calculateOffset(r,"offsetTop")
    }
     
    function calculateOffset(r,attr){
      var kb=0;
      while(r){
        kb+=r[attr];
        r=r.offsetParent
      }
    //  alert(kb);
      return kb
    }
    // calcule la largeur du champ
    function calculateWidth(inputField){
    //  alert(inputField.offsetWidth-2*1);
      return inputField.offsetWidth-2*1
    }
    function setCompleteDivSize(div, inputField){
      div.style.left=calculateOffsetLeft(inputField)+"px";
      div.style.top=calculateOffsetTop(inputField)+inputField.offsetHeight+"px";
      div.style.width=calculateWidth(inputField)+"px"
    }
    //////////////////////////////////////////////////////////////////////////////////////////
    //FindPos(document.getElementById("prenom"));
    function FindPos(AObject){
      var posX = 0;
      var posY = 0;
      do{
        posX += AObject.offsetLeft;
        posY += AObject.offsetTop;
        AObject = AObject.offsetParent;
      }
      while( AObject != null );
      var pos = [];
      pos['X'] = posX;
      pos['Y'] = posY;  
     
      alert(posX);
      return pos;
    }
    Voilà, en espérant contribuer constructivement au sujet, je reste à votre écoute pour d'éventuelles explications.

    Etienne

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 19
    Points : 11
    Points
    11
    Par défaut
    Merci pour ta contribution.

    Joli travail que tu as fait. Franchement pas bête l'idée toute simple de rajouter un paramètre "champ" lors de l'appel de la génération XML. J'y avait pas pensé !

    Je vais tester ça ...

    Merci encore !

  6. #6
    Candidat au Club
    Inscrit en
    Juin 2007
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Salut,

    J'ai oublié de mentionner que dans les fichiers plus haut, j'ai rajouté qques fonctionnalités dont j'avais besoin par rapport au script d'origine de Denis Cabasson:

    - si l'internaute inscrit le nom d'un pays dans le champ 'pays', je fais la requete sur ma table 'pays', et j'affiche le nom du pays sélectionné par l'internaute dans le champ (jusque là, rien de spécial, AJAX normal). Mais j'aimerais bien que quand je valide le formulaire, j'aie directement l'id du pays sélectionné plutôt que son nom (sinon je dois de nouveau faire une requete pour connaitre l'id du pays dans ma table). Et comme ça ne va pas de mettre l'id directement dans le champ (ça ne dit rien à l'internaute qui clique sur la proposition 'Belgique' d'avoir '12' qui s'affiche dans le champ), j'ai donc rajouté la possibilité d'ajouter à la volée un champ hidden name='idPays' value='12'.

    - autre fonctionnalité: la possibilité de rajouter la valeur d'un autre champ dans la requete. Je m'explique. Si l'internaute cherche le nom d'une ville dans un champ 'ville', j'aimerais bien envoyer dans la requete la valeur que l'internaute a déjà inscrite dans le champ 'pays' juste avant, ou plus exactement l'id du pays sélectionné par l'internaute et qui est stocké dans le champ hidden généré plus haut. Ca permet d'affiner la requete.
    Pour ce faire, je rajoute (dans le premier fichier d'initialisation):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    document.getElementById('ville').champsSupp = new Array('idpays');
    - j'ai aussi rajouté la possibilité d'afficher une valeur différente dans la liste déroulante et dans le champ texte. Par exemple: si l'internaute n'a pas encore inscrit de pays dans le champ 'pays', et qu'il inscrit une ville dans le champ 'ville', je lui affiche dans les suggestions les propositions comme ceci:
    'Nom_de_la_ville - code_postal - pays'. Mais quand il sélectionne une proposition, il ne faut pas mettre le nom du pays ou le code postal dans le champ 'ville'. Il n'y aura donc que 'Nom_de_la_ville' qui va s'afficher (et son id qui s'ajoute en champ hidden. (je dois encore travailler sur l'ajout automatique du nom du pays dans le champ 'pays' et de son id en champ hidden.

    Un réponse type renvoyée par mon script php suite à ma requete:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <ul>
    <li class="sugg" valeur="Nivelles" uniqueId="00000001823">Nivelles - 1400 - Belgique</li>
    <li class="sugg" valeur="Niverlée" uniqueId="00000001824">Niverlée - 5680 - Belgique</li>
    <li class="sugg" valeur="Nives" uniqueId="00000001825">Nives - 6640 - Belgique</li>
    <li class="sugg" valeur="Saint-Pée-sur-Nivelle" uniqueId="00000028564">Saint-Pée-sur-Nivelle - 64310 - France</li>
    </ul>
    Donc:
    - 'valeur' est ce qui s'affichera dans le champ texte 'ville'
    - la présence de 'uniqueId' va générer automatiquement un champ hidden 'idVille=00000001825'

    Voilà, je pense avoir tout dit. N'ésitez pas à poser des questions.
    A+,
    Etienne

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2004
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 20
    Points : 12
    Points
    12
    Par défaut
    Je fais autrement pour le moment :

    Pour chaque champs input "nom_champ" je rajoute un on_focus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    onfocus="initAutoComplete(document.getElementById('form_gestion'),document.getElementById('nom_champ'));"
    Qu'en pensez vous ?

Discussions similaires

  1. plusieurs iViewer sur une même page ajax
    Par tigunn dans le forum jQuery
    Réponses: 15
    Dernier message: 18/04/2012, 15h18
  2. Plusieurs formulaires sur une même page
    Par patsak dans le forum Langage
    Réponses: 3
    Dernier message: 11/06/2008, 16h14
  3. [JpGraph] Plusieurs graphes sur une même page
    Par Dam1en dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 28/12/2007, 23h13
  4. Réponses: 2
    Dernier message: 18/07/2007, 08h38
  5. [C#][SVG] Combinaison de plusieurs graphe sur une même page
    Par doudoustephane dans le forum ASP.NET
    Réponses: 2
    Dernier message: 22/11/2006, 09h19

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