Crear lista desplegable dinámica

Estoy buscando en Internet por bastante tiempo para encontrar una solución adecuada pero hasta ahora no he tenido éxito.

Lo que trato de lograr: creo un cuadro desplegable dynamic con provincias. Tan pronto como el usuario seleccione una de las entradas dinámicas creadas, un segundo cuadro desplegable dynamic para distritos solo debe mostrar las entradas correctas dependiendo de la provincia seleccionada.

Por lo tanto, he comstackdo el siguiente código:

search.php

//$i is running up to the max amount of provinces //for each province there shall be one option in the html select //the session array provinceresults contains key1, key2, province (english), province (other language) for($i=0; $i < $countProvinces; $i++) { echo "".$_SESSION['provincesresults'][$i][1].""; } 

En la parte del cuerpo de search.php tengo el siguiente código JavaScript que se ejecutará cuando seleccione una de las opciones generadas anteriormente por onClick:

   function removeUnselected($key){ document.getElementById(\"php_code\").innerHTML=\" \"; } 

Entonces necesito sacar el contador $ i de la primera parte de PHP en la función Javascript. Después de eso necesito los $ distritos llenos seleccionados para su uso posterior en mi search.php

La función php removeUnselected (“. $ _ SESSION [‘provincesresults’] [$ key] [0].”); se ve así y está incluido en search.php:

 <?php /** *This php file is used to retrieve the districts for a selected province. *This file is called by search.php. *As input, the function needs to be called with the ID of the selected province, it will return all related districts. */ function removeUnselected($provinceKey) { //Build the array which returns the needed districts $districtsSelected = array(); //Loop through all the districts that have been read out of the database by get_value_help.php for($i = 0; $i  

¡Cualquier sugerencia sobre cómo puedo construir esto de una manera trabajadora es muy apreciada!

Gracias y saludos,

codac

EDITAR: Estoy usando el siguiente JavaScript: http://www.mattkruse.com/javascript/dynamicoptionlist/index.html

Ahora tengo dos problemas: como hay 24 provincias, 86 distritos, 1600 comunas y 13500 aldeas, la creación de cuadros desplegables demora varios segundos.

Las tablas se ven así (Provincias):

 country_id province_id province_en province_kh 000000 010000 Banteay Mean Chey Khmer 1 000000 020000 Bat Dambang Khmer 2 000000 030000 Kampong Cham Khmer 3 000000 040000 Kampong Chhnang Khmer 

(distritos) province_id district_id district_en district_kh 010000 010200 Mongkol Borei Khmer 1 010000 010300 Phnum Srok Khmer 2 010000 010400 Preah Netr Preah Khmer 3 010000 010500 Ou Chrov Khmer 4

… lo mismo para comunas y aldeas.

Obtengo los valores de Microsoft SQL Server a través de:

  $sqlProvinces = "SELECT country_id, province_id, province_en, province_kh FROM dbo.vhp"; $sqlDistricts = "SELECT province_id, district_id, district_en, district_kh FROM dbo.vhd"; 

… lo mismo para comunas y aldeas.

Como mencioné en mi comentario, guardo estos valores en $ _SESSION:

 $_SESSION["provincesresults"]=$provincesResults; $_SESSION["districtsresults"]=$districtsResults; 

Después de eso, uso la función “dyndrpdwn.php” para generar la lista desplegable:

 <?php function dyndrpdwn() { //count the number of provinces, districts, communes and villages for the counters of the for-statements $countProvinces = count($_SESSION["provincesresults"]); $countDistricts = count($_SESSION["districtsresults"]); $countCommunes = count($_SESSION["communesresults"]); $countVillages = count($_SESSION["villagesresults"]); //NULL the return values $returnPD = NULL; $returnC = NULL; $returnV = NULL; $defaultP = NULL; $defaultD = NULL; $defaultC = NULL; $defaultV = NULL; //Set start value for the counters to 0 $j = 0; $k = 0; $l = 0; //Start the JavaScript and create the DynamitOptionList $returnPD = " var makeGeo = new DynamicOptionList(\"provinces\",\"districts\",\"communes\",\"villages\");"; //Loop through all Provinces for($i = 0; $i < $countProvinces; $i++) { //Create the optionlist for provinces $returnPD = $returnPD."makeGeo.forValue(\"".$_SESSION["provincesresults"][$i][1]."\").addOptionsTextValue("; //Create the optionlist for districts ("while" if more performant than "for"!) and make sure that counter is not getting out of index while($j < $countDistricts && $_SESSION["provincesresults"][$i][1] == $_SESSION["districtsresults"][$j][0]) { $returnPD = $returnPD."\"".$_SESSION["districtsresults"][$j][2]."\",\"".$_SESSION["districtsresults"][$j][1]."\","; $returnC = $returnC."makeGeo.forValue(\"".$_SESSION["provincesresults"][$i][1]."\").forValue(\"".$_SESSION["districtsresults"][$j][1]."\").addOptionsTextValue("; //Create the optionlist for communes ("while" if more performant than "for"!) and make sure that counter is not getting out of index while($k < $countCommunes && $_SESSION["districtsresults"][$j][1] == $_SESSION["communesresults"][$k][0]) { $returnC = $returnC."\"".$_SESSION["communesresults"][$k][2]."\",\"".$_SESSION["communesresults"][$k][1]."\","; $returnV = $returnV."makeGeo.forValue(\"".$_SESSION["provincesresults"][$i][1]."\").forValue(\"".$_SESSION["districtsresults"][$j][1]."\").forValue(\"".$_SESSION["communesresults"][$k][1]."\").addOptionsTextValue("; //Create the optionlist for villages ("while" if more performant than "for"!) and make sure that counter is not getting out of index while($l < $countVillages && $_SESSION["communesresults"][$k][1] == $_SESSION["villagesresults"][$l][0]) { $returnV = $returnV."\"".$_SESSION["villagesresults"][$l][2]."\",\"".$_SESSION["villagesresults"][$l][1]."\","; //Set the Default Value $defaultV = "makeGeo.forValue(\"".$_SESSION["communesresults"][$k][1]."\").setDefaultOptions(\"".$_SESSION["searchresultspmd"][0][8]."\");"; //Increase the counter by 1 $l++; } //Cut the last "," of the string after the last value of $returnC $returnV = substr($returnV, 0, -1); //Close the JavaScript statement $returnV = $returnV.");"; //If there is no village for the commune, remove the already prepared string "makeGeo.forValue(\"".$_SESSION["provincesresults"][$i][1]."\").forValue(\"".$_SESSION["districtsresults"][$j][1]."\").forValue(\"".$_SESSION["communesresults"][$k][1]."\").addOptionsTextValue(" if(substr($returnV,-21) == "addOptionsTextValue);") { $returnV = substr($returnV, 0, -86); } //Set the Default Value $defaultC = "makeGeo.forValue(\"".$_SESSION["districtsresults"][$j][1]."\").setDefaultOptions(\"".$_SESSION["searchresultspmd"][0][7]."\");"; //Increase the counter by 1 $k++; } //Cut the last "," of the string after the last value of $returnC $returnC = substr($returnC, 0, -1); //Close the JavaScript statement $returnC = $returnC.");"; //If there is no commune for the district, remove the already prepared string "makeGeo.forValue(\"".$_SESSION["provincesresults"][$i][1]."\").forValue(\"".$_SESSION["districtsresults"][$j][1]."\").addOptionsTextValue(" if(substr($returnC,-21) == "addOptionsTextValue);") { $returnC = substr($returnC, 0, -66); } //Set the Default Value $defaultD = "makeGeo.forValue(\"".$_SESSION["provincesresults"][$i][1]."\").setDefaultOptions(\"".$_SESSION["searchresultspmd"][0][8]."\");"; //Increase the counter by 1 $j++; } //Cut the last "," of the string after the last value of $returnPD $returnPD = substr($returnPD, 0, -1); //Close the JavaScript statement $returnPD = $returnPD.");"; //If there is no district for the province, remove the already prepared string "makeGeo.forValue(\"".$_SESSION["provincesresults"][$i][1]."\").addOptionsTextValue(" if(substr($returnPD,-21) == "addOptionsTextValue);") { $returnPD = substr($returnPD, 0, -47); } //Set the Default Value $defaultP = "makeGeo.forValue(\"provinces\").setDefaultOptions(\"".$_SESSION["provincesresults"][$i][1]."\");"; } //Put Provinces, Districts, Communes and Villages together and close the Javascript $returnPDCV = $returnPD.$returnC.$returnV.$defaultD.$defaultC.$defaultV.""; //Return the result return sprintf($returnPDCV); } ?> 

Para usar JavaScript, uso el siguiente código en patient_update.php:

 //include the dynamic drop down generator include("/functions/dyndrpdwn.php");   //Call the dynamic drop down function echo dyndrpdwn(); echo" "; //Fill the drop down, when data is received by get_value_help.php or if session array is already filled if(isset($_GET["value"]) == "true" && $_GET["value"] == "receive" || isset($_SESSION["provincesresults"]) == "true" && count($_SESSION["provincesresults"]) > 0) { //Get all the values out of the Province array out of pdo.vhd 

$ countProvinces = count ($ _ SESSION [“provincesresults”]);

  for($i=0; $i < $countProvinces; $i++) { //Display the Khmer or the English language depending on the website settings. $_SESSION["searchresultspmd"][0][5]) = province_id in dbo.pmd //$_SESSION["provincesresults"][$i][1] = province_id in dbo.vhp if(isset($_SESSION["lng"]) == "true") { switch ($_SESSION["lng"]) { case "english": if($_SESSION["provincesresults"][$i][2] == $_SESSION["searchresultspmd"][0][5]) { echo""; } else { echo""; } echo"".$_SESSION["provincesresults"][$i][2]." "; break; case "khmer": if($_SESSION["provincesresults"][$i][2] == $_SESSION["searchresultspmd"][0][5]) { echo""; } else { echo""; } echo"".$_SESSION["provincesresults"][$i][3]." "; break; } } } } echo"       makeGeo.printOptions(\"districts\")        makeGeo.printOptions(\"communes\")        makeGeo.printOptions(\"villages\")    

Entonces hay dos preguntas ahora:

  1. Llamar a la función dyndrpdwn.php toma bastantes segundos, ya que hay ~ 24 provincias, ~ 86 distritos, ~ 1600 comunas y ~ 13500 aldeas y las recorro. ¿Hay alguna manera de mejorar el rendimiento?
  2. Con setDefaultOptions bash establecer el valor predeterminado para la lista desplegable correcta. Pero en mi código no funciona. Lo comparé con los ejemplos en [el sitio web de JavaScript] [1] pero no pude encontrar el error … ¿Puedes ver por qué no funciona de la manera en que lo hago?

El resultado se ve así actualmente:

  var makeGeo = new DynamicOptionList("provinces","districts","communes","villages"); 

Esto crea las entradas para provincias y distritos:

 makeGeo.forValue("010000").addOptionsTextValue("Mongkol Borei","010200","Phnum Srok","010300","Preah Netr Preah","010400","Ou Chrov","010500","Serei Saophoan","010600","Thma Puok","010700","Svay Chek","010800","Malai","010900"); 

Esto crea las entradas para las comunas

 makeGeo.forValue("010000").forValue("010200").addOptionsTextValue("Banteay Neang","010201","Bat Trang","010202","Chamnaom","010203","Kouk Ballangk","010204","Koy Maeng","010205","Ou Prasat","010206","Phnum Touch","010207","Rohat Tuek","010208","Ruessei Kraok","010209","Sambuor","010210","Soea","010211","Srah Reang","010212","Ta Lam","010213"); 

Esto crea las entradas para los pueblos:

 makeGeo.forValue("010000").forValue("010200").forValue("010201").addOptionsTextValue("Ou Thum","01020101","Phnum","01020102","Banteay Neang","01020103","Kouk Pnov","01020104","Trang","01020105","Pongro","01020106","Kouk Tonloab","01020107","Trabaek","01020108","Khile","01020109","Samraong Pen","01020110","Dang Run Lech","01020111","Dang Run Kaeut","01020112","Ou Snguot","01020113","Prey Changha Lech","01020114","Prey Changha Kaeut","01020115","Ou Andoung Lech","01020116","Ou Andoung Kandal","01020117","Ou Andoung Kaeut","01020118","Kouk Kduoch","01020119"); 

Y esto debería establecer el valor predeterminado para la provincia, el distrito y la comuna (solo 3 ejemplos; no funcionan hasta el momento …):

 makeGeo.forValue("240000").setDefaultOptions("Boeng Trakuon"); makeGeo.forValue("240200").setDefaultOptions("Ou Andoung"); makeGeo.forValue("240204").setDefaultOptions("Boeng Trakuon");   Banteay Mean Chey Bat Dambang Kampong Cham Kampong Chhnang Kampong Spueu Kampong Thum Kampot Kandal Kaoh Kong Kracheh Mondol Kiri Phnom Penh Preah Vihear Prey Veaeng Pousat Rotanak Kiri Siem Reab Krong Preah Sihanouk Stueng Traeng Svay Rieng Takaev Otdar Mean Chey Krong Kaeb Krong Pailin       makeGeo.printOptions("districts")        makeGeo.printOptions("communes")        makeGeo.printOptions("villages")    

Sé que es un montón de cosas que hay que revisar, lo siento por eso. ¡Toda ayuda es muy apreciada!

Lamentablemente, el enfoque que describe anteriormente no funcionará. Cuando utiliza php dentro de un segmento de JavaScript, debe recordar que el código php se evaluará cuando el archivo que contiene el javascript se solicite solo desde el servidor. Cualquier cosa que el código PHP haya emitido durante la solicitud (por ejemplo, a través de un comando ‘echo’) se convertirá en parte de su función javascript. En el caso anterior, no ha .innerHTML=\" \"; nada, por lo que su código de JavaScript esencialmente leerá .innerHTML=\" \"; una vez que la página se carga. Incluso si hiciera salir datos allí, no sería dynamic.

Como yo lo veo, tienes 3 opciones:

  1. Use AJAX para cargar el HTML para el segundo menú desplegable de un archivo php. Este es definitivamente el camino a seguir si ya está familiarizado con AJAX, pero podría ser un poco complicado de lo contrario. Si no está familiarizado, definitivamente recomendaría revisar algunos tutoriales antes de intentar implementar esta opción.

  2. Vuelva a cargar la página cuando el usuario cambie el primer menú desplegable y use un parámetro de cadena de consulta para indicar a su script PHP qué provincia ha sido seleccionada. Probablemente esta no sea una opción muy buena, especialmente si este par de menús desplegables forma parte de una forma más grande en la que el usuario podría haber ingresado algunos datos.

  3. Haga que su salida de PHP sea el HTML del primer menú desplegable, y luego un menú desplegable por separado para cada provincia que enumere sus respectivos distritos. (Entonces, si tiene 10 provincias, crearía 11 desplegables totales.) Luego, usaría la display: none; estilo CSS display: none; para ocultar los menús desplegables secundarios y usar javascript para alternar su estilo para display: inline-block; . Esta opción no es ideal para un gran número de opciones, ya que está cargando toneladas de datos potencialmente innecesarios.

Por curiosidad, ¿por qué está almacenando los datos de la provincia en la variable $_SESSION del usuario? Por lo general, trato de reservar eso para datos específicos del usuario o información relacionada con el estado de la interfaz.