I'm trying to programmatically use the execCommand in Chrome (Build 43) to copy the result of an asynchronous JSONP request to the clipboard. Here is a snippet of the logic :
loadContent()
function loadContent(callback) {
$.getJSON('http://www.randomtext.me/api/lorem/p-5/10-20?&callback=myFunc',function(result){
console.log('result=',result.text_out);
$("#container").html(result.text_out);
if (callback) {
callback();
}
});
}
function copyAjax() {
loadContent(copy);
}
function copy() {
var copyDivText = $('#container').text();
console.log('copyDivText=',copyDivText);
executeCopy(copyDivText);
}
document.addEventListener("DOMContentLoaded", function(){
document.getElementById("copy").onclick = copy;
});
document.addEventListener("DOMContentLoaded", function(){
document.getElementById("copyAjax").onclick = copyAjax;
});
// Copy text as text
function executeCopy(text) {
var input = document.createElement('textarea');
document.body.appendChild(input);
input.value = text;
input.focus();
input.select();
document.execCommand('Copy');
input.remove();
}
I know that starting build 43 of Chrome you code use the execCommand with clipboard. The problem, however is that you need to do it in within the execution of a user originated event (In which the permissions are elevated). This is a similar restriction that ZeroClipboard flash based solution has. Except from getting an answer that it is not possible (which is what I ponder about now), these are the other options I thought of doing as last resort(warning, they are all Hail Mary Passes):
I've already looked into Stackoverflow questions such as this, but they do not address an asynchronous scenario. Please let me know if you can find any other workable solution (or a tweak on the existing one).
This is working timeout approach based on your snippet:
HTML:
<div id="container">
Enter Text To Copy</br>
<textarea id="clipboard"></textarea>
</div>
<input type="button" value="Copy" id="copy"/>
JS:
var timeout = 600; // timeout based on ajax response time
var loaded = false;
function loadContent() {
loaded = false;
$.getJSON('http://codepen.io/gkohen/pen/QbvoQW.js',function(result){
document.getElementById("clipboard").value = result.lorem;
loaded = true;
});
}
// Copy text as text
function copy() {
clipboard = document.getElementById("clipboard");
if (!loaded || clipboard.value.length == 0) {
alert("Ajax timeout! TIP: Try to increase timeout value.");
return;
}
clipboard.focus();
clipboard.select();
if (document.execCommand('Copy'))
alert("Successfuly coppied to clipboard!");
// set defaults
clipboard.value = "";
loaded = false;
}
document.addEventListener("DOMContentLoaded", function(){
document.getElementById("copy").onmousedown = loadContent;
document.getElementById("copy").onclick = function() {
setTimeout(copy, timeout); // wait for ajax
}
});
The main issue is execCommand specification. There are some restrictions about security and trusted actions. So you have to make event calling copy and ajax call aparte. This can be done dirty way - by fixed timeout (code above) or proper way - by breakable sleep. New sleep feature is mentioned here and maybe can be modified to breakable variant via clearTimeout, but I did not try.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With