0

0

使用 PHP、MySQL 和 jQuery 实现多行动态依赖下拉菜单

霞舞

霞舞

发布时间:2025-09-23 11:12:29

|

195人浏览过

|

来源于php中文网

原创

使用 php、mysql 和 jquery 实现多行动态依赖下拉菜单

本文详细介绍了如何使用 PHP、MySQL 和 jQuery/Ajax 技术构建一个支持多行动态添加的表单,其中包含依赖下拉菜单。通过优化数据库查询、完善前端 JavaScript 逻辑以及确保动态生成元素间的正确关联,本教程旨在帮助开发者实现复杂表单的交互功能,并提供清晰的代码示例和最佳实践。

在现代 Web 应用中,用户经常需要输入结构化数据,其中某些字段的值依赖于其他字段的选择。当这种依赖关系需要应用于一个可以动态添加多行的表单时,实现起来会变得更具挑战性。本教程将指导您如何构建一个设备修改日志系统,该系统允许用户在单页上添加多条修改记录,每条记录都包含一个“子系统”下拉菜单和一个动态加载的“组件”下拉菜单,其中“组件”列表会根据所选的“子系统”实时更新。

1. 数据库结构与连接

首先,我们需要定义用于存储子系统和组件信息的数据库表,并建立数据库连接。

数据库表结构:

lu_subsystem (子系统查找表) | 字段 | 类型 | 描述 | | :----------- | :---------- | :----------- | | id | INT(11) | 主键,自增 | | subsystem_name | VARCHAR(255)| 子系统名称 |

lu_component (组件查找表) | 字段 | 类型 | 描述 | | :----------- | :---------- | :----------- | | component_id | INT(11) | 主键,自增 | | subsystem_id | INT(11) | 外键,关联 lu_subsystem.id | | component_name | VARCHAR(255)| 组件名称 |

database_connection.php - 数据库连接与辅助函数:

立即学习PHP免费学习笔记(深入)”;

小羊标书
小羊标书

一键生成百页标书,让投标更简单高效

下载

此文件负责建立与 MySQL 数据库的连接,并提供两个 PHP 函数用于从数据库中获取下拉菜单选项。

<?php
// database_connection.php

// 建立 PDO 数据库连接
$connect = new PDO("mysql:host=localhost; dbname=bunker_logs;", "root", "");
$connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 设置错误模式为抛出异常

/**
 * 从 lu_subsystem 表中获取所有子系统作为下拉菜单选项。
 *
 * @param PDO $connect 数据库连接对象。
 * @return string 包含 <option> 标签的 HTML 字符串。
 */
function fill_subsystem_options($connect)
{
    $query = "SELECT id, subsystem_name FROM lu_subsystem ORDER BY subsystem_name ASC";
    $statement = $connect->prepare($query);
    $statement->execute();
    $result = $statement->fetchAll(PDO::FETCH_ASSOC);

    $output = '';
    foreach($result as $row)
    {
        $output .= '<option value="'.$row["id"].'">'.$row["subsystem_name"].'</option>';
    }
    return $output;
}

/**
 * 根据给定的子系统 ID 从 lu_component 表中获取相应的组件作为下拉菜单选项。
 *
 * @param PDO $connect 数据库连接对象。
 * @param int $subsystem_id 子系统 ID。
 * @return string 包含 <option> 标签的 HTML 字符串。
 */
function get_component_options_by_subsystem($connect, $subsystem_id)
{
    // 使用预处理语句防止 SQL 注入
    $query = "SELECT component_id, component_name FROM lu_component WHERE subsystem_id = :subsystem_id ORDER BY component_name ASC";
    $statement = $connect->prepare($query);
    $statement->bindParam(':subsystem_id', $subsystem_id, PDO::PARAM_INT);
    $statement->execute();
    $result = $statement->fetchAll(PDO::FETCH_ASSOC);

    $output = '';
    foreach($result as $row)
    {
        $output .= '<option value="'.$row["component_id"].'">'.$row["component_name"].'</option>';
    }
    return $output;
}
?>

注意事项:

  • 我们使用 PDO (PHP Data Objects) 进行数据库操作,这是一种更安全、更灵活的方式。
  • fill_subsystem_options 函数用于获取所有子系统,用于初始加载。
  • get_component_options_by_subsystem 函数是关键,它接收一个 subsystem_id 参数,并返回该子系统下的所有组件。请注意,这里修正了原始代码中查询条件错误的问题,确保通过 subsystem_id 进行过滤。

2. AJAX 后端接口 (fetch_components.php)

这个 PHP 文件将作为前端 AJAX 请求的端点,负责接收子系统 ID,并返回对应的组件列表。

<?php
// fetch_components.php (原 fill_component.php)

include('database_connection.php');

if (isset($_POST["subsystem_id"]) && !empty($_POST["subsystem_id"])) {
    // 调用辅助函数获取组件选项
    echo get_component_options_by_subsystem($connect, $_POST["subsystem_id"]);
} else {
    // 如果没有提供 subsystem_id,返回一个默认选项
    echo '<option value="">Select Subsystem First</option>';
}
?>

3. 前端页面结构与逻辑 (index.php)

