1

I am new to programming so I really really appreciate if any of you would be able to help me with my code. I managed to solve my problem before this by referring to this link :

previous row is not computing/updating from appended rows using jquery

But then I have to combine that code with this :

function cloneMore(selector, prefix) {
    var newElement = $(selector).clone(true);
    var total = $('#id_' + prefix + '-TOTAL_FORMS').val();
    newElement.find(':input:not([type=button]):not([type=submit]):not([type=reset])').each(function() {
         var name = $(this).attr('name').replace('-' + (total-1) + '-', '-' + total + '-');
         var id = 'id_' + name;
         $(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
    });
    total++;
    $('#id_' + prefix + '-TOTAL_FORMS').val(total);
    $(selector).after(newElement);
    fullrowname = selector.substring(0,selector.length - 4) + 'not(:last)'
    var conditionRow = $(fullrowname);
    conditionRow.find('.btn.add-form-row')
    .removeClass('btn-success').addClass('btn-danger')
    .removeClass('add-form-row').addClass('remove-form-row')
    .html('<span class="fas fa-minus" aria-hidden="true"></span>');
    return false;
}

$("input.quantity,input.price").on('change', function() {
    Total($(this).attr("for"));
});  

The id is increment perfectly everytime I click the add button but the for="0" attribute is not increment. Hence my calculation for the dynamic input is not working :(

Can you guys show me the way of how to increment the "for" attribute in the code above ?

jojo1711
  • 93
  • 2
  • 10

1 Answers1

1

The approach you're using, and the previous answer you were given are flawed. Incremental id attributes which are generated at runtime in dynamic content is an anti-pattern which should, IMO, never be used. The code quickly becomes an unmaintainable, verbose, mess.

A far better approach is to use common classes on elements grouped by behaviour. Then you can use a single delegated event handler for all these elements. Inside those event handlers you can use DOM traversal methods to relate the elements to each other and interact with them.

In addition you should not put that much HTML code in the JS logic. Ideally, there should be none at all. To fix that you can instead clone() existing DOM elements and append them in a new location to create the new rows.

Finally, note that when sending AJAX requests you should hook to the submit event of the form, not the click of the submit button.

With all that said, try this:

jQuery($ => {
  let $table = $('#articles');

  $table.on('input', '.quantity, .price', function() {
    let $row = $(this).closest('tr');    
    let qty = $row.find('.quantity').val();
    var price = $row.find('.price').val();
    var total = (qty * price).toFixed(2);
    $row.find('.total').val(total);  
  })

  $table.on('click', '.btn-remove', function() {
    if ($table.find('tr').length > 1) // prevent deletion of all rows
      $(this).closest('tr').remove();
  })
 
  $table.on('click', '.btn-add', function() {
    let $clone = $table.find('tr:first').clone().appendTo($table);
    $clone.find('.quantity, .price').val('0');
    $clone.find('.total').val('');
  });

  $('#add_name').on('submit', function(e) {
    e.preventDefault();
    let $form = $(this);
    $.ajax({
      url: "wwwdb.php",
      method: "POST",
      data: $form.serialize(),
      success: function(data) {
        $form[0].reset();
      }
    });
  });
});
table tr:first-of-type td:last-of-type button {
  visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<div class="container">
  <br />
  <br />
  <div class="form-group">
    <form name="add_name" id="add_name">
      <div class="table-responsive">
        <table class="table table-bordered" id="articles">
          <tr class="rrjeshta">
            <td><input value="0" type="number" name="quantity[]" placeholder="quantity" class="form-control name_list quantity" /></td>
            <td><input value="0" type="number" name="price[]" placeholder="price" class="form-control name_list price" /></td>
            <td><input type="number" name="total[]" placeholder="total" class="form-control name_list total" readonly /></td>
            <td><button type="button" name="add" class="btn btn-success btn-add">Add new</button></td>
            <td><button type="button" name="remove" class="btn btn-danger btn-remove">X</button></td>
          </tr>
        </table>
        <input type="submit" class="btn btn-info" value="Submit" />
      </div>
    </form>
  </div>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339