Search Posts

Building Copy To Clipboard with ZeroClipboard

2014-06-12 10_04_04-ZeroClipboard

Some ago days, When I did a new feature ‘Copy To Clipboard’ on website page. I researched and found some JavaScript library and some guide to resolve it. Luckily, I saw ZeroClipboard on GitHub 

“The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface” – http://zeroclipboard.org/

Advantages:

  • Stylized the button
  • Easy to use and configure
  • Work well on Chrome, Firefox

Disadvantages:

  • No flash, no action
  • This clipboard injection can ONLY occur when the user clicks on the invisible Flash

Scenario: There is a table in a website application with 5.000 rows and 10 columns. User want to copy this table data to paste into Excel files. Currently they have to Copy/Paste from Exported file or data on page. It takes too much time.

Solution: Firstly, should prepare data by Ajax’s response. The data should be ready in DOM. Now add a button to do that, when data is ready then show a dialog and ask user to click on confirmation button (truly ZeroClipboard button)

Now, Let’s make it real!

1. Surely, import JQuery and ZeroClipBoard. I’m using JQuery 1.8+, JQuery UI 1.10+ and ZeroClipBoard 2.0 

<script type="text/javaScript" src="../scripts/jquery-1.8.0.min.js"></script>
<script type="text/javaScript" src="../scripts/jquery-ui/js/jquery-ui-1.10.4.custom.min.js"></script>
<script type="text/javaScript" src="../scripts/zeroclipboard2/ZeroClipboard.js"></script>

2. Prepare Html – A Copy To Clip Board

<input onclick="copyToClipboard()" value="Copy To Clipboard" type="button"></button>

– Display a loading.gif when Ajax is loading data

<span id='copy_loading' style="background: url('../ajax-loading.gif') no-repeat center;"></span>

– A dialog with ‘Yes’ to confirm (CopyToClipboard button and style like a button jquery) and No to close without any action

<div id="dialog-holder-hidden" style="display: none;">
<div id="dialog-confirm" title="Copy all results to clipboard?">
<p><span class="ui-icon ui-icon-alert"></span><span id="myDialogText"></span></p>
<span class="z-clip-wrap" style="float:right;padding-right: 10px;">
<a href="#" id="copy-button" class="z-clip-button" data-clipboard-target="data-holder-hidden">Yes</a>
<a href="#" id="copy-button-no" class="z-clip-button">No</a>
</span>
</div>
</div>

— This is a holder div to store data table from Ajax’s response

<div id="data-holder-hidden" style="display: none;">
<table>
<tbody>
<tr><td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td><td>Data5</td><td>Data5</td><td>Data7</td><td>Data8</td><td>Data9</td><td>Data10</td></tr>
<tr><td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td><td>Data5</td><td>Data5</td><td>Data7</td><td>Data8</td><td>Data9</td><td>Data10</td></tr>
<tr><td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td><td>Data5</td><td>Data5</td><td>Data7</td><td>Data8</td><td>Data9</td><td>Data10</td></tr>
<tr><td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td><td>Data5</td><td>Data5</td><td>Data7</td><td>Data8</td><td>Data9</td><td>Data10</td></tr>
<tr><td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td><td>Data5</td><td>Data5</td><td>Data7</td><td>Data8</td><td>Data9</td><td>Data10</td></tr>
</tbody>
</table>
</div>

3. Write all code JavaScript into main.js or inline of html: – Add a function to listen 1st click event’s from user

function copyToClipboard(){
    $('#copy_loading').show();
    fetchData();
}

– Init ZeroClipboard button on dialog form and stylize it like a JQuery button

$( document ).ready(function() {
     // Hide loading when page load
     $('#copy_loading').hide();
     // Stylize Yes (truly zeroclipboard button)
     $('.z-clip-button').button();
     // Init a client
     var client = new ZeroClipboard($('#copy-button'));
     // Bind event copy into Yes button on the dialog
     client.on( 'ready', function(event) {
     console.log('movie is loaded' );

    client.on( 'beforecopy', function(event) {
        console.log('before copy');
    }

    client.on( 'copy', function(event) {
        console.log('copying...');
        event.clipboardData.setData('text/html', $('#data-holder-hidden').html();
        console.log('copied');
    });

    client.on( 'aftercopy', function(event) {
        $('#dialog-confirm').dialog('close');
        // alert/noti('Copied results to clipboard successfully!', 'success', 'topCenter');
        console.log('Copied results to clipboard successfully!');
    });
});

    client.on( 'error', function(event) {
        console.log( 'ZeroClipboard error of type "' + event.name + '": ' + event.message );
        ZeroClipboard.destroy();
    });
});
function fetchData(){
    try { // Firefox, Opera 8.0+, Safari
       xmlHttp=new XMLHttpRequest();
    } catch(e) { // Internet Explorer
       try {
          xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
       } catch(e) {
          try {
             xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
          }catch(e) {
              alert("Your browser does not support AJAX!");
           return false;
          }
      }
   }

   xmlHttp.onreadystatechange = function() { populateData(); };

   xmlHttp.open("GET", URLToGetData, true);

   xmlHttp.send(null);

}

— Get data

function populateData(){
    if(xmlHttp.readyState == 4){
       var response = xmlHttp.responseText;
       if (response.length > 0) {
          // Store data into div holder
          $('#data-holder-hidden').html(response);
          // Change text of dialog
          $("#myDialogText").text("Warning! There are ??? found rows! Do you want to copy all results to clipboard?");
          // Show Dialog
          $('#dialog-confirm').dialog();
          // Hide Loading by data is ready
          $('#copy_loading').hide();
       }
    }
}

– If user click No dialog is closed

$("#copy-button-no" ).click(function( event ) {
   $('#dialog-confirm').dialog('close');
   event.preventDefault();
});

From now run the code, see How does ZeroClipboard work on Chrome and FireFox!?. Again, Thanks ZeroClipboard’s team very much.

Leave a Reply

Your email address will not be published. Required fields are marked *