My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
IdeasAndSuggestions  
Please post your ideas and suggestions as comments on this page.
Featured
Updated Feb 4, 2010 by jhuck...@gmail.com

Thanks!

Comment by mikedp...@gmail.com, Jan 8, 2009

I'm trying to add new/alternative functionality to your code, but I'm having trouble getting it to work.

What I want to do is have the innerHTML of an element copied to the clipboard whenever that element is clicked. I create a new ZeroClipboard?.Client, use the getHTML method to manually embed the SWF into the page, and call setText whenever a specified element is clicked.

The text never ends up on the clipboard, so I think I'm not doing something right in between embedding the SWF and calling setText. Any suggestions?

Comment by project member jhuck...@gmail.com, Jan 8, 2009

The problem is that Flash requires that the copy-to-clipboard operation be initiated by a click inside the Flash movie. This means that you have to get the text to be copied into the movie BEFORE the click happens. You can do this with a mouseOver handler.

Here is a test page showing this working:

http://bowser.macminicolo.net/~jhuckaby/zeroclipboard/innerhtmlclick.html

- Joe

Comment by mikedp...@gmail.com, Jan 8, 2009

Thanks for the quick reply! Using that the test page, I was able to get my page working.

In my case, I have a dynamically generated table that I want to copy values from by just clicking. What I ended up doing was overlaying the flash over a table and then using a combinations of show,hide,mouseover, and mousemove events to figure out which td element the mouse was hovering over and copying that value when the table was clicked.

I figured that was a better solution than dynamically generating clips for each individual td. It's a bit of a hack, but it works.

var clip = new ZeroClipboard.Client();
var toBeCopied = '';
var lastX = 0;
var lastY = 0;

$(".copiable").mouseover(function(element) {
	toBeCopied = this.innerHTML;
	clip.show();
});

clip.glue('membersTable');
clip.hide();

$("#ZeroClipboardMovie_1").mousemove(function(event) {
	clip.setText(toBeCopied);										  
	if(Math.abs(event.clientX-lastX) > 5 || Math.abs(event.clientY-lastY) > 3) {
		lastX = event.clientX;
		lastY = event.clientY;
		clip.hide();
	}
});
Comment by project member jhuck...@gmail.com, Jan 8, 2009

Ah, very clever!

I suppose if I updated the library to support dynamic sized elements, you could re-glue the movie to each table element as you moused over it (would eliminate the need for the clientX/clientY threshold hack).

Anyway, nice work. Glad you found a solution :-)

Comment by project member jhuck...@gmail.com, Jan 9, 2009

Adobe Flash requires that the copy operation originate from a click on the flash movie itself. It cannot work from a body onload handler. You have to glue the movie to a specific element on the page, THEN the user must click on that element, which is intercepted by the flash movie (which is floating on top). Then and only then will Adobe allow flash to manipulate the clipboard.

Comment by phoenix....@gmail.com, Jan 9, 2009

Hello. Thank you for the code. But it is not working for me.

(1) Is it not possible to automatically some code when the body loads?

(2) The Flash movie is too large or something? The copy is working when I click on the buttons in my code (below) but it takes some time. After the body has loaded, I click on a button but it doesn't copy. I click a few times and it does copy then.

(3) In my example, the second button copy works eventually (slow). But clicking on the first button shows me the message from inside the body! Any thoughts on why?

<html>
<head>
<script type="text/javascript" src="ZeroClipboard.js"></script>
<script language="JavaScript">
function copyfunc(thetext, elemname) 
{
    var clip = new ZeroClipboard.Client();
    clip.setText( thetext);
    clip.glue(elemname);
}  
</script>
</head>
<body >
<script language="JavaScript">
copyfunc('My text from body onload', 'copied');
</script>
<a class="button" id="copied"  href="javascript://" onclick="copyfunc('My text from click', 'copied'); ">
<span class="copyb">Copy</span>
</a>

<a class="button" id="copied2"  href="javascript://" onclick="copyfunc('My text from second click', 'copied2'); ">
<span class="copyb">Copy Me Too</span>
</a>


</body>
</html>
Comment by phoenix....@gmail.com, Jan 9, 2009

Thanks jhuckaby, sorry for reposting because my code in the previous post was wrong.

Anyway if it doesn't automatically copy then it's a little useless for me. Keep up the good work though.

Comment by Stoyano...@gmail.com, Jan 10, 2009

Hello,

1) thank about your work!

2) I try to run it on a page with many things but I got problems... It copy only the last row...

Here is my code

<?php
echo '
<html>
<head>
<style type="text/css">
#d_clip_button_1,
#d_clip_button_2,
#d_clip_button_3,
#d_clip_button_4,
#d_clip_button_5,
#d_clip_button_6,
#d_clip_button_7,
#d_clip_button_8,
#d_clip_button_9{
	text-align:center; 
	border:1px solid black; 
	background-color:#ccc; 
	margin:10px; padding:10px; 
}
</style>
</head>
<body>
<script type="text/javascript" src="ZeroClipboard.js"></script>';

for($i=1;$i<=9;$i++) {
	echo '
	<div id="d_clip_button_'.$i.'">'.$i.'00000</div>
	
	<script language="JavaScript">
	var clip = new ZeroClipboard.Client();
	
	clip.setText( \'\' ); // will be set later on mouseDown
	clip.setHandCursor( true );
	clip.addEventListener( \'mouseDown\', function(client) { 
			// set text to copy here
			//clip.setText( document.getElementById(\'clip_text\').value );
			clip.setText(\''.$i.'00000\');
	} );
	
	clip.addEventListener( \'complete\', function(client, text) {
	alert("Copied text to clipboard: " + text );
	} );
						
	clip.glue( \'d_clip_button_'.$i.'\' );
	</script>';
}
echo '
</body>
</html>';
?>
Comment by project member jhuck...@gmail.com, Jan 11, 2009

Ah ha, so there are two problems here, and one of them is a bug in my code.

(1) Your code is using a "closure" for the mouseDown handler. This closure refers to the global "clip" variable, which is overwritten 9 times by each iteration through your loop. So it always adds the text to the last client. Instead of using the "clip" global, use the "client" object passed to your mouseDown function.

(2) There is a bug in ZeroClipboard? 1.0.2 and below that causes all the event handlers to be shared between the different clients on a page. I have fixed this bug and uploaded ZeroClipboard? 1.0.3.

Here is a test page using your code (with the change made so it uses "client" instead of the global "clip"). Please clear your browser's cache before testing this:

http://bowser.macminicolo.net/~jhuckaby/zeroclipboard/multiple.php

Thanks for catching the bug!

Comment by Stoyano...@gmail.com, Jan 12, 2009

Thanks! :)

Comment by rvdbb...@gmail.com, Jan 12, 2009

Thank you very much for providing the only cross-browser working solution I've come across so far!

I would like to implement this clipboard copy functionality in an interface for textual annotation. In this case, an HTML rendered text should allow a user to click single words or select word ranges to automatically copy their underlying ID values (each word will be tokenized in its own <span>). These can then be pasted in an editor in order to provide formal anchors for an annotation. I guess this is very similar to StoyanovRR's use case above.

However, while the examples work like a charm on-line, I notice that they don't work locally (ie. after unzipping zeroclipboard-1.0.3.tar.

Is there something I've missed in my enthousiasm?

Comment by project member jhuck...@gmail.com, Jan 12, 2009

Ah, this is a security restriction by Adobe Flash Player. Unfortunately, since we are utilizing the JavaScript?-to-Flash interface ("ExternalInterface?") this only works while truly online (if the page URL starts with "http://" or "https://"). It won't work running from a local file on disk.

There is a way for you to edit your local Flash Player security settings and allow this. Go to this website:

http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04a.html

And add the path to your local "ZeroClipboard?.swf" file to the trusted files list, or try the "allow all" option. This works perfectly for me.

Good luck!

Comment by imad.yam...@gmail.com, Jan 12, 2009

Thanks for this great library. Let me contribute my 2 cents :)

