Saturday, June 20, 2009

JavaScript downloaded function executor

Ran into a really annoying problem trying to use the YUI text editor in a jqueryUI modal dialog. I am using jquery to load a file "richEditor.html" that has my YUI editor on it. Problems:

  1. required YUI script and link tags, that are needed by YUI, are defined on my page richEditor.html. I need to be move said tags from head to body, because jQuery.load function only loads the body of the HTML page.
  2. said script and link tags *begin* downloading from yahoo when jQuery calls your load callback function. That's becuase richEditor.html itself has been downloaded by jQuery, but the said script and link tags referenced ON richEditor.html have only just begun asynchronously downloading. So if you need to access a function in one of the script tags that is downloading, you have no way to be sure the function has completed downloading.
As a solution, I wrote this JS Object that will simply try to invoke your function, and try again, after a configurable delay, up to maxTries. If the function fails to execute maxTries times, a fail handling function, provided by you, is executed.

Here is the Object:


function DownloadedFunctionCaller(funcToInvoke, waitMS, maxTries, _failHandler){
var funcToInvoke = funcToInvoke;
var waitMS = waitMS;
var maxTries = maxTries;
var failHandler = function(){
alert("Unable to access the network. Please reload the page or try again.");
}
if(null != _failHandler){
failHandler = _failHandler;
}
var that = this;
var tries = 0;
this.invoke = function(){
try{
funcToInvoke();
}catch(err){
if(++tries >= maxTries){
failHandler();
return;
}
setTimeout(that.invoke, waitMS);
}
}
}


and here is an example of using it to invoke a function named setEditor that is defined
in an external file, richEditor.html. The setEditor function will only work if all the YUI scripts are downloaded, hence the need to use the DonwloadedFunctionCaller




var div = $("<div></div>");
div.addClass("yui-skin-sam");
div.load("richEditor.html", null, function(content){
var invokeMe = function(){
setEditor("Script loaded and executed.");
}
new DownloadedFunctionCaller(invokeMe, 500,10,function(){
alert("failed to download rich text editor")
}).invoke();
});


If you click on this screengrab, to get a bette look at it, you will see that the text "script loaded and executed" has been set into the YUI editor's text area by the successful invocation of the setEditor method.