Search This Blog

Sunday, April 5, 2009

Elapsed Counter Webpart for MOSS/Sharepoint 2007



Background: One of our clients wanted an Elapsed Counter Webpart, which shows the elapsed days & time from a specified start date. Start date should be persisted & user should be able to sett the value of Start Date & Caption string.


Solution: I developed a webpart using VS 2005 with help of javascript. Javascript code is used to display the ticking clock. Clock value is initilized using StartDate webpart property & user can set the value of startDate property at runtime. Another property named Caption is used to set the caption of counter. There are two approach to include the javascript resource(file) in webpart.
1: add as embedded resource(the case is have used in this solution). Advantage of this approach is you need not to deploy the js file separately in sharepoint environment. Bad part of this approach is you have to recompile entire solution if there any change in javascript [I have used this approach].
2: deploy to C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS & refer the file there.

Step 1: Create new webpart project using VS 2005[C# is the language in my case] & add following code in webpart(.cs file)

using System;
using System.Drawing ;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

namespace Safety
{
[Guid("b1ac74f7-0edf-4fca-90bd-51e109d4950b")]
public class SafeHours : System.Web.UI.WebControls.WebParts.WebPart
{
Label lblError;
System.DateTime startDate=DateTime.Now ;//default value for startDate
string caption = "Days without L.T.A.";//default value for caption

public SafeHours()
{
}

//add Caption property & attributes
[WebBrowsable(true),
XmlElement(typeof(System.DateTime)),
Personalizable(PersonalizationScope.Shared),
SPWebCategoryName("Other Options"),
WebPartStorage(Storage.Personal),
FriendlyName("Caption"),
WebDescription("Set Caption")]
public string Caption
{
get
{
return caption;
}
set
{
caption = value;
}

}

//add Start Date property & attributes
[WebBrowsable (true),
XmlElement(typeof(System.DateTime)),
Personalizable(PersonalizationScope.Shared),
SPWebCategoryName("Other Options"),
WebPartStorage(Storage.Personal),
FriendlyName("Start Date-Time (format: mm/dd/yyyy hh:mi:ss AM"),
WebDescription("Set Start Date Time")]
public System.DateTime Startdate
{
get
{
return startDate;
}
set
{
startDate = value;
}
}


protected override void CreateChildControls()
{

try
{
//embed java script file(dont' forget append the namespace of webpart before file name)
Page.ClientScript.RegisterClientScriptResource(GetType(), "Safety.elapsed.js");
base.CreateChildControls();
Literal litData = new Literal(); //Literal control to write the control values
Literal litDataTemp = new Literal();//Tempporary Literal control to write the control values

DateTime ts = this.startDate; //get Start date from webpart property

//here we assign the start date values to named td(s) of dummy table be used by Javascript code
(replace [ with < & ] with >)

litDataTemp.Text = "[table style='font-size: 1 pt; width: 479px; color: white'] [tr] "+
"[td id='startYear_" + this.ID + "' style='height: 4px; font-size: 1pt;']" + ts.Year +
"[/td][td id='startMonth_" + this.ID + "' style='height: 4px; font-size: 1pt;']" + ts.Month +
"[/td][td id='startDay_" + this.ID + "' style='height: 4px; font-size: 1pt;']" + ts.Day +
"[/td][td id='startHour_" + this.ID + "' style='height: 4px; font-size: 1pt;']" + ts.Hour +
"[/td][td id='startMinute_" + this.ID + "' style='height: 4px; font-size: 1pt;']" + ts.Minute +
"[/td][td id='startSecond_" + this.ID + "' style='height: 4px; font-size: 1pt;']" + ts.Second +
"[/td][/tr][/table]";

//add dummy table
this.Controls.Add(litDataTemp);

//add another table which shows the counter (replace [ with < & ] with >)

litData.Text = "[table style='width: 500px'] [tr] [td id='elapsedDays_" + this.ID + "' style='width: 700px; " +
"background-color: steelblue; font-weight: bold; font-size: 18pt; vertical-align: middle; " +
"color: white; height: 35px; text-align: center;'][/td][/tr][tr] " +
"[td id='elapsedHours_" + this.ID + "' style='width: 700px; background-color: lightsteelblue; " +
"font-weight: bold; font-size: 18pt; vertical-align: middle; color: black; height: 35px; " +
"text-align: center;'][/td][/tr] [/table]";
//add counter table
this.Controls.Add(litData);

//define new HtmlGenericControl to call the javascript function
System.Web.UI.HtmlControls.HtmlGenericControl c = new System.Web.UI.HtmlControls.HtmlGenericControl("script");
c.Attributes.Add("language", "javascript");
//call javascript function
c.InnerText = "showElapsedTime('" + this.ID + "','" + this.caption + "')";
//add javascript control
this.Controls.Add(c);
}
catch(Exception ex)
{
//add label to show the error
lblError = new Label();
lblError.ForeColor = System.Drawing.Color.Red;
lblError.Text = ex.Message;
this.Controls.Add(lblError);
}

}

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}
}
}

