Creating a Web Part with Client-side Script

This programming task describes how to create a Web Part with client-side scripting.

About creating client-side scripts for Web Parts

Scripts are blocks of code that are inserted into a Web page and are interpreted at run time. Just like a browser interprets HTML on a Web page to determine what to display, a browser also interprets scripts to determine what actions to take when an event occurs (for example, what happens when a user clicks a button on a Web page).

Client-side scripts run on the client as opposed to the server. After a Web page is downloaded to the client computer, if the browser has enabled scripts to run, all the client-side scripts will run in the browser. Although script languages are simpler than programming languages, scripts can add sophisticated logic to Web pages and increase interactivity.

You can implement client-side scripting in a Web Part in one of two ways:

  • Linking a script file to a Web Part
  • Embedding a script in a Web Part

Linking a script file to a Web Part

You can write script in a separate file and place the file on a server running Microsoft Windows Server 2003 with Microsoft Windows SharePoint Services. The first time the script file is referenced, the file is fetched from the server and placed in the browser's cache. Subsequent references to the script file only require the script to be fetched from the browser's cache.

Advantages

  • It is more efficient for different Web Parts and Web Part Pages to share script placed in a common script file because the script is only fetched from the server the first time it is referenced and subsequent references fetch the script from the browser's cache.
  • The benefit is more obvious if the script is long. In this case, the Web Parts that reference the script are not burdened with the overhead of the lengthy script, and the script is only fetched once from the server and subsequently loaded into the browser's cache.
  • Placing a complex script into a separate file is also organizationally more practical and easier to maintain than embedding the entire script in the Web Part class definition.

To Link a script file to a Web Part  

  • Place the script in a separate file. For example, place a script that displays the alert "Hello" in myHello.js:

    function Hello() {
       alert ('Hello');
    }
    
  • Create the appropriate folder to save the script file:

    • Locate the virtual directory _wpresources on the server. _wpresources is created when you install Windows SharePoint Services. It maps to C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/wpresources on the server computer.

    • Under _wpresources, create a folder whose name is composed of the assembly name. For example, if the project is WebControlLibrary1, then the folder under wpresources is "WebControlLibrary1".

    • Under the folder created in the last step, create another folder whose name is composed of the assembly version number, the culture, and the public key token of the project, delimited by underscores:

      <assembly version>_<culture>_<public key token>
      

      If the culture is the default culture, this information should be skipped in the folder name. For example, if the assembly version number is 2.0.0.0, the culture is the default culture, and the public key token is 1fb6e50da183910, then the folder you create is:

      C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/wpresources/WebPartLibrary/2.0.0.0__1fb6e50da183910
      
    • To check the assembly version number and the public key token, place the project assembly file in the Global Assembly Cache (GAC) and use Windows Explorer to locate the file in the C:\Windows\Assembly folder.

      Note  This will work only if the assembly is deployed in the GAC. If the assembly is deployed in the bin, then you need to locate and deploy the script file in the virtual directory called wpresources, not _wpresources.

      For more information on specifying an assembly version number, refer to the section on modifying the file AssemblyInfo.cs in the Creating a Basic Web Part programming task.

    • You can now save the script file in the following location:

      C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/wpresources/WebControlLibrary1/2.0.0.0__1fb6e50da183910/myHello.js
      
  • Add the following code to your Web Part:

    • Specify a key for the script. The Page object will use this key to determine if the script has already been loaded onto the Web Part Page. Add the following lines to the Web Part object you're creating:

      private const string HelloFileName = "myHello.js";
      private const string HelloIncludeScriptKey = "myHelloIncludeScript";
      private const string IncludeScriptFormat = @"<script language=""{0}"" src=""{1}{2}""></script>";
      
    • Then add an event handler to the PreRender event that loads the script onto the page on prerendering:

      public WebPart_ClientScript()
            {
               this.PreRender += new EventHandler(WebPart_ClientScript_PreRender);
            }
      
    • Then add the following lines:

      private void WebPart_ClientScript_PreRender(object sender , System.EventArgs e )
            {
      
               // Make sure that the script was not already added to the page.
               if (!Page.IsClientScriptBlockRegistered(HelloIncludeScriptKey))
               {
                  String location = this.ClassResourcePath + "/";
      
      
                  // Create the client script block.
                  string includeScript = String.Format(IncludeScriptFormat, "javascript", location, HelloFileName);
                  Page.RegisterClientScriptBlock(HelloIncludeScriptKey, includeScript);
               }
            }
      

Embedding script in a Web Part

You can explicitly specify your script in a Web Part and have the script loaded only once for all instances of the same Web Part on a Web Part Page. The IsClientScriptBlockRegistered method of the System.Web.UI.Page class can check if the script has been loaded for the same Web Part Page.

Advantages

  • Similar to linking to a script file, the script is loaded only once for all instance of the same Web Part on that Web Part Page.
  • For short scripts, clarity and convenience outweigh performance gains.

To Embed a script in a Web Part  

