jQuery动态添加的表单行无法提交至数据库问题排查
问题分析与解决方案
问题根源
通过Ajax添加新行时,前端生成的隐藏字段row_id[]值始终为0,数据库插入新记录后会生成自增ID,但这个ID没有同步到前端。后端表单提交处理逻辑大概率只会更新带有有效row_id的记录,导致新增行的修改无法被识别;而刷新页面后,eda_retrieve_discount_rules会从数据库读取正确的row_id,此时修改提交就能正常生效。
修复步骤
1. 修改Ajax处理函数,获取插入后的自增ID
更新eda_add_row函数,插入数据库后获取新记录的ID,并将其传入eda_add_new_row生成正确的HTML:
function eda_add_row() { if (!wp_verify_nonce($_REQUEST['nonce'], "my_user_like_nonce")) { exit("Woof Woof Woof"); } global $wpdb; $row_table = $wpdb->prefix . 'eda_custom_pricing_users'; $data = array( 'customer_id' => 0, 'brand_id' => 0, 'category_id' => 0, 'product_id' => 0, 'discount' => 0, 'table_order' => 0, ); $format = array( '%d', '%d', '%d', '%d', '%d', '%d' ); $wpdb->insert( $row_table, $data, $format ); // 获取插入后的自增ID $new_row_id = $wpdb->insert_id; $result['type'] = "success"; // 传入新生成的row_id,生成带正确ID的HTML行 $result['like_count'] = eda_add_new_row($new_row_id,0,0,0,0,0,0,false,'#fff'); if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { echo json_encode($result, JSON_HEX_QUOT | JSON_HEX_TAG); } else { header("Location: " . $_SERVER["HTTP_REFERER"]); } die(); }
2. 调整eda_add_new_row函数逻辑
移除函数内的数据库插入代码(已移到eda_add_row中),同时将重复的id属性改为class避免DOM冲突:
function eda_add_new_row($row_id=0,$customer_id=0,$brand_id=0,$category_id=0,$product_id=0,$discount=0,$table_order=0,$add_to_db=false,$color='#fff'){ global $wpdb; ob_start(); $selected = ' selected'; ?> <tr style="background-color: <?php echo $color;?>;"> <td> <input name="row_id[]" type="hidden" value="<?php echo $row_id;?>"> <select name="customers[]" class="customers-select"> <option value="0">选择客户</option> <?php $customers = get_all_wholesale_customers(); foreach ($customers as $customer) { echo '<option'.(($customer->get_id()==$customer_id) ? $selected : ''). ' value="' . $customer->get_id() . '">' . $customer->get_billing_first_name() . ' ' . $customer->get_billing_last_name() . ' (' . $customer->get_billing_company() . ')' . ' </option>'; } ?> </select> </td> <td> <select name="brands[]" class="brands-select"> <option value="0">所有品牌</option> <?php $brands = eda_get_all_brands(); foreach ($brands as $brand) { echo '<option'.(($brand->term_id==$brand_id) ? $selected : ''). ' value="' . $brand->term_id . '">' . $brand->name . '</option>'; } ?> </select> </td> <td> <select name="categories[]" class="categories-select"> <option value="0">所有分类</option> <?php $categories = eda_get_top_level_categories(); foreach ($categories as $category) { echo '<option'.(($category->term_id==$category_id) ? $selected : ''). ' value="' . $category->term_id . '">' . $category->name . '</option>'; } ?> </select> </td> <td> <select name="products[]" class="products-select"> <option value="0">所有产品</option> <?php $products = eda_make_ordered_products_list(eda_get_all_b2b_products(0)); usort($products, function ($a, $b) { return [$a['BRAND'], $a['NAME']] <=> [$b['BRAND'], $b['NAME']]; }); foreach ($products as $product) { echo '<option'.(($product['ID']==$product_id) ? $selected : ''). ' value="' . $product['ID'] . '">' . $product['BRAND'] . ' - ' . $product['NAME'] . ' (' . $product['SKU'] . ')</option>'; } ?></select> </td> <td><input type="number" class="discount" name="discount[]" min="0" max="100" value="<?php echo $discount;?>"></td> <td> <?php $nonce = wp_create_nonce("delete_row_nonce");?> <button type="button" class="button action eda-remove-row" value="<?php echo $row_id;?>" data-nonce="<?php echo $nonce; ?>">删除规则</button> </td> <td> <img class="eda-drag-row" src="<?php echo plugin_dir_url(__FILE__); ?>/img/drag.png" alt=""> </td> </tr> <?php $html = ob_get_contents(); ob_end_clean(); return $html; }
3. 确认后端提交处理逻辑
确保表单提交的处理函数eda_submit_form_user_discounts中,对row_id[]数组的每一项进行判断:
- 如果
row_id> 0:执行更新操作 - 如果
row_id= 0:可选择执行插入操作(避免重复插入)
修复原理
- 通过
$wpdb->insert_id获取数据库自增ID,同步到前端的row_id[]隐藏字段,后端就能识别这是已存在的记录,修改后会执行更新而非忽略。 - 移除重复的数据库插入逻辑,避免代码冗余,同时保证前后端ID一致。
- 替换重复的
id属性为class,解决DOM元素ID冲突问题,避免后续JS操作出现异常。
内容的提问来源于stack exchange,提问作者Eduard
相关产品推荐
相关产品推荐

