Copy selected input box with javascript doesn't work properly

Viewed 992

For my programming culture I'm experimenting with audio html tag and audio sources, and OS clipboard. It's 3 days I'm trying to solve the issue exposed as follows.

Situation

I have an html page on server with a js which has a bunch of code in it. The js does a lot of things, among the others generates two inputs inserting where I need the appropriate html:

a text input:

<input type="text" id="titleToCopy" value="" />

and a button:

    <input type="button" value="Copy" onclick="copyTitleOnClipboard()"/>


Into the js code there are also these two functions

function execThings() //This execute some operations and also calls other functions
{
    console.log(arguments.callee.name);
    var dest = document.getElementById(myplayerID); // Gets my player by its ID
    var osrc = getOriginalPlayer().src;
    dest.src = osrc;
    updateTitleToCopy();
    copyTitleOnClipboard();
    stopOriginalPlayer();
}


function copyTitleOnClipboard() // This function select and copies to the Operative System clipboard the content of the related text input
{
    console.log(arguments.callee.name);
    var titleInput = document.getElementById("titleToCopy");
    titleInput.focus(); // The function works good with or without this line
    titleInput.select();

    var r = document.execCommand("copy");
    r = r === true ? "has been" : "not";

    console.log("Title " + r + " copied to clipboard");
}

For debugging purposes I added in both functions the row

console.log(arguments.callee.name);

In this way on Chrome console is shown the name of the function, so I can check if it starts execution.

The Behavior

  • If I click the button the related onclick function copyTitleOnClipboard() executes and copies the value of the input into the OS clipboard.
  • If I write by hands the name of the function copyTitleOnClipboard() into the Google Chrome console it works too.

For me this means that the copyTitleOnClipboard() function per se works properly. In fact on the console in both cases I get the debug feedback thanks to the row:

console.log("Title " + r + " copied to clipboard");

which as expected returns the output Title has been copied to clipboard

And if I paste elsewhere (for example into notepad) the content of the clipboard the result is the value of the text box input, as expected.

The problem

The problem is that when the execution is due to the other function execThings(), which calls the copyTitleOnClipboard() function, it doesn't work anymore: the copyTitleOnClipboard() function is executed in fact on the console is shown its name as expected but I also get the fail feedback message: Title not copied to clipboard and if I paste the clipboard content in notepad it doesn't contain the text box value that has to be copied or is empty at all

Questions

  • Why calling the copyTitleOnClipboard() function from another function doesnt' work as if I call it by clicking the button or by hands by the Chrome console?
  • How do I solve the issue?

Thanks in advance.

2 Answers

eeeehhhmmm...

Sir I've copied your code and replaced copyTitleOnClipboard() with execThings() in the onclick="copyTitleOnClipboard()" of the button.... And it works properly, execThings() and copyTitleOnClipboard() are printed in the console and the value of the input box is copied to the clipboard and I verified that...

this clearly states that the problem is with the other code omitted from the question and replaced with the //some other code comment. Please include that code in addition to the code of the question because I think something there messes up the execThings() function.

I was able to replicate the issue you are facing.

Checkout this code here: https://jsfiddle.net/t1pe6zw8/

Open this link, wait for 5 seconds and see what happens.

Here is the explanation for the behavior:

I am assuming here that the execThings() function is triggered by some event that's not raised by user action.

The basic JS method document.execCommand(), requires that it be triggered by user interaction to prevent web pages from messing with the clipboard without the user's knowledge. This is a security feature and is enforced by every browser.

$(document).ready(function(){
    setTimeout(function(){ execThings(); }, 5000);
});

This code above, once the document is ready, triggers the execThings() function after 5 seconds and since it's triggered without user action, it fails to copy the text.

Now, if you click Click Me to Exec Things button on JSFiddle link above, it triggers the same execThings() function, and it is able to copy the text.

You can get more details here: https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand#Return_value

Now, I am not sure what are your use-cases, but you will need to get user action to copy the text.

Hope this helps!

Related