动态添加Form Repeater项后Select2下拉框UI初始化异常问题
动态添加Repeater项后Select2 UI初始化异常解决
页面加载时Select2插件运行正常,但添加新的repeater项后,Select2下拉框功能正常但UI显示异常。
原表单结构
<div id="repeaterItems"> <div class="repeater-item"> <div class="row form-group"> <div class="col-md-6 mb-3"> <label class="control-label">Action Plan</label> <input type="text" class="form-control" name="action[]" placeholder="Enter action plan.." required> </div> <div class="col-md-5 mb-3"> <label class="control-label">Implementer</label> <select class="select2 form-control d-inline w-50" multiple="multiple" name="department[][]" style="width: 100%"> <option disabled value="">-- Please Choose --</option> @foreach ($depts as $dept) <option value="{{ $dept->dp_code }}">{{ $dept->dp_name }}</option> @endforeach </select> </div> <div class="col-md mt-auto mb-3"> <button type="button" class="btn btn-danger removeButton"><span class="mdi mdi-close-circle-outline"></span></button> </div> </div> </div> </div> <div class="col-md mb-3"> <button type="button" class="btn btn-info" id="addButton"><span class="mdi mdi-plus-circle-outline"></span> Add Plan</button> </div>
原尝试脚本
$(document).ready(function() { $('.select2').select2({ placeholder: "-- Choose Department --", allowClear: true }); $('#addButton').click(function() { var newItem = $('#repeaterItems .repeater-item:first').clone(); newItem.find('input').val(''); newItem.find('.removeButton').show(); $('#repeaterItems').append(newItem); newItem.find('.select2-container').remove(); newItem.find('.select2').select2({ placeholder: "-- Choose Department --", allowClear: true }); }); $('#repeaterItems').on('click', '.removeButton', function() { $(this).closest('.repeater-item').remove(); }); });
问题原因
你克隆的是已经被Select2初始化过的DOM元素,此时原生select元素上已被添加额外属性、事件绑定,还伴随Select2生成的.select2-container等DOM结构。即使移除.select2-container,残留的状态和属性会导致重新初始化时UI渲染异常。
解决方案
方案1:使用独立隐藏模板(推荐)
将初始项作为隐藏模板,克隆未被初始化的原生DOM元素,避免残留状态。
修改后的HTML
<!-- 隐藏的模板,不参与初始渲染 --> <div id="repeaterTemplate" style="display: none;"> <div class="repeater-item"> <div class="row form-group"> <div class="col-md-6 mb-3"> <label class="control-label">Action Plan</label> <input type="text" class="form-control" name="action[]" placeholder="Enter action plan.." required> </div> <div class="col-md-5 mb-3"> <label class="control-label">Implementer</label> <select class="select2 form-control d-inline w-50" multiple="multiple" name="department[][]" style="width: 100%"> <option disabled value="">-- Please Choose --</option> @foreach ($depts as $dept) <option value="{{ $dept->dp_code }}">{{ $dept->dp_name }}</option> @endforeach </select> </div> <div class="col-md mt-auto mb-3"> <button type="button" class="btn btn-danger removeButton"><span class="mdi mdi-close-circle-outline"></span></button> </div> </div> </div> </div> <div id="repeaterItems"> <!-- 初始项将通过JS从模板克隆生成 --> </div> <div class="col-md mb-3"> <button type="button" class="btn btn-info" id="addButton"><span class="mdi mdi-plus-circle-outline"></span> Add Plan</button> </div>
修改后的JS
$(document).ready(function() { // 封装添加项的函数 function addRepeaterItem() { var newItem = $('#repeaterTemplate .repeater-item').clone(); newItem.find('input').val(''); $('#repeaterItems').append(newItem); // 初始化新项的Select2 newItem.find('.select2').select2({ placeholder: "-- Choose Department --", allowClear: true }); } // 页面加载时生成第一个项 addRepeaterItem(); // 绑定添加按钮事件 $('#addButton').click(addRepeaterItem); // 绑定移除按钮事件 $('#repeaterItems').on('click', '.removeButton', function() { $(this).closest('.repeater-item').remove(); }); });
方案2:克隆前销毁原项的Select2
如果不想修改HTML结构,可以先销毁原项的Select2,克隆后再重新初始化原项和新项。
修改后的添加按钮事件代码
$('#addButton').click(function() { var originalItem = $('#repeaterItems .repeater-item:first'); // 先销毁原项的Select2 originalItem.find('.select2').select2('destroy'); // 克隆原项 var newItem = originalItem.clone(); newItem.find('input').val(''); newItem.find('.removeButton').show(); $('#repeaterItems').append(newItem); // 重新初始化原项的Select2 originalItem.find('.select2').select2({ placeholder: "-- Choose Department --", allowClear: true }); // 初始化新项的Select2 newItem.find('.select2').select2({ placeholder: "-- Choose Department --", allowClear: true }); });
内容的提问来源于stack exchange,提问作者Jasmirulnaim
相关产品推荐
相关产品推荐

