php - 创建动态下拉列表

标签 php javascript html dynamic drop-down-menu

我现在在互联网上搜索了很长一段时间来寻找合适的解决方案,但到目前为止我还没有成功。

我试图实现的目标:我创建一个包含省份的动态下拉框。一旦用户选择了动态创建的条目之一,地区的第二个动态下拉框就应该仅根据所选省份显示正确的条目。

因此我构建了以下代码:

搜索.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 "<option value=".$_SESSION['provincesresults'][$i][0]." onClick=\"removeSelected(\".$i.\")\">".$_SESSION['provincesresults'][$i][1]."</option>";
}

在 search.php 的正文部分中,我有以下 JavaScript 代码,当我为每个 onClick 选择上述生成的选项之一时,该代码将被执行:

<!--Javascript which is needed to call the dynamic_drop_down.php function per onClick event-->
<script type=\"text/javascript\"> 
  function removeUnselected($key){
      document.getElementById(\"php_code\").innerHTML=\"
        <?php  

           //Get all the values out of the district array out of pdo.vhd
           $districtsSelected = removeUnselected(".$_SESSION['provincesresults'][$key][0].");
           }
       ?>\"; 
  } 

所以我需要将 $i 计数器从第一个 PHP 部分取出到 Javascript 函数中。 之后,我需要填充 $districtsSelected 以便在我的 search.php 中进一步使用

php函数removeUnselected(".$_SESSION['provincesresults'][$key][0].");看起来像这样并包含在 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 < count($_SESSION['districtsresults']); $i++) {

      //Check if the province id out of the table dbo.vhp matches with the id out of the table dbo.vhd
      if(strcmp($provinceKey, $_SESSION['districtsresults'][$i][1]) == 0) {

         //Give back the district names in english if the language settings are english
         if($_SESSION['lng'] == "english") {

            //Remove any districts that were not selected
            $districtsSelected[] = $_SESSION['districtsresults'][$i][2];
         }
          //Give back the district names in khmer if the language settings are khmer
         elseif ($_SESSION['lng'] == "khmer") {

            //Remove any districts that were not selected
            $districtsSelected[] = $_SESSION['districtsresults'][$i][3];
         }
      }
   }

   //Return the result
   return($districtsSelected);
}
?>

任何有关我如何以工作方式构建此项目的建议都将受到高度赞赏!

谢谢您并致以问候,

科达克

编辑: 我正在使用以下 JavaScript: http://www.mattkruse.com/javascript/dynamicoptionlist/index.html

我现在有两个问题: 由于有24个省、86个区、1600个公社和13500个村庄,创建下拉框需要几秒钟的时间。

表格如下(省份):

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 

(地区) Province_id District_id District_en District_kh 010000 010200 Mongkol Borei 高棉语 1 010000 010300 Phnum Srok 高棉 2 010000 010400 圣剑高棉 3 010000 010500 欧 Chrov 高棉语 4

...公社和村庄也是如此。

我通过以下方式从 Microsoft SQL Server 获取值:

 $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";

...公社和村庄也是如此。

就像我的评论中提到的,我将这些值存储在 $_SESSION 中:

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

之后我使用函数“dyndrpdwn.php”生成下拉列表:

<?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 = "<script type=\"text/javascript\">
                   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."</script>";

   //Return the result
   return sprintf($returnPDCV);
}
?>

为了使用 JavaScript,我在 Patient_update.php 中使用以下代码:

//include the dynamic drop down generator
include("/functions/dyndrpdwn.php");

<!--Adding JavaScript for dynamic dropdown list-->
<script type=\"text/javascript\" src=\"/js/dynamicoptionlist.js\"></script>

//Call the dynamic drop down function
echo dyndrpdwn();

echo"<!--Province Create Drop-Down Field-->
     <select name=\"provinces\" class =\"dropdown\">";

//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"<option value=".$_SESSION["provincesresults"][$i][1]." SELECTED>";
               }
               else {

                  echo"<option value=".$_SESSION["provincesresults"][$i][1].">";
               }

               echo"".$_SESSION["provincesresults"][$i][2]."
                  </option>";
               break;

            case "khmer":

               if($_SESSION["provincesresults"][$i][2] == $_SESSION["searchresultspmd"][0][5]) {

                  echo"<option value=".$_SESSION["provincesresults"][$i][1]." SELECTED>";
               }
               else {

                  echo"<option value=".$_SESSION["provincesresults"][$i][1].">";
               }

               echo"".$_SESSION["provincesresults"][$i][3]."
                  </option>";
               break;
         }
      }
   }
}

