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
相关产品推荐
相关产品推荐

