7

I want to include a button on an existing webpage that will copy text to the Windows clipboard.

The webpage and the PHP in it already works well to create and display text like this:

Output on webpage:

'Abby Normal' <abnormal@rockyhorror.com>, 'Brad Majors' <bm@rockyhorror.com>, 'Frank N. Furter' <franknfurter@rockyhorror.com>

So now I want to add a Javascript function and an html button that calls that function to copy that output to the Windows clipboard.

Problem: nothing is copied when the button is pressed. What am I doing wrong? Thank you in advance.

<?PHP
  session_start();
  include('include/_initsess.php');
  include('include/_setdb.php');
  if(!isset($_SESSION['userlist'])) exit;
  $users = $_SESSION['userlist'];
  $emails = '';
  $qry = "SELECT FIRST,LAST,EMAIL FROM users WHERE PKEY IN ($users)";
  $result  = mysql_query($qry);     
  $numrows = mysql_num_rows($result);   
  for ($m=0; $m<$numrows; $m++) {
    $row = mysql_fetch_array($result); 
    list($fn,$ln,$em) = $row;
    $emails .= ($m==0) ? "'".$fn." ".$ln."' &lt;".$em."&gt;" : (", '".$fn." ".$ln."' &lt;".$em."&gt;");
    } // end for
?>

<html>
<head>
</head>
<body>
<span class=mono id="theList" value="<?php echo $emails; ?>">
  <?PHP echo($emails); ?>
</span>

<script>
function copyToClipboardWithJavascript() {
  /* Get the text field */
  var copyText = document.getElementById("theList");
  /* Select the text field */
  copyText.select();
  /* Copy the text inside the text field */
  document.execCommand("copy");
}
</script>

<button onclick="copyToClipboardWithJavascript()">Click here</button>

</span>
</body>
</html>

I've tried the way a Javascript tutorial suggested:

var copyText = = document.getElementById("theList");

And my own variations using PHP within Javascript:

var copyText = <?PHP echo($emails); ?>;
var copyText = `<?PHP echo($emails); ?>`;
var copyText = "<?PHP echo($emails); ?>";
var copyText = '<?PHP echo($emails); ?>';

But the result is that nothing causes any errors and nothing is copied to the clipboard.

I know the web page is being immediately saved and used because I also make a trivial change to the letters 'Click here' in the button and can see the difference after refreshing.enter code here

***UPDATE WITH ANSWER I USED:****

<span class=mono id="theList">
<?PHP echo($emails); ?>
</span>
<button id="copyButton" onclick="myCopyFunction()">Copy email address list to clipboard.</button>
<script>
function myCopyFunction() {
  var myText = document.createElement("textarea")
  myText.value = document.getElementById("theList").innerHTML;
  myText.value = myText.value.replace(/&lt;/g,"<");
  myText.value = myText.value.replace(/&gt;/g,">");
  document.body.appendChild(myText)
  myText.focus();
  myText.select();
  document.execCommand('copy');
  document.body.removeChild(myText);
}
</script>
Bear. Teddy Bear.
  • 139
  • 1
  • 2
  • 12
  • Are you sure you want to expose those email addresses? – GolezTrol Jun 06 '18 at 21:14
  • 3
    @GolezTrol Those email addresses represent fictional characters. See Rocky Horror Picture Show. Valid concern though :) – Burgan Jun 06 '18 at 21:17
  • @Flashdrive Valid concern, because it is an existing domain (of the RHPS fanclub actually), and therefore maybe existing e-mail addresses too. And if this is indeed the code of that website, this question also exposed that it uses an old version of PHP which doesn't get any patches anymore, and a piece of code that seems to be vulnerable to SQL injection attacks. I'd make a backup, just to be sure. ;-) – GolezTrol Jun 06 '18 at 21:17
  • In that line were echo in span it should be class="mono" missing quotes – Michael Jun 06 '18 at 21:18
  • I just made up the emails. – Bear. Teddy Bear. Jun 07 '18 at 14:26
  • @Michael the missing quotes around mono in class=mono don't seem to be an issue after testing. They are also missing around ttl and note. – Bear. Teddy Bear. Jun 07 '18 at 14:28
  • What have you tried to resolve the problem? Where are you stuck? Is this a PHP problem (printing the markup that makes it work), or a JS problem (finding the proper code to copy something to the clipboard)? – Nico Haase Dec 02 '21 at 13:05

3 Answers3

12

Here is a working example I made:

There are two things you need to know.

  1. Contrary to the previous answer, you CAN actually copy a variable string to the clipboard, as shown in my example.
  2. The user MUST EXPLICITLY take an action which causes the copy function to be called. If it is called automatically, the copy will be denied. This is most likely the cause of your problem.

