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

Laravel8中多条件给多输入框设属性及动态表单行jQuery事件失效如何解决

问题根因

  • 所有表单元素重复使用相同ID,HTML规范要求ID全局唯一,jQuery通过ID选择器获取元素时只会匹配第一个加载的元素,导致后续新增行的元素无法被选中
  • 当前使用的$('selector').change()/keyup()属于直接事件绑定,只会绑定页面初始化时已存在的DOM元素,后续动态新增的元素不会自动绑定对应事件

修复步骤

第一步:修改HTML结构,替换重复ID为类名

把原来所有行内重复的ID属性统一改为class属性,同时给每行的根容器加统一类名item-row,示例修改片段:

<div class="row item-row" id="add_item_detail_1">
    <div class="col-sm-2">
        <div class="form-group" style="position: relative">
            <label class="col-form-label">Service Category</label>
            <select name="serviceCategory[]" class="form-control serviceCategory">
                <option value="0" selected disabled>--- Select Service Category ---</option>
                @foreach ($service_category as $category)
                    <option value="{{ $category->id }}">{{ $category->name }}</option>
                @endforeach
            </select>
        </div>
    </div>
    <div class="col-sm-2">
        <div class="form-group">
            <label class="col-form-label">Select Item</label>
            <select name="serviceItem[]" class="form-control serviceItem">
                <option value="0" selected disabled>--- Select Item ---</option>
                @foreach ($service_items as $item)
                    <option value="{{ $item->id }}">{{ $item->name }}</option>
                @endforeach
            </select>
            <img class="serviceloader" src="{{ asset('admin/img') }}/loader.gif" alt="Loading..." />
        </div>
    </div>
    <!-- 剩下的元素同理,把id="price"改为class="price",id="product_qty"改为class="product_qty",以此类推 -->
    <div class="col-sm-1">
        <div class="form-group">
            <label class="col-form-label">Price/Item</label>
            <input type="text" name="price[]" value="" placeholder="Price" class="form-control price" readonly="readonly">
        </div>
    </div>
    <!-- 其他元素全部替换对应ID为类名,此处省略重复部分 -->
</div>

第二步:修改jQuery为事件委托模式,按行匹配元素

事件委托需要绑定到页面加载时就存在的父级容器(比如body、或者你包裹所有行的固定容器),操作元素时先找当前触发事件所在的行,再匹配该行内的对应元素,避免影响其他行:

$(function() {
    // 初始化默认行的状态
    $('.item-row').each(function() {
        let row = $(this);
        row.find('.serviceloader').hide();
        row.find('.serviceItem').prop('disabled', true);
        row.find('.vendorName').prop('disabled', true);
    });

    // 服务分类联动
    $('body').on('change', '.serviceCategory', function() {
        let row = $(this).closest('.item-row');
        let id = $(this).val();
        let serviceLoader = row.find('.serviceloader');
        let serviceItem = row.find('.serviceItem');
        
        if (id) {
            serviceLoader.show();
            serviceItem.prop('disabled', true);
            $.ajax({
                url: "/getServiceItem/" + id,
                type: "GET",
                dataType: "json",
                success: function(response) {
                    let sItem = '<option value="0">---Select Item---</option>';
                    response.forEach(function(item) {
                        sItem += '<option value="' + item.id + '">' + item.name + '</option>';
                    });
                    serviceItem.prop('disabled', false).html(sItem);
                    serviceLoader.hide();
                }
            });
        }
    });

    // 服务项联动填充价格
    $('body').on('change', '.serviceItem', function() {
        let row = $(this).closest('.item-row');
        let id = $(this).val();
        if (id) {
            $.ajax({
                url: "/getItemPriceByID/" + id,
                type: "GET",
                dataType: "json",
                success: function(response) {
                    row.find('.price').val(response[0].price);
                    row.find('.product_qty').val('');
                    row.find('.totalPrice').val('');
                }
            });
        }
    });

    // 数量计算总价
    $('body').on('keyup', '.product_qty', function() {
        let row = $(this).closest('.item-row');
        let itemPrice = row.find('.price').val();
        let itemQty = $(this).val();
        let totalPrice = (itemPrice * itemQty).toFixed(2);
        row.find('.totalPrice').val(totalPrice);
    });

    // 区域联动供应商
    $('body').on('change', '.vendorArea', function() {
        let row = $(this).closest('.item-row');
        let id = $(this).val();
        let vendorName = row.find('.vendorName');
        if (id) {
            vendorName.prop('disabled', true);
            $.ajax({
                url: "/getVendorByID/" + id,
                type: "GET",
                dataType: "json",
                success: function(response) {
                    let sVendor = '<option value="0">---Select Vendor---</option>';
                    response.forEach(function(vendor) {
                        sVendor += '<option value="' + vendor.id + '">' + vendor.ven_name + ',' + vendor.ven_phone + '</option>';
                    });
                    vendorName.prop('disabled', false).html(sVendor);
                }
            });
        }
    });
});

第三步:新增行函数注意事项

你的add_more_item函数新增行时,只要保证新增的行和你修改后的HTML结构一致、类名正确即可,不需要额外绑定事件,事件委托会自动处理新增行的交互。

多条件为多个输入框设置单个属性的方法

可以通过jQuery选择器选中目标元素,配合filter方法筛选符合多条件的元素,统一设置属性,示例:

// 示例:为所有值为空、且不是只读的输入框设置禁用属性
$('input.form-control').filter(function() {
    return $(this).val() === '' && !$(this).prop('readonly');
}).prop('disabled', true);

// 示例:为所有下拉框中选中值为0的元素设置红色边框
$('select.form-control').filter(function() {
    return $(this).val() == 0;
}).css('border', '1px solid red');

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 15:36:09