This blog post is more of a continuation of 2 of my earlier blog posts, Cross-browser approach to copy content to clipboard in javascript, and Copying GridPanel content to clipboard. I would advise reading of the above blog posts if you haven’t already to understand the code being discussed below.

But this time, my requirement was to allow copying of GridPanel’s individual row content to clipboard. The basis for implementing the new code was already available (as you would know from the above 2 blog posts).

The first task was to have the clipboard flash movie in each row of the GridPanel. This was accomplished easily with the GridPanel’s TemplateColumn. An object tag was specified for the flash movie in the XTemplate for the column as follows:

 

{syntaxhighlighter brush: jscript;fontsize: 100; first-line: 1; }{
dataIndex: ‘company’,
width: 30,
xtype: “templatecolumn”,
tpl: new Ext.XTemplate(
“<object id=’clipboard{[this.getClipboardId(values)]}’ codebase=’http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0′ width=’16’ height=’16’ align=’middle’>”,
“<param name=’allowScriptAccess’ value=’always’ />”,
“<param name=’allowFullScreen’ value=’false’ />”,
“<param name=’movie’ value=’/sites/default/files/content/blog/javascript_clipboard/clipboard.swf’ />”,
“<param name=’quality’ value=’high’ />”,
“<param name=’bgcolor’ value=’#ffffff’ />”,
“<param name=’flashvars’ value=’callback=f1&callbackArg={[this.getClipboardId(values)]}’ />”,
“<embed src=’/sites/default/files/content/blog/javascript_clipboard/clipboard.swf’ flashvars=’callback=f1&callbackArg={[this.getClipboardId(values)]}’ quality=’high’ bgcolor=’#ffffff’ width=’16’ height=’16’ name=’clipboard{[this.getClipboardId(values)]}’ align=’middle’ allowscriptaccess=’always’ allowfullscreen=’false’ type=’application/x-shockwave-flash’ pluginspage=’http://www.adobe.com/go/getflashplayer’ />”,
“</object>”,
{
getClipboardId: getClipboardId
})
}{/syntaxhighlighter}

Notice the use of the template member function getClipboardId. More on it below.

Now, the real challenge was to identify the row in which the flash movie was placed when it was clicked. After some thinking, I thought flashvars was a good place to do so.

I updated my clipboard flash movie to support a new flash var called, callbackArg (discussed here). This variable is passed back to the javascript callback function by the flash movie, and the javascript function can easily use this to maintain any state it wants (in our case, identify the GridPanel row that was clicked).

So, in the column template, I used XTemplate’s member function feature to add each row’s id value for the callbackArg. When the Flash movie is clicked, it passes this id back to the callback method, which uses it to identify the row that was clicked and then appropriately return data to the flash movie that can be placed on the clipboard.

Here’s the code for the javascript callback method:

 

{syntaxhighlighter brush: jscript;fontsize: 100; first-line: 1; }function f1(company) {
var store = Ext.getCmp(‘grid’).store;
var record = store.getById(company);

var s = ”;
for (key in record.data) {
s += key + ‘: ‘ + record.data[key] + ‘\n’;
}

alert(‘Following data copied to clipboard:\n\n’ + s);

if (window.clipboardData)
window.clipboardData.setData(‘text’, s);
else
return (s);
}{/syntaxhighlighter}

And here’s the first-hand experience for copying each individual row. Try clicking the icon in each row of the GridPanel below and then try pasting into Notepad or any other editor to see how easily you can copy each individual row:

 

The html file for the above demonstration is attached below. You can easily modify the javascript callback method to transform or format data before it is copied to the clipboard.

A very important thing to note above is that the flash movie should not have its window mode (wmode) set to transparent. Otherwise the click event on the movie is not passed to the movie but to the underlying grid, which prevents the movie from executing its functionality.