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 :

problème avec le innerHTML des listes déroulantes


Sujet :

JavaScript

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 102
    Points : 120
    Points
    120
    Par défaut problème avec le innerHTML des listes déroulantes
    Bonjour à tous.

    Je fais un semblant d'Ajax en essayant de synchroniser une liste déroulante en fonction du onChange d'une autre liste déroulante.
    Je travaille avec les XMLhttprequest.

    Bon ça marchait nikel en travaillant avec des flux XML en récupérant le response XML mais comme je veux faire une fonction javascript portable a tout objet (bref peu importe) je veux qu'elle exploite du html en retour de requete http.
    au lieu de renvoyer de l'XML et exploiter responseXML j'essaie de renvoyer directement le source "<option value= etc." et exploiter au niveau du client le responseText.
    Or le "ma_select.innerHTML=responseText" foire.

    D'ailleurs plus généralement j'ai remarqué qu'indépendamment de ma petite sauce et pour être précis et concrêt pour cet exemple de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <select id="test">
    </select>
     
    <script language="Javascript">
    var a = '<OPTION value=a selected>a</option><OPTION value=b>b</OPTION><OPTION value=c>c</OPTION><OPTION value=d>d</OPTION><OPTION value=c>c1</OPTION>';
    document.getElementById('test').innerHTML = a;
    alert(document.getElementById('test').innerHTML);
    </script>
    l'alert() à la fin ne me restitue non pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <OPTION value=a selected>a</option><OPTION value=b>b</OPTION><OPTION value=c>c</OPTION><OPTION value=d>d</OPTION><OPTION value=c>c1</OPTION>
    mais systématiquement quelque chose de tronqué genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    a</option><OPTION value=b>b</OPTION><OPTION value=c>c</OPTION><OPTION value=d>d</OPTION><OPTION value=c>c1</OPTION>
    Pourquoi innerHTML peut-il se comporter ainsi ?

  2. #2
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 650
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 650
    Points : 11 142
    Points
    11 142
    Par défaut
    bonjour,

    d'abord ce n'est pas un innerHTML que tu pourras ajouter des options dans ta liste.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    var a = '<OPTION value=a selected>a</option><OPTION value=b>b</OPTION><OPTION value=c>c</OPTION><OPTION value=d>d</OPTION><OPTION value=c>c1</OPTION>';
    document.getElementById('test').innerHTML = a;
    alert(document.getElementById('test').innerHTML);
    c'est quoi test ? L'id de ta liste ?
    Plutôt que faire un alert sur l'innerHTML fais un alert sur a.

  3. #3
    Membre actif
    Avatar de nicolas.pied
    Profil pro
    Ingénieur d'Etudes
    Inscrit en
    Janvier 2005
    Messages
    249
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur d'Etudes

    Informations forums :
    Inscription : Janvier 2005
    Messages : 249
    Points : 235
    Points
    235
    Par défaut
    Déjà ton code n'est pas conforme aux standards minimaux, c'est à dire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <OPTION value=a selected>a</option>
    <OPTION value=b>b</OPTION>
    <OPTION value=c>c</OPTION>
    <OPTION value=d>d</OPTION>
    <OPTION value=c>c1</OPTION>
    ... serait plus de la forme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <option value="a" selected="selected">a</option>
    <option value="b">b</option>
    <option value="c">c</option>
    <option value="d">d</option>
    <option value="c">c1</option>
    Pas de majuscules dans les noms de balises et il faut mettre des guillemets. Sachant que certains navigateur travaille à partir de l'arbre DOM (comme firefox), tes erreurs peuvent donc venir de là.

    Sinon avec ResponseXML, il te suffit de faire du code XHTML et ça fonctionnera aussi. Le code que je t'ai donné est respecte le format XHTML.

  4. #4
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 650
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 650
    Points : 11 142
    Points
    11 142
    Par défaut
    Citation Envoyé par nicolas.pied
    Déjà ton code n'est pas conforme aux standards minimaux
    en plus...

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 102
    Points : 120
    Points
    120
    Par défaut
    Salut,

    merci pour vos réponses;

    oui pour la conformité vous prêchez un converti !
    Mais c'est un faux problème de par ma faute, moi qui pourtant suis maniaque sur ce point, c'est qu'au fil des tests j'avais fini par copié la valeur telle qu'elle m'était restituée en espionnant innerhtml, et ce malgré une construction carrée de mon select à la base.
    Donc ce que vous voyez d'aussi affeux j'en conviens, n'est qu'une chaine récupérée en espionnant la propriété innerHTML sur la base d'un select qui avait pourtant été soigné sur ce plan (merci IE).

    Oui 'test' est l'id du select.

    Quel est l'interêt de faire une alert sur "a"? je connais la valeur de a puisque c'est moi qui lui donne pour ma démonstration.
    Ce que je cherche a démontrer c'est que si j'affecte le getElementById('test').innerHTML d'une chaine représentant des options, (qu'elle sont aux norme ou pas), ben effectivement ca foire.
    alors que d'après moulte exemples fructueux sur le net notamment en "pseudo Ajax" (puisqu'on fait l'economie d'un parsing XML), mais hélas dont la nuance m'échappe, il est théoriquement possible de renouveler ainsi et d'un seul trait les options d'un select.

    Sur qui semble logique car si vous avez la curiosité d'espionner le innerHTML d'un select bati classiquement, il en ressort une telle chaine.

    Bref si çà continue je vais retourner à l'Ajax pur avec XML et tant pis pour la portabilité (select div etc...) de ma fonction.
    Je me console en me disant qu'elle reste portable d'un select à l'autre.

    Merci à vous.

  6. #6
    Membre actif
    Avatar de nicolas.pied
    Profil pro
    Ingénieur d'Etudes
    Inscrit en
    Janvier 2005
    Messages
    249
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur d'Etudes

    Informations forums :
    Inscription : Janvier 2005
    Messages : 249
    Points : 235
    Points
    235
    Par défaut
    Je viens de saisir deux mots clefs (select et innerHTML) sous Google et le premier lien me donne cette adresse :

    BUG: Internet Explorer Fails to Set the innerHTML Property of the Select Object

    Je crois que ça parle de soit même, en plus Microsoft a même fournit la solution

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 102
    Points : 120
    Points
    120
    Par défaut
    Salut Ah bah comme un beignet j'ai bien bien essayé de combiner innerhtml dans google mais avec l'expression "liste déroulante".

    Merci infiniment en tout cas pour ce lien éclairant très précisément mon problème.

    J'ai exploité celà sans pour autant résoudre mon problème de portabilité.

    la technique microsoft préconise d'englober le tout dans un div, et d'en écraser le contenu y compris la balise select et ses attributs, ca n'a pas grand interet si l'on veut exploiter des evennement ou les résultat du formulaire ensuite (sauf a pouvoir le remetre a l'identique bien sur).

    Enfin si, on peut conserver l'initialisation des attributs grace a un replace() uniqment de la partie "options".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    html = document.getElementById(object_id).innerHTML;
    new_html = html.replace(/(<OPTION([ ]|.)+<\/OPTION\>)/i, ajax.responseText);
    document.getElementById(object_id).innerHTML = new_html;
    mais du coup le gain est nul (voir négatif) par rapport au XML.
    je ne suis plus portable d'un type d'objet a l'autre, cela redevient une fonction partageable uniquement entre les SELECT d'une application.

    retour au point de départ.

    Merci à vous tous. je vais considérer mon sujet comme réglé, mais je reste bien entendu plus que jamais ouverts aux conseils éclairés.

  8. #8
    Membre actif
    Avatar de nicolas.pied
    Profil pro
    Ingénieur d'Etudes
    Inscrit en
    Janvier 2005
    Messages
    249
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur d'Etudes

    Informations forums :
    Inscription : Janvier 2005
    Messages : 249
    Points : 235
    Points
    235
    Par défaut
    Sinon, utilises le XML et exploite les données en utilisant DOM qui permet d'ajouter ou de modifier les options des select.

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 102
    Points : 120
    Points
    120
    Par défaut
    C'est ce que je faisais au départ et ce a quoi je viens de retourner :-).


    En Xml, la structure du flux doit etre adapté a l'objet par exemple pour le select un attribut a a chaque noeud (text de chaque l'option à afficher) + 3eme attribut value (le value de chaque option), et la façon dont je parse le flux en retour devient alors la contrainte, pour tout objet qui voudrait également utiliser cette fonction quoiqu'en rusant un peu ....

    Mais effectivement à inconvénient égal j'ai largement préféré revenir au XML.

    en gros je suis revenu à çà :
    2 de mes nombreux selects :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <select name="base" style="width : 150px" onChange="Javascript : update_content('keywords', this.value);document.getElementById('dkeywords').innerHTML = '';" >
    [...]
    <select name="keywords" id="keywords" style="width : 150px" size="5" onClick="Javascript : add_keyword(this.options[this.selectedIndex].text);">
    </select>
    Je suis censé synchroniser la deuxieme sur le onChange de la 1ere en appelant
    update_content(id_du_select_a_updater, valeur_a_recuperer)

    Ensuite donc ma fonction javascript appelé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
     
    function update_content(object_id, param_to_send) 
    {
    	if(!ajax)
    		alert('blemme pas d ajax');
    	ajax.open('get', url + '?object_id=' + object_id + '&param=' + param_to_send);
    	ajax.onreadystatechange = function() 
    	{
    		if(ajax.readyState == 4) 
    		{
    			var data = ajax.responseXML.getElementsByTagName('option');
    			for(var i=0;i<data.length;i++) 
    			{
    				var my_option = document.createElement('option');
    				my_option.setAttribute('value',data[i].getAttribute("value"));
    				my_option.appendChild(document.createTextNode(data[i].getAttribute("label")));
    				document.getElementById(object_id).appendChild(my_option);
    			}
    		}
    	}
    	ajax.send(null);
    }
    Et donc cette fonction enverra la requette http au server vers un fichier rpc.php, dans lequel chaque fonction porte le nom d'un select , ce qui permet l'appel dynamique de la fonction php qui renverra le flux approprié en fonction de l'id du select + valeur à exploiter tout deux passés en GET.

    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
     
    function keywords()
    {
       sql ="...$_GET["param"];
       $r mysql_query($sql);
       return $r;
    }
    function autre_fonction
    {
       sql ="...$_GET["param"];
       $r mysql_query($sql);
       return $r;
    }
    etc.
     
    //appel dynamique de la fonction
    $fonction = $_GET["object_id"];
    $r = $fonction();
    //remplissage du flux XML avec les retours
    while ($d = mysql_fetch_row($r))
    {
       $keyword = $dom->create_element('option');
       $keyword = $message->append_child($keyword);
       $keyword->set_attribute('value', $d[0]);
       $keyword->set_attribute('label', $d[1]);
    }
    //renvoie du flux XML vers la fonction chez le client
    echo $dom->dump_mem(true);
    Voilà ben si çà peut servir, j'ai taché grâce à AJAX de faire un modèle le plus portable possible c'est à dire qui puissent marcher pour autant de select qu'on veut en utilisant 2 paramètres :
    -l'id du select afin de le manipuler mais qui en plus sert à identifier la bonne fonction PHP.
    -une valeur exploitable au niveau de la requete SQL (valeur selectionnée etc.)

    Il suffit de greffer à chaque fois une fonction php portant comme nom l'id du select à laquelle elle est dédiée.

    Je pensais juste pouvoir simplifier en patatant dans le innerHTML de n'importe qu'elle objet une chaine htlml que me retournerait la procedure distante.
    J'aurais pu partager ma fonction javascript pour des objets autres que les SELECT mais ne faisons pas la fine bouche(d'ailleurs en rusant un peu ...).

    Partout dans une appli ou j'ai besoin de d'updater un SELECT via une requete au serveur une seule façon de faire :

    update_content(id_du_select_a_updater, valeur_a_recuperer)

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

Discussions similaires

  1. [AC-2010] Problème avec les zones de liste déroulante multi critères
    Par mumen dans le forum Contribuez
    Réponses: 0
    Dernier message: 10/05/2013, 11h19
  2. Réponses: 0
    Dernier message: 09/03/2009, 19h01
  3. [MySQL] IF avec des listes déroulantes
    Par HekThor dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 14/11/2008, 09h54
  4. Problème avec des listes déroulantes liées
    Par guitsch dans le forum GTK+ avec C & C++
    Réponses: 9
    Dernier message: 22/10/2008, 16h07
  5. Réponses: 1
    Dernier message: 19/01/2006, 17h54

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