I was having problems getting ZeroClipboard? working inside a Google Gadget. Turns out there were cross domain issues (gadgets are hosted on Google's servers), which were resolved by doing the following:

1. Instantiate the flash object using allowScriptAccess="always" instead of "sameDomain"

2. Call flash.system.Security.allowDomain("") inside the ZeroClipboard?() constructor and rebuild the ZeroClipboard?.swf file.

Now it works great!

- Imad
Comment by imad.yam...@gmail.com, Jan 13, 2009

One more issue that I noticed, at least on Windows. You need to make sure that newline characters (\n) are preceded by a carriage return (\r), otherwise the newlines won't make it into the clipboard. This was an issue on Safari, Firefox and Chrome on my machine were I was getting the text from a TEXTAREA html element.

- Imad
Comment by pierre...@gmail.com, Jan 13, 2009

I've put together a very basic usage of ZeroClipboard? to see how it integrates. The PHP backend dynamically outputs the correct JS for clip.setText('xxx') which I can see in the page's code.

Also, the flash object is loaded correctly and the hand cursor shows up as expected.

But: the load event is never fired - an alert() in the listener doesn't pop up - and the copy certainly doesn't happen.

I tried a variation using onMouseDown with an alert and the setText and that didn't work either.

Which leads me to one theory: is there a specific time during the page loading when the ZeroClipboard? JS must be called? And by specific time I do include "after the page has finished loading", the equivalent of of document ready.

Otherwise, what gives? Any pointers?

Thanks! Pierre

Comment by project member jhuck...@gmail.com, Jan 13, 2009

pierrefar, please post your code here, or a URL where I can test it. Also, please let me know which browser and OS you are using. I can then help you troubleshoot further.

Imad, I am working on a new version which incorporates your suggestions, thanks!

Comment by pierre...@gmail.com, Jan 13, 2009

Would it be possible to email you a private testing URL please?

My email is my username at the gmail dot com.

Comment by project member jhuck...@gmail.com, Jan 13, 2009

Just posted version 1.0.4, which should correct the cross-domain issues reported by pierrefar and imad.

Imad, I was unable to reproduce any of the multi-line issues on Windows. I tried using "\n", "\r" and "\r\n" and all three work fine. I'll continue to investigate this.

Comment by pierre...@gmail.com, Jan 15, 2009

Hi Joe

Another bug report: It seems 1.0.4 is causing problems for some IE users. Haven't been able to reproduce it yet and I'm collecting info from the affected users.

Anyone else seeing this?

Cheers, Pierre

Comment by pierre...@gmail.com, Jan 15, 2009

More info: IE 6 is the offending bully. Surprised?

Comment by project member jhuck...@gmail.com, Jan 15, 2009

Ah, makes sense. IE 6 isn't officially supported, but I'll see if I can find a PC with it installed so I can test it out.

Comment by imad.yam...@gmail.com, Jan 15, 2009

Hi, Joe

Regarding the linefeed issue, here's how I could make it happen:

1. Type some text in a TEXTAREA that includes linefeeds on Safari, Chrome or Firefox on Windows

2. Use setText, passing in the textarea value.

My fix was to modify the clipText assignment line from:

this.clipText = newText;

to

this.clipText = newText.replace(/\n/g, "\r\n").replace(/\r\r/g, "\r");

By the way, congrats for the post on Ajaxian. This library saved me a lot of grief, and we now use it on Yamli.com.

- Imad
Comment by project member jhuck...@gmail.com, Jan 15, 2009

Okay, I just tested Zero Clipboard on MSIE 6 and it works perfectly (just using the test page). There must be something on your page causing some kind of conflict with the library.

Sorry I can't be of more help, but I deliberately dropped IE 6 support because it is such a difficult browser to deal with.

Comment by project member jhuck...@gmail.com, Jan 15, 2009

Hey Imad,

Curious, I tried those exact steps and I cannot reproduce the linefeed bug on my Windows machine. However, your fix seems harmless enough, so I'll roll it into the next version. Thanks a ton!

- Joe

Comment by mt.d...@gmail.com, Jan 22, 2009

Would be nice if we had a way to easily use this on multiple items on the page using classes instead of IDs. Currently the amount of redundant code needed to make this happen is a little silly. I'd suggest making it into a jQuery plugin, a lot of people use jQuery already, or at least they should.

Comment by rvdbb...@gmail.com, Jan 24, 2009

In a previous comment I briefly explained how I'm trying to create an HTML interface that lets text encoders find the underlying ID values of the text ranges they select in their browser. Ideally, a text selection should produce a popup tooltip, displaying the relevant ID codes, with a link to automatically copy them.

Since that comment, I've advanced quite a bit in putting the pieces together. I've managed to put something together

  • collects underlying ID codes for a text selection
  • displays the string-to-copy
  • copies the string with the ZeroClipboard? script

However, there is a problem with positioning of the flash movie. I try to add it to the generated tooltip using the clip.glue() function. It is added to the DOM, but positioned at the top left of the screen instead of over the element containing the tooltip. I tried to improve this by calling clip.reposition(), but this doesn't help.

I've put up an example page at http://www.kantl.be/ctb/temp/selecttest.htm. For clarity's sake, I've put a border around each div element (including the zeroclipboard wrapper). Just hold CTRL and select some text; this will produce a tooltip (using the MojaveLinux? domTT library -- see http://www.mojavelinux.com/projects/domtooltip/). I specify the 'close' link of this tooltip as target for the clip.glue() function, but the div with the flash movie remains positioned at the top left. Clicking this upper left div does its job (copying the right text), but at the wrong position.

I'feeling that I'm just 2 lines of javascript from my perfect solution... What am I doing wrong?

PS: I second the previous commenter: this could be a smashing JQuery plugin!

Comment by project member jhuck...@gmail.com, Jan 24, 2009

Hey rvdbbdvr,

I am unable to get your test page to do anything (how do I get a tooltip to appear? I am using Firefox and Safari on Mac). However, I suspect the problem has to do with my function that tries to calculate the absolute position of any element on the page. If you know a better way to do this (I'm sure jQuery has its own function that does this), feel free to swap it out.

You can do this by moving the ZeroClipboard? DIV to any position on the page that you wish. Example:

clip.div.style.left = '400px';
clip.div.style.top = '300px';

Replace the "400" and "300" with the absolute pixel location of your DOM element, calculated by using jQuery or a function of your choice.

I am not sure why my positioning function is not working for your page, but I have never tested it with floating elements before -- mine have always been relatively positioned. I'll begin testing this myself and see if I can reproduce your issue.

Comment by project member jhuck...@gmail.com, Jan 24, 2009

Hey rvdbbdvr,

Here is a test page I just created which shows ZeroClipboard? working with an absolutely positioned element on the page, as well as showing how you can dynamically show and hide the element, and create and destroy the ZeroClipboard? object along with it.

http://bowser.macminicolo.net/~jhuckaby/zeroclipboard/absolute.html

This works for me in all supported browsers.

So I guess the problem isn't absolutely positioned elements per se, but perhaps a combination of things, including possibly how your domTT library renders its tooltips. I'll keep looking.

Comment by rvdbb...@gmail.com, Jan 25, 2009

Hi Joe,

I've changed the test page a bit: the first heading now contains a link that should produce a toolitp on mouseover. At least, if domTT doesn't choke on Mac browsers (hope not).

Anyway, thanks for that quick investigation and demonstration! I'll have a look and try to figure out positioning issues when I find the time, but your example seems encouraging.

Cheers,

Ron

Comment by project member jhuck...@gmail.com, Jan 25, 2009

Hey Ron,

I think I found your problem. You are trying to glue the clipboard to your "copylink" element before it is actually moved into place. Try wrapping the glue command in a setTimeout() call with a closure. Example:

setTimeout( function() {
  clip.glue('copylink');
  clip.reposition();
}, 1 );

This will wait for 1 millisecond before trying to locate the "copylink" element position in the DOM. It looks like the domTT library does some trickery to get the tooltip onscreen, which means you cannot measure the global absolute position of elements inside the tooltip content until after the current JavaScript? thread completes.

After the tooltip appears on the screen and the thread completes, I am able to properly measure the position of your "copylink" element using the ZeroClipboard.getDOMObjectPosition function, so this should work.

Comment by rvdbb...@gmail.com, Jan 25, 2009

Hmm, did you get that working? It doesn't seem to have any effect here: the flash movie remains in the top left of my page. Sounds like a plausible solution, though.

Comment by project member jhuck...@gmail.com, Jan 25, 2009

Apologies, I missed something. The ZeroClipboard? tries to initialize LONG before the tooltip appears. The code runs when the tooltip initial delay first starts (the tooltip delays for about 500ms or so before appearing). You need to change the setTimeout delay to some value longer than domTT waits to show the tooltip. Try 500ms or 1000ms.

The rule of thumb is, the DOM element must be moved into place and visible for the glue code to work.

Comment by rvdbb...@gmail.com, Jan 25, 2009

Ok, perfect now! Sorry, I totally missed an apparent default delay of 500ms for the domTT toolitps to appear. It also required some z-index finetuning (both domTT and zeroclipboard want to be on top ;-) and now I have it working.

Many thanks, Joe!

Comment by NoneCanT...@gmail.com, Jan 29, 2009

Hello there,

I am trying to develop a script for the University I work for, in order to prevent copying/pasting/printscreen/etc during online test taking.

The one I used previously was based on http://blog.gilluminate.com/2006/04/25/prevent-copy-paste-and-print-screen-online , but as we know Flash 10 now requires the user to initiate the allowance of setting the clipboard.

My question for you is whether or not there is a way to have the flash movie used for ZeroClipboard? to be floating ON BOTTOM of all other elements on the page? This way, if a user clicks almost any where on the page (and tries to highlight text) then a message will be sent to the clipboard.

Example: http://www.creativegroundmedia.com/scripts/zeroclipboard

I understand that this won't fix the problem of print screen however. So going even further, another question is whether its possible to setup a timer to keep repeating the System.setClipboard("text"); function call for say 5 hours? I've tried implementing the call to a timer in Flash, but it only seems to send an item to the clipboard only the first time being clicked.

Example: http://www.creativegroundmedia.com/scripts/noprint

Any help would be greatly appreciated. Thank you!

Comment by project member jhuck...@gmail.com, Jan 29, 2009

You don't need Zero Clipboard at all. You need to float a transparent IFRAME above your entire page using CSS "position:fixed", preventing users from clicking on the content. You should also capture keyboard entry and stop the events from reaching the browser, to prevent "Select All" (Ctrl-A) and "Copy" (Ctrl-C). These are both way out of scope for Zero Clipboard. Recommend you try a JavaScript? library such as jQuery.

That said, you can always have Zero Clipboard give you the raw HTML for its Flash movie, and you can stick it anywhere on the page you like. See the instructions regarding the get_html() function. Pass it an enormous width and height like 9999,9999 and stick it in a floating DIV to cover the entire page. Again, jQuery should help you with this, but it really sounds like you don't need Zero Clipboard at all, and can achieve what you want with jQuery alone.

Regarding your final question, you cannot call the Flash System.setClipboard() more than once per each user click, so there is no way to implement the 5 hour thing you are proposing.

Good luck, and sorry I could not help further.

Comment by project member jhuck...@gmail.com, Jan 29, 2009

Correction on my previous post: You don't even need to float an IFRAME. Just use jQuery to capture all keyDown, mouseDown, mouseUp and click events and "stop" the events so they don't reach the browser (call cancelBubble() and preventDefault(), google these for proper instructions, jQuery may even have an easier way).

Of course, you probably have buttons and links on the page which you want to remain clickable, so use jQuery to target only the DOM elements you want to prevent clicking on. See jQuery for further instructions.

Comment by NoneCanT...@gmail.com, Jan 29, 2009

Thank you for your fast response. I will definitely look into that.

Comment by brettajo...@gmail.com, Jan 30, 2009

Have you tried to get this to work as part of a Greasemonkey script? I have a Greasemonkey script that I use at work that adds a toolbar to certain pages and creates some code snippets about that page that I can paste in other locations.

I attempted to implement this method within Greasemonkey. I embedded your Javascripts within my Greasemonkey script. Set the moviepath to point to the swf file on my server. Added the clip items and glued them to my elements. I verified using Firebug that the SWF was loaded, once for each item I referenced, I also verified that the SWF object was placed within the DOM in what appeared to be the correct locations.

I used your complete example and the event listeners in there to try to track down what was going on. No events were surfaced. No onload, no mouseovers, nothing was triggered even though the swf objects were in the page.

Any ideas why this might not work? Cross domain issues? I'd prefer not to post the Greasemonkey code here because its for internal use at work. I can send directly if necessary.

Comment by project member jhuck...@gmail.com, Jan 31, 2009

Hey everyone, since several people have asked, here is how you can use a single ZeroClipboard object for multiple elements on the same page. This also uses jQuery.

http://bowser.macminicolo.net/~jhuckaby/zeroclipboard/multiple.html

Comment by project member jhuck...@gmail.com, Jan 31, 2009

Hey brettajohnson,

Sorry, I have never used Greasemonkey before. If I find the time I'll install it and try to see why ZeroClipboard doesn't work with it.

Comment by shashank...@gmail.com, Feb 1, 2009

Hi. Is there a Google-hosted "ZeroClipboard?.js" that we can link to? This way

(1) We can reuse cached copies of JS for those users who have it (2) We don't have to bother with downloading the new 0.0.xx version :)

Or do you already have this hosted here?

Comment by shashank...@gmail.com, Feb 1, 2009

Joe, I am excited about the multiple example using jquery. But it seems one limitation of your example is that only the code that's showing is copied. Unlike your previous examples, where I could style the displayed DIVs as "Copy button" and clicking on it would copy a certain text. Any tips on how to achieve that with this multiple example of yours? Thanks for all the work!

Comment by project member jhuck...@gmail.com, Feb 1, 2009

Shashank,

You can copy any text you want to the clipboard, I was just using the visible text in the DIVs as an example. Change this line:

clip.setText( this.innerHTML );

...and you can copy whatever you want to the clipboard. The this.innerHTML pulls out the HTML from each DIV element, which is just one way to do it. You can change this to pull from an array you have, for example, or put the desired text to be copied inside a DOM attribute beforehand, then pull it out (using the built-in setAttribute() and getAttribute()).

Regarding hosting ZeroClipboard at Google, they only do this with the most popular libraries. See here:

http://code.google.com/apis/ajaxlibs/

There is no way to post your own library to the list. They only have a very, very small set of the most popular.

- Joe

Comment by shashank...@gmail.com, Feb 1, 2009

Thanks Joe. I like the idea of pulling something from an attribute of the same div that is getting clicked. Is this possible?

E.g., let's say I had this HTML:

<div class="button">
   <span class="multiple" copytext="My copytext 1">Copy this</span>
</div>
<div class="button">
   <span class="multiple" copytext="My copytext 2">Copy that</span>
</div>

In this case, if I were to use your one init() function, how would I set the text of the currently clicked DIV to the attribute? I know how to call getAttribute() as a part of getElementById(), but here there's no need for an ID it seems, so I'm a bit stumped.

Any thoughts would be super.

Thanks!

Comment by project member jhuck...@gmail.com, Feb 1, 2009

Just replace this:

clip.setText( this.innerHTML );

with this:

clip.setText( this.getAttribute('copytext') );

Here is a working example:

http://bowser.macminicolo.net/~jhuckaby/zeroclipboard/shashank.html

Good luck.

Comment by nickserg...@gmail.com, Feb 11, 2009

Joe,

First off - this solution rocks, thanks so much for your hard work on it.

Second - I'm having an issue with the multiple copy functionality you demonstrated above. It seems the first time a user encounters the copy link and clicks on it, nothing happens. The user must take the mouse off the link, then back onto the link, and it'll work fine.

See my implementation here:

http://snipt.net/public

Thanks!

Comment by shashank...@gmail.com, Feb 17, 2009

Joe, one quick request. Would it be possible to use JQuery's innate code to somehow attach keystrokes to each of the DIVs? For example:

<span class="multiple" copytext="My copytext 1" key="A">Copy this</span>
<span class="multiple" copytext="My copytext 2" key="B">Copy that</span>

This would attach the key "A" to the first button and "B" to the second. I am sure it's an easy fix but some code hacks I've tried are not working. Any thoughts in the right direction would be much appreciated...thanks!

Comment by project member jhuck...@gmail.com, Feb 17, 2009

I'm sorry, this is not possible. Adobe Flash requires that copying to the clipboard be initiated by a "mouse click". You cannot do it with a keyboard event. Sorry, this is nothing I did, this is the new security added to Flash Player.

Comment by brutsnbe...@hotmail.com, Feb 17, 2009

Hi Joe

Is it possible to integrate ZeroClipboard? with something like the example(s) on these pages?:

http://davidwalsh.name/mootools-clipboard-plugin http://davidwalsh.name/dw-content/moo-copy.php

I'm afraid I'm not a coder but MAY be able to hack something just not sure if the 2 can go together. I see you commented on his blog.

I'm essentially looking for a way to mimick something like retailmenot's functionality where someone could "click" a coupon code and have a "messenger" like in davidwalsh's example say to the effect "the code has been copied" or whatever.

Here's another idea that could work and seems more closely integrated with ZC

http://beckelman.net/post/2009/01/22/Copy-to-Clipboard-with-ZeroClipboard-Flash-10-and-jQuery.aspx

Or would all this be over the head of a coding rookie like myself?

cheers

Comment by mrr...@gmail.com, Feb 21, 2009

No suggestions, just a note of appreciation. Thanks! :)

Comment by t12...@gmail.com, Feb 26, 2009

Took quite a bit of playing around to finally get it to work for just a simple copy button, but it works like a charm. Thank you all very much for your work and input.

Comment by jy...@hotmail.com, Feb 28, 2009

Hey, this is really useful, thanks!

I'm just wondering if it'd be possible to detect if the necessary version of flash is available and perhaps run a custom function if it's not? For example, I want to hide my 'copy to clipboard' button if it's not going to work.

Also, I had a problem with the swf only loading intermittently in Safari, but I notice you've commented: "firefox on pc needs a "kick" in order to set these in certain cases" - I added Safari in there as well and it seems to work every time now.

Comment by project member jhuck...@gmail.com, Feb 28, 2009

Hey, thanks for the suggestion. I'll add Safari to that list. To detect the Flash version, please check out SWFObject, which has a very nice Flash player version detection function.

Comment by snakewar...@gmail.com, Mar 6, 2009

I read something here about using AIR to do paste: http://www.senocular.com/air/tutorials/clipboardtext/

I don't have any Flash dev knowledge, so it may be off the mark.

Comment by griffol...@gmail.com, Mar 7, 2009

Got it working, and I love it. Thanks! Any thoughts on how to attach a unique link (I'm using the div.multiple with jquery) to each instance?

Comment by grant.bl...@gmail.com, Mar 11, 2009

Copying text to the clipboard seems fine; but our client wants to be able to copy a graph (which is rendered in Flash) to the clipboard as an image.

Only solution I have thought of so far is to use zeroclipboard to copy text to the clipboard, with the text being HTML & including an image tag, which then points to an image on the server. This raises other issues, so the best solution would be if we could somehelp transfer the image. Any ideas? Have seen a suggestion to use UUEncoding... but looks complex and image sizes would have to be small.

Comment by leebreis...@gmail.com, Mar 16, 2009

I'm attaching a client to an ordinary <a href..> link and I want a click on the link to "go through" after copying text to the clipboard. Is there a recommended way to do this, or do I just attach a onComplete event handler and explicitly click the link in there?

Comment by project member jhuck...@gmail.com, Mar 16, 2009

@leebreisacher: There is no official way to do it, so I'd recommend the onComplete event, like you suggested. Good luck!

Comment by hkyu...@gmail.com, Mar 19, 2009

there is a bug : wrong javascript code.

code of function removeClass is

this.className = this.className.replace( new RegExp("\\s" + name + "\\s"), " ").replace(/^\s+/, '').replace(/\s+$/, '');

this regexp replace output wrong result.

ex)

"abc".replace( new RegExp("\\s" + "b" + "\\s"), " ").replace(/^\s+/, '').replace(/\s+$/, '')

== "a c"

the fellowing is a right code.

this.className = this.className.replace( new RegExp("(^|\\s+)" + name + "(\\s+|$)"), " ").replace(/(^\s+)|(\s+$)/g, '');

end.

Comment by alexan...@gmail.com, Mar 23, 2009

Hi, i have the following situation: i use telerik treeview component. It has some underlying hierarchy structure, every element of treeview should be copied to clipboard when clicked on it. The problem is that copying should be possible already AT FIRST CLICK - for root elements. So i can't apply glue method within onclick event for every node. But, if i apply glue before clicking - all onclick events for treeview are blocked :(

How to solve this problem in elegant way, without adding some 'Copy' button to make extra clicks?

Comment by google%r...@gtempaccount.com, Mar 24, 2009

Hi,

I'm working on an application where the users need to copy the text rather than the innerHTML.

I had something working before Flash 10, and I was using the following code to work out what to do depending on the browser:

`function grabArea(objId) {

var text2copy; fnDeSelect();
if (window.getSelection) {
// w3c method, FF, Safari, Opera - copy the range directly.
var range = document.createRange(); range.selectNode(document.getElementById(objId));
text2copy = range;
}
else if (document.selection) {
// Microsoft method - IE

var text2copy = document.body.createTextRange(); text2copy.moveToElementText(document.getElementById(objId));

if (text2copy.text)
text2copy = text2copy.text;
}

return (text2copy);

} `

I've been trying to integrate my method with yours, but it doesn't work. For example:

`var my_textblock = grabArea('my_div_1234'); / clip.setText( document.getElementById('my_div_1234').innerHTML ); / clip.setText(my_textblock); `

returns the error in firebug: too much recursion on this error? if (this.ready) this.movie.setText(newText);

Any ideas for a way forward?

Thanks!

Comment by ple...@gmail.com, Apr 22, 2009

I did a cut down version of ZeroClipboard? with all the code in the page rather than ZeroClipboard?.js so you can copy and paste the whole code with one click (the copy demo link). It is function based rather than using the clip object which I found too involved to modify.

It is at http://nerveplexus.com/Copy_to_Clipboard.htm and changes the button or link clicked to red on mousedown and back to blue on mouse up. This can be edited using the zc_events() function. Starting at STARTUP in the code it should be fairly easy to follow the sequence of what is going on.

All you need in the ZeroClipboard? object is ZeroClipboard?.dispatch which is used by ZeroClipboard?.swf as a pointer to the event handler. In this case it is set to zc_events() which then routes the mousedown (click) event to zc_click() and this sets the text you want to copy to the clipboard.

Comment by ulasoz2...@mynet.com, Apr 26, 2009

Hi joe i am trying to add this code to a highlighter plugin. all textareas and divs have different names. how can i use this code?

i think if there was a function like that copy('link_id','copy_area_id') it would be nicer and easier to use.

Comment by affinity...@gmail.com, May 19, 2009

A jQuery plugin for doing copying Ajax content into clipboard

// A jQuery wrapper for zeroclipboard

(function($) {
    $.fn.clickToClipboard = function() {
        $(this).each( function() {
            var link = $(this);
            if ( link.is('a') ) {
                var clip = new ZeroClipboard.Client();
                clip.glue(this);
                clip.addEventListener('onMouseDown', function(){
                    link.html('copying...');
                    jQuery.ajax({ 
                        url: link.attr('href'),
                        success: function(content) { 
                            clip.setText(content);
                            console.log(content); 
                        },
                        async: false
                    });
                });
                
                clip.addEventListener('onComplete', function(){ 
                    link.html('copied!');
                    clip.reposition();
                });
            }            
        });
    }
})(jQuery);

The anchor url points to a text file and loads its content into the clipboard. It works very well in Safari (even for a 4000+ prototype.js text file). However, it's failing on FF3.0 even on a simple text like "hello". I've logged the content of my Ajax call into the console and the success callback does seem to work. On FF it seems that clicking it a second time will complete the copy (because browser caches the text file from the first Ajax call).

Note that I've used a synchronous Ajax call here in order to wait for the text to finish loading. Anyone knows why my code doesn't work on FF? (Not sure if it's relevant, my backend done in Rails).

Comment by mana...@lifeessensuals.org, Jun 13, 2009

I added a tooltip to the object by doing the following.

Line 90 of the ZeroClipboard?.js file.

handlers: null, // user event handlers

added -> toolTip: 'Copy to Clipboard',

at Line 108:

this.div = document.createElement('div');

added -> this.div.title = this.toolTip;

Simple Enough. :-)

Comment by JoeAll...@gmail.com, Jun 25, 2009

Hello,

I've got an implementation using Jquery with div.multiple. Is there a way to add a link to each div?

Comment by not_some...@bigstring.com, Jul 7, 2009

is there a way to send a context menu event to the event listener? so that I could right click the button and it would copy or use a function

Comment by brookno...@gmail.com, Jul 20, 2009

WHY IS THERE NO PASTE?

Sorry for the caps, but WHY? At the moment it seems "ZeroCopyBoard?" is a more fitting name for this API.

Wouldn't it be possible to provide the ability to have a floating invisible video over a paste button, then when it is clicked, the actionscript would retrieve the clipboard text, then pass it to a javascript callback function. That would be real helpful. Is that possible?

I would try extend it myself but I don't have a copy of Flash, and I can't be bothered learning about it all, you'd probably do a better job. Nice API though, thanks!

Comment by ctemp...@gmail.com, Jul 21, 2009

ZeroClipboard? is a great utility! Thanks!

I'd like to use it in a security-sensitive site that encourages users to verify the non-malicious nature of all client-side code. To this end I'd like to suggest users use HP's SWFScan to check ZeroClipboard? for known vulnerabilities.

Here's a link to SWFScan (windows only): http://www.communities.hp.com/securitysoftware/blogs/spilabs/archive/2009/03/20/exposing-flash-application-vulnerabilities-with-swfscan.aspx

Unfortunately SWFScan can't scan the SWF. Here's what it reports:

"The Flash Application was malformed: Malformed data in SWF Header"

Any chance a fix could be made so ZeroClipboard? plays nice with SWFScan?

Thanks again!

Comment by project member jhuck...@gmail.com, Jul 21, 2009

ctemplin: I don't understand, I merely click "Publish" inside the Adobe Flash IDE. I am doing nothing strange to generate the ZeroClipboard?.swf file. In fact, the source FLA file is included in the source. You can compile it yourself from the source code and produce your own SWF file. I cannot explain why your SWFScan cannot open the file -- it is most definitely a valid SWF file.

Comment by brookno...@gmail.com, Jul 21, 2009

Me again, any thoughts on my previous post? Would it be possible to do paste as well?

Thanks

Comment by project member jhuck...@gmail.com, Jul 21, 2009

brooknovak: ZeroClipboard? relies on Adobe Flash for copying text to the clipboard. Flash does not provide any way to do a "paste" -- it only does a copy. Nothing I can do there.

That said, if you just want to grab the text that was copied, so you can do your own "paste" operation, you can get it all from JavaScript?. You yourself have to pass the text into ZeroClipboard? to be copied. You can then get it back out afterward by accessing the "clipText" property on your ZeroClipboard?.Client object.

Good luck.

Comment by brookno...@gmail.com, Jul 21, 2009

I just need to retrieve the text from the system clipboard when a user clicks a paste button. It should be possible. I will try extent it to do this and post my results... Only I tried to open the zeroclipboard.fla file in flash and it failed to read it. Any ideas?

Comment by project member jhuck...@gmail.com, Jul 21, 2009

I assure you there is no way to read the system clipboard contents in Flash, or in JavaScript?. (The only way is with a Java applet).

You need Adobe Flash CS3 to open the FLA file.

Comment by brookno...@gmail.com, Jul 21, 2009

Thanks!

Comment by ctemp...@gmail.com, Jul 22, 2009

jhuckaby: Thanks for your quick reply.

I'm trying to determine if this is just a problem with my system. Can anyone please confirm that they are able or unable to use HP's SWFScan to scan ZeroClipboard?.swf? Thanks

Here's agagin is a link to SWFScan (windows only): http://www.communities.hp.com/securitysoftware/blogs/spilabs/archive/2009/03/20/exposing-flash-application-vulnerabilities-with-swfscan.aspx

Comment by phoenix....@gmail.com, Jul 27, 2009

Hi. Great library! But I would like some help with a code sample you did for someone earlier (sample by jhuckaby, Feb 01, 2009) --

http://bowser.macminicolo.net/~jhuckaby/zeroclipboard/shashank.html

My question in this case: where in that code should I add the function upon "complete"? I mean after the text is copied, I'd like to show a message. Where should I add that function? Thanks.

Comment by project member jhuck...@gmail.com, Jul 27, 2009

phoenix.kiula, you should read the Instructions Wiki. It explains how to do this. Excerpt:

onComplete

The onComplete event is fired when the text is successfully copied to the clipboard. Example use:

	clip.addEventListener( 'onComplete', my_complete );
	
	function my_complete( client, text ) {
		alert("Copied text to clipboard: " + text );
	}

The handler is passed two arguments: a reference to the clipboard client object, and the text that was copied.

Comment by az9...@gmail.com, Jul 29, 2009

There is an error when you want to copy a text including special char \

Here is the generated error when \ is copied (using example page on http://bowser.macminicolo.net/~jhuckaby/zeroclipboard/) :

Error: syntax error Source File: http://bowser.macminicolo.net/~jhuckaby/zeroclipboard/ Line: 0, Column: 93 Source Code: try { flashtoXML(ZeroClipboard?.dispatch("1","complete","\")) ; } catch (e) { "<undefined/>"; }

Is there a fix ?

Thank you !

Comment by md.xytop, Sep 4, 2009

Hi. Your script does not correctly work, if I place button with your flash movie inside container with style overflow:auto. In this case your movie anyway will on same place if I scroll through this container. Also hardcoded zIndex is not good, and current element which we working can be without zIndex, but his parents can have it. I just modified it (function glue and function getDOMObjectPosition). Here is full modified script (for v1.0.4):

// Simple Set Clipboard System
// Author: Joseph Huckaby
// Modified by: Dyatlov Vitaly <diatlov@idknet.com>

var ZeroClipboard = {
	
	version: "1.0.4",
	clients: {}, // registered upload clients on page, indexed by id
	moviePath: '/control/js/ZeroClipboard.swf', // URL to movie
	nextId: 1, // ID of next movie
	
	$: function(thingy) {
		// simple DOM lookup utility function
		if (typeof(thingy) == 'string') thingy = document.getElementById(thingy);
		if (!thingy.addClass) {
			// extend element with a few useful methods
			thingy.hide = function() { this.style.display = 'none'; };
			thingy.show = function() { this.style.display = ''; };
			thingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; };
			thingy.removeClass = function(name) {
				this.className = this.className.replace( new RegExp("\\s*"
                                    + name + "\\s*"), " ").replace(/^\s+/, '').replace(/\s+$/, '');
			};
			thingy.hasClass = function(name) {
				return !!this.className.match( new RegExp("\\s*" + name + "\\s*") );
			}
		}
		return thingy;
	},
	
	setMoviePath: function(path) {
		// set path to ZeroClipboard.swf
		this.moviePath = path;
	},
	
	dispatch: function(id, eventName, args) {
		// receive event from flash movie, send to client		
		var client = this.clients[id];
		if (client) {
			client.receiveEvent(eventName, args);
		}
	},
	
	register: function(id, client) {
		// register new client to receive events
		this.clients[id] = client;
	},
	
	getDOMObjectPosition: function(obj, parentObj) {
		// get absolute coordinates for dom element
		var info = {
                        left: 0,
                        top: 0,
                        zIndex: 0,
                        width: obj.width ? obj.width : obj.offsetWidth,
                        height: obj.height ? obj.height : obj.offsetHeight
                };

                /*Find relative zIndex*/
                var parent = obj;
                while(parent) {
                    if (parent.style.zIndex) {
                        info.zIndex = parseInt(parent.style.zIndex) + 1;
                        break;
                    }
                    parent = parent.parentElement;
                }
                /**/

                while (obj) {
                        info.left += obj.offsetLeft;
                        info.top += obj.offsetTop;
                        obj = obj.offsetParent;
                }

                /*Find relative offset*/
                while (parentObj) {
                        info.left -= parentObj.offsetLeft;
                        info.top -= parentObj.offsetTop;
                        parentObj = parentObj.offsetParent;
                }
                /**/

                return info;
	},
	
	Client: function(elem) {
		// constructor for new simple upload client
		this.handlers = {};
		
		// unique ID
		this.id = ZeroClipboard.nextId++;
		this.movieId = 'ZeroClipboardMovie_' + this.id;
		
		// register client with singleton to receive flash events
		ZeroClipboard.register(this.id, this);
		
		// create movie
		if (elem) this.glue(elem);
	}
};

ZeroClipboard.Client.prototype = {
	
	id: 0, // unique ID for us
	ready: false, // whether movie is ready to receive events or not
	movie: null, // reference to movie object
	clipText: '', // text to copy to clipboard
	handCursorEnabled: true, // whether to show hand cursor, or default pointer cursor
	cssEffects: true, // enable CSS mouse effects on dom container
	handlers: null, // user event handlers
	parentObj: 'body',

	glue: function(elem) {
		// glue to DOM element
		// elem can be ID or actual DOM element object
		this.domElement = ZeroClipboard.$(elem);

                this.domParent = ZeroClipboard.$(this.parentObj);

		if (this.domElement.style.zIndex) {
			this.zIndex = parseInt(this.domElement.style.zIndex) + 1;
		}

		// find X/Y position of domElement
		var box = ZeroClipboard.getDOMObjectPosition(this.domElement, this.domParent);
		
		// create floating DIV above element
		this.div = document.createElement('div');
		var style = this.div.style;
		style.position = 'absolute';
		style.left = '' + box.left + 'px';
		style.top = '' + box.top + 'px';
		style.width = '' + box.width + 'px';
		style.height = '' + box.height + 'px';
		style.zIndex = box.zIndex;

		// style.backgroundColor = '#f00'; // debug
		var body = document.getElementById(this.parentObj);
		body.appendChild(this.div);
		
		this.div.innerHTML = this.getHTML( box.width, box.height );
	},
	
	getHTML: function(width, height) {
		// return HTML for movie
		var html = '';
		var flashvars = 'id=' + this.id + 
			'&width=' + width + 
			'&height=' + height;
			
		if (navigator.userAgent.match(/MSIE/)) {
			// IE gets an OBJECT tag
			var protocol = location.href.match(/^https/i) ? 'https://' : 'http://';
			html += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="'+protocol
                            +'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'
                            +width+'" height="'+height+'" id="'+this.movieId
                            +'" align="middle"><param name="allowScriptAccess" value="always" />'
                            +'<param name="allowFullScreen" value="false" /><param name="movie" value="'
                            +ZeroClipboard.moviePath+'" /><param name="loop" value="false" />'
                            +'<param name="menu" value="false" /><param name="quality" value="best" />'
                            +'<param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'
                            +flashvars+'"/><param name="wmode" value="transparent"/></object>';
		}
		else {
			// all other browsers get an EMBED tag
			html += '<embed id="'+this.movieId+'" src="'+ZeroClipboard.moviePath
                            +'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'
                            +width+'" height="'+height+'" name="'+this.movieId
                            +'" align="middle" allowScriptAccess="always" allowFullScreen="false"'
                            +' type="application/x-shockwave-flash"'
                            +' pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'
                            +flashvars+'" wmode="transparent" />';
		}
		return html;
	},
	
	hide: function() {
		// temporarily hide floater offscreen
		if (this.div) {
			this.div.style.left = '-2000px';
		}
	},
	
	show: function() {
		// show ourselves after a call to hide()
		this.reposition();
	},
	
	destroy: function() {
		// destroy control and floater
		if (this.domElement && this.div) {
			this.hide();
			this.div.innerHTML = '';
			
			var body = document.getElementsByTagName('body')[0];
			try { body.removeChild( this.div ); } catch(e) {;}
			
			this.domElement = null;
			this.div = null;
		}
	},
	
	reposition: function(elem) {
		// reposition our floating div, optionally to new container
		// warning: container CANNOT change size, only position
		if (elem) {
			this.domElement = ZeroClipboard.$(elem);
			if (!this.domElement) this.hide();
		}
		
		if (this.domElement && this.div) {
			var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
			var style = this.div.style;
			style.left = '' + box.left + 'px';
			style.top = '' + box.top + 'px';
		}
	},
	
	setText: function(newText) {
		// set text to be copied to clipboard
		this.clipText = newText;
		if (this.ready) this.movie.setText(newText);
	},
	
	addEventListener: function(eventName, func) {
		// add user event listener for event
		// event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel
		eventName = eventName.toString().toLowerCase().replace(/^on/, '');
		if (!this.handlers[eventName]) this.handlers[eventName] = [];
		this.handlers[eventName].push(func);
	},
	
	setHandCursor: function(enabled) {
		// enable hand cursor (true), or default arrow cursor (false)
		this.handCursorEnabled = enabled;
		if (this.ready) this.movie.setHandCursor(enabled);
	},
	
	setCSSEffects: function(enabled) {
		// enable or disable CSS effects on DOM container
		this.cssEffects = !!enabled;
	},
	
	receiveEvent: function(eventName, args) {
		// receive event from flash
		eventName = eventName.toString().toLowerCase().replace(/^on/, '');
				
		// special behavior for certain events
		switch (eventName) {
			case 'load':
				// movie claims it is ready, but in IE this isn't always the case...
				// bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function
				this.movie = document.getElementById(this.movieId);
				if (!this.movie) {
					var self = this;
					setTimeout( function() { self.receiveEvent('load', null); }, 1 );
					return;
				}
				
				// firefox on pc needs a "kick" in order to set these in certain cases
				if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {
					var self = this;
					setTimeout( function() { self.receiveEvent('load', null); }, 100 );
					this.ready = true;
					return;
				}
				
				this.ready = true;
				this.movie.setText( this.clipText );
				this.movie.setHandCursor( this.handCursorEnabled );
				break;
			
			case 'mouseover':
				if (this.domElement && this.cssEffects) {
					this.domElement.addClass('hover');
					if (this.recoverActive) this.domElement.addClass('active');
				}
				break;
			
			case 'mouseout':
				if (this.domElement && this.cssEffects) {
					this.recoverActive = false;
					if (this.domElement.hasClass('active')) {
						this.domElement.removeClass('active');
						this.recoverActive = true;
					}
					this.domElement.removeClass('hover');
				}
				break;
			
			case 'mousedown':
				if (this.domElement && this.cssEffects) {
					this.domElement.addClass('active');
				}
				break;
			
			case 'mouseup':
				if (this.domElement && this.cssEffects) {
					this.domElement.removeClass('active');
					this.recoverActive = false;
				}
				break;
		} // switch eventName
		
		if (this.handlers[eventName]) {
			for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) {
				var func = this.handlers[eventName][idx];
			
				if (typeof(func) == 'function') {
					// actual function reference
					func(this, args);
				}
				else if ((typeof(func) == 'object') && (func.length == 2)) {
					// PHP style object + method, i.e. [myObject, 'myMethod']
					func[0][ func[1] ](this, args);
				}
				else if (typeof(func) == 'string') {
					// name of function
					window[func](this, args);
				}
			} // foreach event handler defined
		} // user defined handler for event
	}
	
};
Comment by thesomak...@gmail.com, Oct 1, 2009

