You are hereBlogs / rahul's blog / Cross-Browser approach to Copy content to Clipboard with javascript

Cross-Browser approach to Copy content to Clipboard with javascript


rahul's picture

By rahul - Posted on 20 March 2010

Before anything else, here is a sample demonstration of what I am discussing in this blog post. Enter some text in the textbox, and click the Flash's Copy icon below. You should have the text on your system clipboard. The .swf file for the same is attached with the post. Feel free to use it anywhere you like.

This is one of those topics, that has been blogged and written about furiously on the web. So, when I myself needed this functionality, I expected to find something useful on the web easily. And I thought I immediately hit the jackpot when a quick Google search threw up tons of pages for exactly what I was looking. However, it was not to be so, as I found out later.

Almost every solution that the Google search revealed worked, but the problem was only on Internet Explorer, not on other browsers and certainly not on Firefox. Some more research into the issue led me to pages like this, this and this, which clearly mention that FF considers it a security issue for Clipboard to be accessible to a web page. The crux of the matter was that you either need to explicitly enable Clipboard access to web pages in Firefox, or install add-ons that enable Clipboard access to web pages. As can be seen, none of these was a viable approach, as you do not expect the audience at large to configure settings or install add-ons on a page's request.

I was almost desperate that someone should have found a cross-browser solution of implementing this, as the problem is way too common. The tons of links I searched and followed took me no-where, everyone worked on IE but not on FF out-of-the-box.

I was wondering whether it is at all feasible to accomplish this, when something different struck my mind. Remember, Syntax Highlighter, the good old and wonderful syntax highlighting plugin from from Alex Gorbatchev (that it used on this site also for making the code stand-out and readable). The plugin put a toolbar on every piece of code, that had along with others a Copy button to copy the code. And as far as I knew, it worked on every browser, I had tested it on. Finally, I felt a way out here.

I immediately began debugging my own site's markup through Firebug to see how Syntax Highlighter handled Clipboard copying. And I was immediately stumped to see that it uses Flash for this purpose. Some more research revealed that it uses the Flash's System.setClipboard method for access to Clipboard.

Having figured out this, it should have been easy from here on. But again, it was not so. I immediately created a Flash movie, and enabled it to interact with javascript through Flash's ExternalInterface. What I thought of achieving was to embed a 1x1 pixel Flash movie into a page, and call a Flash javascript exported method from javascript to access Clipboard.

It did not take much time to assemble code, but the code did not work. I tried everything, from tweaking markup to browser settings to ActionScript code, but it simply did not work. Then I came across this post on adobe.com, which clearly spelt out that explicit user interaction is required in Flash 10 for successful access to clipboard (I tried bypassing this by manually raising Click Event on a button, and accessing Clipboard in the handler, needless to say, it failed).

So, in the end, it boiled down to this. The Flash movie itself required to have a UI against which User action would allow me to access clipboard. It was better than having nothing at all.

Now coming on to the coding part, you simple need to embed the Flash movie normally into a web page. Here's how I do it on this page:

<object id='clipboard' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0' width='16' height='16' align='middle'>
	<param name='allowScriptAccess' value='always' />
	<param name='allowFullScreen' value='false' />
	<param name='movie' value='clipboard.swf' />
	<param name='quality' value='high' />
	<param name='bgcolor' value='#ffffff' />
	<param name='wmode' value='transparent' />
	<param name='flashvars' value='callback=f1' />
	<embed src='clipboard.swf' flashvars='callback=f1' quality='high' bgcolor='#ffffff' width='16' height='16' wmode='transparent' name='clipboard' align='middle' allowscriptaccess='always' allowfullscreen='false' type='application/x-shockwave-flash' pluginspage='http://www.adobe.com/go/getflashplayer' />
</object>

There are 2 important things above. One, the Flash has been granted script access vis allowScriptAccess="true". Second, the content for copying normally would come from your page, and the movie is not aware of the content to place in clipboard. Therefore, you specify a callback method in the flashvars for the movie. This should be a fully-qualified reference to a method name in your javascript that should return a string which would be copied onto the clipboard. Here's the javascript method used on this page:

function f1() {
	var s = document.getElementById('text1').value;
    		
	var div = document.createElement('div');
	div.innerText = '"' + s + '" copied to clipboard.';
	document.body.appendChild(div);
    		
	if (window.clipboardData)
		window.clipboardData.setData('text', s);
    	else
    		return (s);
}		

What you should particularly note above is that IE provides out-of-the box window.clipboardData.setData method for putting data on the clipboard, which has been used. The Flash approach is used for all other browsers which do not support this. The user interaction still has to be through the Flash movie by clicking against it for everything to be able to work in a cross-browser fashion.

Use the comment form below to discuss any issue you face using this approach. I have tested it on IE, FF & Chrome, and it works!!

The html file attached below together with the clipboard Flash movie was used to create the example on the page above.

UPDATE:

  • Oct 24, 2010 - I later needed to pass custom parameters to the callback function also. So, enhanced the clipboard flash movie to support another flashvar called: callbackArg. You can use this to pass a string to the flash movie which the movie forwards to the javascript callback method when you click on the movie. Here's a sample code html for the same:
    <object id='clipboard' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0' width='16' height='16' align='middle'>
    	<param name='allowScriptAccess' value='always' />
    	<param name='allowFullScreen' value='false' />
    	<param name='movie' value='../resources/flash/clipboard.swf' />
    	<param name='quality' value='high' />
    	<param name='bgcolor' value='#ffffff' />
    	<param name='flashvars' value='callback=f1&callbackArg=MyCallbackArg' />
    	<embed src='../resources/flash/clipboard.swf' flashvars='callback=f1&callbackArg=MyCallbackArgument' quality='high' bgcolor='#ffffff' width='16' height='16' name='clipboard' align='middle' allowscriptaccess='always' allowfullscreen='false' type='application/x-shockwave-flash' pluginspage='http://www.adobe.com/go/getflashplayer' />
    </object>
    

    If you need to have multiple parameters for the callback method, or non-string argument, you can easily serialize those parameters as json, url encode them, and then set them as the callbackArg for the movie. then in your callback method, you would first url decode them and then deserialize them from json.
    For Json serialization, you can pick code from here or here, and for url encoding/decoding, you can use the browser's native encodeURIComponent and decodeURIComponent methods.
AttachmentSize
Clipboard.swf2.51 KB
Clipboard.htm1.67 KB

thank's for sharing

i wonder, if i want to use it without click the copy button,

but directly attach listener on html tag

like <a href='some text to copy' >clipboard</a>

how can i deal with it ? 

rahul's picture

Hi ovi, If you read the blog post carefully, I have answered this in the post itself. My approach is based on the use of a Flash movie and you could have achieved your objective prior to Flash 10 (i.e. in Flash 9 and earlier).

However, as per security changes in Flash 10 (read this post), user interaction is necessary for setting data on the system clipboard.

The Flash file attached above actually provides a method to call from javascript to do exactly what you are intending, but I did not discuss it in the blog, as any system would receive Flash 10 on a fresh install, and a majority of existing installs have automatic update enabled for Flash Player.

So, there's no point in discussing that option as that would work in only a limited number of cases. 

Is there a cross-browser approach to CLEAR the clipboard with javascript (without user interaction) ?

Greetings,

Martin
The Netherlands

rahul's picture

Hi Martin,

Clearing the clipboard in itself should be as simple as simply using the attached flash file and passing an empty string. That should effectively erase any existing data off the clipboard.

However, as far as I know, there isn't a cross browser approach to accomplish this without user interaction. Only Internet Explorer provides an out-of-the-box way to put data on the clipboard (through window.clipboardData object, that is accessible in javascript). For all other browsers, Flash is your best bet for accessing the system clipboard (javascript does not provide any interface to the System clipboard in browsers except IE).

And as per security changes in Flash Player 10 (links are provided above), User Interaction against the Flash movie is a prerequisite to access the clipboard. Flash Player 10 silently ignores all accesses to clipboard (without raising any error) that happen outside an event handler initiated by user action.


Thanks for your (quick) reply.

Greetings,
Martin

Thanks for the tutorial.  Quite detailed and easy to follow.

