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

动态添加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>&nbsp;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>&nbsp;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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 17:44:55