动态增删输入字段异常:弹窗确认后默认字段被误删求助
问题根源分析
- 重复ID问题:在
@foreach循环中,每个默认产品容器和删除按钮都使用了相同的ID(olddynamic、oldrmvbtn),HTML中ID必须唯一,这会导致事件绑定和DOM选择出现异常。 - 错误的事件绑定逻辑:
rmv()和oldrmv()函数每次点击按钮时都会重复添加委托事件监听,导致多次绑定后,即使后续不满足删除条件,旧的监听事件仍会触发删除操作。 - 内联点击事件与委托事件冲突:内联
onclick属性和jQuery委托事件同时存在,导致事件触发逻辑混乱。 - 默认字段删除限制逻辑错误:原代码尝试通过输入框数量判断是否可删除,但未明确区分默认字段和新增字段,导致限制失效。
修复方案
1. 修正Laravel模板HTML(替换重复ID为类)
@foreach($orders->products as $product) <div class="product-container old-product"> <div class="row mb-3"> <label for="products-{{ $loop->index }}" class="col-md-4 col-form-label text-md-end">{{ __('Product') }}</label> <div class="col-md-6"> <select name="products[]" id="products-{{ $loop->index }}" class="form-control @error('products') is-invalid @enderror" required autocomplete="products"> <option value="" selected="true" disabled>{{$product->name}}</option> @foreach($productList as $item) <option value="{{$item->id}}">{{$item->name}}</option> @endforeach </select> @error('products') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class="row mb-3"> <label for="amount-{{ $loop->index }}" class="col-md-4 col-form-label text-md-end">{{ __('Amount') }}</label> <div class="col-md-6"> <input id="amount-{{ $loop->index }}" type="text" class="form-control @error('amount') is-invalid @enderror" name="amount[]" value="{{ $product->pivot->amount }}" required autocomplete="amount"> @error('amount') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class="col"> <button type="button" class="btn btn-primary rmv-btn"> <span class="bi bi-dash-lg"></span> </button> </div> </div> @endforeach
2. 修正添加按钮(移除内联点击事件)
<div class="col"> <button type="button" id="addbtn" class="btn btn-primary"> <span class="bi bi-plus"></span> </button> </div>
3. 重构JavaScript代码(统一事件绑定,明确字段类型判断)
<script> $(document).ready(function() { // 动态添加产品字段 $('#addbtn').on('click', function() { const containerCount = $('.product-container').length; $('#amm').append(` <div class="product-container new-product"> <div class="row mb-4"> <label for="products-${containerCount}" class="col-md-4 col-form-label text-md-end">{{ __("Product") }}</label> <div class="col-md-6"> <select name="products[]" id="products-${containerCount}" class="form-control @error("products") is-invalid @enderror" required autocomplete="products"> @foreach($productList as $item) <option value="{{$item->id}}">{{$item->name}}</option> @endforeach </select> @error("products") <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class="row mb-3"> <label for="amount-${containerCount}" class="col-md-4 col-form-label text-md-end">{{ __("Amount") }}</label> <div class="col-md-6"> <input id="amount-${containerCount}" type="text" class="form-control @error("amount") is-invalid @enderror" name="amount[]" required autocomplete="amount"> @error("amount") <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class="col"> <button type="button" class="btn btn-primary rmv-btn"> <span class="bi bi-dash-lg"></span> </button> </div> </div> `); }); // 统一处理删除按钮点击事件 $(document).on('click', '.rmv-btn', function() { const $container = $(this).closest('.product-container'); // 禁止删除默认字段 if ($container.hasClass('old-product')) { alert('Order must have minimum one product-2'); return; } // 允许删除新增字段 $container.remove(); }); }); </script>
修复说明
- 唯一标识:使用
$loop->index为默认字段生成唯一ID,避免重复ID导致的DOM操作异常。 - 事件绑定优化:仅在页面加载时绑定一次委托事件,避免重复绑定导致的多次触发问题。
- 字段类型区分:通过
old-product和new-product类明确区分默认字段和新增字段,直接限制默认字段的删除操作。 - 简化逻辑:移除冗余的输入框数量判断,直接根据字段类型决定是否允许删除,符合需求中"仅允许删除新增字段"的要求。
内容的提问来源于stack exchange,提问作者laraCoder
相关产品推荐
相关产品推荐

