Adding script like jQuery to your pages

When working with the post of Andrew Connell I faced some challenges with implementing my solution. I wanted to add multiple scripts with dependencies to my pages. When creating one elements.xml containing all three script links the order of the <CustomAction Location=”X” ScriptScr=”Y” /> elements is important.

The following elements.xml is packaged in a feature.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <CustomAction Location="ScriptLink" ScriptSrc="~site/_layouts/project_name/js/custom-1.0.0.js?rev=20110413" /> <CustomAction Location="ScriptLink" ScriptSrc="~sitecollection/_layouts/project_name/js/ jquery_query-2_1_7.js?rev=20110413" /> <CustomAction Location="ScriptLink" ScriptSrc="~site/_layouts/project_name/js/jquery-1.5.1.min.js?rev=20110413" /> </Elements>

This results in the following HTML in your pages.

document.write('<script type="text/javascript" src="/_layouts/project_name/js/jquery-1.5.1.min.js?rev=20110413"></' + 'script>'); document.write('<script type="text/javascript" src="/_layouts/project_name/js/jquery_query-2_1_7.js?rev=20110413"></' + 'script>'); document.write('<script type="text/javascript" src="/_layouts/project_name/js/custom-1.0.0.js?rev=20110413"></' + 'script>');

Important to know is the order in the elements.xml is the opposite sequence in the HTML. Meaning the script “jquery_query-2_1_7.js” is depending on “jquery-1.5.1.min.js” and needs to be the last item in the elements.xml.

In the script link I’m using “~site” and “~sitecollection” tokens to change the link according to the site or site collection where the user is located. This is important when creating a generic feature used on multiple sites.

By using the “?rev=20110413” at the end of your link you can force the browser to refresh its local cache. A (script) file is downloaded the first time accessing the page. As long as the link does not change the browser does not download the file. By changing the query string you can force a download of the script when changes are made. The actual value “20110413” is todays date, but can be your own versioning logic.

The example above also has a version number in the file name, this is another way of forcing a download. I simply wanted to illustrate the possibilities, you probably will use either query string or version number.

Lessons learned / best practices:

  • Order in elements.xml for <CustomAction /> elements is of influence of the order of script links in the resulting HTML.
  • Use “~site” and “~sitecollection” tokens to control the script link.
  • Use “?rev=20110413” query string or version number in filename to force a download of the file.

Using SP.UI.Dialog and SP.UI.Notify from code behind

SharePoint 2010 comes with the SP.UI framework. This is a JavaScript library which you can use to interact with the SharePoint UI. I wanted to use the SP.UI framework to display a dialog which is only shown when condition are met in code behind.

ValidationDialogWebPart

When I placed the JavaScript in the web part I got a null reference error. The problem originated from the SP.UI object model not being loaded. Especially because it did work when I executed the script on the OnClick event of a button.

The solution is provided by the SP.SOD.executeOrDelayUntilScriptLoaded method. It will wait to execute the function you provide until the script you refer is completely loaded.

ExecuteOrDelayUntilScriptLoaded(ShowDialog, "sp.js");

Within my project I added a JavaScript file containing my method “ShowDialog()” to show the dialog. Within my web part I perform the validation and call the CreateDialog() method.

/// <summary> /// Registers the javascript supporting showing dialog. /// </summary> /// <remarks> /// When calling this method, the dialog is shown /// to the user and blocks the page below. /// </remarks> private void CreateDialog() { // Define the name and type of the client scripts on the page. string csname = "ShowDialogScript"; Type cstype = this.GetType(); // Get a ClientScriptManager reference from the Page class. ClientScriptManager cs = Page.ClientScript; // Check to see if the startup script is already registered. if (!cs.IsStartupScriptRegistered(cstype, csname)) { StringBuilder js = new StringBuilder(); js.Append("<script type='text/javascript'>"); js.Append("ExecuteOrDelayUntilScriptLoaded(ShowDialog, 'sp.js');"); js.Append("</script>"); cs.RegisterStartupScript(cstype, csname, js.ToString()); } }