这是实现多行动态依赖下拉菜单的核心文件。它包含 HTML 结构、引入必要的 JavaScript 库(jQuery 和 Bootstrap),以及处理动态行添加/删除和下拉菜单依赖逻辑的 jQuery 代码。

<?php
// index.php

include('database_connection.php'); // 引入数据库连接和辅助函数
?>

<!DOCTYPE html>
<html>
  <head>
    <title>动态依赖下拉菜单实现多行输入</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <style>
        body { padding-top: 20px; }
        .container { max-width: 960px; }
    </style>
  </head>
  <body>
    <div class="container">
      <h3 align="center">使用 Ajax jQuery 和 PHP 实现动态添加/删除依赖下拉菜单行</h3>
      <br />
      <h4 align="center">输入设备修改详情</h4>
      <br />
      <form method="post" id="insert_form">
        <div class="table-responsive">
          <span id="error"></span>
          <table class="table table-bordered" id="item_table">
            <thead>
              <tr>
                <th>输入项目名称</th>
                <th>子系统</th>
                <th>组件</th>
                <th><button type="button" name="add" class="btn btn-success btn-xs add"><span class="glyphicon glyphicon-plus"></span></button></th>
              </tr>
            </thead>
            <tbody>
                <!-- 初始行或动态添加的行将在这里 -->
            </tbody>
          </table>
          <div align="center">
            <input type="submit" name="submit" class="btn btn-info" value="插入数据" />
          </div>
        </div>
      </form>
    </div>

    <script>
    $(document).ready(function(){

      var count = 0; // 用于跟踪动态生成行的唯一标识符

      // 动态添加行
      $(document).on('click', '.add', function(){
        count++; // 每次添加行,计数器递增,确保每个新行有唯一的 ID
        var html = '';
        html += '<tr>';
        html += '<td><input type="text" name="item_name[]" class="form-control item_name" /></td>';
        // subsystem_id 下拉菜单,使用 data-row-id 属性来关联当前行的组件下拉菜单
        html += '<td><select name="subsystem_id[]" class="form-control subsystem_id" data-row-id="'+count+'"><option value="">选择子系统</option><?php echo fill_subsystem_options($connect); ?></select></td>';
        // item_component_id 下拉菜单,其 ID 包含 count,以便在 JS 中精确选择
        html += '<td><select name="item_component_id[]" class="form-control item_component_id" id="item_component_id_'+count+'"><option value="">选择组件</option></select></td>';
        html += '<td><button type="button" name="remove" class="btn btn-danger btn-xs remove"><span class="glyphicon glyphicon-minus"></span></button></td>';
        $('tbody').append(html); // 将新行添加到表格的 tbody 中
      });

      // 动态删除行
      $(document).on('click', '.remove', function(){
        $(this).closest('tr').remove(); // 找到最近的父级 <tr> 并移除
      });

      // 处理子系统下拉菜单的改变事件,实现组件的动态加载
      $(document).on('change', '.subsystem_id', function(){
        var selectedSubsystemId = $(this).val(); // 获取当前选中的子系统 ID
        var currentRowId = $(this).data('row-id'); // 获取当前行的唯一 ID
        var targetComponentDropdown = $('#item_component_id_' + currentRowId); // 根据行 ID 找到对应的组件下拉菜单

        if (selectedSubsystemId) { // 只有当选择了有效的子系统时才发送 AJAX 请求
          $.ajax({
            url: "fetch_components.php", // AJAX 请求的后端接口
            method: "POST",
            data: { subsystem_id: selectedSubsystemId }, // 发送子系统 ID
            success: function(data)
            {
              var html = '<option value="">选择组件</option>'; // 默认选项
              html += data; // 追加从后端返回的组件选项
              targetComponentDropdown.html(html); // 更新组件下拉菜单的内容
            },
            error: function() {
                targetComponentDropdown.html('<option value="">加载组件失败</option>'); // 错误处理
            }
          });
        } else {
            // 如果未选择子系统,清空组件下拉菜单并显示默认提示
            targetComponentDropdown.html('<option value="">选择组件</option>');
        }
      });

      // 表单提交处理
      $('#insert_form').on('submit', function(event){
        event.preventDefault(); // 阻止表单默认提交行为
        var error = '';

        // 简单的前端验证
        $('.item_name').each(function(index){ // index 从 0 开始
          if($(this).val() == '')
          {
            error += '<p>请在第 ' + (index + 1) + ' 行输入项目名称</p>';
            return false;
          }
        });

        $('.subsystem_id').each(function(index){
          if($(this).val() == '')
          {
            error += '<p>请在第 ' + (index + 1) + ' 行选择子系统</p>';
            return false;
          }
        });

        $('.item_component_id').each(function(index){
          if($(this).val() == '')
          {
            error += '<p>请在第 ' + (index + 1) + ' 行选择组件</p> ';
            return false;
          }
        });

        var form_data = $(this).serialize(); // 序列化表

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

686

2023.06.20

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

534

2023.06.21

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

287

2023.07.18

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

520

2023.07.19

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

267

2023.07.25

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

392

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

542

2023.08.11

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

668

2023.08.14

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

69

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.9万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

CSS教程
CSS教程

共754课时 | 43.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号