The example does not work. The onload event does not get triggered.

Is test.html supposed to be a working example??

I just spent 2-3 hours trying to debug this. I am giving up now, very annoyed. Please don't waste my time with broken examples.

Thanks.

Comment by david.horat, Oct 29, 2009

I would love to be able to copy images using this tool. :)

PS: Very good work!

Comment by m...@gofrwd.com, Dec 26, 2009

I needed to copy content div's of different sizes. Here's my solution:

<div class="clippable-target" id="clippable-target-1">content</div>
<div class="clippable-trigger" id="clippable-trigger-1">Copy<div>
<div class="clippable-target" id="clippable-target-2">content</div>
<div class="clippable-trigger" id="clippable-trigger-2">Copy<div>
...
// function init()
// set the clip text to the innerHTML of the target element
targetId = (this).id.replace('trigger','target');
content = $("div#"+targetId).html();
clip.setText( content );

Hope this helps!

Mike

gofrwd.com

Comment by Gl...@GetYouhealth.com, Jan 12, 2010

I'm using zeroclipboard to add text to the clipboard in FireFox? and works great but was wondering using the same library how to get clipboard text written by another application?

Comment by danielz...@gmail.com, Jan 22, 2010

How can I integrate zeroclipboard with wordpress so that I can create a button in the wordpress post enable reader to copy the textarea?

