Thursday, September 8, 2011

Including a JS file for a custom ribbon control CommandUIHandler without using a ScriptLink CustomAction or Custom Page Components

I've been struggling lately with the proposed solutions for including the javascript for CommandUIHandler's CommandAction and EnabledScript attributes.  Thus far I have only seen the following examples:

  1. JavaScript directly into the attributes (messy),
  2. Including a ScriptLink command action (bad because then the script file is included in every page where the feature is activated causing bloated pages)
  3. Creating a page component (overcomplicated)
Instead of all this, I created a pattern which loads the js file on the fly with javascript and keeps your ribbon development more compact (note I have JQuery loaded in the master page, if you don't have this then you'll have to either load jquery dynamically or reference the elements without JQuery):

<commanduihandler 
  CommandAction="javascript:
                                     $.getScript('/_layouts/myProject/myScriptfile.js', function(){ commandActionMethodInJSFile(); });"
 EnabledScript="javascript:
                           function enabledController()
                           {
                               if(typeof checkIsEnabledMethodFromJSFile == 'undefined')
                               {
                                  $.getScript('/_layouts/myProject/myScriptfile.js', function(){ RefreshCommandUI(); });
                                  return false;
                                }
                                else return checkIsEnabledMethodFromJSFile();
                            }
                           enabledController();
"


/>

The CommandAction is simple, just load the script file with the jQuery getScript() method and call your ribbon action in the callback.


The real trick was handling the Asynchronous load in the EnabledScript since it will just finish before the callback occurs. What this does is check to see if the method in your JS file has been loaded, if not it calls the jQuery getScript to load the file and then keeps the control disabled, then once the callback happens it calls 'RefreshCommandUI' to notify the ribbon that something has happened and it needs to evaluate the Enabled condition again.  This time, the method does exist because the script is loaded and thus you can call your enabled check method in your script file.

Giving credit where it's due, Andrew Connell's post helped me find the missing piece to my solution :  http://www.andrewconnell.com/blog/archive/2010/10/14.aspx
Hopefully this will help you keep your Ribbon development more simplified.