Load an external JavaScript file on demand using a Custom Action in SharePoint 2007

Load an external JavaScript file on demand using a Custom Action in SharePoint 2007

I build a lot of SharePoint Solutions that use JavaScript to enhance user experience. Most of the JavaScript I put in dedicated .js files and deploy them to the 12-hive (or 14-hive) in the layouts-folder. Deploying a JavaScript file (*.js) layouts-folder of SharePoint and loading external JavaScript files (*.js) in SharePoint 2007 can be accomplished in a couple of ways.

1) Add a Content Editor Web Part the the page and load the JavaScript using <script>-tags

Disadvantage: Need to add the Content Editor Web Part to every page necessary

2) Modify the Master Page and add <script>-tags to load the JavaScript

Disadvantage: Modifying the Master Page isn’t always allowed by customer

3) Add a Delegate Control to the AdditionalPageHead and reference the JavaScript from that control

Disadvantage: AdditionalPageHead is not available on all publishing pages

 

Furthermore, all methods described above will always load the JavaScript even if the file is not needed at the moment. Loading large JavaScript files increases page load times. However, it is possible to load a JavaScript from the layouts-folder (or a document library) on demand by using a Custom Action.

The following code will load a external JavaScript file by adding a reference to the head-section of the page:

var th = document.getElementsByTagName('head')[0];
var s = document.createElement('script');
s.setAttribute('id', jsidentifier);
s.setAttribute('type','text/javascript');
s.setAttribute('src',jsname);
th.appendChild(s);

 

It is possible to execute a function from that same JavaScript file as soon as the file is loaded. Because there are some differences between Internet Explorer, Firefox, Chrome and other browsers both the onreadystatechange and onload events are needed:

s.onreadystatechange = function ()
{
	if (s.readyState == 'complete')
	{
		MyExternalFunction();
	}
}; 

s.onload = function ()
{
	MyExternalFunction();
};

 

If you put both code snippets together and combine them with the SharePoint’s custom action tokens as described by Hristo Pavlov you get something like this:

var SiteUrl = '{SiteUrl}';
var ListId = '{ListId}';
var ItemId = '{ItemId}';
var jsidentifier = 'MyScript';
var jsname = '/_layouts/AlainDeKlerk.CustomAction/MyScript.js';
if (document.getElementById(jsidentifier) === null)
{
	var th = document.getElementsByTagName('head')[0];
	var s = document.createElement('script');
	s.setAttribute('id', jsidentifier);
	s.setAttribute('type','text/javascript');
	s.setAttribute('src',jsname);
	th.appendChild(s); 

	s.onreadystatechange = function ()
	{
		if (s.readyState == 'complete')
		{
			MyExternalFunction(SiteUrl, ListId, ItemId)
		}
	}; 

	s.onload = function ()
	{
		MyExternalFunction(SiteUrl, ListId, ItemId)
	};
}
else
{
	MyExternalFunction(SiteUrl, ListId, ItemId);
}

 

The script above can be run from a Custom Action in SharePoint. That Custom Action will:

1) Only load the external JavaScript file when the action is clicked

2) Load the external JavaScript file only once

3) Execute a function from that external JavaScript file when the file is completely loaded

4) Pass the Custom Action tokens as parameters to a function in the external JavaScript file

Here is an example of a Custom Action adding a button to the ECB-menu using the script:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction
     Id ="AlainDeKlerk.CustomAction.MyScript"
     Title="Execute MyExternalFunction"
     Description="Loads a javascript on demand and executes a function from that file"
     Location="EditControlBlock"
     Rights = "AddListItems"
     Sequence="901"
     ImageUrl="/_layouts/images/TBSPRSHT.GIF"
     RegistrationType="ContentType"
     RegistrationId="0x0101">
     <UrlAction Url="var SiteUrl = '{SiteUrl}'; var ListId = '{ListId}'; var ItemId = '{ItemId}'; var jsidentifier = 'MyScript'; var jsname = '/_layouts/AlainDeKlerk.CustomAction/MyScript.js'; if (document.getElementById(jsidentifier) === null) { var th = document.getElementsByTagName('head')[0]; var s = document.createElement('script'); s.setAttribute('id', jsidentifier); s.setAttribute('type','text/javascript'); s.setAttribute('src',jsname); th.appendChild(s); s.onreadystatechange = function () {if (s.readyState == 'complete') {MyExternalFunction(SiteUrl, ListId, ItemId) } }; s.onload = function () {MyExternalFunction(SiteUrl, ListId, ItemId) }; } else { MyExternalFunction(SiteUrl, ListId, ItemId); }" />
  </CustomAction>
</Elements>

 

If you are building a SharePoint 2010 solution you can use Script-On-Demand (SOD) library and load reference the script using the ScriptBlock or ScriptSrc tags in the CustomAction element.

About the author

Alain

You can leave a response, or trackback from your own site.

Leave a Reply