Comment by kaviraj...@gmail.com, Feb 5, 2010

I'm using for multiple instance .would you please tell where wrong function init() {

$('.copytoclipboard').each(function() { cid=jQuery(this).attr('id'); alert(cid);
var clip = new ZeroClipboard???.Client();
clip.setText( ); // will be set later on mouseDown clip.setHandCursor(true); clip.addEventListener('mouseDown',function(client) { client.setText("text"); } ); clip.addEventListener( 'complete', function(client,text) {
alert("Copied text to clipboard" );
} );
clip.glue(cid);
});

} $(document).ready(function(){

init();

});

Comment by allan.ja...@gmail.com, Mar 2, 2010

Hello,

Thanks so much for releasing ZeroClipboard? as open source - its proven to be very useful for a number of projects I've been working on! One of my own open source projects which makes use of it is TableTools (for DataTables?) - and I've made a few modifications which I thought I would share back.

1. The ability to save files (added a setAction function to allow copy to clipboard or saving the text to a local file) - requires Flash 10. As a part of this you can specify if you want the file to be saved in UTF-16LE, or UTF-8 (TableTools? using UTF-16LE for Excel export), and also indicate if you want the BOM included or not.

2. The ability to 'append' and 'clear' to the set text. The reason for introducing this is that the Javascript / Flash bridge appears to have a limit on the string size which can be copied across (it varies from browser to browser apparently). This way you can break the JS string into parts and just send it over piece at a time using appendText(). setText() will still work as normal.

