Sunday, October 7, 2012

"Copy to Clipboard" feature in web

Sometimes we need a "Copy to Clipboard" feature to copy some content from an input field or textarea into the OS clipboard. How to implement this feature in JavaScript? There are a lot of articles with this topic in the web. They say - there is only one way to do this cross-browser. This way is Flash. You can read this article or this one and see that a special Flash object is required. A general problem is that installing Flash in browser breaks the paradigm of plain web applications. There is no guarantee that a next Flash update will not break the "Copy to Clipboard" functionality. Also be aware of security restriction by Adobe Flash Player - it doesn’t work at local computer at all.

What is an alternative way? After reading some posts I came to the thought to select the text to be copied automatically and show a tooltip with a little help. The next example demonstrates this idea in JSF with PrimeFaces components. Assume, you have a button "Copy to Clipboard" and an input field with a link (URL) to be copied. Click on the button should call an JavaScript function, say copyInputToClipboard(). As tooltip I will use pe:tooltip from the PrimeFaces Extensions project. The tooltip has showEvent="false" and doesn't get shown by any event. We will show it programmatically by calling widget's method show().
...

<p:commandButton icon="ui-icon ui-icon-copy" type="button"
 value="Copy to Clipboard"
 title="Copy to Clipboard"
 onclick="copyInputToClipboard('#{cc.clientId}:textUrl','widget_#{cc.clientId.replaceAll('-|:','_')}_tip')"/>

...

<p:inputText id="textUrl" value="#{...}" maxlength="2047" autocomplete="off"/>

<pe:tooltip for="textUrl" widgetVar="widget_#{cc.clientId.replaceAll('-|:','_')}_tip"
     value="Press Ctrl+C to copy this link into the clipboard"
     myPosition="top center" atPosition="bottom center" showEvent="false" hideEvent="blur"/>

...
All components are placed within a composite component. This is why I used cc.clientId. The function copyInputToClipboard() expects two parameters: clientId of the input field and the widget variable of the tooltip. In Internet Explorer we can use the object window.clipboardData to achieve the desired functionality. Just call window.clipboardData.setData('text', inputValue) with some input value and the task is done. In other browsers, the best approach would be to select the input text on button click and to show a tooltip with text "Press Ctrl+C to copy this link into the clipboard".
function copyInputToClipboard(inputId, widgetVarTip) {
    if (window.clipboardData && clipboardData.setData) {
        // IE
        var inputValue = $(PrimeFaces.escapeClientId(inputId)).val();
        window.clipboardData.setData('text', inputValue);
    } else {
        // other browsers
        var el = $(PrimeFaces.escapeClientId(inputId));
        el.focus();
        el.select();
        if (widgetVarTip && window[widgetVarTip]) {
            window[widgetVarTip].hide();
            window[widgetVarTip].show();
        }
    }
}
Note that tooltip disappears on blur. The picture demonstrates my implementation.


I hope you have enjoyed this small excursion into the "Copy to Clipboard" feature.

4 comments:

  1. You have done amazing work. I really impress by your post about approach a development. This is very useful blog for every one.
    Website Development New York

    ReplyDelete
  2. Many thanks for sharing!

    ReplyDelete
  3. Great and extremely help. Thanks for sharing.

    ReplyDelete