Shr4[] do not readjust when any dynamic row is deleted

I am trying to get share on the basis of total amount recieved. for this i have dynamic row created table. for example there are two rows in my dynamic created row table
1 cost 500 amount is
2 cost 1000 amount
total amount receieved 1200 , now this 1200 should distribute as per their cost percentage. everything working fine. even when i add new dynamic, share readjust. but the issue is when I delet any dynamic row, then shr4 unable to readjust. below is my code

<!DOCTYPE html>
<html lang="en">
<head>
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Patient Bill</title> 

	<script src=
		"https://code.jquery.com/jquery-3.2.1.min.js">
	</script>

	<script src=
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
		type="text/javascript">
	</script>
	
	<link rel="stylesheet" href=
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

	<script src=
"https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">
	</script>

   
         <!-- jQuery CDN -->
    <script src="https://code.jquery.com/jquery-3.6.2.slim.js" integrity="sha256-OflJKW8Z8amEUuCaflBZJ4GOg4+JnNh9JdVfoV+6biw=" crossorigin="anonymous"></script>
    
</head>
<body>
    <table class="table table-bordered">
        <thead class="table-success" style="background-color: #3fbbc0;">
            <tr>
                <th width="10%"><center>Service</center></th>
                <th width="10%"><center>Type</center></th>
                <th width="10%"><center>Consultant</center></th>
                <th width="10%"><center>Total</center></th>
                <th width="10%"><center>Share</center></th>
                <th width="5%"></th>
<button type="button" class="btn btn-sm btn-success" onclick="BtnAdd()">Add Item</button>  
            </tr>
        </thead>
        <tbody id="TBody">
            <tr id="TRow" class="d-none">
                <td><select class="country form-control text-end" name="country[]" required></select></td>
                <td><select class="state form-control text-end" name="state[]" required><option value="">select Type</option></select></td>
                <td><select class="city form-control text-end" name="city[]" required onchange="GetDetail(this.closest('tr'))"><option value="">Select Cons</option></select></td>
                <td><input type="text" class="tot4 form-control text-end" name="tot4[]" ></td>
                <td><input type="text" class="shr4 form-control text-end" name="shr4[]"></td>
                <td class="NoPrint"><button type="button" class="btn btn-success" onclick="BtnDel(this)">x</button></td>
            </tr>
        </tbody>
    </table>

    <div class="row">
        <div class="col-lg-4">
            <div class="form-group">
                <label>Total Amount Received:</label>
                <input type="text" name="payrecved3" id="payrecved3" class="form-control" oninput="distributeAmount()" required>
            </div>
        </div>
        <div class="col-lg-4">
            <div class="form-group">
                <center><input type="submit" name="submit" id="submit" value="Submit" class="btn btn-success submit_btn invoice-save-btm"></center>
            </div>
        </div>
    </div>

   


    <!-- Bootstrap Bundle JS -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>


 <!-- Include necessary JS files -->
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <script>
        $(document).ready(function () {
            function distributeAmount() {
                let totalReceived = parseFloat($('#payrecved3').val()) || 0;
                let totalShare = 0;
                let rows = $('#TBody').find('tr');

                // Calculate the total share
                rows.each(function () {
                    let share = parseFloat($(this).find('.tot4').val()) || 0;
                    totalShare += share;
                });

                // Distribute the amount based on share
                rows.each(function () {
                    let share = parseFloat($(this).find('.tot4').val()) || 0;
                    let total = totalShare > 0 ? (share / totalShare) * totalReceived : 0;
                    $(this).find('.shr4').val(total.toFixed(2));
                });
            }

            // Event listener for changes in share input fields
            $(document).on("input", ".tot4", function() {
                distributeAmount();
            });
            
            // Event listener for changes in the total amount received
            $('#payrecved3').on("input", function() {
                distributeAmount();
            });
        });
    </script>





 <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> 
     <script src="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.8.7/chosen.jquery.min.js"></script>
   <link rel = "stylesheet" href = "https://cdnjs.cloudflare.com/ajax/libs/chosen/1.8.7/chosen.min.css">
   
    <script>
        $(document).ready(function() {
            $('.chosen-select').chosen();
        });
    </script>
 </body>
</html>

<script type="text/javascript">

function GetPrint()
{
    /*For Print*/
    window.print();
}

function BtnAdd() {
    // Destroy any existing chosen select elements
    $('.chosen-select').chosen('destroy');
    
    // Clone the row template and append it to the tbody
    var rowCount = $('#TBody tr').length; // Count the number of rows in tbody
    var v = $('#TRow').clone().appendTo('#TBody');
    
    // Remove id and d-none class from the cloned row
    $(v).removeAttr('id').removeClass('d-none');
    
    // Update input names with unique indices
    $(v).find('input').each(function() {
        var name = $(this).attr('name');
        if (name) {
            var newName = name.replace(/\[\d+\]/, '[' + rowCount + ']'); // Replace the first array index with the new index
            $(this).attr('name', newName);
        }
    });
    
    // Update select names with unique indices
    $(v).find('select').each(function() {
        var name = $(this).attr('name');
        if (name) {
            var newName = name.replace(/\[\d+\]/, '[' + rowCount + ']'); // Replace the first array index with the new index
            $(this).attr('name', newName);
        }
    });
    
    // Initialize Chosen plugin for new selects
    $('.chosen-select').chosen({width: '100%'});
    
    // Clear input values in the cloned row
    $(v).find("input").val('');
    
    // Initialize autocomplete if needed
    $(v).find("input").autocomplete({
        source: 'backend-script.php'  
    });
    
    // Update the row number in the first <th> element
    $(v).find("th").first().html(rowCount + 1);
}


function BtnDel(v)
{
    /*Delete Button*/
       $(v).parent().parent().remove(); 
       GetTotal();

        $("#TBody").find("tr").each(
        function(index)
        {
           $(this).find("th").first().html(index);
        }

       );
}




</script>

</body>
</html>

Does this method call the distributeAmount method? I’m guessing not.

i need both, distributedamoutn as well as this, how can i used both with btndel

I’m sorry but I’m not sure I’m understanding what you’re asking.

If you look at the BtnAdd method, there look to be scripts which trigger on the add (like the autocomplete backend script call). These will fire the distributeAmount() method due to the onchange event listeners.

The btnDelete just removes the row, which removes the event listeners since the object doesn’t exist. Thus it needs to call the distributeAmount() method manually to re-distribute the dollar amounts appropriately. If you need a new amount in the #payrecved3 element, you’re going to need to set that manually as well.

I think it’s probably because of this:

OP has bound a delegated listener on $(document).on("input", ".tot4", function() { that forces a refresh because the btnAdd code fiddles with the input value.

Dave’s correct though - you’ll need to trigger a call to distributeAmount inside the btnDel code (preferably at the end, because you don’t want your distribute function to find the fields you’re about to delete but haven’t yet.)

2 Likes