One thing to note - it's is based on 1.0.4 (sorry). I'll merge my changes into 1.0.6 at some point if you are interested in this at all.

Thanks again! Allan

Comment by mloc...@gmail.com, Mar 10, 2010

I had the problem that the ZeroClipboard?.js was included in web pages placed in different subfolders. So I've introduced the possibility to autoconfigure the moviePath propeerty of the ZeroClipboard? object.

Here's what I added to my ZeroClipboard? variabie:

var ZeroClipboard = {
...
	SCRIPT_NAME: 'ZeroClipboard.js', // name of this script (useful for setMoviePathAuto), without path specification
	MOVIE_NAME: 'ZeroClipboard.swf', // name of this flash movie (useful for setMoviePathAuto), relative to the js
...
	setMoviePathAuto:function() {
		try
		{
			var scripts = document.getElementsByTagName('script'), src, re, match, path;
			for(var k = 0; k < scripts.length; k++) {
				if(typeof(src = scripts[k].src) == 'string' ) {
					re = RegExp('(^|\\/)' + ZeroClipboard.SCRIPT_NAME + '($|\\?)', 'ig');
					if ( match = re.exec(src) ) {
						path = ( match.index > 0) ? src.substr(0, match.index + 1) : match[1];
						ZeroClipboard.setMoviePath(path + ZeroClipboard.MOVIE_NAME);
						return true;
					}
				}
			}
			return false;
		}
		catch(e) {
			return false;
		}
	},
...

After that, to configure the movie path of ZeroClipboard? it's enough to call ZeroClipboard.setMoviePathAuto(); before it's used.

Thank you for this great project!

-- Ciao

Michele

Comment by john.pet...@me.com, Mar 14, 2010

By using

Clipboard.generalClipboard.setData(ClipboardFormats.TEXT_FORMAT, clipText); Clipboard.generalClipboard.setData(ClipboardFormats.HTML_FORMAT, clipText);

I made ZeroClipboard?? correctly copy html fragments such that they can be pasted into email programs and visual html editors like yahoo mail and gmail.

The modified action script (now flash 10 only) is here:

http://clp.ly/zc/ZeroClipboard.as

The swf is here:

http://clp.ly/zc/ZeroClipboard10.swf

I'm using it on http://clp.ly to copy clips and quotes of web pages and it's working well.

Comment by project member jhuck...@gmail.com, Mar 14, 2010

Thanks jpp. Unfortunately, I can't get this feature to work in Firefox. The HTML never gets copied to the clipboard. Still trying tho...

Comment by jpp%clp...@gtempaccount.com, Mar 15, 2010

I had to do a manual cache flush then restart to get FF to forget the old .swf file before it would work - it's live on http://clp.ly/

Comment by project member jhuck...@gmail.com, Mar 15, 2010

Yup, I had the same problem, but it only seems to work a few times in FF, then suddenly stops working again. Only another cache flush and restart gets it back. Weird.

Comment by jpp%clp...@gtempaccount.com, Mar 15, 2010

odd - working solidly for me FF 3.5.8 on a mac, IE7/8 on XP and Win7, Safari and Chrome on a mac. I just tried about 50 copy/paste operations in a row and it works every time. Does it work on http://clp.ly for you or is it just your test where it's failing? - and if you want to take this out of the wiki while we solve it you can email me at jpp (at) clp.ly

Comment by dbos...@gmail.com, Apr 8, 2010

If page is served as application/xhtml+xml some adjustments must be made, after 137 line:

		// style.backgroundColor = '#f00'; // debug
        var tempHTML = this.getHTML( box.width, box.height );
		appendElem.appendChild(this.div);
        if (navigator.userAgent.match(/MSIE/)) {
            this.div.innerHTML = tempHTML;
        } else {
            var tempID =  "div_" + this.id;
            this.div.setAttribute("id", tempID);
            document.getElementById(tempID).appendChild(tempHTML);
        }
	},
	
	getHTML: function(width, height) {
		// return HTML for movie
		var flashvars = 'id=' + this.id + 
			'&width=' + width + 
			'&height=' + height;
			
		if (navigator.userAgent.match(/MSIE/)) {
			// IE gets an OBJECT tag
            var html = '';
			var protocol = location.href.match(/^https/i) ? 'https://' : 'http://';
			html += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="'+protocol+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'+width+'" height="'+height+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'" /><param name="wmode" value="transparent" /></object>';
		}
		else {
			// all other browsers get an EMBED tag
            var html = document.createElement("embed");
            html.setAttribute("id", this.movieId);
            html.setAttribute("src", ZeroClipboard.moviePath);
            html.setAttribute("loop", false);
            html.setAttribute("menu", false);
            html.setAttribute("quality", "best");
            html.setAttribute("bgcolor", "#ffffff");
            html.setAttribute("width", width);
            html.setAttribute("height", height);
            html.setAttribute("name", this.movieId);
            html.setAttribute("align", "middle");
            html.setAttribute("allowScriptAccess", "always");
            html.setAttribute("allowFullScreen", "false");
            html.setAttribute("type", "application/x-shockwave-flash");
            html.setAttribute("pluginspage", "http://www.macromedia.com/go/getflashplayer");
            html.setAttribute("flashvars", flashvars);
            html.setAttribute("wmode", "transparent");
		}
		return html;
	}, 

ending with line 161.

Comment by 2sa...@gmail.com, Apr 12, 2010

Sorry, I've just discovered 'multiple elements' example. And that seems to solve the event order problem I've described here.

Comment by 2sa...@gmail.com, Apr 15, 2010

Well, not so fast. :( IE6 still has a problem (with events order?)

As I've mentioned, I need to implement a menu that disappears on mouseout. And while the sample code below works fine in Firefox 3.6.3 in IE6 moving mouse from ZeroClipboard? item to another (e.g. from 'item 2' to either 'item 1' or 'item 3') triggers menu hiding. Do you have an idea on how that can be fixed? Otherwise I will have to use different clipboard approach for IE6.

P.S. Is there a way to prevent Flash from stealing the focus from the page after clicking ZeroClipboard? movie?

<html>
<head>
<style type="text/css">
#popup {
    position: absolute;
    border: 1px solid navy;
    background-color: #4C6382;
}

#popup UL {
    padding: 0;
    margin: 0;
}

#popup LI {
    list-style: none;
    padding: 0;
    margin: 0;
    border: 1px solid #4C6382;
}

