带下拉选项的表单重复器无法配合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>
问题原因
- 事件绑定范围有限:原代码直接给
#id绑定change事件,仅对页面加载时已存在的第一个ID下拉框生效,动态新增的重复项不会继承该事件。 - ID重复冲突:所有重复项的ID和Datapoint下拉框都使用相同的
id属性,HTML规范中ID必须唯一,这会导致DOM选择器无法准确定位到新增项的元素。
解决方案
- 将重复项中的唯一ID替换为类名,避免ID冲突;
- 使用事件委托绑定事件,让父容器监听动态元素的事件;
- 在事件处理函数中,定位当前项对应的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
相关产品推荐
相关产品推荐

