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

克隆输入框的OnChange事件失效,AJAX无法传值问题

问题分析与解决方案

核心问题

  1. 重复ID冲突:原代码里的#brand、#model、#serialNo、#deviceLevel这些ID被克隆到新行,DOM中ID必须唯一,jQuery用ID选择器只会匹配第一个元素,导致新行的AJAX永远只操作第一行的输入框。
  2. 事件与逻辑不匹配:内联onchange虽然能被克隆,但checkDeviceStatus函数里的取值/赋值都是全局找ID,没有定位到触发事件的当前行。

修改步骤

1. 修正HTML:用类名替代重复ID,移除内联事件

只修改SLA表格的行内容(非SLA部分无需改动):

<tr>
  <td>
    <select class="form-control form-select brand" data-bs-placeholder="Select" name="brand[]" required>
      <!-- 原PHP循环内容不变 -->
    </select>
  </td>
  <td>
    <select class="form-control form-select model" data-bs-placeholder="Select" name="model[]" required>
      <!-- 原PHP循环内容不变 -->
    </select>
  </td>
  <td><input type="text" name="serialNo[]" class="form-control serialNo"></td>
  <td><input type="text" name="deviceLevel[]" class="form-control deviceLevel" readonly></td>
  <input type="text" name="client[]" class="client" value="<?= $clientID ?>" hidden>
  <td><button type="button" class=" btn text-danger" data-name="del"><i class="fe fe-minus-circle" style="font-size:1.6em;"></i></button></td>
</tr>
  • 移除所有重复ID,改用类名(.brand、.model、.serialNo、.deviceLevel、.client)
  • 移除内联onchange事件
  • 把name属性改成数组形式(比如brand[]),方便表单提交时获取所有行的数据

2. 重构JS:事件委托+行内逻辑定位

替换原JS中的AJAX部分和事件绑定:

function restrictAlphabets(e) {
  var x = e.which || e.keyCode;
  return (x >= 48 && x <= 57);
}

// 克隆表格行逻辑不变,无需修改
document.querySelector('button[data-name="add"]').addEventListener('click', e => {
  let tbody = e.target.closest('table').querySelector('tbody');
  let clone = tbody.firstElementChild.cloneNode(true);
  clone.querySelector('button[data-name="del"]').hidden = false;
  clone.querySelectorAll('input, select').forEach(n => {
    n.value = '';
  });
  tbody.appendChild(clone);
});

document.querySelector('form table#dyntbl').addEventListener('click', e => {
  e.stopPropagation();
  if (e.target != e.currentTarget && (e.target.dataset.name == 'del' || e.target.parentNode.dataset.name == 'del')) {
    let tbody = e.target.closest('table').querySelector('tbody');
    if (tbody.childNodes.length > 3) tbody.removeChild(e.target.closest('tr'));
  }
});

// 事件委托:绑定change事件到tbody,覆盖动态新增的行
document.querySelector('#dyntbl tbody').addEventListener('change', function(e) {
  // 只处理目标是品牌、型号、序列号的情况
  if (e.target.classList.contains('brand') || e.target.classList.contains('model') || e.target.classList.contains('serialNo')) {
    let currentRow = e.target.closest('tr');
    checkDeviceStatus(currentRow);
  }
});

// 重构AJAX函数:接收当前行作为参数,只操作该行的元素
function checkDeviceStatus(row) {
  var dModel = row.querySelector('.model').value;
  var dBrand = row.querySelector('.brand').value;
  var dserial = row.querySelector('.serialNo').value;
  var client = row.querySelector('.client').value;

  // 确保必填项都有值再发AJAX
  if (!dModel || !dBrand || !dserial) return;

  $.ajax({
    url: "./handlers/slaChecker.php",
    type: "POST",
    data: {
      dModel: dModel,
      dserial: dserial,
      client: client,
      dBrand: dBrand
    },
    success: function(result) {
      row.querySelector('.deviceLevel').value = result;
      console.log(result);
    }
  });
}
  • 用事件委托绑定change事件到表格tbody,动态新增的行自动继承事件
  • checkDeviceStatus函数接收当前行作为参数,通过行来定位该行的所有元素,确保取值和赋值都只针对当前行
  • 增加必填项判断,避免空值发送AJAX请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 00:18:30