#popup A {
    text-decoration: none;
    color: white;
    padding: 0 4px 0 4px;
    display: block;
    cursor: pointer;
}

#popup A:hover,
#popup A.hover {
    background-color: #2586D7;
    color: yellow;
}
</style>
<script type="text/javascript" src="ZeroClipboard.js"></script>
<script language="JavaScript">
function $(id) { return document.getElementById(id); }

var clip = createClip();

function updateClip(elem, text) {
    // set the clip text
    clip.setText(text);

    // reposition the movie over our element
    // or create it if this is the first time
    if (clip.div) {
        clip.receiveEvent('mouseout', null);
        clip.reposition(elem);
    }
    else
        clip.glue(elem);

    // gotta force these events due to the Flash movie
    // moving all around.  This insures the CSS effects
    // are properly updated.
    clip.receiveEvent('mouseover', null);
}

function debugstr(msg) {
    var p = document.createElement('p');
    p.innerHTML = msg;
    $('d_debug').appendChild(p);
}

function createClip()
{
    var clip = new ZeroClipboard.Client();
    clip.setHandCursor(true);
    clip.addEventListener('mouseOver', stopPopupTimer);
    clip.addEventListener('mouseOut', hidePopupMenu);
    clip.addEventListener('complete', hidePopupMenu);

    return clip;
}

var popupTimer = null;

function stopPopupTimer() {
    if (popupTimer) {
        clearTimeout(popupTimer);
        popupTimer = null;
    }
}

function hidePopupMenu() {
    // kill the previous timer
    stopPopupTimer();
    popupTimer = setTimeout(function() {
        var menu = document.getElementById("popup");
        menu.style.display = 'none';
    }, 500);
}
</script>
</head>
<body>
<div id="popup">
<ul onmouseover='stopPopupTimer()' onmouseout='hidePopupMenu()'>
<li><a id="item1">item 1</a>
<li><a id="item2" onmouseover="updateClip(this, 'item 2');">item 2</a>
<li><a id="item3" onmouseover="updateClip(this, 'item 3');">item 3</a>
</ul>
</div>

<div id="d_debug" style="border:1px solid #aaa; padding: 10px; font-size:9pt; margin-left:200px">
</div>
</body>
</html>
Comment by fantasy....@gmail.com, Apr 16, 2010