For example, let us suppose that you have a script function called ByeBye() that you would like to add to your Web Part, WebPart_ClientScript. Add the following code so that the script is loaded only once for all instances of the same Web Part on the Web Part Page.

      private const string ByeByeIncludeScriptKey = "myByeByeIncludeScript";
      private const string EmbeddedScriptFormat =
            "<script language=javascript>function ByeBye(){alert('Bye Bye'); }</script> ";

      public WebPart_ClientScript()
      {
         this.PreRender += new EventHandler(WebPart_ClientScript_PreRender);
      }

      private void WebPart_ClientScript_PreRender(object sender , System.EventArgs e )
      {

            if(!Page.IsClientScriptBlockRegistered(ByeByeIncludeScriptKey))
                  Page.RegisterClientScriptBlock(ByeByeIncludeScriptKey,
                  EmbeddedScriptFormat);
      }

Sample Web Part with client-side scripts

The following example shows how you can add two client-side scripts to a Web Part, WebPart_ClientScript, first by linking a separate script file to the Web Part, and then by embedding the script in the Web Part. The procedure assumes that you have a general understanding of how to create a Web Part programmatically. For information in this area, refer to the Creating a Basic Web Part programming task.

//---------------------------------------------------------------------
// File : WebPart_ClientScript.cs
//
// Purpose :  Show an example of how to include client side script to your page.
//           1) Linking to a .js file
//           2) Added embedded script to the page.
//---------------------------------------------------------------------
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;

namespace WebPartLibrary2
{
      /// <summary>
      /// Summary description for WebPart_ClientScript.
      /// </summary>
      [DefaultProperty("Text"),
      ToolboxData("<{0}:WebPart_ClientScript runat=server></{0}:WebPart_ClientScript>"),
      XmlRoot(Namespace="WebPartLibrary2")]

public class WebPart_ClientScript : Microsoft.SharePoint.WebPartPages.WebPart
 {
      private const string defaultText = "";
      private string text = defaultText;

    // Used for the linked script file
      private const string HelloFileName = "myHello.js";
      private const string HelloIncludeScriptKey = "myHelloIncludeScript";
      private const string IncludeScriptFormat =
      @"<script language=""{0}"" src=""{1}{2}""></script>";

      // Used for the embedded script
      private const string ByeByeIncludeScriptKey = "myByeByeIncludeScript";
      private const string EmbeddedScriptFormat =
            "<script language=javascript>function ByeBye(){alert('Bye Bye'); }</script> ";


      // Contructor
      public WebPart_ClientScript()
      {
            this.PreRender += new EventHandler(WebPart_ClientScript_PreRender);
      }

       [Browsable(true),Category("Miscellaneous"),
      DefaultValue(defaultText),
      WebPartStorage(Storage.Personal),
      FriendlyName("Text"),Description("Text Property")]
      public string Text
      {
            get
            {
                  return text;
            }
            set
            {
                  text = value;
            }
      }

      /// <summary>
      ///      Gets the custom tool parts for this Web Part by overriding
      ///      the GetToolParts method of the WebPart base class. You must
      ///      implement custom tool parts in a separate class that
      ///      derives from
      ///      Microsoft.SharePoint.WebPartPages.ToolPart.
      /// </summary>
      ///<returns>
      /// An array of references to ToolPart objects.
      ///</returns>
      //      public override ToolPart[] GetToolParts()
      //      {
      //            ToolPart[] toolparts = new ToolPart[2];
      //            WebPartToolPart wptp = new WebPartToolPart();
      //            CustomPropertyToolPart custom = new CustomPropertyToolPart();
      //            toolparts[0] = custom;
      //            toolparts[1] = wptp;
      //            return toolparts;
      //      }

      // Client script registration event
      private void WebPart_ClientScript_PreRender(object sender , System.EventArgs e )
      {
            RegisterCommonScript();
      }

      //Function which will register the linked file script and the
      //embedded script
      protected void RegisterCommonScript()
      {
            string location = null;
            // Make sure that the script was not already added to the
            //page.
            if (!Page.IsClientScriptBlockRegistered(HelloIncludeScriptKey))
            {
                  location = this.ClassResourcePath + "/";
                  // Create the client script block.
                  string includeScript =
                  String.Format(IncludeScriptFormat, "javascript", location, HelloFileName);
                  Page.RegisterClientScriptBlock(HelloIncludeScriptKey, includeScript);
            }

            //Embedded Client Script
      if(!Page.IsClientScriptBlockRegistered(ByeByeIncludeScriptKey))
            Page.RegisterClientScriptBlock(ByeByeIncludeScriptKey,
                              EmbeddedScriptFormat);

      }


      /// <summary>
      /// Render this Web Part to the output parameter specified.
      /// </summary>
      /// <param name="output">
      /// The HTML writer to write out to
      /// </param>
      protected override void RenderWebPart(HtmlTextWriter output)
      {
            //Button which calls a function from the Included File .js
            output.Write(
                  "<br><br><input class='ms-SPButton' value=\'Say Hello\' type=button onclick=\"Hello();\" >");

            //Button which calls a function that is embedded in the page
            output.Write(
                  "<br><br><input class='ms-SPButton' value=\'Say Bye Bye\' type=button onclick=\"ByeBye();\" >");
      }
 }
}

To deploy this sample Web Part  

Perform the steps described in the "Deploying Your Web" section of the Creating a Basic Web Part programming task, making sure to create a SafeControl block and a Web Part Definition file (.dwp) that reflects the appropriate values for your Web Part assembly and deploy the assembly in the GAC.