dede自定义表单联动如何实现?

99ANYc3cd6
预计阅读时长 33 分钟
位置: 首页 DEDE建站 正文

联动,也叫级联,指的是表单中一个字段的选项会根据另一个字段的选择而动态改变,最常见的例子就是“省-市-区”三级联动。

dede自定义表单联动
(图片来源网络,侵删)

DedeCMS本身不直接提供可视化的联动表单创建工具,所以我们需要通过修改模板文件和少量PHP代码来实现,下面我将以最常见的“省份-城市”二级联动为例,为你提供一个详细、可操作的步骤指南。


核心思路

实现联动的核心思路是:

  1. 数据准备:创建两个数据表,一个存省份,一个存城市,并通过 province_id 字段将它们关联起来。
  2. 前端HTML:在模板中创建两个 <select> 下拉框,一个用于省份,一个用于城市,使用 jQuery 监听省份下拉框的 change 事件。
  3. 后端交互:当省份选择改变时,通过 jQuery 的 $.ajax 方法向一个专门处理联动的PHP文件发送请求,并传递所选省份的ID。
  4. PHP处理:联动PHP文件接收省份ID,查询对应的数据库,获取城市列表,并将城市数据以JSON格式返回。
  5. 前端渲染:jQuery 接收返回的JSON数据,动态生成 <option> 选项,并填充到城市下拉框中。

详细步骤

第一步:准备数据库

我们需要在DedeCMS的数据库中创建两个表来存储省份数据和城市数据。

创建省份表 dede_provinces

dede自定义表单联动
(图片来源网络,侵删)
CREATE TABLE `dede_provinces` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '省份ID',
  `name` varchar(50) NOT NULL COMMENT '省份名称',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

创建城市表 dede_cities

CREATE TABLE `dede_cities` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '城市ID',
  `province_id` int(10) unsigned NOT NULL COMMENT '所属省份ID',
  `name` varchar(50) NOT NULL COMMENT '城市名称',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

插入示例数据

向这两个表中插入一些测试数据。

省份表示例数据:

dede自定义表单联动
(图片来源网络,侵删)
INSERT INTO `dede_provinces` (`id`, `name`) VALUES
(1, '广东省'),
(2, '江苏省'),
(3, '浙江省');

城市表示例数据:

INSERT INTO `dede_cities` (`id`, `province_id`, `name`) VALUES
(1, 1, '广州市'),
(2, 1, '深圳市'),
(3, 1, '珠海市'),
(4, 2, '南京市'),
(5, 2, '苏州市'),
(6, 2, '无锡市'),
(7, 3, '杭州市'),
(8, 3, '宁波市'),
(9, 3, '温州市');

第二步:创建Dede自定义表单

  1. 登录DedeCMS后台。
  2. 进入【核心】 -> 【内容模型管理】 -> 【自定义表单】。
  3. 点击【增加新表单】,填写表单信息:
    • 表单名称: 联动表单示例 (可以任意)
    • 数据表: dede_addonlinkage (系统会自动生成,也可以自定义,但要和下面代码中的 $dsql->SetQuery 保持一致)
    • 默认表单模板: default (保持默认)
    • 列表模板: list_linkage.htm (保持默认)
    • 普通模板: post_linkage.htm (保持默认)
    • 成功提示: 提交成功!
  4. 点击【确定】。
  5. 在字段管理中,增加两个字段:
    • 字段名: province,字段类型: 下拉菜单,选项填写:广东省,江苏省,浙江省 (这里先手动填上,后面会被JS覆盖)。
    • 字段名: city,字段类型: 下拉菜单,选项填写:请先选择省份

第三步:创建联动处理文件

我们需要一个PHP文件来处理AJAX请求并返回JSON数据。

  1. 在你的DedeCMS根目录下创建一个新文件,命名为 ajax_getcity.php
  2. 将以下代码复制到 ajax_getcity.php 文件中:
<?php
require_once (dirname(__FILE__) . "/include/common.inc.php");
require_once DEDEINC.'/datalistcp.class.php';
// 获取通过POST传递过来的省份ID
$province_id = isset($_POST['province_id']) ? intval($_POST['province_id']) : 0;
// 初始化城市数组
$cities = array();
if ($province_id > 0) {
    // 查询对应省份下的所有城市
    $dsql->SetQuery("SELECT id, name FROM dede_cities WHERE province_id = {$province_id} ORDER BY id ASC");
    $dsql->Execute('city');
    while ($row = $dsql->GetArray('city')) {
        $cities[] = $row;
    }
}
// 设置响应头为JSON格式
header('Content-Type: application/json');
// 将城市数组以JSON格式输出
echo json_encode($cities);
exit();
?>

代码解释:

  • 引入了DedeCMS的必要配置文件。
  • 接收前端POST过来的 province_id
  • 使用 $dsql 查询 dede_cities 表,找出 province_id 匹配的所有城市。
  • 使用 json_encode() 将PHP数组转换为JSON字符串,这是前端JavaScript可以直接识别的格式。
  • header('Content-Type: application/json'); 告诉浏览器返回的是JSON数据,这是一个好习惯。

第四步:修改前端模板文件

这是最关键的一步,我们要在表单模板中引入jQuery并编写联动逻辑。

  1. 找到你的自定义表单模板文件,路径通常是 templets/plus/post_linkage.htm (如果第二步中你没有修改模板名)。

  2. 打开这个文件,找到 <form> 标签,并在里面定位到省份和城市的下拉菜单,它们看起来可能像这样:

    <select name="province" id="province">
        <option value='0'>请选择省份</option>
        <option value='1'>广东省</option>
        <option value='2'>江苏省</option>
        <option value='3'>浙江省</option>
    </select>
    <select name="city" id="city">
        <option value='0'>请选择城市</option>
    </select>
  3. 修改这两个下拉框,并加入我们的JS代码,修改后的 post_linkage.htm 文件内容如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">联动表单提交</title>
    <!-- 引入jQuery库,DedeCMS默认在 /include/js/jquery.js -->
    <script src="/include/js/jquery/jquery.js"></script>
