Form Repeater中关联Select仅首行生效问题求助
解决Form Repeater新增行AJAX联动失效问题
我创建了一个包含3个关联select的表单重复器(form repeater),目前仅首行的AJAX联动功能正常,新增行的联动完全失效。我尝试过循环等方案但未解决,如何实现对所有已存在及新增行的关联控制?
原HTML代码
<form class="row mb-30" action="{{ route('Classrooms.store') }}" method="POST"> @csrf <div class="card-body"> <div class="repeater"> <div data-repeater-list="List_Classes"> <div data-repeater-item> <div class="row"> <div class="col"> <label for="Name" class="mr-sm-2">اسم الفصل :</label> <input class="form-control" type="text" name="ClassName" /> </div> <div class="col"> <div class="form-group"> <label for="exampleFormControlTextarea1">الكلية :</label> <select class="form-control form-control-lg p-1 College" id="exampleFormControlSelect1" name="College" required> <option disabled selected>الكليات....</option> @foreach ($Colleges as $College) <option value="{{ $College->id }}">{{ $College->CollageName }}</option> @endforeach </select> </div> </div> <div class="col"> <div class="form-group"> <label for="exampleFormControlTextarea1">القسم :</label> <select class="form-control form-control-lg p-1 Section" id="exampleFormControlSelect1" name="Section" required> <option disabled selected>الاقسام....</option> </select> </div> </div> <div class="col"> <div class="form-group"> <label for="exampleFormControlTextarea1">التخصص :</label> <select class="form-control form-control-lg p-1 Specialtie" id="exampleFormControlSelect1" name="Specialtie" required> <option disabled selected>التخصص الدراسي ....</option> </select> </div> </div> <div class="col"> <label for="Name_en" class="mr-sm-2">حذف صف :</label> <input class="btn btn-danger btn-block" data-repeater-delete type="button" value="حذف" /> </div> </div> </div> </div> <div class="row mt-20"> <div class="col-12"> <input class="button" data-repeater-create type="button" value="أضافة صف"/> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">الرجوع</button> <button type="submit" class="btn btn-success">حفظ</button> </div> </div> </div> </form>
原JS代码
<script> $('.College').on('change', function() { var Colleges = $(this).val(); var Section = $(this).closest('div[data-repeater-item]').find('.Section'); var Specialtie = $(this).closest('div[data-repeater-item]').find('.Specialtie'); if (Colleges) { $.ajax({ url: "{{ URL::to('classes') }}/" + Colleges+'/0', type: "GET", dataType: "json", success: function(data) { console.log(data) Section.empty(); Specialtie.empty(); Section.append( '<option selected disabled>الاقسام الموجودة :</option>'); $.each(data, function(key, value) { $(Section).append('<option value="' + key + '">' + value + '</option>'); }); if (data.length == 0) { $(Section).append( '<option selected disabled>لايوجد أقسام بعد...</option>'); } }, }); } else { console.log('AJAX load did not work'); } }); $('.Section').on('change', function() { var Colleges = $(this).val(); var Specialtie = $(this).closest('div[data-repeater-item]').find('.Specialtie'); console.log(Colleges) if (Colleges) { $.ajax({ url: "{{ URL::to('classes') }}/" + Colleges + '/1', type: "GET", dataType: "json", success: function(data) { console.log(data) Specialtie.empty(); $.each(data, function(key, value) { $(Specialtie).append('<option value="' + key + '">' + value + '</option>'); }); if (data.length == 0) { $(Specialtie).append( '<option selected disabled>لايوجد تخصصات بعد...</option>'); } }, }); } else { console.log('AJAX load did not work'); } }); </script>
解决方案
问题出在事件绑定方式上:直接给.College和.Section绑定change事件,只能作用于页面加载时已经存在的元素,动态新增的行不会继承这些事件。需要使用事件委托,把事件绑定到一个已经存在的父容器上,通过事件冒泡机制监听动态元素的事件。
修改后的JS代码
<script> // 用事件委托绑定College的change事件,父容器选[data-repeater-list="List_Classes"]更精准 $('[data-repeater-list="List_Classes"]').on('change', '.College', function() { var CollegeId = $(this).val(); var Section = $(this).closest('div[data-repeater-item]').find('.Section'); var Specialtie = $(this).closest('div[data-repeater-item]').find('.Specialtie'); if (CollegeId) { $.ajax({ url: "{{ URL::to('classes') }}/" + CollegeId+'/0', type: "GET", dataType: "json", success: function(data) { console.log(data) Section.empty(); Specialtie.empty(); Section.append('<option selected disabled>الاقسام الموجودة :</option>'); $.each(data, function(key, value) { $(Section).append('<option value="' + key + '">' + value + '</option>'); }); if (data.length == 0) { $(Section).append('<option selected disabled>لايوجد أقسام بعد...</option>'); } }, }); } else { console.log('AJAX load did not work'); } }); // 同样用事件委托绑定Section的change事件 $('[data-repeater-list="List_Classes"]').on('change', '.Section', function() { var SectionId = $(this).val(); var Specialtie = $(this).closest('div[data-repeater-item]').find('.Specialtie'); console.log(SectionId) if (SectionId) { $.ajax({ url: "{{ URL::to('classes') }}/" + SectionId + '/1', type: "GET", dataType: "json", success: function(data) { console.log(data) Specialtie.empty(); $.each(data, function(key, value) { $(Specialtie).append('<option value="' + key + '">' + value + '</option>'); }); if (data.length == 0) { $(Specialtie).append('<option selected disabled>لايوجد تخصصات بعد...</option>'); } }, }); } else { console.log('AJAX load did not work'); } }); </script>
关键说明
- 事件委托的核心是将事件绑定到静态存在的父元素(这里选择
[data-repeater-list="List_Classes"],因为它是所有重复项的容器,页面加载时就存在),而不是直接绑定到动态生成的子元素上。 - 当子元素触发
change事件时,事件会冒泡到父元素,父元素再根据选择器.College/.Section判断是否触发处理函数,这样新增的动态元素也能正常触发事件。 - 调整了变量名
Colleges为CollegeId/SectionId,更符合语义,避免混淆。
内容的提问来源于stack exchange,提问作者Mahmod Algeriany
相关产品推荐
相关产品推荐