Here is my example. To briefly explain how this works: a new temporary element of type input type='text' is created, given the value to copy to the clipboard, then the copy command is executed, then that temporary item is removed.

copyToClipboard(document.getElementById("content"));

document.getElementById("clickCopy").onclick = function() {
 copyToClipboard(document.getElementById("goodContent"));
}

document.getElementById("clickCopyString").onclick = function() {
 copyToClipboard("This is a variable string");
}

/**
* This will copy the innerHTML of an element to the clipboard
* @param element reference OR string
*/
function copyToClipboard(e) {
    var tempItem = document.createElement('input');

    tempItem.setAttribute('type','text');
    tempItem.setAttribute('display','none');
    
    let content = e;
    if (e instanceof HTMLElement) {
      content = e.innerHTML;
    }
    
    tempItem.setAttribute('value',content);
    document.body.appendChild(tempItem);
    
    tempItem.select();
    document.execCommand('Copy');

    tempItem.parentElement.removeChild(tempItem);
}
div {
  border: 1px solid black;
  margin: 10px;
  padding: 5px;
}
<div id="content">
This is example text which will NOT be copied to the clipboard.
</div>
<div id="goodContent">
This WILL be copied to the cliboard when you push the button below:
</div>
<button id="clickCopy">
Copy Text from 2nd
</button>

<button id="clickCopyString">
Copy STRING to Clibpoard from Variable
</button>
Brandon Dixon
  • 1,036
  • 9
  • 16
  • This answer works in stackoverflow's "Run Code Snippet" button. Pretty cool of this site to let you test it here. But it and the other answer that uses a javascript variable don't work on my system. I'll get back to you with the javascript version. I've been able to pull the info with this code into an alert window: var myText = document.getElementById("theList"); myText.value = ; alert(myText.value); ----or---- var myText = document.getElementById("theList").innerHTML; alert(myText.value); – Bear. Teddy Bear. Jun 07 '18 at 20:58
  • Do you mean that it does not work at all, or just that it doesn't work automatically? Don't forget that this only works if the user directly causes it to happen, by pushing a button for example. You can't run it automatically because of browser security restrictions. – Brandon Dixon Jun 07 '18 at 21:10
  • I mean it doesn't work when the user presses the button @Brandon Dixon – Bear. Teddy Bear. Jun 08 '18 at 19:34
  • I got it to work. Basically your answer is the one I used @Brandon Dixon. Make an element. Put the text in it. Attach element to the document tree. Select my element. Copy to clipboard. Remove element from document tree. Except I added a myElement.focus(); call right before selecting my element, as specified in https://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript – Bear. Teddy Bear. Jun 08 '18 at 20:15
  • The lack of the .focus() call was causing this error: Uncaught TypeError: myText.select is not a function – Bear. Teddy Bear. Jun 08 '18 at 20:25
  • Thanks a lot! your function is exactly what i need to add "copytoclipboard" function in my project! thank you very much! – P.Davide Jul 06 '20 at 23:23
3

You can't copy directly from a string, only from an HTML element. You need to put the PHP string into the value of the element.

function copyToClipboardWithJavascript() {
  /* Get the text field */
  var copyText = document.getElementById("theList");
  /* Put emails into the text field */
  copyText.value = <?php echo json_encode($emails); ?>;
  /* Select the text field */
  copyText.select();
  /* Copy the text inside the text field */
  document.execCommand("copy");
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 1
    "You can't copy directly from a string, only from an HTML element" is incorrect. My example in my answer shows that this is possible. – Brandon Dixon Jun 06 '18 at 21:33
  • your answer doesn't copy directly from the string, it creates a temporary element, sets its value, then uses the copy command. I'm doing the same thing except the element is in the HTML, not a temporary. – Barmar Jun 06 '18 at 21:38
  • Yes, sorry, I believe I misinterpreted your statement the first time I read it into saying that you can't do it at all. – Brandon Dixon Jun 06 '18 at 21:40
0

This simple solution may work for you. It is what I use. With jQuery.

function copy() {
  navigator.clipboard.writeText($('#link-to-copy').val());
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<span onclick="copy();">
  Copy link
</span>

<input type="hidden" id="link-to-copy" value="<?= $link_copy ?>">

When you click the "Copy link" span element, it will call the copy() function which will then write the value of the hidden input (with the id of 'link-to-copy') to the clipboard of your navigator.

The value of the hidden input can be whatever you want, here I am using a PHP variable. This PHP value will then be copied to you clipboard.

Isaac Muniz
  • 70
  • 11