Intranet Journal   Earthweb  
Events Jobs Premium Services Media Kit Network Map E-mail Offers Vendor Solutions Webcasts

   Intranet Journal Subjects
Search Earthweb

Privacy Policy



internet.com
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

internet commerce
Be a Commerce Partner
















 

[ Home | Discussion Forum | How Do I... | Lotus Notes Intranets | Microsoft SharePoint | Products | Shopping  ]

free news!


Developing a Custom Web Part, Part 3


Paul Schaeflein

12/5/2005

Printer Friendly Version

This article is the third in series that discusses developing a custom Web Part. Be sure to read Part 1 and Part 2 before continuing.

In Part 3, we will complete the Web Part Development Process. The process is repeated here for review:

  • Define requirements
  • Create an HTML mockup of the output
  • Identify sources of data
  • Create form(s) for user input (if necessary)
  • Create data access code (if necessary)
  • Create output code

Milestone Countdown Web Part, Continued

Countdown

Our custom Web Part project is to develop a part that outputs a countdown timer to a project milestone, or some other event. Part 1 concluded with the sources of data. Part 2 concluded with the user input forms. In Part 3, I will discuss how to save the data entered on the form and then how to render the output of the Web Part.

Create Data Access Code (If Necessary)
Our Milestone Countdown Web Part has very minimal data requirements. All of the data required for our part is entered in the Tool Pane using our custom Tool Parts. In the previous article I showed how to create the hierarchy of controls in the Tool Part. At the beginning of the CreateChildControls method, the Tool Part retrieves the data from the Web Part storage.

The Tool Part class has a property named ParentToolPane that contains a reference to the Tool Pane that contains the Tool Part. The Tool Pane in turn has a property named SelectedWebPart that contains a reference to the Web Part being edited. Once we have the reference to the Web Part, we can access its properties. In my Tool Part code, I copy the property values to local variables for processing.

 ' Retrieve the current values from the web part
  Dim wp As MilestoneCountdownWP 
  wp = CType(Me.ParentToolPane.SelectedWebPart, MilestoneCountdownWP)
  _imageLink = wp.ImageLink
  _altText = wp.AlternateText
  _imageWidth = wp.ImageWidth
  _imageHeight = wp.ImageHeight
  

Conversely, when the Tool Pane is submitted, the values need to be stored in the Web Part properties. The Web Part framework will call a method in the Tool Part named ApplyChanges. In this method, we need to store the values entered by the user using the same technique.

