Feb 10

 

  UPDATE: a jQuery version can be downloaded on this other post

After my previous post about enhancing rich text field, I want to show you how easy it is to improve the DateTime field. I will rely on ExtJS library and use their DateField but you can use the library of your choice.

Here is the final result:

 


 

 

First override the RenderingTemplate

<SharePoint:RenderingTemplate ID="DateTimeField" runat="server">

       <Template>

             <my:ExtjsDateTimeExtender runat="server" />

             <SharePoint:DateTimeControl ID="DateTimeField" DateOnly="true" UseTimeZoneAdjustment="false" runat="server"/>

       </Template>

</SharePoint:RenderingTemplate>

 

As we see previously, nothing new here. What do we need to extend a textbox with Extjs? From what I read in the doc, giving the ID of the textbox should be enough. Fine! We will handle also some properties like MinDate, MaxDate, … See the docs from more customization.

var datefield = new Ext.form.DateField({

       applyTo: clientId,

       minValue: minDate != null ? Date.parseDate(minDate, 'Ymd') : null,

       maxValue: maxDate != null ? Date.parseDate(maxDate, 'Ymd') : null,

       startDay: startDay

});

 

Now we need to retrieve the clientId of the textbox to extend. This is the role of the ExtjsDateTimeExtender control:

[ToolboxData("<{0}:ExtjsDateTimeExtender runat=\"server\" />"),

 AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal),

 AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]

public class ExtjsDateTimeExtender : Control

{

protected override void OnLoad(EventArgs e)

{

       base.OnLoad(e);

 

       // Leave the default field shipped for IE as it works well

       // Comment the following line to apply this patch to IE too.

       if (Page.Request.Browser.Browser.Contains("IE")) return;

 

       DateTimeControl dtControl = FindDateTimeControl(this.Parent);

       if (dtControl.TimeOnly) return;

 

       // Not a very elegant way but hey, it works...

       String textBoxClientID = dtControl.Controls[0].ClientID;

 

       ClientScriptManager cs = this.Page.ClientScript;

       cs.RegisterClientScriptInclude("spdatetime", "/_layouts/spdatetime.js");

 

       System.Text.StringBuilder script = new System.Text.StringBuilder();

       script.AppendFormat("Ext.onReady(function() {{ ExtjsDateTimeConvert('{0}',", textBoxClientID);

 

       if (dtControl.MinDate == DateTime.MinValue) script.Append("null,");

       else script.AppendFormat("'{0:yyyyMMdd}',", dtControl.MinDate);

 

       if (dtControl.MaxDate == DateTime.MaxValue) script.Append("null,");

       else script.AppendFormat("'{0:yyyyMMdd}',", dtControl.MaxDate);

 

       script.AppendFormat("{0}", dtControl.FirstDayOfWeek);

       script.AppendLine("); });");

 

       cs.RegisterClientScriptBlock(base.GetType(),

             "extjsdatetime" + this.UniqueID.GetHashCode().ToString("X"),

             script.ToString(), true);

}

 

private DateTimeControl FindDateTimeControl(Control templateContainer)

{

       return (DateTimeControl) templateContainer.FindControl(this.Target);

}

 

/// <summary>

/// Gets or sets the ClientID of the DateTimeControl to extend.

/// If you leave empty, it will search for a control named DateTimeField inside its parent template.

/// </summary>

public String Target

{

       get { return targetClientID ?? "DateTimeField"; }

       set { targetClientID = value; }

}

}

 

The code is easy but can look complicated; in fact, there is a lot of code related to formatting the parameters adequately.

NB: Ext.onReady is a helper method (shipped with Extjs) that executes some code when the document has finished loading. We then perform the conversion in our javascript function ExtjsDateTimeConvert.

 

The extender class works as a standalone control. You can declare a SPDateTimeControl anywhere in your page and extend it: you just need to set the Target property with the appropriate ClientID.

<SharePoint:DateTimeControl runat="server" ID="dtpOther" EnableViewState="true" DateOnly="true" />

<my:ExtjsDateTimeExtender runat="server" target="dtpOther" />

 

 

Hacks for Extjs:

This works well but sometimes, the textbox remains empty… This may occurs when another culture (other than en-us) is used because for example in French, 1st March is formatted as 1/3 and not 01/03. So a bit of additional code is required: we split the textbox value and prepend a ‘0’ when required. This is the purpose of the 2 additional parameters given to the javascript function.

 

Source code and solution package : SPDateTimeFeature.zip (25.03 kb)

Comments

Nazar

Posted on Tuesday, 19 January 2010 13:33

Alternate free solution using jQuery library http://sharepointdatetime.codeplex.com/

Lesena Vrata

Posted on Monday, 1 March 2010 16:30

I have been reading the articles on this website for some time. This is my first comment. Your blog has been very useful for me and it provides very good content.

Comments are closed