I am, however, running into problems when I try to pass the id of a textarea field as a parameter for the callback function.  In IE, everything works as expected, but in Firefox the value doesn't get copied to the clipboard.

This is how I pass the parameter (which is also specified in the embed tag):

<param name='flashvars' value="callback=f1('MyTextareaId')" />

Again, the return value from the f1 function is correct (I checked using an alert box), but it's just not copying to the clipboard.  Any idea what I might be doing wrong?

Thanks in advance,

Tony

rahul's picture

Hi Tony, I think you have got it completely wrong. The callback needs to be the name of the function (i.e. just f1 and not f1('MyTextareaId')).

If you need to pass-in some parameter to the callback method, maintain it as a global variable or some other Object Oriented way.

See the attached file for an example with textarea. It's just identical for a text input field.

AttachmentSize
Clipboard-Textarea.htm 1.68 KB

Hi,

I've been postponing this for a while, but I can't seem to do it no longer. So when i found your examples working I was really happy. However, when I started implementing it in my environment I can't seem to get it to work.

I need to copy ExtJS grid data as in you other blog, but went back to your original examples after having some problems. Also in this case I can not get it to work in my environment even tough ot works fine from you're site. 

I've done the following:

Saved the htm and the swf to my local disk. Opened the htm file in the same browser that succesfully ran you're demo (FF 3.5.9). The page is shown fine, but when clicking the copy icon nothing new is inserted to the clipboard.

If inserting an alert in the f1 script, nothing is displayed when clicking the copy icon. Any ideas as to what I'm missing here?

BR

Roger

rahul's picture

