Thursday, April 14, 2011

How to create a custom field type in SharePoint 2010 using visual studio 2010?

There are default field types like Text, Note, Boolean, Integer, Number, Decimal, DateTime, Choice, Lookup etc. We can also make our custom field types by using visual studio 2010.
Why Necessary?

For initialization and format field values.
Also used for data validation on user inputs.
Some points to remember:

Field types cannot be deployed in sandbox solution.
Might cause problem with Microsoft office products.
Might cause problem while viewing list items through data grid ir whenever trying to program against list using LINQ.

The structure should look like the below figure:

Steps to create custom field types:
1.     First create a new SharePoint project using the Empty SharePoint project template.

2.   Inside the project you need to add a public class for each custom field type.
3.     You need to add a special xml file namely fldtypes_{project name}.xml, to deploy the field type.
For each custom field type, you must create a field type class that inherits from one of the built-in field type classes, such as SPFieldText, SPFieldNumber, SPFieldDateTime, and SPFieldMultiColumn.
Then you required to add two public constructor. Here you don’t need to add any code within that constructor, only need to define the parameter list and pass these parameters on to the base class constructor with a matching parameter list. The code is below.
public class EmployeeStartDate : SPFieldDateTime
        public EmployeeStartDate(SPFieldCollection fields, string fieldName)
            : base(fields, fieldName) { }

        public EmployeeStartDate(SPFieldCollection fields, string typeName, string displayName)
            : base(fields, typeName, displayName) { }

        // configure field to display date but not time
        public override void OnAdded(SPAddFieldOptions op)
            this.DisplayFormat = SPDateTimeFieldFormatType.DateOnly;

The next step is to override whatever base class methods and properties make sense for your particular scenario. Here is the code sample that I have done here:
// add logic to create default date as first Monday
        public override string DefaultValue
                DateTime startDate = DateTime.Today;
                while (startDate.DayOfWeek != DayOfWeek.Monday)
                    startDate = startDate.AddDays(1);
                return SPUtility.CreateISO8601DateTimeFromSystemDateTime(startDate);

        // add validation to ensure start date is a Monday
        public override string GetValidatedString(object value)
            DateTime input = System.Convert.ToDateTime(value);
            if (input.DayOfWeek != DayOfWeek.Monday)
                throw new SPFieldValidationException("Employee start date must be a monday");
            return base.GetValidatedString(value);

Here we have completed the creation of the custom field type and now we need to deploy.

For this we need to create a XML file. The naming convention is very much important, it must start with fldtypes then _  and then the project name.xml. For example fldtypes_FieldTypeDemo.xml.
Within that XML file each field type is created using a FieldType element, which must reside inside top-level FieldTypes element. The Field elements are required to provide information about the custom field type, its parent type, its display name, the field class name, the name of the assembly etc. Below is the code sample.

<?xml version="1.0" encoding="utf-8" ?>

    <Field Name="TypeName">EmployeeStartDate</Field>
    <Field Name="ParentType">DateTime</Field>
    <Field Name="TypeDisplayName">Employee Start Date</Field>
    <Field Name="TypeShortDescription">Employee Start Date (demo)</Field>
    <Field Name="UserCreatable">TRUE</Field>
    <Field Name="FieldTypeClass">
      FieldTypeDemo.EmployeeStartDate,FieldTypeDemo, Version=, Culture=neutral, PublicKeyToken=2a494da19a21cf85

TypeName and FieldTypeClass name are very much important.
Now deploy the solution and enjoy.