Second Life of a Hungarian SharePoint Geek

September 9, 2009

How to default calendar item to All day Event?

Filed under: Calendar, Reflection, SharePoint — Tags: , , — Peter Holpar @ 00:43

It was the question in one of the MSDN forum threads.

My first idea was a JavaScript or jQuery included in the NewForm.aspx of the specific Calendar list instance, but this solution would have a few drawbacks. First, it requires you to tamper with one of the form pages of the list using SharePoint Designer – one activity don’t like too much. Second, since the scripts can run only after the page is loaded, and the page is loaded with All Day Event checkbox not selected, and time controls for Start Time and End Time visible, selecting the All Day Event option and hiding the four controls (hours and minutes for both Start Date and End Date) might requires either a postback of the page or more line of script I wish to write now. Third, the script on the customized page should run each time the page is displayed.

My second approach was to modify the default value of the field. The first challange here is that one can not find the All Day Event field in the list of fields when using the „Customize Calendar” page, although the field is there when you check the list of fields in the All Events view.

The All Day Event field is a special out-of-the-box field. When you check the Type property of the „All Day Event” field in a calendar list, it returns AllDayEvent. The class that represents this field is the SPFieldAllDayEvent class, that is inherited from the SPFieldBoolean. The field has no default value defied, as the DefaultValue returns null. When you try to modify this property and call the Update() method of the field, you can see that the it has no effect, the DefaultValue of the field remains null.

It is because this field is „inherited” to the list from the Event content type. You can verify this by attaching the content types of the calendar list (there is only one by default, that is Event), and checking the FieldLinks collection of the Event content type. It includes the All Day Event. Here comes the next problem. The SPFieldLink class has no property that can be used to set the default value. Or maybe it has? Yes, it has, just it is not public.

Here comes reflection into the picture. The property is called Default, it is internal and fortunately has both get and set accessors.

Here is the code one can use to set its value, for example from a command line utility:

 

// Don’t forget this

using System.Reflection;

...

using(SPSite site = 

new SPSite("http://yoursite"))

{

 using(SPWeb web = 

site.OpenWeb())

 {

 SPList list = 

web.Lists["Calendar"];

 SPContentType ct = 

list.ContentTypes["Event"];

 SPFieldLink fieldLink = 

ct.FieldLinks["All Day Event"];

 // Now comes the magic 

 :-)

 Type type = typeof(SPFieldLink);

 

PropertyInfo pi = type.GetProperty("Default", BindingFlags.NonPublic | 

BindingFlags.Instance);

 pi.SetValue(fieldLink, "1", 

null);

 ct.Update();

 }

} 

After running the code, you can try to create a new calendar item, and see that now the All Day Event checkbox is selected, and only the date field for the Start Time and End Time fields are visible.

The advantage of this solution is that you should not modify the NewForm.aspx, it must be run only once and the form is loaded every time with the default value already set. The possible drawback is that tampering with the reflection might be not really supported and can have unforeseeable side-effects to your SharePoint installation, so the code above is really only for demonstration purposes, please use that at your own risk.

Finally I should note, that beyond the specific example I discussed above, the method can be used to set list level default values for the site columns.

About these ads

8 Comments »

  1. Thanks for your solution.
    I’m not a programmer, how should I put this code in my SharePoint?

    Comment by XexeX — December 3, 2009 @ 08:06

  2. XexeX,

    You should not put the code in SharePoint, but you shoud create a simple console application including that code using Visual Studio and run it on the SharePoint server. You should add reference to the Microsoft.SharePoint.dll in your project and add the using Microsoft.SharePoint; to the namespaces. It is rather simple, but if you don’t know how to do it, it might be better to ask for help of a local developer.

    Comment by pholpar — December 3, 2009 @ 09:09

  3. Yes, I’m don’t know how to do this.
    Anyway, thanks for your help :D

    Comment by XexeX — December 4, 2009 @ 08:42

  4. [...] Es gibt dazu mehrere Lösungsansätze, u.a. kann man einen programmatischen Ansatz wählen, den ich hier gefunden [...]

    Pingback by SharePoint ContentType ‘Event’ adaptieren « uliarmbruster — January 3, 2011 @ 18:58

  5. The line “pi.SetValue(fieldLink, “1″, null);” is throwing an error: “non-static method requires a target.” Any idea what would be causing that?

    Comment by utahbrent — August 5, 2011 @ 01:46

    • It means probably you call SetValue with the first parameter (fieldLink) is null. Check for the name of your field, in my example it was “All Day Event”, you might have another name. The post was tested for MOSS 2007, there is no guarantee it works with SP 2010.

      Comment by Peter Holpar — August 5, 2011 @ 09:05

  6. Thanks for the how-to. I was trying this against SP 2010 Foundation and it worked, with one difference: name of “All Day Event” is “fAllDayEvent”.

    Comment by Jiri Hrazdil — February 13, 2013 @ 23:02

  7. If you don’t have Visual Studio (or don’t want to fire it up) you can do it in Powershell (Sharepoint 2010 Management Shell) as well:

    $web = Get-SPWeb http://yoursite
    $list = $web.Lists["MyCalendar"]
    $ct = $list.ContentTypes["Event"] // or whatever content type your calendar is using
    $fieldLink = $ct.FieldLinks["All Day Event"] // this may be localized in your language
    // Now comes the magic
    $type = $fieldLink.GetType()
    [System.Reflection.BindingFlags]$flags = [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance
    $pi = $type.GetProperty(“Default”, $flags)
    $pi.SetValue($fieldLink, “1″, $null)
    $ct.Update()

    Comment by momma — April 30, 2013 @ 13:49


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Theme: Shocking Blue Green. Get a free blog at WordPress.com

Follow

Get every new post delivered to your Inbox.

Join 53 other followers

%d bloggers like this: