PHP+JQuery库存表单问题:多行数据及PDF附件AJAX提交失败
Hey there! Let's work through this problem together. You're trying to build a bulk inventory submission form with dynamic row management and a PDF attachment, but you're stuck combining the row CRUD with AJAX submission—totally understandable when you're new to AJAX and file handling. Let's break down the issues and fix this step by step.
First, Let's Fix the Immediate Conflicts & Outdated Code
Your current setup has a few key issues causing the conflict:
- Duplicate IDs: Your Submit button has two
id="Submit"attributes—this breaks jQuery selectors, so your click handler might not fire correctly. - Static Table Rows: You're just appending text to the table, not actual form fields. This means those row values can't be submitted to PHP.
- Incorrect File Handling: You're trying to pass the file name (
$("#Annexure").val()) instead of the file itself, and regular AJAX data can't handle file uploads. - Outdated jQuery: Version 1.4.1 is way too old (released in 2010!) and doesn't support modern features like
FormDataproperly. Upgrade to at least jQuery 3.x (I'll use 3.7.1 in the example).
Modified Full Code (HTML + JS)
Let's rewrite your code to support bulk row submission and file uploads:
<html lang="en"> <head> <meta charset="utf-8"> </head> <body> <form action="insert_indents.php" method="post" name="indform" id="indform" enctype="multipart/form-data"> <!-- Input fields for adding new rows --> <label for="new_Part_No">Part No.:</label> <input type="text" id="new_Part_No" placeholder="Part No"> <label for="new_Part_Make">Part Make:</label> <input type="text" id="new_Part_Make" placeholder="Part Make"> <!-- Single PDF attachment for the entire submission --> <label for="Annexure">Attach PDF File: <input type="hidden" name="MAX_FILE_SIZE" value="3000000" /> <!-- Increased size to 3MB for PDFs --> <input id="Annexure" name="Annexure" type="file" class="form-control" style='width:20em' accept=".pdf" /> </label> <input type="button" class="add-row" value="Add Row"> <input type="button" id="Submit" class="ind-row" value="Submit" /> </form> <table> <thead> <tr> <th>Select</th> <th>Part No</th> <th>Part Make</th> </tr> </thead> <tbody> <!-- Dynamic rows will be added here --> </tbody> </table> <button type="button" class="delete-row">Delete Selected Row(s)</button> <!-- Updated jQuery --> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ // Add new row with form fields (using array names for bulk submission) $(".add-row").click(function(){ var partNo = $("#new_Part_No").val().trim(); var partMake = $("#new_Part_Make").val().trim(); // Don't add empty rows if(partNo === "" || partMake === ""){ alert("Please fill both Part No and Part Make!"); return; } // Append row with hidden input fields (or visible if you want editing) var markup = ` <tr> <td><input type='checkbox' name='record'></td> <td> ${partNo} <input type="hidden" name="items[][Part_No]" value="${partNo}"> </td> <td> ${partMake} <input type="hidden" name="items[][Part_Make]" value="${partMake}"> </td> </tr> `; $("table tbody").append(markup); // Clear input fields after adding row $("#new_Part_No").val(""); $("#new_Part_Make").val(""); }); // Delete selected rows $(".delete-row").click(function(){ $("table tbody").find('input[name="record"]:checked').parents("tr").remove(); }); // Submit form via AJAX with bulk data and file $("#Submit").click(function(){ var formData = new FormData($("#indform")[0]); // Check if there are rows to submit if($("table tbody tr").length === 0){ alert("Please add at least one item!"); return; } // Check if a PDF is attached if($("#Annexure")[0].files.length === 0){ alert("Please attach a PDF file!"); return; } $.ajax({ url: 'insert_indents.php', type: 'POST', data: formData, processData: false, // Don't process the form data (required for files) contentType: false, // Don't set content type (let browser handle it) success: function(response) { alert(response); // Optional: Clear form and table after successful submission $("#indform")[0].reset(); $("table tbody").empty(); }, error: function(xhr, status, error) { alert("Error submitting data: " + error); } }); }); }); </script> </body> </html>
PHP Code (insert_indents.php)
Now, let's write the PHP to handle the bulk data and file upload. We'll insert each item into the database, and save the PDF to a server folder (storing paths is better than BLOBs for performance):
<?php // Database connection (replace with your credentials) $servername = "localhost"; $username = "your_username"; $password = "your_password"; $dbname = "your_database"; $conn = new mysqli($servername, $username, $password, $dbname); if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } // Handle file upload $annexurePath = ""; if(isset($_FILES['Annexure']) && $_FILES['Annexure']['error'] === UPLOAD_ERR_OK){ $targetDir = "uploads/"; // Create this folder in your project root $fileName = uniqid() . "_" . basename($_FILES['Annexure']['name']); $targetPath = $targetDir . $fileName; // Ensure upload directory exists if(!is_dir($targetDir)){ mkdir($targetDir, 0777, true); } if(move_uploaded_file($_FILES['Annexure']['tmp_name'], $targetPath)){ $annexurePath = $targetPath; } else { echo "Failed to upload PDF file."; exit; } } else { echo "No PDF file uploaded or upload error."; exit; } // Insert bulk items into database if(isset($_POST['items']) && is_array($_POST['items'])){ $successCount = 0; foreach($_POST['items'] as $item){ $partNo = $conn->real_escape_string($item['Part_No']); $partMake = $conn->real_escape_string($item['Part_Make']); $sql = "INSERT INTO inventory (Part_No, Part_Make, Annexure_Path) VALUES ('$partNo', '$partMake', '$annexurePath')"; if($conn->query($sql) === TRUE){ $successCount++; } } echo "Successfully inserted $successCount items. PDF saved to: $annexurePath"; } else { echo "No items to insert."; } $conn->close(); ?>
Key Changes Explained
- Dynamic Rows with Array Fields: We're using
name="items[][Part_No]"which lets PHP receive all rows as a 2D array ($_POST['items']). - FormData for File Uploads:
FormDatais required to send files via AJAX—we pass the entire form to it, which includes both the bulk items and the PDF. - Input Validation: Added checks for empty rows and missing PDF to prevent bad submissions.
- File Handling: The PDF is saved to an
uploadsfolder (you need to create this), and its path is stored in the database (better for performance than storing the file as a BLOB). - Fixed jQuery Issues: Removed duplicate IDs, upgraded jQuery, and cleaned up event handlers.
This setup will let you add/delete rows freely, then submit all the rows plus the PDF via AJAX without conflicts. Let me know if you need help tweaking any part of this!
内容的提问来源于stack exchange,提问作者Shripad Saraswat

