动态填充下拉菜单

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 为您旅程的各个阶段提供云产品。立即开始使用 $200 免费赠送额度!

您有一个下拉菜单,根据用户在该菜单中的选择,第二个下拉菜单将填充相应的选项。我们将介绍三种不同的方法。

查看演示   下载文件

标记

在我们的示例中,标记始终相同,只有两个简单的选择元素。第一个有三个选项。第一个只是通知用户选择一个选项,接下来的两个是实际的选择。第二个选择只有一个选项,告诉用户请先从第一个下拉菜单中选择。第二个下拉菜单中的选项将被动态替换。

<select id="first-choice">
  <option selected value="base">Please Select</option>
  <option value="beverages">Beverages</option>
  <option value="snacks">Snacks</option>
</select>

<br>

<select id="second-choice">
  <option>Please choose from above</option>
</select>

选项 1:使用文本文件

这篇文章的灵感来自 Robert Young,他写信给我分享了这种技术。这种方法易于使用和理解。并非每个人都希望处理数据库等问题。

为每种可能性准备一个文本文件

在这些文本文件中,准备好用于新选项的替换 HTML

<option>Coffee</option>
<option>Coke</option>

现在,我们将使用 jQuery 来监控第一个选择的更改。所有示例都将使用 jQuery。

$("#first-choice").change(function() {
   $("#second-choice").load("textdata/" + $(this).val() + ".txt");
});

这种方法效果很好,确实很容易实现。潜在的缺点是 1) 以这种方式将数据存储在 HTML 标签中可能不是最佳选择,难以将数据重新用于其他目的。2) 可扩展性不强,需要为每种可能性创建新的文本文件。

选项 2:使用 JSON 数据

另一种方法是将所需的数据存储在 JSON 格式中。您可以将其直接放在正在加载的 JavaScript 中,也可以将其保存在外部文件中。对于此演示,我们将使用一个名为 data.json 的外部文件。以下是其内容

{
  "beverages": "Coffee,Coke",
  "snacks": "Chips,Cookies"
}

我们再次监控第一个选择值的更改,然后加载 JSON 并找出我们需要哪些部分

$("#first-choice").change(function() {

	var $dropdown = $(this);

	$.getJSON("jsondata/data.json", function(data) {
	
		var key = $dropdown.val();
		var vals = [];
							
		switch(key) {
			case 'beverages':
				vals = data.beverages.split(",");
				break;
			case 'snacks':
				vals = data.snacks.split(",");
				break;
			case 'base':
				vals = ['Please choose from above'];
		}
		
		var $secondChoice = $("#second-choice");
		$secondChoice.empty();
		$.each(vals, function(index, value) {
			$secondChoice.append("<option>" + value + "</option>");
		});

	});
});

这里的优势是我们以一种相当通用的方式存储数据,因此可以很容易地将其用于其他用途。请注意,我们在 JavaScript 本身中添加了 option 标签,这非常灵活。这种方法的缺点是它稍微复杂一些(但实际上并不难)。我们可能需要考虑将 JSON 拆分成单独的文件,这样我们就不需要在每次更改时加载所有数据,但这样一来,我们又会遇到与文本文件相同可扩展性问题。使用数据库返回 JSON 也是一种选择。

选项 3:使用数据库

我们仍然会使用 jQuery 监控第一个选择,并仍然使用 jQuery 的 .load() 函数动态加载新选项。但是要从数据库中提取数据,我们需要一个可以进行数据库交互的中间伙伴(JavaScript 本身无法做到这一点)。因此,我们将使用一个名为“getter.php”的文件,该文件将返回我们需要的内容。

首先,我们需要一个非常简单的数据库来提取数据

CREATE TABLE `dd_vals` (
  `index` int(11) NOT NULL,
  `category` varchar(255) NOT NULL,
  `dd_val` varchar(255) NOT NULL,
  UNIQUE KEY `index` (`index`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `dd_vals` (`index`, `category`, `dd_val`) VALUES (1, 'snacks', 'Chips'),
(2, 'snacks', 'Cookies'),
(3, 'beverages', 'Coffee'),
(4, 'beverages', 'Coke');

现在,我们可以查询数据库,在“dd_vals”表中查找类别为零食或饮料的条目,并获取我们想要的内容。我们的查询需要类似于以下内容

SELECT * FROM dd_vals WHERE category='beverages'

因此,让我们创建我们的 getter.php 文件,连接到该数据库,并获取类别选择作为 GET 参数,将其插入查询中,并返回它在 option 标签中找到的内容。

<?php

	$username = "username";
	$password = "password";
	$hostname = "localhost";
	
	$dbhandle = mysql_connect($hostname, $username, $password) or die("Unable to connect to MySQL");
	$selected = mysql_select_db("dropdownvalues", $dbhandle) or die("Could not select examples");
	$choice = mysql_real_escape_string($_GET['choice']);
	
	$query = "SELECT * FROM dd_vals WHERE category='$choice'";
	
	$result = mysql_query($query);
		
	while ($row = mysql_fetch_array($result)) {
   		echo "<option>" . $row{'dd_val'} . "</option>";
	}
?>
Keith Silgard 写信帮助我确保代码的安全性。无论何时您使用通过 POST 或 GET 收到的数据运行数据库命令,都需要确保数据安全。也就是说,它不包含像“; DROP TABLE …” 这样的恶意代码,这通常被称为 SQL 注入。此代码已更新,使用 mysql_real_escape_string 来确保不会发生这种情况。另请注意,此函数仅在建立数据库连接之后使用才能正常工作。

现在我们的 JavaScript 非常简单,我们再次监控第一个下拉菜单的更改,并将 getter.php 文件加载到第二个下拉菜单中。这里的花招是将第一个下拉菜单的值作为 URL 参数传递给 getter.php 文件。

$("#first-choice").change(function() {
  $("#second-choice").load("getter.php?choice=" + $("#first-choice").val());
});

对于非常小的网站和孤立的示例,数据库可能感觉工作量很大甚至过头了,但这无疑是最灵活的选择。代码干净,速度快,数据以一种我们可以做任何事情的方式存储等等。

不只是这些?

就像 Web 上的任何东西一样,还有更多方法可以解决这个问题。我们可以将值存储在关联数组中。我们可以使用 MongoDB。我们可以将不同的选择元素准备好放在 HTML 中,并根据需要使用 JavaScript 显示和隐藏它们。每种方法都有其优点和缺点。

查看演示   下载文件

注意:我没有将数据库示例包含在下载文件中,因为在您拥有自己的数据库可以连接到并进行所有操作之前,它将无法运行。这样会更简洁明了。