Creating elements using a loop in JS.

Joined
Nov 19, 2024
Messages
1
Reaction score
0
I'm using AJAX to retrieve data from a MySQL Database and create a table. In the end column of the table, I want a series of buttons, to carry out different actions for that record (the same actions, using the same set of functions, just with a different record).

What I've tried is:

Code:
for (var line of liveFeedJSON) {

  //Create <tr> and <tds>

  tscButton = document.createElement('button');
  tscButton.innerHTML = '<span class="fa-solid fa-keyboard">';
  tscButton.className = 'actionButton';
  tscButton.onclick = function() {checkAction(this, currentUser, line['svcID'], 'shtTSC', 'System updated.');};

  functionsCell.appendChild(tscButton);
}

The trouble is, it seems to pass the arguments from the last line created, whichever button is clicked on and I can't work out how to get round this. Any ideas would be very welcome!

Thanks
Chris
 
Joined
Jul 4, 2023
Messages
589
Reaction score
78
You might want to consider using the HTML data-* attribute and an event.target to recognize which button was clicked.
Check this example:
HTML:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet"
          href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.1/css/all.min.css">

    <style>
      table {
        cursor: default;
        width: 70dvw;
        margin-inline: auto;
        text-align: center;
      }
      thead tr {
        background-color: black;
        color: white;
      }
      tbody tr {
        transition: background-color 120ms;
      }
      tbody tr:nth-child(even) {
        background-color: rgba(0,0,0,0.1);
      }
      tbody tr:hover {
        background-color: rgba(0,0,0,0.4);
      }    
      tbody .action-button button {
        cursor: pointer;
        border: none;
        background-color: transparent;
      }
      tbody .action-button button + button {
        margin-left: .5rem;
      }
     
     
      #console {
        width: 70dvw;
        height: 10ch;
        margin-inline: auto;
        font: 300 .9rem/1 system-ui, monospace, sans-serif;
        background-color: black;
        color: limegreen;
        padding: .5rem;
        overflow-y: auto;
      }
    </style>
  </head>
  <body>
    <table>
      <thead>
        <tr>
          <th>currentUser</th>
          <th>line['svcID']</th>
          <th>shtTSC</th>
          <th>action</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
    <pre id="console"></pre>

    <script>
      const liveFeedJSON = [
        { id: 'u01', currentUser: 'currentUser1', line: 'svcID1', shtTSC: 'shtTSC1' },
        { id: 'u02', currentUser: 'currentUser2', line: 'svcID2', shtTSC: 'shtTSC2' },
        { id: 'u03', currentUser: 'currentUser3', line: 'svcID3', shtTSC: 'shtTSC3' },
        { id: 'u04', currentUser: 'currentUser4', line: 'svcID4', shtTSC: 'shtTSC4' },
        { id: 'u05', currentUser: 'currentUser5', line: 'svcID5', shtTSC: 'shtTSC5' },
        { id: 'u06', currentUser: 'currentUser6', line: 'svcID6', shtTSC: 'shtTSC6' },
        { id: 'u07', currentUser: 'currentUser7', line: 'svcID7', shtTSC: 'shtTSC7' }
      ];

      const tbody = document.querySelector('table tbody');
      const table_html = document.createDocumentFragment();

      for (const line of liveFeedJSON) {
        const tr = document.createElement('tr');
        tr.innerHTML += `
          <td>${line.currentUser}</td>
          <td>${line.line}</td>
          <td>${line.shtTSC}</td>
          <td class="action-button">
            <button title="edit ${line.currentUser}"
              data-action="edit"
              data-current-user="${line.currentUser}"
              data-line="${line.line}"
              data-shttsc="${line.shtTSC}">
                <span class="fa-solid fa-keyboard"></span>
            </button>
           
            <button title="delete ${line.currentUser}"
              data-action="delete"
              data-id="${line.id}">
                <span class="fa-solid fa-trash-can"></span>
            </button>
          </td>
        `;
        table_html.appendChild(tr);
      }
      tbody.appendChild(table_html);

      tbody.addEventListener('click', checkAction);
      function checkAction(e) {// event alias
        if (!e.target.matches('.action-button button, span')) return;
       
        const button = (e.target.matches('.action-button span'))
        ? e.target.closest('button')
        : e.target;

        if (button.dataset.action === 'edit') {
          // here code for action: edit
          const log = `${button.dataset.action}: ${button.dataset.currentUser} [ ${button.dataset.line}, ${button.dataset.shttsc}]`;
          consoleLog(log);
        }
       
        if (button.dataset.action === 'delete') {
          // here code for action: delete
          const log = `${button.dataset.action}: ${button.dataset.id}`;
          consoleLog(log);
        }      
      }

      function consoleLog(log) {
        const console_ = document.querySelector('#console');
        console_.textContent += log.trim() + '\n';
        console_.scrollTop = console_.scrollHeight;
      }
    </script>
  </body>
</html>
1733367765489.png
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,260
Messages
2,571,038
Members
48,768
Latest member
first4landlord

Latest Threads

Top