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

带下拉选项的表单重复器无法配合AJAX响应正常工作

表单重复器中新增项的Datapoint下拉框无响应问题

表单重复器问题示意图

我正在构建一个表单重复器,其中ID和Datapoint为下拉选择框。选择ID后,Datapoint的选项将通过AJAX响应获取并填充。首次调用选择功能时Datapoint下拉框能正常显示值,但添加新的重复项后,新的Datapoint无响应。

原代码

<form method="post" class="repeater" enctype="multipart/form-data">
  <div data-repeater-list="samplernetwork">
    <div data-repeater-item="data-repeater-item" class="row">
      <div class="mb-3 col-lg-2">
        <label for="id">ID</label>
        <select class="form-control" name="id" id="id">
          <option></option>
          {% for id in id %}
            <option value="{{id.id}}">{{id.id}}</option>
          {% endfor %}
        </select>
      </div>

      <div class="mb-3 col-lg-2">
        <label for="datapoint">Datapoint</label>
        <select class="form-control" name="datapoint" id="datapoint"></select>
      </div>

      <div class="col-lg-2 align-self-center">
        <div class="d-grid">
          <input data-repeater-delete="data-repeater-delete" type="button" class="btn btn-primary" value="Delete"/>
        </div>
      </div>
    </div>

  </div>
  <input data-repeater-create="data-repeater-create" type="button" class="btn btn-success mt-3 mt-lg-0" value="Add"/>

</form>

<script src="/libs/jquery.repeater/jquery.repeater.min.js"></script>
<script src="/js/pages/form-repeater.int.js"></script>

<script>
  $("#id").on('change', function (e) {
    var consti = $(this).val()
    console.log(consti)
    if (consti === "") {
      $('#datapoint').find('option').remove()
    } else if (consti != null) {
      var url = '{{path(' app_info ',{' id ':' ReplaceMeWithCorrectValue '})}}';
      url = url.replace("ReplaceMeWithCorrectValue", consti);
      var options = ""
      $.ajax({
        type: "POST",
        url: url,
        success: function (response) {
          var information = JSON.parse(response)
          for (let item in information) {
            options += `<option value=${item}>${item}</option>`;
          }
          $("#datapoint").html(options);
        }
      });
    }
  });
</script>

<script src="/js/app.js"></script>

问题原因

  1. 事件绑定范围有限:原代码直接给#id绑定change事件,仅对页面加载时已存在的第一个ID下拉框生效,动态新增的重复项不会继承该事件。
  2. ID重复冲突:所有重复项的ID和Datapoint下拉框都使用相同的id属性,HTML规范中ID必须唯一,这会导致DOM选择器无法准确定位到新增项的元素。

解决方案

  1. 将重复项中的唯一ID替换为类名,避免ID冲突;
  2. 使用事件委托绑定事件,让父容器监听动态元素的事件;
  3. 在事件处理函数中,定位当前项对应的Datapoint下拉框,而非全局修改第一个匹配元素。

修改后的代码

<form method="post" class="repeater" enctype="multipart/form-data">
  <div data-repeater-list="samplernetwork">
    <div data-repeater-item="data-repeater-item" class="row">
      <div class="mb-3 col-lg-2">
        <label>ID</label>
        <select class="form-control id-select" name="id">
          <option></option>
          {% for id in id %}
            <option value="{{id.id}}">{{id.id}}</option>
          {% endfor %}
        </select>
      </div>

      <div class="mb-3 col-lg-2">
        <label>Datapoint</label>
        <select class="form-control datapoint-select" name="datapoint"></select>
      </div>

      <div class="col-lg-2 align-self-center">
        <div class="d-grid">
          <input data-repeater-delete="data-repeater-delete" type="button" class="btn btn-primary" value="Delete"/>
        </div>
      </div>
    </div>

  </div>
  <input data-repeater-create="data-repeater-create" type="button" class="btn btn-success mt-3 mt-lg-0" value="Add"/>

</form>

<script src="/libs/jquery.repeater/jquery.repeater.min.js"></script>
<script src="/js/pages/form-repeater.int.js"></script>

<script>
  // 使用事件委托,绑定到静态父容器
  $('.repeater').on('change', '.id-select', function (e) {
    const $currentItem = $(this).closest('[data-repeater-item]');
    const consti = $(this).val();
    const $datapointSelect = $currentItem.find('.datapoint-select');

    if (consti === "") {
      $datapointSelect.find('option').remove();
      return;
    }

    var url = '{{path(' app_info ',{' id ':' ReplaceMeWithCorrectValue '})}}';
    url = url.replace("ReplaceMeWithCorrectValue", consti);
    var options = "";

    $.ajax({
      type: "POST",
      url: url,
      success: function (response) {
        const information = JSON.parse(response);
        for (let item in information) {
          options += `<option value="${item}">${item}</option>`;
        }
        $datapointSelect.html(options);
      }
    });
  });
</script>

<script src="/js/app.js"></script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:05:22