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

动态表单添加新项后Select2功能消失的问题求助

解决动态添加表单项后原有Select2失效的问题

问题原因

核心问题是:每次点击添加按钮后,你对所有已存在的同class Select2元素重复调用select2()方法,这会破坏已经初始化完成的Select2实例,导致原有组件的样式和交互功能失效。

解决方案

只对新添加的表单项中的Select2元素进行初始化,避免影响已有的组件实例。同时需要修正HTML中的重复id问题(id必须唯一,否则会引发DOM冲突)。

步骤1:移除模板中的重复id属性

修改动态生成的tr模板,删除所有select和input的id属性(每个新项都会生成相同id,违反HTML规范):

let productItem = `
    <tr>
        <td>
            <select name="productItems[${productItems}][product_type_id]" class="form-control product_type_id">
                <option value="">-- Product Type --</option>
                @foreach ($productTypes as $productType)
                    <option value="{{ $productType->id }}"
                        @selected(old("productItems.{$loop->index}.product_type_id"))>
                        {{ $productType->title }}
                    </option>
                @endforeach
            </select>
        </td>
        <td>
            <select name="productItems[${productItems}][product_id]" class="form-control product_id">
                <option value="">-- Product --</option>
                @foreach ($products as $product)
                    <option value="{{ $product->id }}"
                        @selected(old("productItems.{$loop->index}.product_id"))>
                        {{ $product->product_name }}
                    </option>
                @endforeach
            </select>
        </td>
        <td>
            <input type="text" name="productItems[${productItems}][serial_number]" class="form-control serial_number">
        </td>
        <td>
            <input type="text" name="productItems[${productItems}][brand]" class="form-control brand">
        </td>
        <td>
            <select name="productItems[${productItems}][unit_of_measure_id]" class="form-control unit_of_measure_id">
                <option value="">-- UOM --</option>
            </select>
        </td>
        <td>
            <input type="number" name="productItems[${productItems}][quantity]" class="form-control quantity" value="1">
        </td>
        <td>
            <input type="number" name="productItems[${productItems}][item_cost]" class="form-control item_cost" value="0.00">
        </td>
        <td>
            <a href="#" class="deleteProductItemBtn">Delete</a>
        </td>
    </tr>
`;

步骤2:仅初始化新添加的Select2元素

修改添加按钮的点击事件,在append新tr后,只针对刚添加的tr中的select元素初始化Select2:

$('#addProductItemBtn').click(function(e) {
    e.preventDefault();
    let productItems = $('tbody tr').length;
    let productItem = `
        <!-- 上面修改后的模板内容 -->
    `;
    $('tbody').append(productItem);
    
    // 定位刚添加的最后一个tr,仅初始化其中的Select2组件
    const newRow = $('tbody tr').last();
    newRow.find('.product_type_id').select2();
    newRow.find('.product_id').select2();
    newRow.find('.unit_of_measure_id').select2();
});

原理说明

  • 原有代码中$('.product_id').select2()会选中页面上所有带product_id类的元素,包括已经初始化过的Select2组件,重复初始化会覆盖原有实例,导致样式和功能失效。
  • 通过$('tbody tr').last()定位新添加的行,再用find()找到该行内的select元素,只对这些未初始化的元素调用select2(),既完成了新组件的初始化,又不会影响已有的Select2实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 14:37:56