Hello i have made a dynamic add and remove input fields and the code works great except the part when you reach the maximum limit to delete fields, this is my code:
function rmv()
{
var count = document.getElementsByTagName('input');
if(count.length > 6){
$(document).on('click', '#rmvbtn', function () {
$(this).closest('#dynamic').remove();
});
}else{
alert('Order must have minimum one product-1');
}
}
When the alert shows up and i click okay the last field is deleted, i tried debugging the code to see if it enters in the delete function after i press okay but it does not.
The reason there is a 6
is because there are 6 fields by default and user can add more and delete the new added but not the 6 default ones. So this error is deleting fields from the default part.
This is the html part its an edit panel where user can edit orders made for a client, this part is made with Laravel. The rows are printed as much times as many order prodcuts exist so each duplicated row has a button next to it to delete that specific row, this is the code:
@foreach($orders->products as $product)
<div id="olddynamic">
<div >
<label for="products" >{{ __('Product') }}</label>
<div >
<select name="products[]" id="products" type="text" 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 role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div >
<label for="amount" >{{ __('Amount') }}</label>
<div >
<input id="amount" type="text"
name="amount[]" value="{{ $product->pivot->amount }}" required autocomplete="amount">
@error('amount')
<span role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div ><button type="button" id="oldrmvbtn" onclick="oldrmv()" ><span ></span></button></div>
</div>
@endforeach
There is also this add row button that adds new rows to the existing order this is the code:
<div ><button type="button" id="addbtn" onclick="add()" ><span ></span></button></div>
This is the whole Javascript code:
<script>
function add()
{
$('#amm').append(
'<div id="dynamic"><div ><label for="products" >{{ __("Product") }}</label><div ><select name="products[]" id="products" type="text" products") is-invalid @enderror" required autocomplete="products">@foreach($productList as $item)<option value="{{$item->id}}">{{$item->name}}</option>@endforeach</select>@error("products")<span role="alert"><strong>{{ $message }}</strong></span>@enderror</div></div> <div ><label for="amount" >{{ __("Amount") }}</label><div ><input id="amount" type="text" amount") is-invalid @enderror" name="amount[]" required autocomplete="amount">@error("amount")<span role="alert"><strong>{{ $message }}</strong></span>@enderror</div></div> <div ><button type="button" id="rmvbtn" onclick="rmv()" ><span ></span></button></div> </div>'
);
}
function rmv()
{
var count = document.getElementsByTagName('input');
if(count.length > 6){
$(document).on('click', '#rmvbtn', function () {
$(this).closest('#dynamic').remove();
});
}else{
alert('Order must have minimum one product-1');
}
}
function oldrmv()
{
var count = document.getElementsByTagName('input');
if(count.length > 6){
$(document).on('click', '#oldrmvbtn', function () {
$(this).closest('#olddynamic').remove();
});
alert(count.length);
}else{
alert('Order must have minimum one product-2');
}
}
</script>
CodePudding user response:
Please delete onclick="add()"
, onclick="rmv()"
and onclick="oldrmv()"
in HTML.
After change Javascript
$(document).ready(function() {
$(document).on('click', '#addbtn', function () {
$('#amm').append(
'<div id="dynamic"><div ><label for="products" >{{ __("Product") }}</label><div ><select name="products[]" id="products" type="text" products") is-invalid @enderror" required autocomplete="products">@foreach($productList as $item)<option value="{{$item->id}}">{{$item->name}}</option>@endforeach</select>@error("products")<span role="alert"><strong>{{ $message }}</strong></span>@enderror</div></div> <div ><label for="amount" >{{ __("Amount") }}</label><div ><input id="amount" type="text" amount") is-invalid @enderror" name="amount[]" required autocomplete="amount">@error("amount")<span role="alert"><strong>{{ $message }}</strong></span>@enderror</div></div> <div ><button type="button" id="rmvbtn" onclick="rmv()" ><span ></span></button></div> </div>'
);
});
$(document).on('click', '#rmvbtn', function () {
let count = document.getElementsByTagName('input');
if(count.length > 6){
$(this).closest('#dynamic').remove();
}else{
alert('Order must have minimum one product-1');
}
});
$(document).on('click', '#oldrmvbtn', function () {
let count = document.getElementsByTagName('input');
if(count.length > 6){
$(this).closest('#olddynamic').remove();
}else{
alert('Order must have minimum one product-2');
}
});
});
CodePudding user response:
The main issue is due to the nested click
event handler within the rmv()
function. You should remove that and use a single delegate event handler for the dynamic content.
That being said, there's quite a few other things you can do to improve the code quality here:
- Avoid putting HTML in your JS. If you do include HTML in the JS, it should absolutely not be an entire multi-line structure. Use a
<template>
to store it. - Remove the
id
attributes in the content which can be dynamically repeated, otherwise you'll create duplicates which will cause problems. Change them to classes instead. - The 'Remove' logic is broken, assuming that your intention is to ensure there is always at least 1 item added - as the error message states.
With that said, try this working version:
const $container = $('#amm');
const $template = $('#amm-template');
$('#add').on('click', () => {
$container.append($template.html());
});
$container.on('click', '.rmvbtn', e => {
if ($('.amm-item').length > 1) {
$(e.target).closest('.amm-item').remove();
} else {
alert('Order must have minimum one product-1');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<button id="add">Add</button>
<div id="amm"></div>
<template id="amm-template">
<div >
<div ><label for="products" >{{ __("Product") }}</label>
<div >
<select name="products[]" type="text" products") is-invalid @enderror" required autocomplete="products">
@foreach($productList as $item)
<option value="{{$item->id}}">{{$item->name}}</option>
@endforeach
</select>
@error("products")
<span role="alert"><strong>{{ $message }}</strong></span>
@enderror
</div>
</div>
<div >
<label for="amount" >{{ __("Amount") }}</label>
<div >
<input type="text" amount") is-invalid @enderror" name="amount[]" required autocomplete="amount">
@error("amount")
<span role="alert"><strong>{{ $message }}</strong></span>
@enderror
</div>
</div>
<div >
<button type="button" >
<span >REMOVE</span>
</button>
</div>
</div>
</template>