Search code examples
htmlfunctionhtml-tablerowmultiple-columns

Table cloning error, duplicating the rows, adding two rows at the time


I have issue in my coding, it clone my rows doubled. And I want the label 1 to have increments like +1. Please see the screenshot below. My Table Screenshot

Here is my codes.

<div class="row g-0" id="chartNine" style="display:none;">
  <h4 class="card-title">TOWN'S MAIN FED - SPRINKLER ANNUBAR FLOW TEST</h4>
  <table id="dataTable2" style="width: 390px;">
    <thead>
      <th style="background-color: gray">SITE BLOCK PLAN FLOW REQUIREMENTS</th>
    </thead>
    <td>
      <label for="range1">
       1
      </label>
      <input type="text2" value="0" />
      <label> L/MIN @ </label>
      <input type="text2" value="0" />
      <label> KPA </label>
    </td>             
  </table>
  <button onclick="addTable('dataTable2');">+</button>  
</div>

and here is my function:

function addTable(dataTable2){
  var table=document.getElementById(dataTable2)
  for(var l = 0; l < 2; l++){ 
    var cl = table.tBodies[0].rows[l].cloneNode(true)
    table.tBodies[0].appendChild( cl ) 
  }
}

Your help is what I need, Thank you so much!


Solution

  • you can just use a css counter

    your code (with the corrected HTML):

    function addTable(tableId) 
      {
      let tbody = document.querySelector(`#${tableId} tbody`)
      tbody.appendChild( tbody.querySelector('tr').cloneNode(true) )
      }
    body
      {
      font-family : Arial, Helvetica, sans-serif;
      font-size   : 14px
      }
    #dataTable2 
      {
      counter-reset : nRow;
      }
    #dataTable2 thead th 
      {
      font-size        : 1.2em;
      padding          : .4em 0;
      background-color : gray;  
      min-width        : 34rem;
      }
    #dataTable2 tbody tr td label:nth-child(1) 
      {
      display    : inline-block;
      width      : 2em;
      text-align : center; 
      }
    #dataTable2 tbody tr td label:nth-child(1)::before 
      {
      counter-increment : nRow;             
      content           :  counter(nRow); 
      }
    <div class="row g-0" id="chartNine" >
      <h4 class="card-title">TOWN'S MAIN FED - SPRINKLER ANNUBAR FLOW TEST</h4>
      <table id="dataTable2">
        <thead>
          <tr> <th>SITE BLOCK PLAN FLOW REQUIREMENTS</th> </tr>
        </thead>
        <tbody>
          <tr>
            <td>
              <label></label>
              <input type="text" value="0" />
              <label> L/MIN @ </label>
              <input type="text" value="0" />
              <label> KPA </label>
            </td>
          </tr>
        </tbody>
      </table>
      <button onclick="addTable('dataTable2');">+</button>  
    </div>


    Can I ask another question? what if I want to delete the inserted row or clear it. what can be a useful code?

    normally you should not add a new question to a question that has already been asked and answered. but as this won't bring much to the stackOverflow site and I'm in a good mood, here is a short and technical answer. It uses the event delegation mechanism, properties and methods related to HTML tables you can easily find information on this, both in the developer.mozilla.org doc or here in the questions and answers of SO

    const table2 = document.querySelector('#dataTable2')
      ;
    check4lastOneCantBeActive()   // on init
      ;
    table2.onclick = e =>  // evt delegation code
      {
      if (!e.target.matches('button[data-op]')) return // reject other clicks
    
      if (e.target.dataset.op === 'add')
        {
        let 
          tBody  = table2.querySelector('tbody')
        , newRow = tBody.querySelector('tr').cloneNode(true)
          ;
        newRow.querySelectorAll('input').forEach(el => el.value = 0)
          ;
        tBody.appendChild( newRow )
        }
    
      if (e.target.dataset.op === 'del')
        {
        let rIndx = e.target.closest('tr').rowIndex
        table2.deleteRow(rIndx)
        }
      check4lastOneCantBeActive()
      }
    function check4lastOneCantBeActive() // as it name say's...
      {
      let onlyOne = (table2.tBodies[0].rows.length === 1) 
      table2.querySelectorAll('button[data-op=del]').forEach(bt => bt.disabled = onlyOne )
      }
    body
      {
      font-family : Arial, Helvetica, sans-serif;
      font-size   : 14px
      }
    #dataTable2 
      {
      counter-reset : nRow;
      }
    #dataTable2 thead th 
      {
      font-size        : 1.2em;
      padding          : .4em 0;
      background-color : gray;  
      min-width        : 36rem;
      }
    #dataTable2 tbody tr td label:nth-child(1) 
      {
      display    : inline-block;
      width      : 2em;
      text-align : center; 
      }
    #dataTable2 tbody tr td label:nth-child(1)::before 
      {
      counter-increment : nRow;             
      content           :  counter(nRow); 
      }
    #dataTable2  caption {
      caption-side : bottom;
      text-align   : left;
      margin       : .8em 0 0 0;
      }
      #dataTable2 button[data-op=add] 
      {
      width  : 4em;
      color  : darkblue;
      cursor : pointer;
      }
    #dataTable2 button[data-op=del] 
      {
      width     : 2em;
      color     : crimson;
      cursor    : pointer;
      font-size : .8em;
      margin    : .1em 0 0 1.2em;
      }
    #dataTable2 button[data-op=del]:disabled
      {
      color  : pink;
      cursor : default;
      }
    <div class="row g-0" id="chartNine" >
      <h4 class="card-title">TOWN'S MAIN FED - SPRINKLER ANNUBAR FLOW TEST</h4>
      <table id="dataTable2">
        <caption><button data-op="add"  title="add new row"> &#10010; </button>  </caption>
        <thead>
          <tr> <th>SITE BLOCK PLAN FLOW REQUIREMENTS</th> </tr>
        </thead>
        <tbody>
          <tr>
            <td>
              <label></label>
              <input type="text" value="0" />
              <label> L/MIN @ </label>
              <input type="text" value="0" />
              <label> KPA </label>
              <button data-op="del" title="delete row"> &#10006; </button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>