Javascript - tirer les options d'une bdd

Bonjour,
voila un code qui marche bien.
Comment ajouter des elements d'une bdd dans les <option>?
merci a tous.

var counter = 1;
function addInput()
{
    var nb=document.getElementById('nbr').value;
    for(i=0;i<nb;++i){
          var target 		= document.getElementById('Account_1');
          var newdiv 		= document.createElement('div');
          var newdivname	= 'Div' + counter;
          newdiv.setAttribute('id',newdivname);
          content = newdiv.innerHTML;
          content +="Account number:";
          content +="<input type='text' class='AccountNumber' name='AccountNumber["+i+"]' id='AccountNumber' size='20'>";
          content +='<select type="text" class="AccountCurrency" name="AccountCurrency['+i+']" id="AccountCurrency">';
          content +='<option value="USD">USD<//option>';
          content +='<option value="EUR">EUR<//option>';
          content +='<option value="GBP">GBP<//option>';
          content +='<option value="JPY">JPY<//option>';
          content +='<option value="HKD">HKD<//option>';
          content +='<option value="CHF">CHF<//option>';
          content +='</select>';
          content +='<a id="AccountDelete" href="#" onclick="removeInput(\'' + newdivname + '\');">[Delete]</a>';
          newdiv.innerHTML = content;
          target.appendChild(newdiv);
          counter++;
    }
}

19 réponses

Résumé de la discussion

La question porte sur l'ajout dynamique d'options dans un select à partir d'une base de données lors de la création de champs supplémentaires via JavaScript. Des options peuvent être générées côté client avec une boucle pour éviter de dupliquer le HTML, et la génération des contenus 'option' doit suivre une logique similaire. Si les divs créés nécessitent des options propres à chaque instance, il faut recourir à AJAX pour interroger le serveur et bâtir dynamiquement les options à partir de la base de données. Dans ce cas, le contenu du div est généré côté serveur et renvoyé, ce qui centralise les données et permet d'adapter les options sans modifier le code JavaScript.