Hi Roger, I am not too sure, but you might want to try out multiple options here:

  1. Try running the example over a web-server (i.e. over Http and not over file:/// directly).
  2. Make sure you are not making a mistake like Tony, which I answered above in this comment:
    http://www.rahulsingla.com/blog/2010/03/cross-browser-approach-to-copy-c...
  3. Make sure the clipboard.swf path is correctly setup in the object tag. Also, the flashvars (that contains the callback function reference) are properly set. If you directly saved the page by using the "Save As" browser option, that might well be an issue. Right-click the files attached with the blog post above (both the html & swf file), save them to your disk and then run the example.
  4. I would repeat, the flashvars should be specified correctly both for the object tag (through a nested param tag), as well as in the embed tag.

Hi Rahul,

Thanks for the fast reply. It worked fine if ran through the web server. Now I'll try to make it run ok trough my grid Smile.

Thanks again,

Roger

Can I get the source file for "clipboard.swf".

Thanks
Anandhi

rahul's picture

Although I do not see why would you need to source for this flash movie, still it is attached with this comment.

AttachmentSize
Clipboard.fla 69.5 KB

Hello rahul

Thank you for usefull post,

I used your code and it's worked succesfully but i have to use it  without icon of copy that you use it, i mean i want to connect the function to work on link button in my page so could you please tell me how register the function on link even i try the following

<asp:LinkButton ID="lnkCopy" Text="Copy To Clip Board" OnClientClick="f1(); return false;" runat="server"></asp:LinkButton>

It's work on IE but not working on firefox (working on firefox just on your icon)

rahul's picture

Hi Hesham, did you read the blog post carefully? Or any of the comments following it? Because if you had, then you would have already had your answer. The simple answer is, it's not possible. Check this comment above for details.

Hi Rahul,

First of all, thanks a lot for your tutorial ! As you said, the issue of "javascript copy to clipboard" is often tackled but at the end of the day, there are very few good posts about this...!

I'm not used to flash at all so my question may seem stupid. I just want to know how I can easily convert a gif or png icon into a swf movie "icon" (like the 2 sheets of paper you used).

Thanks again for the tutorial ^^

rahul's picture

Hi Henri, it would be better to keep comments related to the blog post.

Anyways, for your problem, just import the gif/png image on the stage, and resize the stage to fit the image. That's what has been done above for the swf moviec"icon". Please note that these are not 2 sheets of paper, but a single icon for the famous Fam Fam Fam Silk icon set, that I used in the movie.

Hello, and thank you for this.  It is exactly what I was looking for and it works great for what I need it to do.

The only problem, is that I need to create a different button and I have very little experience with creating Flash or writing javascript.  I do own Flash CS4 and was able to create a button that works for me and have exported it as clipboard.swf.  But it doesn't show up on my webpage and the tiny clickable area does not trigger the function. 

From my reading of your post, what is needed is to "enabled it to interact with javascript through Flash's ExternalInterface."

I have been looking for a tutorial on how to do this and I have found several but they all assume the reader knows more about Flash than I do.

Can you either point me to a resource for learning how to do this or could you give those of us who are ignorant the steps needed to impliment this for ourselves?

Any help you offer will be greatly appreciated!

rahul's picture

Hi trishah, well I believe, everything you need to create your custom Flash copy button is available in the blog post itself. I attached the source fla file on request, in a comment above, which can be downloaded here:
http://www.rahulsingla.com/sites/default/files/Clipboard.fla

This and the javascript in the html page is all that you should need. Let me know if you are still unable to complete your button. Good Luck!! 

I have made a button that works.  I was able to do it by importing into Flash CS4 the clipboard.fla file you uploaded here for another commenter.  Using that as the basis, I swapped out your graphic for mine.  Exported as a .swf.  And changed the size dimentions in your html to my file size.  And Wah Lah!  It works and LOOKS great Laughing

Thanks again for doing this for us.

Is it possible to get the clipboard data in FF.

rahul's picture

Hi Bala, the above approach is based on using a Flash movie to be truly cross-browser compatible to set the clipboard data. However, as far as I know, there's no way to access clipboard data from native flash (FF as such does not allow access to clipboard natively at all in my knowledge).

However, if you are using Adobe AIR runtime, then you might be interested in the following:
http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/desktop/Clipboard.html 

Hi Rahul,

I tried creating a flash button in Adobe Flash CS3, but somehow its not calling the function f1.

When I try to open the swf file that you had posted, its not opening in Flash CS3.

Can you please specify if there are any special publish setting for this.

If there are any special requirements please let me know.

Thanks,

Arf`a

rahul's picture

Hi, there are no special publish settings that I am aware of. Just ensure that the method is invoked by the Flash's ExternalInterface and that you have allowScriptAccess=true on the object tag.

Both the published movie, as well as the source are attached above. So, feel free to download and modify them as desired (.fla is in CS4 though).

Hi,

I ve put the following code on the frame as follows,

send_btn.addEventListener(MouseEvent.MOUSE_DOWN,callJS);

function callJS(evt:MouseEvent):void
{
    ExternalInterface.call("f1");
}

but its working in IE and not in any other browsers.

i could not attach the file here though

rahul's picture

Its difficult to tell from the outside, but I would suggest verifying that "f1" is the fully qualified name for the function, plus you have allowScriptAccess="always" for object tag (as nested param) as well as the embed tag (as an attribute).

Hi Rahul,

Those two things are set as you have mentioned.

But this doesn't seem to work.

Do you have any script written in the flash file, and is it possible for you to post it.

Also I would  appreciate it if you can upload a CS3 version of your .fla file.

Thanks

rahul's picture

Hi Arf'a, yes there's some ActionScript written in the Flash file. Please find attached CS3 version of the .fla file.

AttachmentSize
Clipboard CS3.fla 31 KB

Thanks Rahul,

That script was missing from my flash file.

Thanks a lot.

Ok,

Everything is working great, but.

How do I put it together so that there is predefined text in the form. The Init Val.

I do not want to enter the text to be copied, I want the text already there and then I just hit copy and it copys the text. Know what I mean. I do not want to have to enter the text to be highlighted and copied. I want it already in the form.

Can you please attach the .swf and .html that I would need to accomplish this.

Pleeeeese.

~Ben
Vancouver, BC, Canada.

rahul's picture

Hi Ben, You just set the value for your input tag to initialize it with a value. See the following w3schools link: http://www.w3schools.com/TAGS/tryit.asp?filename=tryhtml_form_submit

Post new comment

The content of this field is kept private and will not be shown publicly.
Type the characters you see in this picture. (verify using audio)
Type the characters you see in the picture above; if you can't read them, submit the form and a new image will be generated. Not case sensitive.

Recent comments