</head>
<body>
    <h2>联动表单示例</h2>
    <form action='plus/diy.php' enctype='multipart/form-data' method='post'>
        <input type='hidden' name='dede_fields' value='province,text;city,text' />
        <input type='hidden' name='dede_fieldshash' value='<?php echo $_SESSION['dede_fieldshash'];?>' />
        <div>
            <label for="province">省份:</label>
            <!-- 省份下拉框,id="province" 是关键 -->
            <select name="province" id="province">
                <option value="0">请选择省份</option>
                {dede:global name='list' runphp='yes'}
                    $dsql = new DedeSql(false);
                    $sql = "SELECT id, name FROM dede_provinces ORDER BY id ASC";
                    $dsql->SetQuery($sql);
                    $dsql->Execute('pro');
                    $options = '';
                    while($row = $dsql->GetArray('pro')){
                        $options .= "<option value='{$row['id']}'>{$row['name']}</option>";
                    }
                    @me=$options;
                {/dede:global}
            </select>
        </div>
        <div style="margin-top: 10px;">
            <label for="city">城市:</label>
            <!-- 城市下拉框,id="city" 是关键,初始为空 -->
            <select name="city" id="city">
                <option value="0">请先选择省份</option>
            </select>
        </div>
        <div style="margin-top: 10px;">
            <button type="submit">提交</button>
        </div>
    </form>
    <script type="text/javascript">
    $(function(){
        // 监听省份下拉框的改变事件
        $("#province").change(function(){
            // 获取当前选中的省份ID
            var province_id = $(this).val();
            var city_select = $("#city");
            // 如果省份ID为0,则清空城市下拉框并返回
            if(province_id == 0){
                city_select.empty().append("<option value='0'>请先选择省份</option>");
                return;
            }
            // 显示一个加载提示(可选)
            city_select.empty().append("<option value='0'>加载中...</option>");
            // 发起AJAX请求
            $.ajax({
                url: "/ajax_getcity.php", // 我们创建的联动处理文件
                type: "POST",
                data: { "province_id": province_id },
                dataType: "json", // 期望返回的数据类型是JSON
                success: function(data){
                    // 请求成功后,清空城市下拉框
                    city_select.empty().append("<option value='0'>请选择城市</option>");
                    // 遍历返回的JSON数据,生成option并添加到城市下拉框
                    $.each(data, function(i, item){
                        city_select.append("<option value='" + item.id + "'>" + item.name + "</option>");
                    });
                },
                error: function(){
                    // 请求失败时,显示错误信息
                    city_select.empty().append("<option value='0'>加载失败,请重试</option>");
                }
            });
        });
    });
    </script>
</body>
</html>

代码解释:

  • 引入jQuery: <script src="/include/js/jquery/jquery.js"></script> 加载DedeCMS自带的jQuery库。
  • 省份下拉框: 使用 {dede:global} 循环标签从 dede_provinces 表中动态读取省份数据,并生成 <option>,这样比手动维护更方便。
  • 城市下拉框: 初始时只有一个默认选项,内容将由JS动态填充。
  • jQuery联动逻辑:
    • $("#province").change(function(){...}): 当省份选择改变时,触发这个函数。
    • var province_id = $(this).val(): 获取被选中的省份的 value 值。
    • $.ajax({...}): 发起异步请求。
      • url: 指向我们创建的 ajax_getcity.php
      • data: 将 province_id 作为POST数据发送。
      • dataType: "json": 告诉jQuery我们期待服务器返回JSON。
      • success: function(data){...}: 请求成功后的回调函数。data 就是服务器返回的JSON数组。
      • $.each(data, ...): 遍历 data 数组,为每个城市创建一个 <option> 并添加到城市下拉框中。
      • error: 请求失败时的处理。

第五步:测试

  1. 清理一下DedeCMS的缓存:后台 -> 系统 -> 站点清理 -> 清理所有缓存。
  2. 在前台访问你的自定义表单页面(plus/post.php?diyid=你的表单ID)。
  3. 你应该能看到省份下拉框里有“广东省”、“江苏省”等选项。
  4. 当你选择“广东省”时,城市下拉框会自动加载“广州市”、“深圳市”、“珠海市”。
  5. 当你切换省份时,城市列表也会相应改变。

至此,一个完整的DedeCMS自定义表单联动功能就实现了。


总结与注意事项

  • 安全性ajax_getcity.php 文件接收了 province_id,虽然我们用了 intval() 进行了类型转换和简单过滤,但在生产环境中,最好再做一些更严格的校验,防止SQL注入,DedeCMS的 $dsql 对象本身有安全机制,但养成好习惯总是好的。
  • 三级及以上联动:如果要实现“省-市-区”三级联动,原理是一样的,你需要再创建一个区县表,在城市的 change 事件中,去请求另一个处理区县的PHP文件,该文件接收 city_id 作为参数。
  • 数据来源:如果你的省市区数据量很大,手动插入很麻烦,可以考虑从网上下载现成的SQL数据文件直接导入数据库。
  • 模板标签:在模板中直接使用 {dede:global} 循环数据库数据,比在后台手动填写选项更灵活、更易于维护。

希望这个详细的教程能帮助你成功实现DedeCMS的自定义表单联动功能!

-- 展开阅读全文 --
头像
dede网站数据库路径如何修改或配置?
« 上一篇 03-06
dede a目录到底要不要建?
下一篇 » 03-06

相关文章

取消
微信二维码
支付宝二维码

目录[+]