动态依赖的下拉菜单根据前一个下拉菜单的选择来限制用户的选择。
在本教程中,我展示了如何使用JavaScript和PHP用MySQL数据库数据自动填充下拉。

内容
1.表 的结构
在这个例子中,我使用了3个表 -
国家表(存储国家的记录)
CREATE TABLE countries (
id serial PRIMARY KEY,
name varchar(80) NOT NULL
)
状态表(存储国家的状态) - 城市表(存储国家的城市
CREATE TABLE states (
id serial PRIMARY KEY,
name varchar(80) NOT NULL,
country_id bigint NOT NULL
)
城市表(存储各州的城市)。
CREATE TABLE cities (
id serial PRIMARY KEY,
name varchar(80) NOT NULL,
state_id bigint NOT NULL
)
2.配 置
创建一个新的config.php 文件。
完成的代码
<?php
$host = "localhost"; /* Host name */$user = "root"; /* User */$password = "root"; /* Password */$dbname = "tutorial"; /* Database name */
// Create connection
$con = new mysqli($host, $user, $password, $dbname);
// Check connection
if ($con->connect_error) {
die("Connection failed: " . $con->connect_error);
}
3.H TML
从countries 表中获取所有记录并创建3个<select> 元素:
- 第一个
<select >元素是用来显示获取的countries - 第二个元素是使用JavaScript AJAX来显示基于国家选择的州,和
- 第三个元素是使用JavaScript AJAX来显示基于状态选择的城市
完成的代码
<?php
include "config.php";
// Fetch countries
$sql = "SELECT * from countries order by name";
$stmt = $con->prepare($sql);
$stmt->execute();
$result = $stmt->get_result();
?>
<table>
<tr>
<td>Country</td>
<td>
<select id="country" onchange="getStates(this.value);">
<option value="0" >– Select Country –</option>
<?php
while ($row = $result->fetch_assoc() ){
$id = $row['id'];
$name = $row['name'];
echo "<option value='".$id."' >".$name."</option>";
}
?>
</select>
</td>
</tr>
<tr>
<td>State</td>
<td>
<select id="state" onchange="getCities(this.value);" >
<option value="0" >– Select State –</option>
</select>
</td>
</tr>
<tr>
<td>City</td>
<td>
<select id="city" >
<option value="0" >– Select City –</option>
</select>
</td>
</tr>
</table>
4.P HP
创建ajaxfile.php 文件。
处理2个AJAX请求 -
- 如果 country_id
的值从states表中获取记录并分配给result上循环,用id和name键初始化$data` 数组。
以JSON格式返回$data 。
- 如果 state_id
的值从cities表中获取记录并分配给result上循环,用id和name的键初始化$data` 数组。
以JSON格式返回$data 。
完成的代码
<?php
include 'config.php';
// Read POST data
$postData = json_decode(file_get_contents("php://input"));
$request = "";
if(isset($postData->request)){
$request = $postData->request;
}
// Get states
if($request == 'getStates'){
$country_id = 0;
$result = array();$data = array();
if(isset($postData->country_id)){
$country_id = $postData->country_id;
$sql = "SELECT * from states WHERE country_id=?";
$stmt = $con->prepare($sql);
$stmt->bind_param("i", $country_id);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()){
$id = $row['id'];
$name = $row['name'];
$data[] = array(
"id" => $id,
"name" => $name
);
}
}
echo json_encode($data);
die;
}
// Get cities
if($request == 'getCities'){
$state_id = 0;
$result = array();$data = array();
if(isset($postData->state_id)){
$state_id = $postData->state_id;
$sql = "SELECT * from cities WHERE state_id=?";
$stmt = $con->prepare($sql);
$stmt->bind_param("i", $state_id);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()){
$id = $row['id'];
$name = $row['name'];
$data[] = array(
"id" => $id,
"name" => $name
);
}
}
echo json_encode($data);
die;
}
5.J avascript
创建2个函数 -
- getStates() -当国家下拉菜单上的选择被改变时,该函数被调用。
清空州和城市下拉菜单。发送AJAX POST请求到ajaxfile.php ,将{request: 'getStates', country_id: country_id} 作为data ,并设置dataType: 'json' 。
在成功回调后,循环调用response ,并在状态下拉菜单中添加<option > 。
- getCities() -当状态下拉菜单上的选择被改变时,该函数被调用。
清空#city 下拉菜单并向ajaxfile.php 发送AJAX POST请求,将{request: 'getCities', state_id: state_id} 作为data ,并设置dataType: 'json' 。
在成功回调后,在response 上循环,并在城市下拉菜单中添加<option > 。
完成代码
function getStates(country_id){
// Empty the dropdown
var stateel = document.getElementById('state');
var cityel = document.getElementById('city');
stateel.innerHTML = "";
cityel.innerHTML = "";
var stateopt = document.createElement('option');
stateopt.value = 0;
stateopt.innerHTML = '-- Select State --';
stateel.appendChild(stateopt);
var cityopt = document.createElement('option');
cityopt.value = 0;
cityopt.innerHTML = '-- Select City --';
cityel.appendChild(cityopt);
// AJAX request
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "ajaxfile.php", true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Response
var response = JSON.parse(this.responseText);
var len = 0;
if(response != null){
len = response.length;
}
if(len > 0){
// Read data and create <option >
for(var i=0; i<len; i++){
var id = response[i].id;
var name = response[i].name;
// Add option to state dropdown
var opt = document.createElement('option');
opt.value = id;
opt.innerHTML = name;
stateel.appendChild(opt);
}
}
}
};
var data = {request:'getStates',country_id: country_id};
xhttp.send(JSON.stringify(data));
}
function getCities(state_id){
// Empty the dropdown
var cityel = document.getElementById('city');
cityel.innerHTML = "";
var cityopt = document.createElement('option');
cityopt.value = 0;
cityopt.innerHTML = '-- Select City --';
cityel.appendChild(cityopt);
// AJAX request
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "ajaxfile.php", true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Response
var response = JSON.parse(this.responseText);
var len = 0;
if(response != null){
len = response.length;
}
if(len > 0){
// Read data and create <option >
for(var i=0; i<len; i++){
var id = response[i].id;
var name = response[i].name;
// Add option to city dropdown
var opt = document.createElement('option');
opt.value = id;
opt.innerHTML = name;
cityel.appendChild(opt);
}
}
}
};
var data = {request:'getCities',state_id: state_id};
xhttp.send(JSON.stringify(data));
}
6.演 示
7.总 结
按照同样的步骤来自动填充多个下拉菜单。
如果当你选择一个国家或一个州时,数据没有在下拉菜单中弹出,那么请使用浏览器的网络标签来调试。再次检查SQL查询和POST值。