Destroy ZeroClipboard Clients to prevent error when reinitializing multiple times?
Destroy ZeroClipboard Clients to prevent error when reinitializing multiple times?
richard7390
Posts: 2Questions: 0Answers: 0
Scenario: I have a page where a report is generated depending on user input. The input is submitted via an AJAX call, the result of which is placed into a div, then formatted w/ DataTables (1.9.3). User requested the ability to save to pdf/xls/csv, so I am attempting to add TableTools (2.1.3).
The user is free to generate multiple reports, replacing the previous report without reloading the page. Each time, the DataTables instance is destroyed via fnDestroy() and recreated. While debugging (Visual Studio 2010 sp1), I noticed that if I tried to generate more than a single report, I got a "Microsoft JScript runtime error: Object doesn't support property or method 'clearText'" on line 306 of ZeroClipboard.js.
Being the curious sort, but not a javascript expert, I looked at the line in question, looked around the internet for a while (thank you, StackOverflow!), read a few forum threads here, and came up with what I hope is a decent solution. No, it unfortunately does not work auto-magically when you call DataTables' fnDestroy, but it seems to be working so far.
Changes to ZeroClipboard.js:
Add the following to the top of the destroy function. (starting line 193 in my copy)
[code]
// remove event handlers
if (this.handlers) {
for (var eventName in this.handlers) {
if (this.movie != null) {
__flash__removeCallback(this.movie, eventName);
}
this.handlers[eventName] = null;
delete this.handlers[eventName];
}
this.handlers = null;
}
[/code]
Changes to TableTools.js:
Add the following directly above the "Private Methods" comment block. (starting line 567 in my copy)
[code]
/**
* Destroy ZeroClipboard clients for this TableTools instance
* @method fnDestroy
* @returns void
*/
"fnDestroy": function () {
var flash = ZeroClipboard_TableTools;
for (var inst in flash.clients) {
flash.clients[parseInt(inst, 10)].destroy();
delete flash.clients[parseInt(inst, 10)];
}
flash = null;
},
[/code]
Add the following directly before you are call DataTables' fnDestroy:
[code]
var TblTools = TableTools.fnGetInstance('tableName');
TblTools.fnDestroy();
[/code]
And this after you call DataTables' fnDestroy:
[code]
$(".DTTT_collection").remove();
[/code]
Comments, suggestions, or modifications are appreciated.
Thank you!
Where I got some Ideas:
http://datatables.net/forums/discussion/9449/is-there-a-change-to-flash-movie-in-the-nightly-build-of-table-tools/p1
http://stackoverflow.com/questions/2553632/detachevent-not-working-with-named-inline-functions
http://stackoverflow.com/questions/2837542/is-it-possible-to-remove-all-event-handlers-of-a-given-element-in-javascript
The above was what I was going to try to implement, but because named function expressions are used, it wouldn't work.
EDIT----
I ran into a problem where the xls/csv/pdf buttons were retreiving old information, and modified the code to delete the handlers and clients from the objects in question.
The user is free to generate multiple reports, replacing the previous report without reloading the page. Each time, the DataTables instance is destroyed via fnDestroy() and recreated. While debugging (Visual Studio 2010 sp1), I noticed that if I tried to generate more than a single report, I got a "Microsoft JScript runtime error: Object doesn't support property or method 'clearText'" on line 306 of ZeroClipboard.js.
Being the curious sort, but not a javascript expert, I looked at the line in question, looked around the internet for a while (thank you, StackOverflow!), read a few forum threads here, and came up with what I hope is a decent solution. No, it unfortunately does not work auto-magically when you call DataTables' fnDestroy, but it seems to be working so far.
Changes to ZeroClipboard.js:
Add the following to the top of the destroy function. (starting line 193 in my copy)
[code]
// remove event handlers
if (this.handlers) {
for (var eventName in this.handlers) {
if (this.movie != null) {
__flash__removeCallback(this.movie, eventName);
}
this.handlers[eventName] = null;
delete this.handlers[eventName];
}
this.handlers = null;
}
[/code]
Changes to TableTools.js:
Add the following directly above the "Private Methods" comment block. (starting line 567 in my copy)
[code]
/**
* Destroy ZeroClipboard clients for this TableTools instance
* @method fnDestroy
* @returns void
*/
"fnDestroy": function () {
var flash = ZeroClipboard_TableTools;
for (var inst in flash.clients) {
flash.clients[parseInt(inst, 10)].destroy();
delete flash.clients[parseInt(inst, 10)];
}
flash = null;
},
[/code]
Add the following directly before you are call DataTables' fnDestroy:
[code]
var TblTools = TableTools.fnGetInstance('tableName');
TblTools.fnDestroy();
[/code]
And this after you call DataTables' fnDestroy:
[code]
$(".DTTT_collection").remove();
[/code]
Comments, suggestions, or modifications are appreciated.
Thank you!
Where I got some Ideas:
http://datatables.net/forums/discussion/9449/is-there-a-change-to-flash-movie-in-the-nightly-build-of-table-tools/p1
http://stackoverflow.com/questions/2553632/detachevent-not-working-with-named-inline-functions
http://stackoverflow.com/questions/2837542/is-it-possible-to-remove-all-event-handlers-of-a-given-element-in-javascript
The above was what I was going to try to implement, but because named function expressions are used, it wouldn't work.
EDIT----
I ran into a problem where the xls/csv/pdf buttons were retreiving old information, and modified the code to delete the handlers and clients from the objects in question.
This discussion has been closed.
Replies