Bobot (l’IA à votre service)
  1. deux erreurs de principe xml:

    buffer+= "<racine>";  
    buffer+= "<donnee><![CDATA[";  
    ////la il ne faut pas remettre <racine> 
    //buffer+= "<racine>";  
    //mais fermer la balise </donnee>
    buffer+= "]]></donnee>";
    ///// 
    buffer+= "<donnee><![CDATA[";  
    buffer+= medoc;  
    buffer+= "]]></donnee>";  
    buffer+= "<donnee><![CDATA[";      
    buffer+= "reponse2";  
    buffer+= "]]></donnee>";  
            buffer+= "<donnee><![CDATA[";      
      buffer+= "reponse3";  
     buffer+= "]]></donnee>";  
    
    buffer+="</racine>"; 
    


    items=docXML.getElementsByTagName('donnee');
    //tu viens lire ce qu'il y a entre les balises <donnee></donnee>
    
    1. il faut peut être:

      String medoc=request.getParameter("medoc"); 
      buffer=""; 
      buffer+= " header('Content-Type: text/xml');";
      
      1. je l'ai effacé intentionnellement quand j'ai recopié le code. mais ça passe pas?ya-t-il raison?
    2. qq chose me parait bizarre:

      buffer+="<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
      buffer=buffer+"<racine>";

      la première ligne est écrasée
      ce ne serait pas plutôt:

      //et avec la première ligne le header ou son équivalent en jsp
      
      buffer="header('Content-Type: text/xml'); // cas reponse XML, obligatoire  avec IE ";
      buffer+="<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
              buffer+=buffer+"<racine>"; 
      


      tu peux tester si ton script jsp te renvoie bien qq chose en l'appelant directement depuis ton navigateur.

      Sinon regardes du côté de JSON
      la je ne connais pas trop
      1. j'ai corrigé mais ça donne pas:
        ma jsp (page d'essai), avec l'ajax:
         <%@page import="java.sql.*"%>
         <html>
              <head>  
                  <title>ajax</title>
              <script type="text/javascript">  
               
              
              function showCity(medoc,i){
              
              if (typeof XMLHttpRequest != "undefined"){
                xmlHttp= new XMLHttpRequest();
                }
              else if (window.ActiveXObject){
                xmlHttp= new ActiveXObject("Microsoft.XMLHTTP");
                }
              if (xmlHttp==null){
              alert("Le navigateur supporte pas la Requete XMLHTTP")
              return;
              } 
              var url="city.jsp";
              url +="?medoc=" +medoc+ "&num_med="+i;
              xmlHttp.onreadystatechange = stateChange1;
              xmlHttp.open("GET", url, true);
              xmlHttp.send(null);
              alert("sssssssssssssssss");
              
              }
              function stateChange1(){  
                        if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete"){   
              //document.getElementById("city").innerHTML=xmlHttp.responseText  
              //avec ca, ca marche 
              //}  
        
         
               			var docXML=http_request.responseXML;
        			var items=docXML.getElementsByTagName('racine');
        			var reponse1=items.item(0).firstChild.data;
                                var reponse2=items.item(1).firstChild.data;
                                var reponse3=items.item(2).firstChild.data;
                            document.getElementById("sa1").value=reponse1;
                         document.getElementById("sa2").value=reponse2;
                          document.getElementById("sa3").value=reponse3;
        
         }
              }
              </script>  
              </head>  
              <body>  
              <select name='state' onchange="showCity(this.value,1)">  
               <option value="none">Select</option>  
            <%
        String url = "jdbc:odbc:medic";
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        Connection con;
        con = DriverManager.getConnection(url,"root","root");
        Statement stmt = con.createStatement();  
         ResultSet rs = stmt.executeQuery("Select * from e_dci");
         while(rs.next()){
             %>
              <option value="<%=rs.getString("num_dci")%>"><%=rs.getString("lib_dci")%></option>  
              <%
         }
             %>
              </select>  
              <br> 
                    <input type="text" id="sa" />
                   <input type="text" id="sa1" />
                   <input type="text" id="sa2" />
                   <input type="text" id="sa3" />
               <div id='city'>  
                   
                   <select name="city">
                       <option value="-1">Select</option>
                   </select>
              </div>
              </body> 
              </html>


        et la jsp qui traite l'info:
        <%@page import="java.sql.*"%>
        
        
        <%
        
        String medoc=request.getParameter("medoc");  
        buffer+= " header('Content-Type: text/xml');";
        buffer+= "<?xml version='1.0' encoding='ISO-8859-1'?>;";
        buffer+= "<racine>"; 
        buffer+= "<donnee><![CDATA["; 
        buffer+= "<racine>"; 
        buffer+= "<donnee><![CDATA["; 
        buffer+= medoc; 
        buffer+= "]]></donnee>"; 
        buffer+= "<donnee><![CDATA[";     
        buffer+= "reponse2"; 
        buffer+= "]]></donnee>"; 
                buffer+= "<donnee><![CDATA[";     
          buffer+= "reponse3"; 
         buffer+= "]]></donnee>"; 
        
        buffer+="</racine>";
        response.getWriter().println(buffer);
        
        
         }
         catch(Exception e){
             response.getWriter().println(e);
             //System.out.println(e);
         }
         %>
    3. dans ce cas il faut que le script php ou jsp réponde en XML

      <?php 
      header('Content-Type: text/xml'); // cas reponse XML, obligatoire  avec IE 
      echo "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"; 
      
      ........ 
      
      ///// Reponse XML    
      echo "<racine>"; 
       echo "<donnee><![CDATA["; 
        echo $reponse1; 
       echo "]]></donnee>"; 
       echo "<donnee><![CDATA[";     
        echo $reponse2; 
       echo "]]></donnee>"; 
              echo "<donnee><![CDATA[";     
        echo $reponse3; 
       echo "]]></donnee>"; 
           //etc......
      echo "</racine>"; 
      
      


      et coté Ajax:

      
      //dans fct traitement de la réponse: 
      
      if (http_request.readyState == 4) { 
        if (http_request.status == 200) { 
           // cas avec reponse de PHP en XML 
         var docXML=http_request.responseXML; 
         var items=docXML.getElementsByTagName('donnee'); 
         var reponse1=items.item(0).firstChild.data; 
                              var reponse2=items.item(1).firstChild.data; 
                              var reponse3=items.item(2).firstChild.data; 
      
      //et ensuite tu fais tes document.getElementById(........ 
      

      </code>

      </code>
      1. j'ai essayé mais ça donne rien:y a rien qui s'affiche.
        dans le serveur:
        ...
                buffer+="<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
                buffer=buffer+"<racine>"; 
                Integer ii = 1;
         ResultSet rs = stmt1.executeQuery("Select * from a_dci_ir where num_dci_adi="+medoc+" ");  
           while(rs.next()){
             String valny=rs.getString("num_ir_adi");
                 buffer=buffer+"<donnee><![CDATA["; 
                 buffer=buffer+valny+ ii ;
                 buffer=buffer+"]]></donnee>";
                 ii++; 
           }  
                 buffer=buffer+"</racine>";
         response.getWriter().println(buffer);
        ...
        


        dans la réponse:
              			var docXML=http_request.responseXML;
        			var items=docXML.getElementsByTagName('racine');
        			var reponse1=items.item(0).firstChild.data;
                                var reponse2=items.item(1).firstChild.data;
                                var reponse3=items.item(2).firstChild.data;
                                
                                document.getElementById('sa').value=reponse1;
                                document.getElementById('sa1').value=reponse2;
                                document.getElementById('sa2').value=reponse3;
        
      2. et si on faisait avec JSON?
        j'ai essayé ça dans la fonction qui traite la réponse, ça marche, il reste a apprendre comment l'envoyer a partir du serveur(ResponseText) et le comment le recevoir.
            
           var myFirstJSON = {"firstName": "John", 
                             "lastName": "Doe", 
                             "age": 23}; 
        
        document.getElementById("sa").value= (myFirstJSON.firstName); // Sorties John 
        document.getElementById("sa1").value= (myFirstJSON.lastName); // Sorties Doe 
         document.getElementById("sa2").value=(myFirstJSON.age);
    4. Merci pour l'attention Alain.
      j'ai pas été très clair, je voulais changer plusieurs input,checkbox et autres en même temps. Or,je ne vois qu'une seule XHR.responseText.
      1. Oui bien sur tu peux changer seulement le contenu d'un input par exemple

        //fonction traitement_reponse
        function traitement_reponse(XHR,id_lire,id_ecrire){
        	if(XHR.readyState == 4 ){
        		if(XHR.status == 200) {
        			// cas avec reponse de PHP en mode texte				
        			var reponse=XHR.responseText;				
        			//affichage
        			//document.getElementById(id_ecrire).innerHTML = reponse;
        
        //devient pour un input: (attention cet input type="text" doit avoir id=id_a_ecrire )
        
        				document.getElementById(id_ecrire).value = reponse;
        		}
        	}
        }
        
        


        pour un bouton radio ou case a cocher document.getElementById(id_ecrire).checked = 'checked';

        par contre pour une liste <select, il faut ecrire toute la liste y compris <select name= etc..
        </select>
        1. serait-il possible de modifier le contenu des champs (input ou autres dans un div) plutôt que de changer tout le contenu du <div> avec ajax? c'est cela qui m'aiderai beaucoup et résoudrai mon problème. merci!
          1. voici un petit exemple Ajax avec du php essayes de t'en inspirer et de l'adapter avec du jsp

            fichier page_exemple.html:
            <html>
            <head>
            <script type="text/javascript">
            							/////// fonctions Ajax. ///
            //fonction de base de creation de la request ------------------------------------------
            function getXMLHttpRequest(){
            	var XHR = false;
            		//créer une instance (un objet) de la classe désirée fonctionnant sur plusieurs navigateurs
                    if (window.XMLHttpRequest) { // Mozilla, Safari,...
                        XHR = new XMLHttpRequest();
                        if (XHR.overrideMimeType) {
                            XHR.overrideMimeType('text/xml');//un appel de fonction supplémentaire pour écraser l'en-tête envoyé par le serveur, juste au cas où il ne s'agit pas de text/xml, pour certaines versions de navigateurs Mozilla
                        }
                    } else if (window.ActiveXObject) { // IE
                        try {
                            XHR = new ActiveXObject("Msxml2.XMLHTTP");
                        } catch (e) {
                            try {
                                XHR = new ActiveXObject("Microsoft.XMLHTTP");
                            } catch (e) {}
                        }
                    }
            
                    if (!XHR) {
                        alert('Abandon : Impossible de créer une instance XMLHTTP');
                        return false;
                    }
            	return XHR;  
            }
            /////// --------------------------------------------------------------------------
            function request(url,id_lire,id_ecrire) {
            	//on lit l'element selectionné dans la liste
            	var obj1=document.getElementById(id_lire); 
            	if(obj1.value ==-1){
            		//cas ou selection du titre --choisissez-- on ne fait rien
            		return false;
            	}else{
            		var XHR = getXMLHttpRequest(); //init requette Ajax
            		 
            		XHR.onreadystatechange = function (){traitement_reponse(XHR,id_lire,id_ecrire);} 	
            		XHR.open('POST', url, true);
            		//changer le type MIME de la requête pour envoyer les données avec la méthode POST ,  !!!! cette ligne doit etre absolument apres XHR.open('POST'....
            		XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            		data="choix="+obj1.value;
            		//alert("Data envoyees:  "+data);
            		XHR.send(data);	
            	}
            }
            //fonction traitement_reponse
            function traitement_reponse(XHR,id_lire,id_ecrire){
            	if(XHR.readyState == 4 ){
            		if(XHR.status == 200) {
            			// cas avec reponse de PHP en mode texte				
            			var reponse=XHR.responseText;				
            			//affichage
            			document.getElementById(id_ecrire).innerHTML = reponse;
            				
            		}
            	}
            }
             </script>
            </head>
            <body>
            <div>
            <!-- attention ci dessous dans le onchange le nom du script php appelé par ajax -->
            <select name="liste1" id="liste1" onchange="request('scriptPhpAjax.php','liste1','affichage_reponse');">
            	<option value="-1">---Choisissez--</option>
            	<option value="A">choix A</option>
            	<option value="B">choix B</option>
            	<option value="C">choix C</option>
            </select>
            </div>
            <div id="affichage_reponse"><!-- ici Ajax va ecrire la réponse que le script va faire --></div>
            </body>
            </html>


            et le fichierscriptPhpAjax.php

            <?php
             //script php appelé par Ajax sur le onchange de la liste 
             
            	//recup des valeurs passées en parametres (en POST) 
            	$choix_liste=$_POST['choix'];
            	//avec ça on peut faire une lecture dans BDD etc..
            	//pour l'exemple on va seulement renvoyer ce qu'on a reçu
            	$reponse='Le script php a recu :'.$choix_liste;
            	
            	//envoi réponse à Ajax
            	echo $reponse;
            ?>
            1. merci bcp, ça m'a permis d'apprendre plus vite. jusque la, je sais relier 2 listes en utilisant ajax et jsp, et je suis en train de mettre en oeuvre ces connaissances dans la vraie application
          2. je ne connait pas du tout jsp désolé
            1. c pas grave! merci.
              je vais patienter si d'autres pointent par ici, tout en cherchant bien sur.
          3. tu as mis alert dans ton script jsp ça ne correspond pas au principe de ajax.
            rapidement le principe de Ajax:
            - tu mets ta liste a modifier dans un <div id="id_ecrire">
            <select .....
            </div>
            - sur un événement
            de ta page html, un onchange dans une liste etc;;

            ça appelle une fonction javascript/ajax
            - cette fonction crée la requette Ajax XMLHttpRequest
            - cette fonction appelle "en arrière plan",sans rechargement de la page, le script jsp sur le serveur, en lui passant un ou plusieurs parametres (par exemple le choix fait dans la liste qui a déclenché ajax)
            - le script jsp lit dans la BDD en fct du parametre reçu, generer une liste <select avec les nouvelles lignes option
            - le script par un echo renvoie la réponse à Ajax
            - lorsqu'ajax reçoit cette réponse il va l'écrire dans la page html par un innerHTML dans un div atteint grace à son id="id_ecrire"
            document.getElementByid('id_ecrire').innerHTML=reponse;


            ça écrase l'existant
            1. merci Alain.
              tu parle de mon dernier commentaire la?

              page principale:
              <% @ Taglib uri = "taglib.tld" prefix = "j"%> 
              <j:jscall name="f" url="test.jsp"/> 
              <form name="rrr"> 
              <input name="b1" type="button" value="Test" onClick="f('Tested');"> 
              </ form> 
              


              et dans test.jsp:
              document.rrr.b1.value ='<%= request.getQueryString()%>';

              c'est un tutoriel suivi depuis: je m'en souvient plus,
              et même sans l'alerte: ça marche mais ça donne 'count=1&Tested' au lieu de 'Tested' tout court.
          4. fais une recherche sur le site CCM "listes liees ajax", ça te servira d'exemple

            @lain
            1. thanks!
            2. mon premier tuto ajax:

              page principale:
              <% @ Taglib uri = "taglib.tld" prefix = "j"%> 
              <j:jscall name="f" url="test.jsp"/> 
              <form name="rrr"> 
              <input name="b1" type="button" value="Test" onClick="f('Tested');"> 
              </ form> 


              et dans test.jsp:
              document.rrr.b1.value ='<%= request.getQueryString()%>';
              var r='<%= request.getQueryString()%>';
              alert(r);

              pourquoi ça donne 'count=1&Tested' au lieu de 'Tested' tout court?
          5. mon autre problème c'est qu'a l'appelle de recueill1fo(obj), je dois encore tirer des éléments de la base de données, et, j'aurai donc encore vraiment besoin de détails sur vos réponses(XMLHttpRequest,...) car c'est pas possible du tout de le faire de la même manière que précédemment.

            function recueill1fo(objid){
                // element
            
            var elt = objid;
            
            // id de l'element
            
            var idElt = objid.getAttribute('id');
            
            document.getElementById('Forme['+idElt+']').value = "oueeeeee";
            //ca marche mais c'est pas complet car a la place "oueeeeee" je devrai avoir un enregistrement de ma bdd. plusieurs input sont a compléter par ces enregistrement. 
            }
            1. Merci bcp a vous. La, j'ai réussi a charger mes <option> par copie d'un <select> via ceci:
              function cp(obj){
              var select1 = document.getElementById("listeMED"); 
              var select2 = obj;
              select2.innerHTML = select2.innerHTML+select1.innerHTML; 
              }


              et l'autre fonction:
              function newMED()
              {    
                        var target 		= document.getElementById('Account_1');
                        var newdiv 		= document.createElement('div');
                        var newdivname	= 'Div' + counter;
                        newdiv.setAttribute('id',newdivname);
                        
                        var i= document.getElementById('stok').value; 
                        i=parseInt(i);
                        document.getElementById('stok').value=i+1;
                        content = newdiv.innerHTML;
                        content += "<table cellpadding=\"6\" cellspacing=\"10\" border=\"2\" width=\"1000\"><tr><td>"
                        content +="N*"+i+"<br><br>        NC:";
                        content +='<select type="text" name="NC['+i+']" id="NC['+i+']" onChange="recueill1fo(this);">';
                        content+='<option selected>Faites un choix<//option>';
                        content +='</select>';
                        content+="<br><input type='button' value='ok' id='"+i+"' onclick='recueill1fo(this);' >";
                        content +="</td><td><table><tr><td>       Forme:";
                        content +="</td><td><input type='text' name='Forme["+i+"]' id='Forme["+i+"]' size='20'>";
                        content +="</td></tr><tr><td>       Presentation:";
                        content +="</td><td><input type='text' name='Pres["+i+"]' id='Pres["+i+"]' size='20'>";
                        content +="</td></tr><tr><td>Mode de prise:";
                        content +="</td><td><input type='text' name='Mode["+i+"]' id='Mode["+i+"]' size='20'>";
                        content +="</td></tr><tr><td>Posologie(x g/y kg/y jr):";
                        content +="</td><td><input type='text'  maxlength='4' size='1' name='Masse["+i+"]' id='Masse["+i+"]' size='3'>";
                        content +="<input type='text'  maxlength='3' size='1' name='MasseU["+i+"]' id='MasseU["+i+"]' size='3'>";//Select
                        content +="<input type='text'  maxlength='3' size='1' name='poi["+i+"]' id='poi["+i+"]' size='3'>";
                        content +="<input type='text'  maxlength='3' size='1' name='poiU["+i+"]' id='poiU["+i+"]' size='3'>";//Select
                        content +="<input type='text'  maxlength='4' size='1' name='par["+i+"]' id='par["+i+"]' size='3'>";
                        content +="<input type='text'  maxlength='3' size='1' name='parU["+i+"]' id='parU["+i+"]' size='3'>";//Select
                        content +="</td></tr><tr><td>Pendant:";
                        content +="</td><td><input type='text'  maxlength='3' size='1' name=Pdt["+i+"]' id='Pdt["+i+"]' size='3'>";
                        content +="<input type='text'  maxlength='4' size='1' name=PdtU["+i+"]' id='PdtU["+i+"]' size='3'>";//Select
                        content +="</td></tr></table></td><td>Quantite a delivrer:";
                        content +="<input type='text' name='Quant["+i+"]' id='Quant["+i+"]' size='20'>";
                        content +="</td></tr></table>"
                        //content +='<a id="AccountDelete" href="#" onclick="removeInput(\'' + newdivname + '\');">[Delete]</a>';
                        newdiv.innerHTML = content;
                        target.appendChild(newdiv);
                        counter++;
                        cp(document.getElementById('NC['+i+']')); <----------------------ICI
              }
              


              ca roule! mais c'est pas totalement reglee.
              1. tu pourrais faire un appel grâce à XMLHttpRequest à un script php ou jsp qui te génère ce que tu veux
                1. genre?
              2. Tu n'as pas dit si tu voulais les mêmes options dans tous les <div> de ta page, ou si elles étaient différentes d'un div à l'autre.
                Nous aurions besoin de connaître un peu ce que tu cherches à obtenir.
                1. c vrai, désolée! eh oui, c ça que je voulais.
              3. jsp je ne connait pas ,

                mais en php on peut par une boucle generer les lignes d' <option
                1. en jsp je sais comment générer les <option> par une boucle mais le fait que je dynamise ma page avec javascript me rend la tache difficile
                2. Bonjour

                  Si tu sais générer des <option> par une boucle, je ne vois pas très bien où est le problème. Tu dois aussi bien savoir générer des "content+='<option".
                  Si le problème est que les différents <div> que tu veux créer dans une même page avec ton addInput doivent avoir des options différentes, il faut utiliser AJAX pour interroger le serveur à chaque appel à addInput, en lui fournissant les informations nécessaires pour qu'il puisse interroger la bdd pour déterminer quelles options doivent être incluses. C' est le serveur plutôt que le javascript lui-même qui va générer le contenu de ton <div>
                3. merci pour ta réponse, ça commence a s'éclaircir mais peut-tu me pousser un peu plus? comment pourrai appeler mon code jsp, dans lequel j'inclue le javascript (avec le content+='<option et tout ça), avec un onchange?
              4. une piste:

                var array_elements=document.forms["mon_formulaire"].elements

                contient tous les elements du formulaire

                document.forms["mon_formulaire"].elements.length

                la taille de cet array

                donc par une boucle qui parcours cet array et en filtrant par rapport au <input tu dois pouvoir retrouver le nombre que tu cherches
                1. merci bcp pour ta réponse. et pour l'ajout de données d'une table dans les <option>?
                  ou est-ce que ça serait plus facile de dynamiser avec jsp (le langage original de ma page)?
              5. et entre-autres, comment pourrai-je récupérer le vrai nombre de lignes créées dynamiquement (ceux qui n'ont pas été effacées ), avant de récupérer les données du formulaire ?