37

I was trying to make "Copy to Clipboard" work on all browsers but no luck.

Am using javascript and I don't want to use Zero Clipboard to do.

Please let us know what wrong in my code.

Appreciate for your help.

Below is the code (Currently my code is working only on IE browser):-

<script type="text/javascript">
function copyToClipboard(s)
{
    if( window.clipboardData && clipboardData.setData )
    {
        clipboardData.setData("Text", s);
    }
    else
    {
        // You have to sign the code to enable this or allow the action in about:config by changing
        user_pref("signed.applets.codebase_principal_support", true);
        netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');

        var clip = Components.classes['@mozilla.org/widget/clipboard;[[[[1]]]]'].createInstance(Components.interfaces.nsIClipboard);
        if (!clip) return;

        // create a transferable
        var trans = Components.classes['@mozilla.org/widget/transferable;[[[[1]]]]'].createInstance(Components.interfaces.nsITransferable);
        if (!trans) return;

        // specify the data we wish to handle. Plaintext in this case.
        trans.addDataFlavor('text/unicode');

        // To get the data from the transferable we need two new objects
        var str = new Object();
        var len = new Object();

        var str = Components.classes["@mozilla.org/supports-string;[[[[1]]]]"].createInstance(Components.interfaces.nsISupportsString);

        var copytext=meintext;

        str.data=copytext;

        trans.setTransferData("text/unicode",str,copytext.length*[[[[2]]]]);

        var clipid=Components.interfaces.nsIClipboard;

        if (!clip) return false;

        clip.setData(trans,null,clipid.kGlobalClipboard);      
    }
}
</script>

<textarea id='testText' rows="10" cols="100">Enter your Sample text</textarea><br />
<button onclick="copyToClipboard(document.getElementById('testText').value);" >clipboard</button><br /><br />
<textarea rows="10" cols="100">Paste your text here</textarea><br />
robsch
  • 9,358
  • 9
  • 63
  • 104
Siva Charan
  • 17,940
  • 9
  • 60
  • 95
  • Duplicate of http://stackoverflow.com/questions/400212/how-to-copy-to-clipboard-in-javascript ? – John Keyes Oct 10 '11 at 13:07
  • 4
    As I know, you can't use js to access clipboard in firefox by default. The only universal way is flash, instead of js. – OpenGG Oct 10 '11 at 13:07
  • @Rufus: But in my case, I need to do without flash. – Siva Charan Oct 10 '11 at 13:10
  • @SivaCharan Then I'm sorry, you have to ask your visitors to change their settings of firefox, some modifications in `about:config`. – OpenGG Oct 10 '11 at 13:12
  • 2
    @JohnKeyes: I don't want to use flash. Actually I have refered this existing question but most of people given solution that to use flash only. But in my case, I can't do this using flash. I want to implement as a javascript. Let me know if any IDEA's about this. – Siva Charan Oct 10 '11 at 13:14
  • Whats with [[[]]]? Your example would work if you used `"@mozilla.org/supports-string;1"` etc, also you cannot call `user_pref("signed.applets.codebase_principal_support", true);` in code you would need your users to change that pref manually – Alex K. Oct 10 '11 at 13:15
  • Thanks guys for addressing. Any IDEA's please update. – Siva Charan Oct 10 '11 at 13:15
  • @Siva, JavaScript cannot and will not do this for you. Even Google's JS solution embeds a hidden flash movie to do this. – John Strickler Oct 10 '11 at 13:17
  • @AlexK.: I tried your suggestion, but no luck. – Siva Charan Oct 10 '11 at 13:23
  • @SivaCharan a pure JavaScript solution is not currently possible AFAIK. – John Keyes Oct 10 '11 at 13:29
  • I had the same problem with my html editor (tinyMCE), eventually i told my costumer to ctrl+v/x/c – Alon Eitan Oct 10 '11 at 13:46

4 Answers4

10

This works on firefox 3.6.x and IE:

    function copyToClipboardCrossbrowser(s) {           
        s = document.getElementById(s).value;               

        if( window.clipboardData && clipboardData.setData )
        {
            clipboardData.setData("Text", s);
        }           
        else
        {
            // You have to sign the code to enable this or allow the action in about:config by changing
            //user_pref("signed.applets.codebase_principal_support", true);
            netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');

            var clip = Components.classes["@mozilla.org/widget/clipboard;1"].createInstance(Components.interfaces.nsIClipboard);
            if (!clip) return;

            // create a transferable

            var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
            if (!trans) return;

            // specify the data we wish to handle. Plaintext in this case.
            trans.addDataFlavor('text/unicode');

            // To get the data from the transferable we need two new objects
            var str = new Object();
            var len = new Object();

            var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);

            str.data= s;        

            trans.setTransferData("text/unicode",str, str.data.length * 2);

            var clipid=Components.interfaces.nsIClipboard;              
            if (!clip) return false;
            clip.setData(trans,null,clipid.kGlobalClipboard);      
        }
    }