echo"          </select>
            </td>
            <td>

               <!--District Create Drop-Down Field-->
               <select name=\"districts\" class =\"dropdown\">
                  <script type=\"text/javascript\">
                     makeGeo.printOptions(\"districts\")
                  </script>
               </select>
            </td>
            <td>

               <!--Commune Create Drop-Down Field-->
               <select name=\"communes\" class =\"dropdown\">
                  <script type=\"text/javascript\">
                     makeGeo.printOptions(\"communes\")
                  </script>
               </select>
            </td>
            <td>

               <!--Village Create Drop-Down Field-->
               <select name=\"villages\" class =\"dropdown\">
                  <script type=\"text/javascript\">
                     makeGeo.printOptions(\"villages\")
                  </script>
               </select> 
            </td>

...

现在有两个问题:

  1. 调用 dyndrpdwn.php 函数需要相当长的时间,因为有 ~24 个省、~86 个区、~1600 个公社和 ~13500 个村庄,我循环遍历它们。有什么办法可以提高性能吗?
  2. 使用setDefaultOptions,我尝试为正确的下拉列表设置默认值。但在我的代码中它不起作用。我已将其与 [JavaScript 网站][1] 上的示例进行了比较,但我找不到错误...您能明白为什么它不能按照我的方式工作吗?

结果目前看起来是这样的:

<script type="text/javascript">
var makeGeo = new DynamicOptionList("provinces","districts","communes","villages");

这将创建省份和地区的条目:

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");

这会创建公社的条目

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");

这会创建村庄的条目:

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");

这应该设置省、区和公社的默认值(只有 3 个例子;到目前为止它们还不起作用......):

makeGeo.forValue("240000").setDefaultOptions("Boeng Trakuon");
makeGeo.forValue("240200").setDefaultOptions("Ou Andoung");
makeGeo.forValue("240204").setDefaultOptions("Boeng Trakuon");</script>

<!--Province Create Drop-Down Field-->
<select name="provinces" class ="dropdown">
   <option value=010000>Banteay Mean Chey
   </option><option value=020000>Bat Dambang
   </option><option value=030000>Kampong Cham
   </option><option value=040000>Kampong Chhnang
   </option><option value=050000>Kampong Spueu
   </option><option value=060000>Kampong Thum
   </option><option value=070000>Kampot
   </option><option value=080000>Kandal
   </option><option value=090000>Kaoh Kong
   </option><option value=100000>Kracheh
   </option><option value=110000>Mondol Kiri
   </option><option value=120000>Phnom Penh
   </option><option value=130000>Preah Vihear
   </option><option value=140000>Prey Veaeng
   </option><option value=150000>Pousat
   </option><option value=160000>Rotanak Kiri
   </option><option value=170000>Siem Reab
   </option><option value=180000>Krong Preah Sihanouk
   </option><option value=190000>Stueng Traeng
   </option><option value=200000>Svay Rieng
   </option><option value=210000>Takaev
   </option><option value=220000>Otdar Mean Chey
   </option><option value=230000>Krong Kaeb
   </option><option value=240000 SELECTED>Krong Pailin
   </option></select>

   </td>
   <td>

      <!--District Create Drop-Down Field-->
      <select name="districts" class ="dropdown">
         <script type="text/javascript">
            makeGeo.printOptions("districts")
         </script>
      </select>
   </td>
   <td>

      <!--Commune Create Drop-Down Field-->
      <select name="communes" class ="dropdown">
         <script type="text/javascript">
            makeGeo.printOptions("communes")
         </script>
      </select>
   </td>
   <td>

      <!--Village Create Drop-Down Field-->
      <select name="villages" class ="dropdown">
         <script type="text/javascript">
            makeGeo.printOptions("villages")
         </script>
      </select> 
   </td>

我知道有很多东西需要查看,对此表示抱歉,但非常感谢您的每一次帮助!

最佳答案

不幸的是,您上面概述的方法行不通。当您在 javascript 段中使用 php 时,您必须记住,仅当服务器请求包含 javascript 的文件时,才会计算 php 代码。 PHP 代码在请求期间输出的任何内容(例如通过“echo”命令)都将成为 JavaScript 函数的一部分。在上面的例子中,您没有输出任何内容,因此一旦页面加载,您的 javascript 代码实际上将读取 .innerHTML=\"\"; 。即使您确实在那里输出数据,它也不会是动态的。

据我所知,您有 3 个选择:

  1. 使用 AJAX 从 php 文件加载第二个下拉菜单的 HTML。如果您已经熟悉 AJAX,这绝对是可行的方法,但否则可能会有点棘手。如果您不熟悉,我绝对建议您在尝试实现此选项之前先阅读一些教程。

  2. 当用户更改第一个下拉列表时重新加载页面,并使用查询字符串参数告诉 PHP 脚本选择了哪个省份。这可能不是一个很好的选择,特别是如果这对下拉菜单是用户可能已经输入了一些数据的较大表单的一部分。

  3. 让 PHP 输出第一个下拉列表的 HTML,然后为每个省份输出一个单独的下拉列表,列出其各自的地区。 (因此,如果您有 10 个省份,则总共会创建 11 个下拉菜单。)然后您将使用 CSS 样式 display: none; 隐藏辅助下拉菜单,并使用 javascript 将其样式切换为 显示:内联 block ;。此选项对于大量选项来说并不理想,因为您正在加载大量可能不必要的数据。

出于好奇,为什么要将省份数据存储在用户的 $_SESSION 变量中?我通常尝试将其保留给用户特定的数据或与界面状态有关的信息。

关于php - 创建动态下拉列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4825002/

相关文章:

javascript - JQuery $.post 函数在 Firefox 中有效,但在 IE 中无效

javascript - 调用函数会出现引用错误,因为函数未定义

javascript - 如何将对象添加到 jquery 结果对象?

PHP 登录 - 多个 IF 条件不起作用

CSS - Internet Explorer 和 <main> 标签背景

php - 循环 mysql 表并从 api grabs 更新内容

php - 数组映射使用变量来标识要返回的列

javascript - 单击按钮临时更改 div 背景颜色,而不是按预期永久更改

php - 如何使用键查找数组/字典值?

php - Laravel 在保存到数据库之前改变日期?