well,I have a problem. when I create a project in fx 4, copy these code into it , and compile it, it seems to process not so good .when the mouse cross over the button (copy to clipboard), nothing changes. But use your ZeroClipboard?.swf, it can work. why this?

  public function ZeroClipboard() {
            // constructor, setup event listeners and external interfaces
            stage.scaleMode = StageScaleMode.EXACT_FIT;
            flash.system.Security.allowDomain("*");
            
            // import flashvars
            var flashvars:Object = LoaderInfo( this.root.loaderInfo ).parameters;
            id = flashvars.id;
            
            //width = 137  height = 39
            var width:Number = Number(flashvars.width);
            var height:Number = Number(flashvars.height);
                
            // invisible button covers entire stage
            button = new Sprite();
            button.buttonMode = true;          
            button.useHandCursor = true;
            button.graphics.beginFill(0x00FF00);            
           
           // if exec this code , it would work well. 
           // button.graphics.drawRect(0, 0, 10 * width, 10 * height); 

           // if chose this code , something wrong.
            button.graphics.drawRect(0, 0, width,  height);
            ......

It seems that the parameters passed meet something wrong. Is there any one can account for this ?

Comment by fantasy....@gmail.com, Apr 16, 2010

well,I have a problem. when I create a project in fx 4, copy these code into it , and compile it, it seems to process not so good .when the mouse cross over the button (copy to clipboard), nothing changes. But use your ZeroClipboard?.swf, it can work. why this?

  public function ZeroClipboard() {
            // constructor, setup event listeners and external interfaces
            stage.scaleMode = StageScaleMode.EXACT_FIT;
            flash.system.Security.allowDomain("*");
            
            // import flashvars
            var flashvars:Object = LoaderInfo( this.root.loaderInfo ).parameters;
            id = flashvars.id;
            
            //width = 137  height = 39
            var width:Number = Number(flashvars.width);
            var height:Number = Number(flashvars.height);
                
            // invisible button covers entire stage
            button = new Sprite();
            button.buttonMode = true;          
            button.useHandCursor = true;
            button.graphics.beginFill(0x00FF00);            
           
           // if exec this code , it would work well. 
           // button.graphics.drawRect(0, 0, 10 * width, 10 * height); 

           // if chose this code , something wrong.
            button.graphics.drawRect(0, 0, width,  height);
            ......

It seems that the parameters passed meet something wrong. Is there any one can account for this ?

Comment by adrya.st...@gmail.com, Jun 1, 2010

This utility works perfectly, except that it conflicts with an AJAX updater on the same page. I've traced the problem to this:

function $(id) { return document.getElementById(id); }

Commenting this line out allows my AJAX updater to work, but the "Copy to Clipboard" button is no longer able to receive click events.

Is there another way to trigger the copy function (such onClick)?

Comment by loupi...@gmail.com, Jun 1, 2010

plugins are not allowed in content that is displayed in sandboxed frames. chrome 5.0 enforces that, and google-image search now return image search results in sandboxed frames.

this means that zeroclipboard does not work in pages that are returned by a google image search when using chrome.

my question is: how can i detect that zeroclipboard is not available. when i call clip = new ZeroClipboard?.Client();

it still returns an object, but the object is non-funhctional, i.e. it will never call the callbacks and it will never be able to copy text in the clipboard (because flash is disabled in that case).

i would prefer new ZeroClipboard?.Client(); to return null in this case, or to have some way to detect programmatically whether zeroclipboard will work - if it does not, then i can use some other way or change the display on my page.

Comment by david.p...@gmail.com, Jun 23, 2010

multi copy to clipboard sample:

<html>
<head>
	<title>Zero Clipboard Test</title>
	<script type="text/javascript" src="ZeroClipboard.js"></script>
	<script language="JavaScript">		
		function toClipboard(strID,strMsg) {
			var clip = new ZeroClipboard.Client();
			clip.setHandCursor( true );
			clip.setText(strMsg);		
			clip.addEventListener('complete', function (client, text) {
				alert("Copy Ok!!");
			});
			clip.glue(strID);
		}
	</script>
</head>
<body>
	<div id="c1" style="position:relative;width:60px;" onmouseOver="toClipboard(this.id,'11')">
		<input type="button" value="copy(11)" style="width:60px;"/>
	</div>
	<br/>
	<div id="c2" style="position:relative;width:60px;" onmouseOver="toClipboard(this.id,'22')">
		<input type="button" value="copy(22)" style="width:60px;"/>
	</div>
	<br/>
	<div id="c3" style="position:relative;width:60px;" onmouseOver="toClipboard(this.id,'33')">
		<input type="button" value="copy(33)" style="width:60px;"/>
	</div>
</body>
</html>
Comment by shek...@gmail.com, Jul 9, 2010

Is there a way of having the first format of the script abit like the second format that has been made.

So example: Textarea1 Button1

Textarea2 Button2

So basically if you click on button1 it only reads from the textarea1 and not read from textarea2. And same if you click textarea2, it doesn't interfear with the first.

If this is possible can it be done more than 2 times so allowing you to do as many as you want providing you change the values.

Ive been trying to do this myself but not having any luck. I have used most of the examples posted but none of them work for me.

Comment by project member jhuck...@gmail.com, Jul 9, 2010
Comment by shek...@gmail.com, Jul 9, 2010

Awesome that is exactly what i was looking for, now all i gotta do is get a alert added and ill be able to get this added to my website...

Comment by shek...@gmail.com, Jul 9, 2010

Right jhuckaby this is what i got so far, it seems it works without any problems using a .htm type page.

LINK: http://www.hostingalerts.com/index22.htm

But as soon as i attempt to add it to my website I get errors to do with identifing this line see my below link for example of site.

LINK: http://www.hostingalerts.com/index.php?id=linkus

clip.setText( ($('#textarea' + this.id.replace(/\D+/g, '' + )))0?.value );

Line: 686

Could it be comflicting with my current coding that my site uses to id? as my site uses it as a way to mask the URL. index.php?id=filename

Do you think this could be the cause and if so can a work around be created maybe.

Comment by project member jhuck...@gmail.com, Jul 9, 2010

@shekanw: This has nothing to do with ZeroClipboard?. Your site is adding a "+" character after it finds two single-quotes together on a line. This is breaking the JavaScript? on the page. Try something else which returns an empty string, maybe: new String().

clip.setText( ($('#textarea' + this.id.replace(/\D+/g, new String() )))0?.value );

Best of luck. Sorry but I cannot help you further.

Comment by shek...@gmail.com, Jul 9, 2010

Yea jhuckaby, hmm i added + in the hope i could do something but i must of forgot to delete it out before posting. I have taken it out and same result, i also tried new String and same result still not working..

I have put it back to how you gave it to me in the first place so it should show as is.

Comment by project member jhuck...@gmail.com, Jul 9, 2010

@shekanw: This is the very last post I am writing on this. You need to look at your HTML source. Your textarea fields have incorrect IDs which do not match up with the code. Your textareas have IDs like "fe_text" and "fe_text2". The JavaScript? code is expecting them to be "textarea1" and "textarea2" and so on. Note that not only are the names incorrect, but you are also missing a numerical digit on the first one. Best of luck. I really cannot help you anymore, and am not going to answer any more posts. Sorry.

Comment by shek...@gmail.com, Jul 9, 2010

Ah very sorry, I think i can sort it now. Thank you and i apologize for wasteing anymore of your time.

Comment by shek...@gmail.com, Jul 9, 2010

All Fixed, Thank you so much jhuckaby, I simply messed up due to the fact im tired and i was doing to much copying and pasteing and not watching what i was doing. (NOTE TO ALL - GET SLEEP BEFORE WORKING ON YOUR CODES :P)

Comment by Paul.Jos...@gmail.com, Jul 12, 2010

Need Scripting Help

First, I want to send a huge thank you to you Mr. Huckaby. You are amazing!! I've been studying the example code you've made for others in this forum, and you really do go far above and beyond here. I'm learning tons!

I've only got one link (but may consider a 2nd) on a very generic page, for which I need to copy text over to the clipboard. At least, it's like a link (I think). The plain text that needs to be copied over to clipboard changes dramatically, depending on the name of the page.

Before I go too much farther though, here's the page (minus your zero clipboard script):

<html><head>

<script type="text/javascript">

//This script will grab the URL for the page this is on
//and parse out just the filename string (between indexes, aka
// after the last "/", but without the dot and 3 letter ext). 
// It then creates a variable with the same path & filename, 
// but ending in .png (for the image, named the same).
// Lastly, it preloads the rollover images used on this page.

var str = document.location.href
var number_1 = str.lastIndexOf('/') + 1
var number_2 = str.lastIndexOf('.')
var myFile = str.substring(number_1, number_2)
var forgrndPath = "../images/" + myFile + ".png"; 

ForgrndImg = new Image(675,735);  
ForgrndImg.src = forgrndPath; 
//all other images used for Foreground, are preloaded here also

// document.write(myFile)
// document.write("<br>")
// document.write(forgrndPath)
// document.write("<br>")

</script>

<js script "directorytext" included here for lots of different clipboard text possibilities>
</head><body>

<script type="text/javascript">
<div id="contactInfo" style="padding: 0px; background-image: url('../images/Background.png'); background-repeat: no-repeat; border-style: none; border-width: 0px; width: 675px; height: 735px; right: 0px; margin-right: 0px; float: right; clip: rect(auto, 0px, auto, auto);">
</script>

<script type="text/javascript">
document.write('<img name="AncientComputerImageMap" src="'+forgrndPath+'" width="675" height="735" border="0" id="AncientComputerImageMap" usemap="#m_AncientComputerImageMap" alt="" />');
</script>

<map name="m_AncientComputerImageMap" id="m_AncientComputerImageMap">

<area shape="rect" coords="532,537,577,561" href="Next.asp" title="NEXT:  Click here for the next entry in the directory." alt="NEXT:  Click here for the next entry in the directory." />
<area shape="rect" coords="264,561,312,586" href="Previous.asp" title="PREVIOUS: Click here for the previous entry in the directory." alt="PREVIOUS: Click here for the previous entry in the directory." />
<area shape="rect" coords="309,367,459,476" href="blahblahblah.pdf" title="Click here for a printable blah." alt="Click here for a printable full list of blah." />
<area shape="rect" coords="125,367,303,476" href="Javascript-Function" title="Click here to copy blah info to your clipboard (which you can then paste elsewhere)." alt="Click here to blah info to your clipboard (which you can then paste elsewhere)." />
<area shape="rect" coords="155,231,398,279" href="mailto:fake@fake.com" title="Click here to email fake" alt="Click here to email fake" />
</map>

</div>

</body></html>

----

Now, notice the 4th area shape above. This is the one great link that I want to use (there's no text though, it's just a hotspot). Mouseover and mouseout just change rollover behaviors by modifying the (mostly transparent) foreground image. I'm going to use the onclick event with ZeroClipboard? technology to parse another file for the correct text to send to the clipboard.

Regarding the rollover behavior: On mouse over, the link will simply change the forgrndPath (maybe call a function to set it), and this will then change the foreground image used by this image map. On mouse out, it goes back to what it was before.

OnClick?, this hotspot link will call a function like DirectoryList?(myFile) which is inside the "directorytext" script, which looks at the value of myFile, and if = DirectoryEntry1?, then Entry1 Text will be sent to the ZeroClipboard? function to be copied to clipboard. ElseIf? myFile=DirectoryEntry2?, then Entry2 Text will be sent to the ZeroClipboard? function to be copied, etc. There is a 1:1 correspondence between the pages and entries in this directory.

I hope this makes sense? Please accept my apologies for making this entry so long. I'm in way over my head here, and not sure what details to include or not in this.

Thanks again for any help you can provide :-)

Comment by project member jhuck...@gmail.com, Jul 14, 2010

@Paul.Joseph.Richardson: Hey Paul, unfortunately Zero Clipboard does not support maps, so you will have to implement some sort of custom solution. Check the docs for the "Custom Implementation" section -- what you need is to get the raw HTML for the Flash Movie, and float it in an element by yourself (do not call the "glue()" method). Quick example (sorry I don't have time to fully explain this):

First, wrap your map in a container element with position:relative, then create a floating DIV that is positioned and sized perfectly for the area of your map that should have a copy-to-clipboard button:

<div id="container" style="position:relative">
<div id="zeroclipboard" style="position:absolute; left:125px; top:367px; width:178px; height:109px; z-index:2"></div>
<!-- YOUR MAP HERE -->
</div>

Then, when your document is loaded, issue this JavaScript??:

var clip = new ZeroClipboard.Client();
clip.setText( "text to copy here" );
var html = clip.getHTML( 150, 20 );
document.getElementById('zeroclipboard').innerHTML = html;

This is all untested, but the idea is this. The Flash movie has to "intercept" the clicks to make the copy-to-clipboard happen, so it has to float above the element you want clickable. This is usually handled automatically by the glue() function, but this is the manual way to do it, because we aren't floating above an element, but rather a specific area of a map.

Sorry I don't have time to help further, but you can find great resources on the internet for doing things like this. Zero Clipboard is just a Flash Movie that has to float above the element you want clickable. Good luck!

- Joe

Comment by project member jhuck...@gmail.com, Jul 14, 2010

@Paul.Joseph.Richardson: Hey Paul, unfortunately Zero Clipboard does not support maps, so you will have to implement some sort of custom solution. Check the docs for the "Custom Implementation" section -- what you need is to get the raw HTML for the Flash Movie, and float it in an element by yourself (do not call the "glue()" method). Quick example (sorry I don't have time to fully explain this):

First, wrap your map in a container element with position:relative, then create a floating DIV that is positioned and sized perfectly for the area of your map that should have a copy-to-clipboard button:

<div id="container" style="position:relative">
<div id="zeroclipboard" style="position:absolute; left:125px; top:367px; width:178px; height:109px; z-index:2"></div>
<!-- YOUR MAP HERE -->
</div>

Then, when your document is loaded, issue this JavaScript??:

var clip = new ZeroClipboard.Client();
clip.setText( "text to copy here" );
var html = clip.getHTML( 150, 20 );
document.getElementById('zeroclipboard').innerHTML = html;

This is all untested, but the idea is this. The Flash movie has to "intercept" the clicks to make the copy-to-clipboard happen, so it has to float above the element you want clickable. This is usually handled automatically by the glue() function, but this is the manual way to do it, because we aren't floating above an element, but rather a specific area of a map.

Sorry I don't have time to help further, but you can find great resources on the internet for doing things like this. Zero Clipboard is just a Flash Movie that has to float above the element you want clickable. Good luck!

- Joe

Comment by josh.mcc...@wishabi.com, Jul 19, 2010

I've looked around some issues/posts and have seen some issues with "Operation aborted" for IE. The "problem" I'm having doesn't seem to be the same as that one. My problem is when I click the flash player IE's pop up blocker triggers saying that it blocked a pop up from the site. Why is the flash movie causing pop up blocker to catch something?

Comment by mpus...@gmail.com, Jul 20, 2010

Ever think about working with DojoToolKit? organization. I know they are looking for a cross browser copy to clipboard functionality. BTW great tool, we are using in a J2EE environment with jQuery.

Comment by krem...@gmail.com, Jul 28, 2010

I tried to make a phpBB3 BBCode using zeroClipboard but I have great problems. Sometimes it works, sometimes not, sometimes scrolling the site moves the movie away from the DOM object, sometimes after resizing the window and calling clip.reposition() the SWF movie is gone for good. Did anybody try to make a BBCode using zeroclipboard? What were the results?

Comment by terrilyn...@gmail.com, Jul 29, 2010

Thank you mana...@lifeessensuals.org!!! Your tool tip code "nudge" was excellent! Now I have tooltips to describe things! Thanks again!

Comment by xab...@gmail.com, Aug 3, 2010

Anyone has an example how to use it with multiple copy buttons? I don't understand how to create one or more Clients. Thanks a lot

Comment by gaurabm...@gmail.com, Aug 3, 2010

Doesn't copy content from a ajax loaded content Here is a piece of code from my ajax loaded file


<script type="text/javascript" src="ZeroClipboard.js"></script> <script language="JavaScript"> window.onload=init(); var clip = null;

function $(id) { return document.getElementById(id); }

function init() {

clip = new ZeroClipboard?.Client(); clip.setHandCursor( true );
clip.addEventListener('load', function (client) {
alert("Flash movie loaded and ready.");
});
clip.addEventListener('mouseOver', function (client) {
// update the text on mouse over clip.setText( $('ajax_area').value );
});
clip.addEventListener('complete', function (client, text) {
alert("Copied text to clipboard: " + text );
});
clip.glue( 'btn_copy', 'd_clip_container' ); document.getElementById('ajax_area').select();
} </script>

The script responds up to the "load" event listener and loads the flash movie sucessfully but doesn't responds to the "mouseOver" and "complete" event listener so doesn't copy content. What can be the reason behind this.

Comment by desperad...@yahoo.com, Sep 7, 2010

i have this code <script language="JavaScript">

var clip = null;
function init() {
clip = new ZeroClipboard?.Client(); clip.addEventListener('mouseOver', my_mouse_over); clip.glue( 'pass1' ); clip.addEventListener('complete', function (client, text) {
alert('Password copied to clipboard.');
});
}
function my_mouse_over(client) {
clip.setText(document.getElementById('pass1').value );

}

</script> i want to make it for multiple inputs like pass1 pass2 pass3 until 6 i tried some things but nothing worked. Please help

Comment by Paul.Jos...@gmail.com, Sep 7, 2010

Hi Joe,

I got the image map working.

YEAH!! Plus, it works in IE, FF, Opera, and Chrome. Overall, this is a very cool image map now, with several rollover's and special functions, including zeroclipboard!

thanks, Paul

Comment by ericban...@gmail.com, Sep 21, 2010

I have problem making this work on CakePHP, it says something about "thingy" being null (line 14 of ZeroClipboard?.js). TIA

Comment by gbco...@gmail.com, Nov 15, 2010

Hello,

i need a code the same www.gbpicsonline.com. 1 Button it is going more not !! It is a Php-Script and make the result dynamic. have ideas ?

Comment by couponco...@gmail.com, Nov 19, 2010

Thanks for a nice project. I have a suggestion to improve. On sites with multiple copy places, each place calls the swf file again and again, this causes http requests to increase. If you can reuse the first movie it will reduce number of http calls. For example this test (http://www.webpagetest.org/result/101120_D6ZX/6/details/) shows 20 http calls for 20 copy spots. thanks

Comment by r.twe...@gmail.com, Jan 26, 2011

is there any way to clear the clipboard automatically?

Comment by sirom...@gmail.com, Feb 14, 2011

Joe,

Would it be possible to support images as well? The Flash plug-in would detect the image on the clipboard, then convert it to Base64, and return it to Javascript since JS doesn't support binary objects. Thanks...

Comment by mdw...@gmail.com, Feb 22, 2011

Thank you for your script!

I have a question: How can I make the text copy when page loads? I mean by default it copies when you click the element. How to make it copy "OnLoad?"?

Thanks in advance!

Comment by talk2pra...@gmail.com, Mar 23, 2011

Suggest adding explicit instruction and / or an option to set the allowScriptAccess parameter to 'always' or 'sameDomain'. The default option of 'always' can be a security concern in some instances.

Thanks for great script !!

Comment by vibrant....@gmail.com, Mar 25, 2011

John, could you please provide detailed build instructions for the ZeroClipboard?.as file?

I'm tried two options:

1. Flash Builder 4 SDK, using mxmlc.exe (both versions: 3.50 and 4.0.0). They compiled fine, but when loading the resulting SWF file, ZeroClipboard? would not respond to any mouse or click messages.

2. Adobe Flash CS5. Opened a new Actionscript 3.0 project. Clicked on the first frame. Opened up "Actions", typed in "ZeroClipboard?.as" (located in the relevant project folder). Saved. Clicked "Publish". Compiles okay, but the against the resulting SWF file doesn't even load.

All the combinations I've tried result in malfunctioning ZeroClipboard?.swf files. Only your .swf seems to produce consistent results.

----> John, could you please provide a detailed description of how to compile ZeroClipboard?.as into a fully functioning SWF file? Please include all your application versions where necessary.

(I'm trying to chase down some even bugs, so it's important that I be able to debug the SWF file.)

Thanks.

Comment by vibrant....@gmail.com, Mar 26, 2011

Update: I found the FLA project file at: http://zeroclipboard.googlecode.com/svn/trunk/

That seems to be compiling okay and producing a reliable result. I'll start experimenting with that.

Comment by chinnu.i...@gmail.com, Apr 11, 2011

Hi Joe, and others who could help me with my query. After searching for days I came across zeroclipboard which was what I needed to enable copy paste from FireFox?. But I have a requirement which has multiple text areas which would be modified and they have to be copied with a different button.. example.. different text areas, different buttons.. all in one page(different text to be copied with each button). I tried to modify the code, but with no sucess(I am not a hard-time coder, but if this gets done I could proceed with the rest of the page, which is mainly php). I would appreciate any help that would comes my way. thank you

Comment by chinnu.i...@gmail.com, Apr 12, 2011

I found an answer.. thank you Stoyano...@gmail.com the code is working.. would test it in the real page and post to tell if it was a success. You guys rock! keep up the good work ;)

Comment by gregory....@gmail.com, Apr 14, 2011

Hi zeroclipboard experts, I need some help. I have a popup context menu and I press a button on that menu to copy some text. This works fine the first time. However, when I open the menu in another place, the flash file no longer copies the text to the clipboard.

The flash movie is appearing in the correct position and disappearing correctly when the menu is closed, but it is not copying the text to the clipboard. In fact, it is copying '' to the clipboard.

Any help with how to fix this/why this is happening would be appreciated.

Comment by gregory....@gmail.com, Apr 15, 2011

Never mind, I figured it out. Apparently I need to destroy the the old clipboard and make a new one every time a new context menu is created, rather than reusing the same clipboard.

Comment by walterg....@gmail.com, Apr 18, 2011

Hi! it's fine but I have a problen I copy html rendering of the source and get the text part alright. the text is betwwen <div> tags : <div id =xxx">30 lines of text with links</div> the text is copied but as the script for copying is after this diw and just before the </body> it gets copied as well. Have a look at http://w3.gril.univ-tlse2.fr/LISTA11.htm Is there a solution to only copy the text between the <div id=xxx></div> Thanks for a very useful tool

Comment by fabiobareta@gmail.com, Apr 28, 2011

after use o ajax scripts i have a lot of problems with position of the swf in the page...

the solution used is reposition of the clip.. !!!

var el = document.getElementById("cop"); if (el.addEventListener) {
el.addEventListener ("mouseover",function(){clip.reposition()},false);
} else if (el.attachEvent) {
el.attachEvent ("onmouseover",function(){clip.reposition()});
} else {
el.onmouseover = function(){clip.reposition()};
}
Comment by axl.disi...@gmail.com, May 17, 2011

First af all, thanks for your ZeroClipboard?: great idea.

I propose a little hint. This code is not necessary, IMHO:

var html = ''; if (navigator.userAgent.match(/MSIE/)) {

// IE gets an OBJECT tag var protocol = location.href.match(/^https/i) ? 'https://' : 'http://'; html += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="'+protocol+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'+width+'" height="'+height+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><param name="wmode" value="transparent"/></object>';
} else {
// all other browsers get an EMBED tag html += '<embed id="'+this.movieId+'" src="'+ZeroClipboard.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+width+'" height="'+height+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'" wmode="transparent" />';
}

Instead it works fine on all browsers:

var html = '<object type="application/x-shockwave-flash" data="'+ZeroClipboard.moviePath+'" width="'+width+'" height="'+height+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><param name="wmode" value="transparent"/></object>';

Comment by 19scot...@gmail.com, Jun 9, 2011

Greetings, I'm encountering a problem where zeroclipboard is failing to copy text from a js variable. in particular it seems to be choking on a carriage return character or newline.

The js String is ".aligncenter, div.aligncenter"

any ideas as to what is causing this to happen?

Comment by jpell...@gmail.com, Jul 13, 2011

Is it possible to trigger the clipboard copy from a KEY event? If so, most browsers treat the Enter key on a focused element as a click on that element. Do Flash objects even have 'focus'? If they do, can you add key handlers for KEY_DOWN and KEY_UP for the enter key similar to the mouse handlers?

Comment by redak...@ekutno.pl, Jul 25, 2011

ZeroClipboard? + CkEditor? = not working.

could anybody help me. iam PHP programmer, my knowlage of javascript is poor, soo i cannot rebuild zeroclipboard scripts to my needs. i have city-portal with few jurnalists writing on CMS. unfortunetely internet connection is breaking from time to time. efect is that somebody was writing a lot of text and after press SEND (input POST button) - connection is lost and all text is gone. the problem is:

1) how to unite SUBMIT or IMAGE input that is sending text in POST variable with zeroclipboard script?

2) i decidet to do 2 buttons - fist with zeroclipboard funciton and secound with POST all text (i can teach my emploers to them one after one). But there is another problem - when CKEDITOR is installed on webpage zeroclipboard script can see only text that was loaded from database, and no changes inside text (textarea width CKEDITOR) are recognized :(

contact: bm@netstar.pl

Comment by edu200...@gmail.com, Jul 26, 2011

hello.

i am having some trouble with this script. any help would greatly be appreciated.

i have successfully managed to setup a "copy to clipboard" image with the SWF on it, which works.

what i want to do now, is do the very same thing to an input. basically this: when the user clicks the input (actually the SWF over it), the text from another hidden input is copied to the clipboard.

the problem about this, is that the page IS generating the SWF object, placing it correctly, but it sets the height and width wrong (both are zero). is there any way to do this? or maybe to access the CSS properties of a certain SWF object?

here is my code if it helps: <code> var embedInputCode = new ZeroClipboard.Client(); embedInputCode.glue('input_id','input_parent_id'); //this is the only way i got it to work -- with specifying the parent also embedInputCode.setText($('#hidden_input_id').val()); </code>

thank you. (and sorry, i know this is not an idea, nor a suggestion)

Comment by prince...@gmail.com, Jul 26, 2011

// float just above object, or zIndex 99 if dom element isn't set

var zIndex = 99; if (this.domElement.style.zIndex) {
zIndex = parseInt(this.domElement.style.zIndex, 10) + 1;
}

i've read the javascript code,the snippets above dont work correctly when the glued obj do not be set the 'z-index' but its parent elements do.

Comment by andy.sco...@gmail.com, Oct 3, 2011

Hi,

Is this script still being developed or has development been depreciated ?

Comment by Ayub...@gmail.com, Oct 4, 2011

I am trying to copy text from an input text box below embedded in td element of table, below is the script in a JSF page

$(document).ready(function(){

$(function() {
$("#tableForm\\:fileTable tbody td\\:last-child").each(function() { //Create a new clipboard client var clip = new ZeroClipboard?.Client();

//Cache the last td and the parent row var lastTd = $(this); var parentRow = lastTd.parent("tr");
//Glue the clipboard client to the last td in each row clip.glue(lastTd0?);
//Grab the text from the parent row of the icon var txt = $.trim($("td\\:nth-child(2)", parentRow).text()); clip.setText(txt);
//Add a complete event to let the user know the text was copied clip.addEventListener('complete', function(client, text) {
alert("Copied text to clipboard:\n" + text);
});
});
});

});
Could any one point what might be the issue ? Data Table is dynamically generated. tableForm:fileTable is the id of the table generated by JSF

