skip to Main Content

I am trying to do an onclick delete on selected dynamic elements but for some reason it only selects the first element every time.

// Function to delete entries
$("#timesheet").on('click', '.delRow', function () {
    const firstUrl = "API LINK..."
    const secondUrl = document.getElementById("timesheetDetailsID").innerText
    console.log(secondUrl)
    const settings = {
        "async": true,
        "crossDomain": true,
        "url": JSON.stringify(firstUrl + secondUrl),
        "method": "DELETE",
        "headers": {
            "Content-Type": "application/json"
        },
        "processData": false,
        success: function () {
            alert("Yay")
        },
        error: function () {
            //error handler
            alert("Boo")
        }
    };
    $.ajax(settings).done(function (response) {
        console.log(response);
    });
});

Example of the HTML page:
Example of the HTML

//Dynamic HTML 
const htmlTemplate = `
    <tr id = "testDeleteTimesheet">
      <td>${entry.hours}</td>
<td id = "timesheetDetailsID" style = "display: none;">${entry.timesheetDetailsId}</td>
      <td>${chartDate}</td>
      <td>${entry.contractCode}</td>
      <td>${entry.activityCode}</td>
      <td>${entry.otFlag}</td>
      <td>${entry.notes}</td>
      

<td><button id="edit-" + counter + "" class="btn editRow btnStyle btn-primary btn-sm"><span class= "bi bi-pencil"></span></button> 
<button id="delete-" + counter + "" class="btn delRow btnStyle btn-danger btn-sm"><span class="bi bi-eraser"></span></button></td>
    </tr>
    `;

This is my static html where the dynamic content targets

//.html page
 <table class="table" id="timesheet">
     <thead>
        <tr>
          <th scope="col">Hours</th>
          <th scope="col">Date</th>
          <th scope="col">ContractCode</th>
          <th scope="col">Activity Code</th>
          <th scope="col">OT</th>
          <th scope="col">Notes</th>
          <th scope="col" id="rowBtns"></th>
        </tr>
   </thead>
<tbody id="tsdata"></tbody>
</table>

3

Answers


  1. If you have more timesheets, you have to use class instead ID.

    Login or Signup to reply.
  2. You are re-using the same id value multiple times in your HTML. If you have multiple elements with id="timesheetDetailsID" then which element do you expect document.getElementById("timesheetDetailsID") to return and why? Since IDs are supposed to be unique, the browser stops looking when it finds one.

    Use a class instead of an id:

    <tr class="testDeleteTimesheet">
      <td>${entry.hours}</td>
      <td class="timesheetDetailsID" style="display: none;">${entry.timesheetDetailsId}</td>
      <!-- etc. -->
    

    Then in your click handler, traverse the DOM from $(this) to find the element you want for that specific row:

    const secondUrl = $(this).closest('tr.testDeleteTimesheet').find('td.timesheetDetailsID').text();
    

    This will start at the clicked element, use .closest() to traverse up to the parent <tr> element, then use .find() to traverse back down to the intended <td> element, then get that element’s text.

    Login or Signup to reply.
  3. Below is a working example:

    const data = [{
        hours: 8,
        timesheetDetailsId: '/url/1',
        contractCode: 'NT/00008',
        activityCode: 'TEST',
        otFlag: false,
        notes: 'Test Test Test'
      },
      {
        hours: 8,
        timesheetDetailsId: '/url/2',
        contractCode: 'NT/00008',
        activityCode: 'TEST',
        otFlag: false,
        notes: 'Test Test Test'
      },
      {
        hours: 8,
        timesheetDetailsId: '/url/3',
        contractCode: 'NT/00008',
        activityCode: 'TEST',
        otFlag: false,
        notes: 'Test Test Test'
      },
      {
        hours: 8,
        timesheetDetailsId: '/url/1',
        contractCode: 'NT/00008',
        activityCode: 'TEST',
        otFlag: false,
        notes: 'Test Test Test'
      },
      {
        hours: 8,
        timesheetDetailsId: '/url/4',
        contractCode: 'NT/00008',
        activityCode: 'TEST',
        otFlag: false,
        notes: 'Test Test Test'
      },
    
    ];
    
    const chartDate = '1-Sep-2021';
    let counter = 0;
    
    
    data.forEach(entry => {
      counter++;
      const htmlTemplate = `
    <tr id = "testDeleteTimesheet">
        <td>${entry.hours}</td>
        <td class="timesheetDetailsID" style = "display: none;">${entry.timesheetDetailsId}</td>
        <td>${chartDate}</td>
        <td>${entry.contractCode}</td>
        <td>${entry.activityCode}</td>
        <td>${entry.otFlag}</td>
        <td>${entry.notes}</td>
        <td>
          <button id="edit-${counter}" class="btn editRow btnStyle btn-primary btn-sm">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil" viewBox="0 0 16 16">
              <path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
            </svg>
          </button> 
          <button id="delete-${counter}" class="btn delRow btnStyle btn-danger btn-sm">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eraser" viewBox="0 0 16 16">
              <path d="M8.086 2.207a2 2 0 0 1 2.828 0l3.879 3.879a2 2 0 0 1 0 2.828l-5.5 5.5A2 2 0 0 1 7.879 15H5.12a2 2 0 0 1-1.414-.586l-2.5-2.5a2 2 0 0 1 0-2.828l6.879-6.879zm2.121.707a1 1 0 0 0-1.414 0L4.16 7.547l5.293 5.293 4.633-4.633a1 1 0 0 0 0-1.414l-3.879-3.879zM8.746 13.547 3.453 8.254 1.914 9.793a1 1 0 0 0 0 1.414l2.5 2.5a1 1 0 0 0 .707.293H7.88a1 1 0 0 0 .707-.293l.16-.16z"/>
            </svg>
          </button>
        </td>
    </tr>`;
    
      $(`#tsdata`).append(htmlTemplate)
    })
    
    $(`.delRow`).on(`click`, function(){
      const tr = $(this).closest(`tr`);
      const timesheetDetailsID = tr.find(`.timesheetDetailsID`);
      console.log(timesheetDetailsID.text())
      tr.remove();
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
    
    <table class="table" id="timesheet">
      <thead>
        <tr>
          <th scope="col">Hours</th>
          <th scope="col">Date</th>
          <th scope="col">ContractCode</th>
          <th scope="col">Activity Code</th>
          <th scope="col">OT</th>
          <th scope="col">Notes</th>
          <th scope="col" id="rowBtns"></th>
        </tr>
      </thead>
      <tbody id="tsdata"></tbody>
    </table>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search