Search code examples
javascriptjquery

Get the contents of a table cell for all selected rows


I have a table of user info. When you click the button, I want to get the email address from each selected row, output into a comma-separated string.

<table>
   <tr>
      <td><input type="checkbox" class="selector"></td>
      <td class="name">John Doe</td>
      <td class="country">Australia</td>
      <td class="email">[email protected]</td>
    </tr>
    <tr>
      <td><input type="checkbox" class="selector"></td>
      <td class="name">Jane Smith</td>
      <td class="country">Canada</td>
      <td class="email">[email protected]</td>
    </tr>
</table>

<button onclick="tableToEmail()">Get Emails</button>

I got it to work with the following code, but I'm a novice with JS so I assume it must be inefficient:

function tableToEmail() {

  var recipients = [];
  $('input.selector:checked').each(function(){
      var email = $(this).closest('tr').find('.email');
      recipients.push(email.text());
  });
  console.log(recipients.join(','));

}

Is there a better way to achieve this, preferably with vanilla JS if jQuery is not needed?

Thank you!


Solution

  • Here is a vanilla version using eventListeners

    Note I added a tbody to make the HTML valid

    window.addEventListener('DOMContentLoaded', () => { // page elements are available
      const table = document.querySelector('table tbody'); // change to suit how to access the table
      document.getElementById('tableToEmailButton').addEventListener('click', () => {
        const emails = Array.from(table.querySelectorAll('input.selector:checked')) // get only the checked checkboxes
          .map(chk => chk.closest('tr').querySelector('.email').textContent.trim()); // trim is always a good idea
        console.log(emails. length > 0 ? emails.join(', ') : 'None checked'); 
      });
    });
    <table>
    <tbody>
       <tr>
          <td><input type="checkbox" class="selector"></td>
          <td class="name">John Doe</td>
          <td class="country">Australia</td>
          <td class="email">[email protected]</td>
        </tr>
        <tr>
          <td><input type="checkbox" class="selector"></td>
          <td class="name">Jane Smith</td>
          <td class="country">Canada</td>
          <td class="email">[email protected]</td>
        </tr>
        <tbody>
    </table>
    
    <button id="tableToEmailButton">Get Emails</button>

    Same in jQuery

    $(() => { // page elements are available
      const $table = $('table tbody'); // change to suit how to access the table
      $('#tableToEmailButton').on('click', () => {
        const emails = $('input.selector:checked', $table) // get only the checked checkboxes
          .map(function() { // NOTE this is a jQuery map, not an array.map
            return $(this).closest('tr').find('.email').text().trim(); // trim is always a good idea 
          })
          .get(); // now it is an array
        console.log(emails.length > 0 ? emails.join(', ') : 'None checked');
      });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <table>
      <tbody>
        <tr>
          <td><input type="checkbox" class="selector"></td>
          <td class="name">John Doe</td>
          <td class="country">Australia</td>
          <td class="email">[email protected]</td>
        </tr>
        <tr>
          <td><input type="checkbox" class="selector"></td>
          <td class="name">Jane Smith</td>
          <td class="country">Canada</td>
          <td class="email">[email protected]</td>
        </tr>
        <tbody>
    </table>
    
    <button id="tableToEmailButton">Get Emails</button>