Haga
  • 109
  • 1
  • 3
  • 2
    Wow! This works! But by invoking things suc as "Components.classes['@mozilla.org/widget/transferable;1']", are we going to the Mozilla site? – Donald T May 23 '12 at 15:56
  • This does not work in recent versions of Firefox, where `Components` is deprecated. – Jan Pöschko Feb 19 '13 at 09:36
  • 12
    ! We need something universal for all browsers!!! , com'on browsers... where ya at. y'all gonna let IE beat you guys on this one?! – Oneezy Feb 19 '13 at 23:43
  • What should I use for image data? (btw did you guys notice that @ravz is notifying himself in his comment?) – Tomáš Zato Dec 01 '14 at 10:24
8

I spent a lot of time looking for a solution to this problem too. Here's what i've found thus far:

If you want your users to be able to click on a button and copy some text, you may have to use Flash.

If you want your users to press Ctrl+C anywhere on the page, but always copy xyz to the clipboard, I wrote an all-JS solution in YUI3 (although it could easily be ported to other frameworks, or raw JS if you're feeling particularly self-loathing).

It involves creating a textbox off the screen which gets highlighted as soon as the user hits Ctrl/CMD. When they hit 'C' shortly after, they copy the hidden text. If they hit 'V', they get redirected to a container (of your choice) before the paste event fires.

This method can work well, because while you listen for the Ctrl/CMD keydown anywhere in the body, the 'A', 'C' or 'V' keydown listeners only attach to the hidden text box (and not the whole body). It also doesn't have to break the users expectations - you only get redirected to the hidden box if you had nothing selected to copy anyway!

Here's what i've got working on my site, but check http://at.cg/js/clipboard.js for updates if there are any:

YUI.add('clipboard', function(Y) {


// Change this to the id of the text area you would like to always paste in to:

pasteBox = Y.one('#pasteDIV');


// Make a hidden textbox somewhere off the page.

Y.one('body').append('<input id="copyBox" type="text" name="result" style="position:fixed; top:-20%;" onkeyup="pasteBox.focus()">');
copyBox = Y.one('#copyBox');


// Key bindings for Ctrl+A, Ctrl+C, Ctrl+V, etc:

// Catch Ctrl/Window/Apple keydown anywhere on the page.
Y.on('key', function(e) {
    copyData();
        //  Uncomment below alert and remove keyCodes after 'down:' to figure out keyCodes for other buttons.
        //  alert(e.keyCode);
        //  }, 'body',  'down:', Y);
}, 'body',  'down:91,224,17', Y);

// Catch V - BUT ONLY WHEN PRESSED IN THE copyBox!!!
Y.on('key', function(e) {
    // Oh no! The user wants to paste, but their about to paste into the hidden #copyBox!!
    // Luckily, pastes happen on keyPress (which is why if you hold down the V you get lots of pastes), and we caught the V on keyDown (before keyPress).
    // Thus, if we're quick, we can redirect the user to the right box and they can unload their paste into the appropriate container. phew.
    pasteBox.select();
}, '#copyBox',  'down:86', Y);

// Catch A - BUT ONLY WHEN PRESSED IN THE copyBox!!!
Y.on('key', function(e) {
    // User wants to select all - but he/she is in the hidden #copyBox! That wont do.. select the pasteBox instead (which is probably where they wanted to be).
    pasteBox.select();
}, '#copyBox',  'down:65', Y);



// What to do when keybindings are fired:

// User has pressed Ctrl/Meta, and is probably about to press A,C or V. If they've got nothing selected, or have selected what you want them to copy, redirect to the hidden copyBox!
function copyData() {
    var txt = '';
    // props to Sabarinathan Arthanari for sharing with the world how to get the selected text on a page, cheers mate!
        if (window.getSelection) { txt = window.getSelection(); }
        else if (document.getSelection) { txt = document.getSelection(); }
        else if (document.selection) { txt = document.selection.createRange().text; }
        else alert('Something went wrong and I have no idea why - please contact me with your browser type (Firefox, Safari, etc) and what you tried to copy and I will fix this immediately!');

    // If the user has nothing selected after pressing Ctrl/Meta, they might want to copy what you want them to copy. 
        if(txt=='') {
                copyBox.select();
        }
    // They also might have manually selected what you wanted them to copy! How unnecessary! Maybe now is the time to tell them how silly they are..?!
        else if (txt == copyBox.get('value')) {
        alert('This site uses advanced copy/paste technology, possibly from the future.\n \nYou do not need to select things manually - just press Ctrl+C! \n \n(Ctrl+V will always paste to the main box too.)');
                copyBox.select();
        } else {
                // They also might have selected something completely different! If so, let them. It's only fair.
        }
}
});

Hope someone else finds this useful :]

John
  • 89
  • 1
  • 1
5

For security reasons most browsers do not allow to modify the clipboard (except IE, of course...).

The only way to make a copy-to-clipboard function cross-browser compatible is to use Flash.

Alex Gyoshev
  • 11,929
  • 4
  • 44
  • 74
José
  • 391
  • 3
  • 14
  • Using `copy` event it's possible to set text data. If not using native functions then by selecting some hidden text to be copied. – Tomáš Zato Dec 01 '14 at 10:26
-3

I think zeroclipboard is great. this version work with latest Flash 11: http://www.itjungles.com/javascript/javascript-easy-cross-browser-copy-to-clipboard-solution.

David
  • 31
  • 1