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

霞舞
发布: 2025-09-23 11:12:29
原创
181人浏览过

使用 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免费学习笔记(深入)”;

行者AI
行者AI

行者AI绘图创作,唤醒新的灵感,创造更多可能

行者AI 100
查看详情 行者AI

此文件负责建立与 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(); // 序列化表
登录后复制

以上就是使用 PHP、MySQL 和 jQuery 实现多行动态依赖下拉菜单的详细内容,更多请关注php中文网其它相关文章!

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

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