Thanks Ayub

Comment by Rob.56...@gmail.com, Oct 4, 2011

attn: jhuck...@gmail.com - is there a way to hire you for a custom zeroclipboard integration with another plugin? I have tried to figure out how to do it reading the docs but I am not a javascript expert by any means and can't figure it out for the life of me. If so, please contact me asap

Comment by xkramb...@gmail.com, Oct 25, 2011

The library works OK, but I it will be better if it could copy not only TEXT, p.e. HTML. Flash Supports the following objects:

BITMAP_FORMAT: a BitmapData? object (AIR only) FILE_LIST_FORMAT: an array of File objects (AIR only) HTML_FORMAT: HTML-formatted string data TEXT_FORMAT: string data RICH_TEXT_FORMAT: a ByteArray? containing Rich Text Format data URL_FORMAT: a URL string (AIR only)

This will be the last update it needs.

Thanks in advance, and great job!

Comment by gperk...@gmail.com, Feb 8, 2012

ZeroClipboard?.swf cannot be served cross-protocol (embedded from an https:// url by an http:// page) without the additional line: flash.system.Security.allowInsecureDomain("*");

Comment by alextim...@gmail.com, Feb 10, 2012

I need a clipboard utility that can copy a link from a webpage, then paste the Hyperlinked Text and the underlying link in plain text, like this:

Chrome browser comes to phones http://edition.cnn.com/2012/02/07/tech/mobile/android-chrome/index.html

Comment by chen...@gmail.com, Feb 19, 2012
// get absolute coordinates for dom element getDOMObjectPosition: function (obj, stopObj) {
var info = {
left: 0, top: 0, width: obj.width ? obj.width : obj.offsetWidth, height: obj.height ? obj.height : obj.offsetHeight
};

// fix the bug to get a wrong position when the element is in a td; while (obj && ($(obj).css('position') == '' || $(obj).css('position') == 'static')) {
info.left += obj.offsetLeft;
info.top += obj.offsetTop;
obj = obj.offsetParent;
}

return info;
},
Comment by assemble...@gmail.com, Feb 27, 2012

Hey!

Put the code after reading the document or other scripts!

In your page, can have elements that decreases his size during the loading of the page, such as accordion or expandable menu, for example.

The swf is embedded with a value for the top, but the end of loading of the page, other elements are changed position. Your flash should consider it after all events

The code:

$(document).ready(function() {

var clip = new ZeroClipboard?.Client(); clip.setText( 'Copy me!' ); clip.setHandCursor( true ); clip.glue( 'd_clip_button' );
});

Comment by p...@sincerely.com, Mar 6, 2012

Having some trouble with the dynamic glue problem. My goal is to have a clickable icon that copies text beside it. Here's what I have so far:

<script type="text/javascript" src="/js/ZeroClipboard.js"></script> <script type="text/javascript"> jQuery(document).ready(function($) {

ZeroClipboard?.setMoviePath( '/scripts/ZeroClipboard?.swf' ); var clip = new ZeroClipboard?.Client(); var toBeCopied = ''; clip.setHandCursor( true );
clip.addEventListener( 'onComplete', my_complete );
function my_complete( client, text ) {
alert("Copied text to clipboard: " + text );
}
clip.addEventListener( 'onMouseDown', mouse_down_handler );
function mouse_down_handler( client ) {
alert( "mouse button is up" + toBeCopied);
}
$(".clipable").mouseover(function(event) {
toBeCopied=$(this).attr('data-href'); clip.setText(toBeCopied); clip.glue(event.target);
});
}); </script>

...

<div id="copy_print_<?=$print->id?>" alt="copy" class="clipable" data-href="<?=$print->id?>" style="position:relative">

<img src="/icons/copy_to_clipboard.png"><?=$print->id?>
</div>

The print id is definitely set, but the complete function is only sometimes firing (very rarely). The mouse up function however reports the expected print id is set. Occasionally, when the complete function does fire it is blank.

Comment by miguel.arroz@gmail.com, Mar 26, 2012

Add a setDebug(boolean) API that makes it become NOT transparent (maybe... red or so) to help with debugging and positioning. Good job, BTW!

Comment by iti...@gmail.com, May 12, 2012

I found a small bug In Ubuntu 11.10 browser Chrome cursor not pointer


Sign in to add a comment
Powered by Google Project Hosting