Step 2: Javascript: Add a javascript file (elapsed.js in my case) in the root folder of webpart project & add following script:

function showElapsedTime(wid,caption)
{

var startYear = document.getElementById("startYear_"+wid).innerHTML;// initialize start year using named td of temp table ;
var startMonth = document.getElementById("startMonth_"+wid).innerHTML;//initialize start month using named td of temp table
var startDay = document.getElementById("startDay_"+wid).innerHTML;// initialize start day using named td of temp table
var startHour = document.getElementById("startHour_"+wid).innerHTML;//initialize start hour using named td of temp table
var startMinute = document.getElementById("startMinute_"+wid).innerHTML;//initialize start minutes using named td of temp table
var startSecond = document.getElementById("startSecond_"+wid).innerHTML;//initialize start seconds using named td of temp table
var startDate = new Date();
startDate.setYear(startYear);
startDate.setMonth(startMonth-1);
startDate.setDate(startDay);
startDate.setHours(startHour);
startDate.setMinutes(startMinute);
startDate.setSeconds(startSecond);

//alert(startDate);
var rightNow = new Date();
//calculate elapsed time
var elapsedTime = rightNow.getTime() - startDate.getTime();

//calculate elapsed days
var one_day=1000*60*60*24;
var elapsedDays = Math.floor( elapsedTime / one_day );
var milliSecondsRemaining = elapsedTime % one_day;

//calculate elapsed hours
var one_hour = 1000*60*60;
var elapsedHours = Math.floor(milliSecondsRemaining / one_hour );
milliSecondsRemaining = milliSecondsRemaining % one_hour;

//calculate elapsed minutes
var one_minute = 1000*60;
var elapsedMinutes = Math.floor(milliSecondsRemaining / one_minute );
milliSecondsRemaining = milliSecondsRemaining % one_minute;

//calculate elapsed seconds
var one_second = 1000;
var elapsedSeconds = Math.round(milliSecondsRemaining / one_second);

//write the out values to couter table
document.getElementById("elapsedDays_"+wid).innerHTML = caption+ elapsedDays ;
document.getElementById("elapsedHours_"+wid).innerHTML =elapsedHours +"Hrs : " + elapsedMinutes + "Min : " + elapsedSeconds + "Sec";

//set function timeout recurrsively
t = setTimeout("showElapsedTime('"+wid+"','"+caption+"')",1000);

}

Step 3: In solution explorer right click on elapsed.js --> properties & set Built Action to Embedded Resource.

Step 4: Build the solution & deploy to sharepoint server.


Step 4: Add the webpart to a webpart page & set Caption & Start Date-time properties in Webpart properties toolpane as given below:


Output: Here is the output

1 comment:

  1. How do you add this Elapsed Counter Webpart on default.aspx page? I can add web part but how to refer to elapsed.js? elapsed.js is not taken as 'embedded resource'. Please help

    ReplyDelete