“联动地区”通常指的是一个多级联动的下拉菜单,比如选择“省份” -> “城市” -> “区/县”,当选择上一级时,下一级的选项会动态加载,在织梦CMS中,这通常通过自定义表单和JS结合来实现。

下面我将提供两种最主流的实现方法:
-
使用“联动类型”表单(最推荐,最规范)
- 优点:数据与网站内容分离,管理方便,代码整洁,性能好。
- 缺点:设置步骤稍多。
-
使用“文本类型”表单 + JS代码(最灵活,适合已有数据)
- 优点:设置简单,可以快速集成到任何地方。
- 缺点:数据需要手动维护在JS文件中,不适合大量数据。
准备工作:获取地区数据
无论使用哪种方法,你都需要一份标准的地区数据,数据格式通常是 id, parentid, name。

数据示例 (data.txt):
1,0,广东省
2,0,北京市
3,1,广州市
4,1,深圳市
5,3,天河区
6,3,越秀区
7,4,南山区
8,4,福田区
9,2,朝阳区
10,2,海淀区
id: 地区的唯一ID。parentid: 该地区所属的父级地区的ID,顶级地区的parentid为0。name: 地区的名称。
你可以从网上搜索“中国省市县区SQL数据”或“中国省市县区TXT数据”来获取完整的数据。
使用“联动类型”表单(推荐)
这是织梦官方推荐且最规范的做法。
步骤 1:创建数据表
- 登录你的网站数据库管理工具(如 phpMyAdmin)。
- 找到织梦CMS对应的数据库名。
- 执行以下SQL语句,创建一个用于存储地区的数据表,你可以给表起一个有意义的名字,
dede_area。
CREATE TABLE `dede_area` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父级ID', `name` varchar(100) NOT NULL COMMENT '地区名称', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
步骤 2:导入数据
- 将你准备好的
data.txt文件导入到dede_area表中,你可以使用phpMyAdmin的“导入”功能,或者编写一个简单的PHP脚本来解析并插入数据。
步骤 3:在后台创建自定义表单
-
登录织梦后台,进入【核心】 -> 【内容模型管理】 -> 【自定义表单】。
(图片来源网络,侵删) -
点击“添加表单”,填写表单名称,用户地区信息”。
-
添加表单字段:
- 省份字段:
- 字段名:
province - 省份
- 字段类型:联动类型
- 数据表:
dede_area(你刚刚创建的表) - 字段:
name - 父级ID字段:
pid - 顶级ID值:
0 - 是否启用:是
- 字段名:
- 城市字段:
- 字单名:
city - 城市
- 字段类型:联动类型
- 数据表:
dede_area - 字段:
name - 父级ID字段:
pid - 顶级ID值:这里留空,让它自动关联到“省份”字段。
- 是否启用:是
- 字单名:
- 区/县字段:
- 字段名:
district - 区/县
- 字段类型:联动类型
- 数据表:
dede_area - 字段:
name - 父级ID字段:
pid - 顶级ID值:这里留空,让它自动关联到“城市”字段。
- 是否启用:是
- 字段名:
- 省份字段:
-
保存表单,织梦会自动生成一个表单模板文件,路径通常是
/templets/plus/diyform.htm。
步骤 4:修改表单模板
打开 /templets/plus/diyform.htm 文件,找到你添加的联动字段,它们默认的HTML结构是正确的,但为了更好的用户体验,可以稍作调整。
原始代码可能类似这样:
<select name="province" id="province" class="input">
<option value='0'>请选择省份</option>
{dede:global name='phpurl'/}/diy.php?action=list&diyid={dede:global.name='diyid'/&table=dede_area&field=pid&condition=pid=0
</select>
<select name="city" id="city" class="input">
<option value='0'>请选择城市</option>
</select>
<select name="district" id="district" class="input">
<option value='0'>请选择区/县</option>
</select>
优化后的代码(更清晰,并添加JS):
<div class="form-group">
<label for="province">省份:</label>
<select name="province" id="province" class="form-control">
<option value="0">请选择省份</option>
{dede:global name='phpurl'/}/diy.php?action=list&diyid={dede:global.name='diyid'/}&table=dede_area&field=name&condition=pid=0
</select>
</div>
<div class="form-group">
<label for="city">城市:</label>
<select name="city" id="city" class="form-control">
<option value="0">请先选择省份</option>
</select>
</div>
<div class="form-group">
<label for="district">区/县:</label>
<select name="district" id="district" class="form-control">
<option value="0">请先选择城市</option>
</select>
</div>
步骤 5:添加联动JS
织梦默认不包含联动JS,所以需要我们自己添加,在 diyform.htm 文件的 <head> 标签内或页面底部添加以下JS代码:
<script language="javascript" type="text/javascript">
// 省份改变时,加载城市
document.getElementById('province').onchange = function(){
var province = this.value;
var citySelect = document.getElementById('city');
var districtSelect = document.getElementById('district');
// 清空城市和区/县下拉框
citySelect.length = 1;
districtSelect.length = 1;
if(province == 0){
citySelect.options[0].text = '请先选择省份';
districtSelect.options[0].text = '请先选择城市';
return;
}
citySelect.options[0].text = '正在加载...';
// 使用织梦的联动接口
citySelect.options[0].value = '{dede:global name='phpurl'/}/diy.php?action=list&diyid={dede:global.name='diyid'/}&table=dede_area&field=name&condition=pid='+province;
};
// 城市改变时,加载区/县
document.getElementById('city').onchange = function(){
var city = this.value;
var districtSelect = document.getElementById('district');
// 清空区/县下拉框
districtSelect.length = 1;
if(city == 0){
districtSelect.options[0].text = '请先选择城市';
return;
}
districtSelect.options[0].text = '正在加载...';
// 使用织梦的联动接口
districtSelect.options[0].value = '{dede:global name='phpurl'/}/diy.php?action=list&diyid={dede:global.name='diyid'/}&table=dede_area&field=name&condition=pid='+city;
};
</script>
注意: 这里的JS代码是一个简化版,织梦官方在 include/foreign.func.php 中有一个 GetOptionList() 函数,可以更好地处理这种情况,更健壮的做法是调用这个函数,但需要一些PHP知识,上面的JS通过直接修改 select 的 option 的 value 来实现,是一种简单有效的方法。
使用“文本类型”表单 + JS代码
这种方法适合不想操作数据库,或者数据量不大的情况。
步骤 1:准备JS数据文件
- 在你的网站根目录下创建一个文件夹,
js。 - 在
js文件夹中创建一个area.js文件。 - 将地区数据格式化为JS对象,格式如下:
js/area.js:
var areaData = [
{
id: 1,
name: "广东省",
children: [
{ id: 3, name: "广州市", children: [
{ id: 5, name: "天河区" },
{ id: 6, name: "越秀区" }
]},
{ id: 4, name: "深圳市", children: [
{ id: 7, name: "南山区" },
{ id: 8, name: "福田区" }
]}
]
},
{
id: 2,
name: "北京市",
children: [
{ id: 9, name: "朝阳区" },
{ id: 10, name: "海淀区" }
]
}
];
步骤 2:创建自定义表单
- 进入后台【自定义表单】。
- 添加表单,但这次字段类型选择 “文本类型”。
- 字段名:
province(实际存储的是省份ID) - 字段名:
city(实际存储的是城市ID) - 字段名:
district(实际存储的是区县ID)
- 字段名:
- 保存表单。
步骤 3:在模板页面调用JS和HTML
在你需要显示联动菜单的页面(例如文章内容页、列表页或其他自定义页面),引入JS文件并编写HTML和JS逻辑。
HTML部分:
<select id="province-select">
<option value="">请选择省份</option>
</select>
<select id="city-select">
<option value="">请选择城市</option>
</select>
<select id="district-select">
<option value="">请选择区/县</option>
</select>
JS部分(可以放在HTML后面):
<script src="/js/area.js"></script>
<script>
// 初始化省份
function initProvince() {
var provinceSelect = document.getElementById('province-select');
areaData.forEach(function(province) {
var option = new Option(province.name, province.id);
provinceSelect.add(option);
});
}
// 加载城市
function loadCity(provinceId) {
var citySelect = document.getElementById('city-select');
var districtSelect = document.getElementById('district-select');
// 清空城市和区县
citySelect.length = 1;
districtSelect.length = 1;
if (!provinceId) return;
var province = areaData.find(p => p.id == provinceId);
if (province && province.children) {
province.children.forEach(function(city) {
var option = new Option(city.name, city.id);
citySelect.add(option);
});
}
}
// 加载区县
function loadDistrict(cityId) {
var districtSelect = document.getElementById('district-select');
districtSelect.length = 1; // 清空
if (!cityId) return;
// 找到对应的城市
var province = areaData.find(p => p.children.some(c => c.id == cityId));
if (province) {
var city = province.children.find(c => c.id == cityId);
if (city && city.children) {
city.children.forEach(function(district) {
var option = new Option(district.name, district.id);
districtSelect.add(option);
});
}
}
}
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
initProvince();
document.getElementById('province-select').onchange = function() {
loadCity(this.value);
};
document.getElementById('city-select').onchange = function() {
loadDistrict(this.value);
};
});
</script>
总结与对比
| 特性 | 方法一 (联动类型) | 方法二 (文本+JS) |
|---|---|---|
| 数据来源 | 独立的MySQL数据表 | JS文件 |
| 数据管理 | 在后台统一管理,方便增删改 | 需手动修改JS文件,不适合频繁更新 |
| 性能 | 数据库查询,对数据库有轻微压力 | 纯前端加载,性能高 |
| 适用场景 | 大型网站,数据需要动态维护和管理 | 小型应用,数据固定,或快速实现功能 |
| 复杂度 | 设置步骤较多,需要操作数据库 | 设置简单,只需准备JS文件和编写前端代码 |
推荐: 对于绝大多数网站,强烈推荐使用方法一,它更符合织梦CMS的设计理念,数据管理规范,可扩展性强,是更专业、更长期的解决方案,方法二可以作为快速验证或小型应用的备选方案。
