why does adding the script doesn;t sum all the int PHP adding variables in the text box

Viewed 42

I have following Code which doesn't seems to work correctly when i added the script to add the values in the total that are shown in the total text box

    <tbody id='table'>
                 <tr class="crow">
                    <td style='width:150px;'>1</td>
                    <td style='width:350px;'>
                        <select class="form-control FID" required name="FID[]">
                            <?php 
                                $options="<option value='' Amount='0' >Select</option>";
                                foreach($data["challan"] as $row){
                                    $options.="<option value='{$row["FID"]}' Amount='{$row["Amount"]}'>{$row["Feetype"]}</option>";
                                }
                                echo $options;
                            ?>
                        </select> 
                    </td>
                    <td>
                        <input type="text" name="Amount[]" class="form-control Amount" required>
                    </td>
                    <td>
                        <input type="button" value="Remove" class="btn btn-link btn-xs rmv" required>
                    </td>
                 </tr>
                </tbody>
                <tfoot>
                    <tr>
                        <td ><input type='button' class='btn btn-link add' value='+Add Row'></td>
                       <td colspan="2" class="text-right">Total</td>

                                    <td><input type="text" name="grand_total" id="grand_total" class="form-control" required=""></td>
                     
                    </tr>
                </tfoot>
            </table>
        </div>
    </div>
</div>
    
<script>
$(document).ready(function(){
    
    $("body").on("click",".add",function(){
        var i=1;
        $(".crow").each(function(){
            i++;
        });
        var options="<?php echo $options; ?>";
       
        var row='<tr class="crow"> <td>'+i+'</td> <td> <select class="form-control FID chosen" required name="FID[]">'+options+'</select></td><td> <input type="text" name="Amount[]" class="form-control  Amount" required> </td></td><td> <input type="button" value="Remove" class="btn btn-link btn-xs rmv" required> </td></tr>';
        $("#table").append(row);
    });
    
    
    $("body").on("click",".rmv",function(){
        if(confirm('Are You Sure?')){
            $(this).parents('tr').remove();
        }
    });  
    
    
    $("body").on("change",".FID",function(){
       var p=$(this).find(":selected").attr("Amount");
       $(this).closest("tr").find(".Amount").val(p);
    });


$("body").on("keyup",".Amount",function(){
                    var Amount=Number($(this).val());
                
                    $(this).closest("tr").find(".total").val(Amount*1);
                    grand_total();
                });
                    
                
                function grand_total(){
                    var tot=0;
                    $(".total").each(function(){
                        tot+=Number($(this).val());
                    });
                    $("#grand_total").val(tot);
                }



});
</script>

I want to get little help that How can show the total amount in the total box, it will add all the values that are shown in the total column to show total in total text box at the end. i try to use the code but some how script doesn't seems to work correctly. Thanks

1 Answers

I do not use jQuery ( always find it doesn't work as expected ) but with some simple vanilla Javascript this is fairly straightforward, no doubt some of what I wrote here you will be able to port into your jQuery code if you need to but the following example seems to work as you need it to. There are comments in the code to describe what is occurring but essentially a delegated event listener is bound to the document itself ( alternatively it could be the table ) and all button clicks and mouse events are delegated to the correct component thanks to event bubbling. To help identify which buttons are clicked and the task they are to perform I simply added a dataset attribute to each, other than that the HTML is as per the original though obviously the select menu has been hardcoded with dummy data though the hardcoded row number was replaced with a css counter. Hope you find something of value in the following...

const d=document;
const total=d.querySelector('input[name="grand_total"]');



d.addEventListener('click',e=>{
  /* Add new row */
  if( e.target.classList.contains('btn-link') && e.target.dataset.action=='add' ){
    let tbody=d.querySelector('tbody#table');
    let tr=tbody.querySelector('tr:first-of-type');
    
    /* clone the first table row and clear any values previously entered */
    let clone=tr.cloneNode( true );
        clone.querySelector('input[name="Amount[]"]').value='';

    /* add the new row to the table. */
    tbody.appendChild( clone );
  }
  
  
  
  
  /* Remove existing row - NOT first row though! */
  if( e.target.classList.contains('btn-link') && e.target.dataset.action=='remove' ){
    if( d.querySelectorAll('tbody#table tr').length > 1 ){
      // We need to identify the value entered into 'Amount[]' so that we can remove
      // it from the total.
      let value=e.target.closest('tr').querySelector('input[name="Amount[]"]').value;
      
      // find and remove the button's parent row
      // using closest to move UP the DOM until it finds the TR node.      
      d.querySelector('tbody#table').removeChild( e.target.closest('tr') );
      
      // subtract this value from the total
      total.value-=parseFloat( value )
    }
  }
});



// tally up all numbers entered by iterating through all input elements
// with the name Amount[]
d.addEventListener('keyup',e=>{
  let col=d.querySelectorAll('input[name="Amount[]"]');
  
  // convert nodelist to an array and use regular array methods (map & reduce)
  // to return the sum
  total.value=[...col]
    .map(n=>n.value > 0 ? n.value : 0)
    .reduce((a,b)=>parseFloat(a) + parseFloat(b));
});
html{counter-reset:rows}
tr{counter-increment:rows}
tbody td{border:1px dotted grey;padding:0.25rem}
tbody tr td:first-of-type::before{content:counter(rows);display:table-cell}
tfoot td{background:grey;padding:0.5rem;color:white}
<table>
  <tbody id='table'>
    <tr class='crow'>
      <td style='width:150px;'></td>
      <td style='width:350px;'>
        <select class='form-control FID' required name='FID[]'>
          <option value=1>banana
          <option value=2>giraffe
          <option value=3>hercules
          <option value=4>didgeridoo
          <option value=5>womble
        </select>
      </td>
      <td>
        <input type='text' name='Amount[]' class='form-control Amount' required />
      </td>
      <td>
        <input data-action='remove' type='button' value='Remove' class='btn btn-link btn-xs rmv' required />
      </td>
    </tr>
  </tbody>
  
  <tfoot>
    <tr>
      <td><input data-action='add' type='button' class='btn btn-link add' value='+Add Row' /></td>
      <td colspan='2' class='text-right'>Total</td>
      <td><input type='text' name='grand_total' class='form-control' required /></td>
    </tr>
  </tfoot>
</table>

Related