Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS/jQuery: Copying Contents of td to clipboard

I'm working on a project where I have a table full of first names, last names, and e-mail addresses. The last td should be a button that allows the user to copy that particular person's e-mail address to the clipboard.

Also yes, I'm aware this is in old-school JS, I'm working on a legacy project.

Here's my code on codepen.io: https://codepen.io/anfperez/pen/ZZdwWL

HTML

<table style="width:100%">
  <tr>
    <th>Firstname</th>
    <th>Lastname</th> 
    <th>E-mail</th>
    <th>Button</th>
  </tr>
  <tr>
    <td>Jill</td>
    <td>Smith</td> 
    <td id="email">[email protected]</td>
    <td><button>Click to Copy</button></td>
  </tr>
  <tr>
    <td>Eve</td>
    <td>Jackson</td> 
    <td id="email">[email protected]</td>
    <td><button>Click to Copy</button></td>
  </tr>
</table>

JS

function copyToClipboard() {
    var copyText = document.getElementById("email")
    copyText.select();
    document.execCommand("copy");
    alert("Copied the text: " + copyText.value);
}

So, I have two dilemmas: 1) how can I get each button generated to copy the correct e-mail address (not just one or all of them)? I need to assign unique IDs to each entry it seems, but I don't really know how to start generating those if the list gets longer.

2) I keep getting the error that "copyText.select() is not a valid function". I've been following several tutorials in which this method is used, so I'm not sure why it's not working here.

like image 437
Leia_Organa Avatar asked Jan 02 '23 00:01

Leia_Organa


1 Answers

As Robin Zigmond says, you need to change id="email" to class="email" to be able to find the correct TD, and because each id must be unique.

Once you have done that, you can add an event listener to each button programmatically, and within the listener find the email TD with the email classname.

Selecting text only works in elements that can have text input (i.e. textarea and input type="text"), so you need to create a temporary element to put the text into, and copy it from there.

(function()
{
  let buttons = document.getElementsByTagName('Button');
  for(let i = 0; i < buttons.length; i++)
  {
    let button = buttons[i];
    button.addEventListener('click', e =>
    {
      let button = e.target;
      let email = button.parentNode.parentNode.getElementsByClassName('email')[0].innerHTML;
      let text = document.createElement('input');
      text.setAttribute('type', 'text');
      text.value = email;
      document.body.appendChild(text);
      text.select();
      document.execCommand('copy');
      document.body.removeChild(text);
    });
  }
})();
<table style="width:100%">
  <tr>
    <th>Firstname</th>
    <th>Lastname</th> 
    <th>E-mail</th>
    <th>Button</th>
  </tr>
  <tr>
    <td>Jill</td>
    <td>Smith</td> 
    <td class="email">[email protected]</td>
    <td><button>Click to Copy</button></td>
  </tr>
  <tr>
    <td>Eve</td>
    <td>Jackson</td> 
    <td class="email">[email protected]</td>
    <td><button>Click to Copy</button></td>
  </tr>
</table>
like image 63
Matt Ellen Avatar answered Jan 05 '23 05:01

Matt Ellen