Article Tools
  • Print this article
  • E-mail this article
  • Discuss this article
  • Related resources
  • ASP.NET Web forms use a hierarchical naming convention for controls (text boxes, buttons, etc.). Inside SharePoint, this hierarchy can be several layers deep. In addition, the controls that we are creating in our CreateChildControls method are associated with a Web Part — and the Web Part gets an ID assigned to it by the framework. When the ApplyChanges method is called, we do not know all of the information necessary to access the Request.Form object.

    Fortunately, the ASP.Net framework has a solution to this problem. Since the ToolPart class derives from Web.UI.Control, it contains a method named FindControl that will return the control with a specific name. In the CreateChildControls method, all of the input controls were assigned an ID. Using this ID, we can retrieve the control (and its value) in the ApplyChanges method.

    Public Overrides Sub ApplyChanges()
      ' pull the values from the form
      Dim input As TextBox
    
      input = CType(Me.FindControl("imageLink"), TextBox)
      _imageLink = input.Text
    
      input = CType(Me.FindControl("alternateText"), TextBox)
      _altText = input.Text
    
      input = CType(Me.FindControl("imageWidth"), TextBox)
      If input.Text = "" Then
        _imageWidth = -1
      Else
        _imageWidth = Integer.Parse(input.Text)
      End If
    
      input = CType(Me.FindControl("imageHeight"), TextBox)
      If input.Text = "" Then
        _imageHeight = -1
      Else
        _imageHeight = Integer.Parse(input.Text)
      End If
    
      ' Put the new values in the web part
      Dim wp As MilestoneCountdownWP
      wp = CType(Me.ParentToolPane.SelectedWebPart, MilestoneCountdownWP)
      wp.ImageLink = _imageLink
      wp.AlternateText = _altText
      wp.ImageWidth = _imageWidth
      wp.ImageHeight = _imageHeight
    End Sub
    

    Create Output Code
    We are now ready to create the code to output the Web Part. I use the same technique as in the Tool Part: CreateChildControls. The mock up of the output from Part 1 shows how the image and text should be arranged. However, there is still the matter of the actual countdown clock.

    To render the countdown, I am going to borrow a technique from an article written back in March. In that article, I used client-side script to format the current date and output it inside a DIV tag. Client-side script is the best choice for the countdown because the client-side script environment provides a timer. The last requirement from Part 1 states that the countdown timer has to display down to the second. Having the page connect to the server every second to update the display is not a good idea.

    Accordingly, I need to update my mockup. In this revision, I am not including the HTML, HEAD and BODY tags, since they are not required inside a Web Part. The SCRIPT tag will be generated in the CreateChildControls method, where I can insert the milestone date and display depth properties.

    <P align="center">
      <img alt="New building" src="/images/building.jpg" 
           width="100" height="150">
    </P>
    <H3 align="center">Move to new building<BR>
    <SPAN id="countdownClock_WPQ_">CLOCK DISPLAYS HERE</SPAN></H3>
    <script language="Javascript">
      updateCountdown("[id of element to update]","[milestone date]", _
    "[display depth]");
    </script>
    

    There is another noteworthy item in the above HTML. The tag that will contain the clock has an ID with a token (_WPQ_) appended to it. The Web Part framework has several of these tokens that are used when the same client-side script may be output multiple times. By using this token, and a related line of code, I can put the Web Part on the page multiple times, each with a different milestone date.

    The CreateChildControls method:

    Protected Overrides Sub RenderWebPart(ByVal output As _
                              System.Web.UI.HtmlTextWriter)
      MyBase.EnsureChildControls()
      MyBase.RenderWebPart(output)
    End Sub
    
    Protected Overrides Sub CreateChildControls()
      If Me.ImageLink <> "" Then
        Dim p As HtmlControls.HtmlGenericControl
        p = New HtmlControls.HtmlGenericControl("P")
        p.Attributes.Add("align", "center")
        Dim i As HtmlControls.HtmlImage = New HtmlControls.HtmlImage
        i.Src = Me.ImageLink
        i.Alt = Me.AlternateText
        If Me.ImageHeight <> -1 Then i.Height = Me.ImageHeight
        If Me.ImageWidth <> -1 Then i.Width = Me.ImageWidth
        p.Controls.Add(i)
        Controls.Add(p)
      End If
    
      Dim t As HtmlControls.HtmlGenericControl
      t = New HtmlControls.HtmlGenericControl("H3")
      t.Attributes.Add("align", "center")
      t.InnerHtml = Me.Text
      Controls.Add(t) 
    
      Dim s As HtmlControls.HtmlGenericControl
      s = New HtmlControls.HtmlGenericControl("script")
      s.Attributes.Add("language", "javascript")
      Dim milestone As Date = Date.Parse(Me.MilestoneDate)
      s.InnerText = String.Format("updateCountdown('{0}', '{1}', '{2}');", _
                    clientID, milestone.ToString("r"), Me.DisplayDepth)
      Controls.Add(s)
    End Sub
    

    The updateCountdown function is a client-side javascript routine that will calculate the time remaining until the milestone and formats it based on the timer depth property. This javascript is output to the web page using the standard ASP.NET method named RegisterClientScriptBlock. This can be seen in the full download.

    Web Part Download
    The complete source code and a CAB file for deployment can be found on my Web log at http://www.schaeflein.net/blog/2005/11/29/MilestoneCountdownWebPart.aspx. Please post questions and comments about the web part on the Intranet Journal Discussion Forum.

    Deploy the Web Part

    Once the Web Part has been completely developed, it needs to be deployed to the SharePoint server. There are many different ways to deploy a Web Part, and the procedure differs based on the desired availability of the Web Part. A future article will discuss these options. The download for this article contains a CAB file for deployment using STSADM.

    Summary

    This three-part article on provides a proven process to create SharePoint Web Parts. While there are many other articles that cover Web Part development, I believe that developers can learn something from each different article or approach. I encourage your feedback and questions on the Intranet Journal Discussion Board.

    About this series
    This series of articles on SharePoint is intended to help you understand the capabilities of the product, as well as provide tips and tricks, development ideas, information from Microsoft, information from the community, and perhaps some samples. Like many other series on IntranetJournal.com, I plan to include how-to articles that can help you with your deployments — ways to customize a page; deployment scenarios; content management; etc. With such a diverse product, there is no lack of topics for this series of articles. What would you like to read?

    About the author
    Paul Schaeflein is a developer with more than 20 years experience. Paul has been developing dynamic and interactive Web sites since 1996. Paul has worked on all of the versions of SharePoint and has worked with the .NET framework since its debut. You can reach Paul through his blog at http://www.schaeflein.net/blog/.



    Printer Friendly Version


    Other Resources
    from Intranet Journal
  • Intranet Journal Discussion Board
  • Developing a Custom Web Part, Part 1
  • Developing a Custom Web Part, Part 2
  • Introduction to Microsoft Sharepoint Portal Technology
  • from JupiterWeb
  • Troubleshooting Web Parts and Deployment (DevX)
  • Use the Power of Reflection to Dynamically Set SharePoint Web Part Properties
  • from the Web
  • About Web Parts (MSDN)
  • Web Part Gallery (MSDN)
  • email this page

    Tutorials
    and more at:
    Intranet Journal's Tutorials
    Intranet Journal Favorites

    Creating a PHP-Based Content Management System

    The Spyware Guide

    Introduction to Microsoft SharePoint Portal

    Intranet Journal
    Part of the EarthWeb Network

    Managing Editor
    Intranet Journal

    Tom Dunlap

    EarthWeb Home Page
    Jupitermedia Home Page

    Media Kit




    The Network for Technology Professionals

    Search:

    About Internet.com

    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers