skip to Main Content

Why is .append() creating 2 identical rows in this code when I click Add New button? I don’t see why 2 appends happen. Am I misunderstanding something? This doesn’t happen with vanilla javascript but happens with jquery.

I added the table which includes the tbody tag at the end of the table where I would like to append the template string in function onAddProduct(e).
(Note: I removed html since it was an assignment.)

here is the code snippet

$(function() {
  var $formEl  = $('form');
  var $tbodyEl = $('tbody');
  var $tableEl = $('table');

  function onAddProduct(e) {
    e.preventDefault();
    var $pName = $('#pname').val();
    var $pCat = $('#pcat').val();
    var $pPrice = $('#pprice').val();
    $tbodyEl.append(`
                <tr>
                    <td>${$pName}</td>
                    <td>${$pCat}</td>
                    <td>${$pPrice}</td>
                    <td><button class="deleteBtn">Delete</button></td>
                </tr>
                `);
  }

  function onDeleteRow(e) {
    if (!e.target.classList.contains("deleteBtn")) {
      return;
    }

    const btn = e.target;
    btn.closest("tr").remove();
  }

  //formEl.addEventListener("submit", onAddProduct);
  $formEl.on({
    submit: onAddProduct
  });
  //tableEl.addEventListener("click", onDeleteRow);    
  $tableEl.on({
    click: onDeleteRow
  });
});

2

Answers


  1. Consider the following.

    $(function() {
      var $formEl = $('form');
      var $tbodyEl = $('tbody');
      var $tableEl = $('table');
    
      function onAddProduct(e) {
        e.preventDefault();
        var row = $("<tr>").appendTo($("tbody", $tableEl));
        $("<td>").html($('#pname').val()).appendTo(row);
        $("<td>").html($('#pcat').val()).appendTo(row);
        $("<td>").html($('#pprice').val()).appendTo(row);
        $("<td>").html("<button class='deleteBtn'>Delete</button>").appendTo(row);
        return;
      }
    
      function onDeleteRow(e) {
        if (!e.target.classList.contains("deleteBtn")) {
          return;
        }
        if (confirm("Are you sure you want to delete this Product?")) {
          $(e.target).closest("tr").remove();
        }
      }
    
      $formEl.on({
        submit: onAddProduct
      });
      
      $tableEl.on({
        click: onDeleteRow
      });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <h4>Add Product</h4><br>
    <form>
      <label for="pname">Product Name:</label>
      <input type="text" id="pname" name="pname">
      <label for="pcat">Product Category:</label>
      <input type="text" id="pcat" name="pcat">
      <label for="pprice">Product price:</label>
      <input type="text" id="pprice" name="pprice">
      <button type="submit" class="addBtn">Add New</button>
    </form>
    <table>
      <thead>
        <tr>
          <th>Product Name</th>
          <th>Product Category</th>
          <th>Product Price</th>
          <td>&nbsp;</td>
        </tr>
      </thead>
      <tbody>
      </tbody>
    </table>

    I am not able to replicate the issue with this code. Only 1 Row is added.

    Login or Signup to reply.
  2. Your table is missing the <tbody> around the rows you have added, so the browser is adding it in to create a valid table. This results in 2 <tbody> elements, and is why rows are being added twice:
    enter image description here

    It can be prevented by putting the header and body rows inside the <thead> and <tbody> elements that the browser wants, seen below in the snippet –

    $(function() {
      var $formEl = $('form');
      var $tbodyEl = $('tbody');
    
      function onAddProduct(e) {
        e.preventDefault();
        var $pName = $('#pname').val();
        var $pCat = $('#pcat').val();
        var $pPrice = $('#pprice').val();
        $tbodyEl.append(`
                    <tr>
                        <td>${$pName}</td>
                        <td>${$pCat}</td>
                        <td>${$pPrice}</td>
                    </tr>
                    `);
      }
    
      $formEl.on({
        submit: onAddProduct
      });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <table id="productTable" border="1">
      <thead>
        <tr>
          <th>Product Name</th>
          <th>Product Category</th>
          <th>Product Price</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>M&M</td>
          <td>Snacks</td>
          <td>$1.99</td>
        </tr>
        <tr>
          <td>Table</td>
          <td>Furniture</td>
          <td>$1.99</td>
        </tr>
        <tr>
          <td>Kale</td>
          <td>Vegetables</td>
          <td>$2.49</td>
        </tr>
      </tbody>
    </table>
    <h4>Add Product</h4><br>
    <form>
      <label for="pname">Product Name:</label>
      <input type="text" id="pname" name="pname">
      <label for="pcat">Product Category:</label>
      <input type="text" id="pcat" name="pcat">
      <label for="pprice">Product price:</label>
      <input type="text" id="pprice" name="pprice">
      <button type="submit" class="addBtn">Add New</button>
    </form>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search