You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于MySQL+PHP+JS的级联下拉动态添加行功能实现求助

批量硬件变更记录录入联动下拉故障排查

我正使用MySQL、PHP、JavaScript搭建设备日志系统,已自学相关技术3个月,现有代码多来自技术论坛。已实现单条硬件变更记录录入功能:Subsystem下拉从数据库拉取子系统列表,Component下拉根据选中的Subsystem动态填充,提交入库逻辑正常,提交后可返回页面新增下一条记录。
改造为单页可批量添加多条修改记录的功能时,动态新增行的Subsystem下拉能正常拉取表数据,但对应的Component下拉无法填充。参考的单表适配教程适配双表结构时函数逻辑出错,不确定问题位置,需要排查方向指引。

表结构

  • lu_subsystem表
idsubsystem_name
子系统ID子系统名称
  • lu_component表
component_idsubsystem_idcomponent_name
组件ID关联子系统ID组件名称

现有代码

index.php

<?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>
</head>
<body>
    <br />
    <div class="container">
        <h3 align="center">动态联动下拉批量录入工具</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>
</body>
</html>
<script>
$(document).ready(function(){
    var count = 0;
    $(document).on('click', '.add', function(){
        count++;
        var html = '';
        html += '<tr>';
        html += '<td><input type="text" name="item_name[]" class="form-control item_name" /></td>';
        html += '<td><select name="subsystem_id[]" class="form-control subsystem_id" data-subsystem_id="'+count+'"><option value="">选择子系统</option><?php echo fill_select_box($connect, "0"); ?></select></td>';
        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);
    });
    $(document).on('click', '.remove', function(){
        $(this).closest('tr').remove();
    });
    $(document).on('change', '.subsystem_id', function(){
        var id = $(this).val();
        var component_id = $(this).data('component_id');
        $.ajax({
            url:"fill_sub_category.php",
            method:"POST",
            data:{subsystem_id:subsystem_id},
            success:function(data)
            {
                var html = '<option value="">选择组件</option>';
                html += data;
                $('#item_component_id'+component_id).html(html);
            }
        })
    });
    $('#insert_form').on('submit', function(event){
        event.preventDefault();
        var error = '';
        $('.item_name').each(function(){
            var count = 1;
            if($(this).val() == '')
            {
                error += '<p>第'+count+'行未填写变更内容</p>';
                return false;
            }
            count = count + 1;
        });
        $('.item_category').each(function(){
            var count = 1;
            if($(this).val() == '')
            {
                error += '<p>第'+count+'行未选择子系统</p>';
                return false;
            }
            count = count + 1;
        });
        $('.item_component_id').each(function(){
            var count = 1;
            if($(this).val() == '')
            {
                error += '<p>第'+count+'行未选择组件</p> ';
                return false;
            }
            count = count + 1;
        });
        var form_data = $(this).serialize();
        if(error == '')
        {
            $.ajax({
                url:"insert.php",
                method:"POST",
                data:form_data,
                success:function(data)
                {
                    if(data == 'ok')
                    {
                        $('#item_table').find('tr:gt(0)').remove();
                        $('#error').html('<div class="alert alert-success">变更记录保存成功</div>');
                    }
                }
            });
        }
        else
        {
            $('#error').html('<div class="alert alert-danger">'+error+'</div>');
        }
    });
});
</script>

database_connection.php

<?php
//database_connection.php
$connect = new PDO("mysql:host=localhost; dbname=bunker_logs;", "root", "");
function fill_select_box($connect, $id)
{
    $query = "SELECT * FROM lu_subsystem";
    $statement = $connect->prepare($query);
    $statement->execute();
    $result = $statement->fetchAll();
    $output = '';
    foreach($result as $row)
    {
        $output .= '<option value="'.$row["id"].'">'.$row["subsystem_name"].'</option>';
    }
    return $output;
}
function fill_component_box($connect, $component_id)
{
    $query = "SELECT * FROM lu_component WHERE component_id ='" .$id."'";
    $statement = $connect->prepare($query);
    $statement->execute();
    $result = $statement->fetchAll();
    $output = '';
    foreach($result as $row)
    {
        $output .= '<option value="'.$row["component_id"].'">'.$row["component_name"].'</option>';
    }
    return $output;
}
?>

fill_component.php

<?php
//fill_component.php
include('database_connection.php');
echo fill_component_box($connect, $_POST["subsystem_id"]);
?>

故障修复方案

  1. 修复自定义属性取值错误:subsystem下拉的自定义属性为data-subsystem_id,change事件中取值逻辑要改为var row_index = $(this).data('subsystem_id'),才能匹配对应行Component下拉的ID后缀。
  2. 修复Ajax参数错误:change事件中已将选中的子系统ID存入id变量,传参要改为data:{subsystem_id:id},避免变量未定义报错。
  3. 修复接口地址错误:Ajax请求地址改为fill_component.php,和后端文件名一致。
  4. 修复SQL查询逻辑错误:fill_component_box函数的查询条件要改为WHERE subsystem_id = " .$id,按子系统外键查询对应组件,而非按组件ID查询。
  5. 修复表单校验错误:删除$('.item_category')对应的冗余校验逻辑,该选择器在代码中不存在,会导致校验逻辑异常。

学习路径建议

  • 优先掌握浏览器开发者工具用法:调试时先看控制台JS报错、网络请求的参数和返回值,可快速定位绝大多数前后端交互问题。
  • 夯实SQL基础:搞清楚多表关联的外键对应关系,避免查询条件字段混淆。
  • 学习jQuery基础用法:重点掌握动态元素的事件委托、自定义属性操作、选择器匹配规则。

内容的提问来源于stack exchange,提问作者Delnoth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 11:45:04