24

I have a function in my script that gives me an error. The function purpose is to copy text from static panel(not textbox or input) with onClick event.

Uncaught TypeError: copyText.select is not a function

The thing i want is to make the user able to click the text and it's get copied to his clipboard.

Maybe you can offer better function that works?

https://codepen.io/abooo/pen/jYMMMN?editors=1010

function myFunction() {
  var copyText = document.getElementById("display");
  copyText.select();
  document.execCommand("Copy");
  alert("Copied the text: " + copyText.value);
}

From w3schools

  • `

    ` doesn't have a `.value()` function (Nor does `

    ` have a `.select()` function). Perhaps you're thinking of an input?

    – Blue Dec 21 '17 at 19:51
  • Change `h1` to a `textarea` for example...that way it works.. – Hackerman Dec 21 '17 at 19:57
  • 1
    No need to swap the `header1` tag for a `textarea`. You can use a hidden input to hold the `textContent` of the element that calls the function which will enable you to use `.select()` and `document.execCommand('copy')` [**CodePen Example**](https://codepen.io/anon/pen/RxGGyq?editors=1010) **Updated for multiple use** – NewToJS Dec 21 '17 at 20:09

6 Answers6

29

You can use the new Clipboard API writeText method which is supported by most modern browsers (see Can I use for more details).

//If you want to copyText from Element
function copyTextFromElement(elementID) {
  let element = document.getElementById(elementID); //select the element
  let elementText = element.textContent; //get the text content from the element
  copyText(elementText); //use the copyText function below
}

//If you only want to put some Text in the Clipboard just use this function
// and pass the string to copied as the argument.
function copyText(text) {
  navigator.clipboard.writeText(text);
}
<div id="mytext">This is some text that needs to be copied</div>
<button onclick="copyTextFromElement('mytext')">Copy</button>
miken32
  • 42,008
  • 16
  • 111
  • 154
Coola
  • 2,934
  • 2
  • 19
  • 43
23

This will allow you to copy the text of an element. Though I have not tested it with complicated layout.

If you want to use this then remove the alerts and provide a better way to let the user know the content was copied.

SAFARI: This does not work on Safari before version 10.0. But as of Safari 10.0 this now works.

function copyText(element) {
  var range, selection, worked;

  if (document.body.createTextRange) {
    range = document.body.createTextRange();
    range.moveToElementText(element);
    range.select();
  } else if (window.getSelection) {
    selection = window.getSelection();        
    range = document.createRange();
    range.selectNodeContents(element);
    selection.removeAllRanges();
    selection.addRange(range);
  }
  
  try {
    document.execCommand('copy');
    alert('text copied');
  }
  catch (err) {
    alert('unable to copy text');
  }
}
<h1 id='display' onClick='copyText(this)'>Text Sample</h1>

If you want to use this on an <input> or <textarea> element then let me know the code is different.

The try/catch is for older versions of Safari that would throw an exception. So if you don't plan to support Safari before version 10.0 then you can remove it.

Intervalia
  • 10,248
  • 2
  • 30
  • 60
  • I don't think it matters if you `try` and `catch` on that command. Even if you didn't select the text appropriately it would copy nothing or whatever it is that you actually have selected. – zfrisch Dec 21 '17 at 20:28
  • But this would be not working if when trying to copy email content. – Dhaval Panchal Apr 26 '18 at 11:33
  • The `try`/`catch` is needed for older browsers. Some of which will throw an exception instead of a graceful fail. – Intervalia Dec 09 '18 at 19:50
3

Great answer by Intervalia.

Small improvement to it, sometimes the clicked element is not the one you want to copy.
So I suggest you pass the id of the element you want to copy.

<button onClick='copyText("display")'> Copy </button>
<h1 id='display'> Text Sample </h1>

And then, in the first line of your function do

element = document.getElementById(element); 

Not much of a difference but I think it's more useful this way.

Hike Nalbandyan
  • 994
  • 1
  • 11
  • 28
2

select() method is used to select the contents of text fields. it won't work on h1 element.

mac
  • 114
  • 7
0

hi so I looked into it and since you are not using a textInput you cannot just use the .select()function. I borrowed some code from a fellow stack overflow developer Jason on how to highlight an item in javaScript

selecting text in an element akin to highlighting with your mouse.

function selectedText(element)(){

var doc = document,
text = doc.getElementById(element)
range, selection;

if(doc.body.createTextRange){ 
 range = document.body.createTextRange();
 range.moveToElementText(text);
 range.select(); 
}
else if(window.getSelection){
  selection = window.getSelection();
  range = document.createRange();
  range.selectNodeContents(text);
  selection.removeAllRanges();
  selection.addRange(range);   
}

return range;

I then modified it to return the range. and with that all you would have to do is

document.onclick = function(e){
  if(e.target.className === 'click'){

      var copytext = SelectText('display');
      document.execCommand("copy");
      alert("Copied the text: " + copytext);
   }
}

the key part here is that the string passed in to .execCommand() is lower case 'copy'

Andres C.
  • 1
  • 1
  • 2
-1

I am using this. This is similar to other answers but seems to be working in Chrome.

function CopyToClipBoard(textToCopy) {
var successMessage = 'Success! The text was copied to your clipboard';
var errorMessage = 'Oops! Copy to clipboard failed. ';

// navigator clipboard api needs a secure context (https)
if (navigator.clipboard && window.isSecureContext) {

    // navigator clipboard api method'
    navigator.clipboard.writeText(textToCopy).then(
        function () {
            /* clipboard successfully set */
            console.log(successMessage)
        },
        function () {
            /* clipboard write failed */
            console.warn(errorMessage)
        }
    )
} else
    if (document.queryCommandSupported && document.queryCommandSupported("copy")) {

    // text area method
    var textarea = document.createElement("textarea");
    textarea.value = textarea.textContent = textToCopy;
    textarea.style.opacity = "0"; 

    document.body.appendChild(textarea);
    textarea.focus();
        textarea.select();

        var selection = document.getSelection();
        var range = document.createRange();
        
        range.selectNode(textarea);
        selection.removeAllRanges();
        selection.addRange(range);

    try {
        var successful = document.execCommand('copy'); // Security exception may be thrown by some browsers.
        var msg = successful ? console.log(successMessage) : console.warn(errorMessage);
    }
    catch (ex) {
        console.warn(errorMessage, ex);
    }
    finally {
        selection.removeAllRanges();
        document.body.removeChild(textarea);
    }
}
Gauravsa
  • 6,330
  • 2
  • 21
  • 30