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

JS动态生成表单仅首次数据存入数据库问题排查与解决

问题原因与修复方案

核心问题原因

动态生成的订单表单元素不在<form>标签内部,导致表单提交时这些元素的数据不会被发送到服务器,PHP无法获取到动态表单的字段值,最终插入数据库时除了Batch ID外其余字段为空。

你的JavaScript代码中,createOrderForm函数把新生成的.order-form元素插入到了order-container容器中(也就是<form>标签的外面),而表单提交只会发送<form>内部元素的数据。

修复步骤

1. 修正JavaScript的表单插入位置

修改createOrderForm函数,将动态生成的表单元素插入到<form>标签内部,确保提交时能携带这些字段的数据。

修改后的JavaScript代码:

<script>
    var orderCount = 1;

    function createOrderForm() {
        orderCount++;

        // 获取<form>元素作为插入容器
        var form = document.querySelector('#order-container form');

        var orderForm = document.createElement('div');
        orderForm.classList.add('order-form');
        orderForm.id = `order-form-${orderCount}`;
        orderForm.innerHTML = `
            <h3>Order ${orderCount}</h3>
            <div class="form-row">
                <label for="item-name-${orderCount}">Item Name:</label>
                <select id="item-name-${orderCount}" name="item-name-${orderCount}">
                    <?php include 'php/order_read.php'; ?>
                </select>
            </div>
            <div class="form-row">
                <label for="qty-${orderCount}">Qty:</label>
                <input type="text" id="qty-${orderCount}" name="qty-${orderCount}">
            </div>
            <div class="form-row">
                <label for="supplier-name-${orderCount}">Supplier Name:</label>
                <input type="text" id="supplier-name-${orderCount}" name="supplier-name-${orderCount}">
            </div>
            <div class="form-row">
                <label for="supplier-contact-${orderCount}">Supplier Contact:</label>
                <input type="text" id="supplier-contact-${orderCount}" name="supplier-contact-${orderCount}" pattern="[0-9]+" title="Only numbers allowed">
            </div>
            <div class="form-row">
                <label for="supplier-address-${orderCount}">Supplier Address:</label>
                <input type="text" id="supplier-address-${orderCount}" name="supplier-address-${orderCount}">
            </div>
            <button class="remove-button" onclick="removeOrderForm(${orderCount})">Remove</button>
        `;

        // 将新表单插入到隐藏计数输入框之前
        var orderCountInput = document.getElementById('order-count');
        form.insertBefore(orderForm, orderCountInput);

        document.getElementById('order-count').value = orderCount;
    }

    function removeOrderForm(orderId) {
        var form = document.getElementById(`order-form-${orderId}`);
        form.parentNode.removeChild(form);

        orderCount--;
        document.getElementById('order-count').value = orderCount;
    }
</script>

2. 修复PHP的安全与健壮性问题

原PHP代码存在SQL注入风险,且未处理字段不存在的情况,容易引发错误。修改后的代码:

<?php
// Database connection
$dbHost = "localhost";
$dbUsername = "root";
$dbPassword = "";
$dbName = "main";

$conn = mysqli_connect($dbHost, $dbUsername, $dbPassword, $dbName);
if (!$conn) {
    die("Connection failed: " . mysqli_connect_error());
}

// Check if the form is submitted
if ($_SERVER["REQUEST_METHOD"] === "POST") {
    // Generate the Batch ID
    $batchID = generateBatchID();

    // 使用预处理语句防止SQL注入
    $stmt = mysqli_prepare($conn, "INSERT INTO purchase (`Item Name`, `Qty`, `Supplier Name`, `Supplier Contact`, `Supplier Address`, `Batch ID`) 
                                  VALUES (?, ?, ?, ?, ?, ?)");
    mysqli_stmt_bind_param($stmt, "sissss", $itemName, $qty, $supplierName, $supplierContact, $supplierAddress, $batchID);

    // 获取订单数量,确保为整数
    $orderCount = isset($_POST["order-count"]) ? (int)$_POST["order-count"] : 1;
    for ($i = 1; $i <= $orderCount; $i++) {
        // 检查字段是否存在,避免Undefined Index错误
        $itemName = isset($_POST["item-name-$i"]) ? trim($_POST["item-name-$i"]) : '';
        $qty = isset($_POST["qty-$i"]) ? (int)$_POST["qty-$i"] : 0;
        $supplierName = isset($_POST["supplier-name-$i"]) ? trim($_POST["supplier-name-$i"]) : '';
        $supplierContact = isset($_POST["supplier-contact-$i"]) ? trim($_POST["supplier-contact-$i"]) : '';
        $supplierAddress = isset($_POST["supplier-address-$i"]) ? trim($_POST["supplier-address-$i"]) : '';

        // 执行预处理语句
        if (!mysqli_stmt_execute($stmt)) {
            echo "Error: " . mysqli_error($conn);
            exit(); // 出错时终止脚本
        }
    }

    mysqli_stmt_close($stmt);

    // 重定向回订单页面
    header("Location: ../purchase.php");
    exit();
}

// Close the database connection
mysqli_close($conn);

function generateBatchID()
{
    // 生成更可靠的唯一ID:时间戳+随机数
    return uniqid('', true) . rand(1000, 9999);
}
?>

3. 可选优化:修复删除表单后的计数问题

当前删除表单后,orderCount仅简单递减,若删除的不是最后一个表单,后续生成的表单ID会重复。若需解决此问题,可遍历所有.order-form元素重新计数,示例代码如下:

function removeOrderForm(orderId) {
    var form = document.getElementById(`order-form-${orderId}`);
    form.parentNode.removeChild(form);

    // 重新统计表单数量
    var orderForms = document.querySelectorAll('.order-form');
    orderCount = orderForms.length;
    document.getElementById('order-count').value = orderCount;

    // 重新命名剩余表单的ID和标题
    orderForms.forEach((form, index) => {
        const newIndex = index + 1;
        form.id = `order-form-${newIndex}`;
        form.querySelector('h3').textContent = `Order ${newIndex}`;
        
        // 重命名表单内所有元素的ID和name属性
        form.querySelectorAll('[id^="item-name-"]')[0].id = `item-name-${newIndex}`;
        form.querySelectorAll('[name^="item-name-"]')[0].name = `item-name-${newIndex}`;
        
        form.querySelectorAll('[id^="qty-"]')[0].id = `qty-${newIndex}`;
        form.querySelectorAll('[name^="qty-"]')[0].name = `qty-${newIndex}`;
        
        // 其他字段同理修改ID和name
    });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:02:05