Monday, April 22, 2013

How to create and implement custom field type in SharePoint ?

What is Custom field Type in SharePoint ?

With custom field types, developers can really integrate with the SharePoint platform.Where with other ways of extending new functionality is build mostly on top of the SharePoint. With custom fields the level of integration is a lot higher. This extra integration comes at a price, the development of custom field types is more labor intensive than developing ‘normal’ field controls. But then, ‘normal’ fields can only be used on publishing pages and not in SharePoint display forms or in SharePoint lists. Custom field types can be used in both SharePoint lists and on display forms. The data custom fields use is stored in the SharePoint content database and custom fields can be used in SharePoint workflows and have access to the build in version control system .


create and implement Custom Field Type step by step:

1. Open Microsoft Visual Studio, Go to File-->New-->Project.
2. In the New Project dialog box, select Class Library from the Templates box, give it a name and location, then click OK.
3. Add Reference of Microsoft.SharePoint assembly, and then click OK.
4. Make the project as strong name key file.
5. Now rename class.cs with CountryStateField.cs
6. Creating a class for Custom field Type
7. Create a field definition Schema XML file
8. Create a class which contains FieldTypeValue.

create and implement Custom Field Type step by step.

Open Microsoft Visual Studio, Go to File-->New-->Project.
In the New Project dialog box, select Class Library from the Templates box, give it a name and location, then click OK.
Add Reference of Microsoft.SharePoint assembly, and then click OK.
Make the project as strong name key file.
Now rename class.cs with CountryStateField.cs
Creating a class for Custom field Type
Create a field definition Schema XML file
Create a class which contains FieldTypeValue.
Create a class which is used for to display that , fieldcontrol.




Let us go through every step in detail one by one.

Step No 6 :Creating a Custom Field Type
The first step in creating a custom field type and field control is to create the field type class — the hub of everything related to the field. All field types must inherit from the Microsoft.SharePoint.SPField class or one that is derived from it.

Sample of Code

using System;

using System.Collections.Generic;

using System.Text;

using Microsoft.SharePoint;

using Microsoft.SharePoint.WebControls;

namespace Sample.FieldType

{



class CountryRegionField:SPFieldMultiColumn

public {

public CountryStateField(SPFieldCollection fields, string fieldName): base(fields, fieldName) { }

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

public override object GetFieldValue(string value)

{

if (string.IsNullOrEmpty(value)) return null;

return new CountryStateValue(value);

}

public override BaseFieldControl FieldRenderingControl

{

get

{

BaseFieldControl control = new CountryStateControl();

control.FieldName = this.InternalName;

return control;

}

}

public override string GetValidatedString(object value)

{

if (value == null)

{

if (this.Required) throw new SPFieldValidationException("Invalid value for this field.");

return string.Empty;

}

else

{

CountryStateValue field = value as CountryStateValue;

// if no value obtained, error in the field

if (field == null) throw new ArgumentException("Invalid value.");
// if it is required...

if (this.Required)

{

// make sure that both COUNTRY & State are selected

if (field.Country != string.Empty && field.State != string.Empty)

throw new SPFieldValidationException("Both are required.");

}

else

{

// else, even if not required, if one field is filled in, the other must beas well

if (!string.IsNullOrEmpty(field.Country))

if(string.IsNullOrEmpty(field.State))

throw new SPFieldValidationException("Both are required if one value is entered.");

}

return value.ToString();

}

}

}

}

Let us move to the next step , Create a xml file for Custom field Definition.

Step No. 7 : Creating a Custom Field Type Definition

With a field type class created, the next step is to create the field type definition that will make SharePoint aware of the field. This is done by creating an XML file in the [..]\12\TEMPLATE\XML Folder. When SharePoint starts up ,it looks at the [..]\12\TEMPLATE\XML folder and loads all the field type - defined files named fldtypes[_*].xml .

All the SharePoint fields provided in the WSS 3.0 install are found in the fldtypes.xml file. Other fields are added based on the MOSS 2007 installation. For instance, all the Publishing - specific fields are defined in the fldtypes.publishing.xml file.

CountryStateField definition (fldtypes _ CountryState.xml)

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

< FieldTypes >

< FieldType >

< Field Name=”TypeName” > CountryState< /Field >

< Field Name=”ParentType” > MultiColumn < /Field >

< Field Name=”TypeDisplayName” > Country, State < /Field >

< Field Name=”TypeShortDescription” > Country and state < /Field >

< Field Name=”UserCreatable” > TRUE < /Field >

< Field Name=”FieldTypeClass” > Sample.FieldType. CountryStateField,Sample.FieldType,Version=1.0.0.0, Culture=neutral, PublicKeyToken=e42a63991be18435 < /Field >

< RenderPattern Name=”DisplayPattern” >

< Switch >

< Expr > < Column / > < /Expr >

< Case Value=”” / >

< Default >

< Column SubColumnNumber=”0” HTMLEncode=”TRUE” / >

<![CDATA[;]]>

< Column SubColumnNumber=”1” HTMLEncode=”TRUE” / >

< /Default >

< /Switch >

< /RenderPattern >

< /FieldType >

< /FieldTypes >

TypeName: This is the unique name of the field used when creating items such as site columns using a Feature. For example, if a site column were created that was based on the field type created in this chapter, the element manifest ’ s site element would look like the following (omitting the other required attributes):
ParentType: The parent type is the field type from which the custom field type is derived — in this case, SPFieldMultiColumn or just MultiColumn .
TypeDisplayName: This name is used to display the field type on pages such as the Site Column Gallery or a content type ’ s detail page.
TypeShortDescription: The short description is the string used to display the field type as an option when creating new site or list columns (the long radio button list under the new column ’ s title textbox).
UserCreatable: This Boolean property tells SharePoint whether the field type can be used in the creation of a column in a list by a user. When false , developers can still use the field type in sitecolumns within the definition of list templates created using Features.
FieldTypeClass: This contains the strong name of the field type class and the assembly containing the class. This is also referred to as the five - part name: namespace.type, Assembly,Version, Culture, PublicKeyToken .


The custom field type definition should be added to the Visual Studio project in the following location: \TEMPLATE\XML\fldtypes_ CountryState.xml .

Step no 8 Creating a Custom Field Value
One of the requirements of the ContryStateField custom field type was to store the data within a custom data structure. While it sounds a bit complex, it is actually very simple. The custom field value class is very handy with field types that are derived from the SPFieldMultiColumn field because data is stored in the SPFieldMultiColumn field as a special delimited string using ;# as the delimiter, and not just between two values but surrounding them ;#United States;#Florida;#

CountryStateValue.cs file containing the field value

using System;

using Microsoft.SharePoint;

namespace Sample.FieldType{

public class CountryStateValue : SPFieldMultiColumnValue {

private const int NUM_FIELDS = 2;

public CountryStateValue ()

: base(NUM_FIELDS) { }

public CountryStateValue (string value)

: base(value) { }

public string Country {

get { return this[0]; }

set { this[0] = value; }

}

public string State {

get {return this[1];}

set { this[1] = value; }

}

}

}

Step No 9 : Creating a Custom Field Control

The first piece in a custom field control is the control class. This class must inherit from the Microsoft.SharePoint.WebControls.BaseFieldControl class or one that derives from it. For the CountryStateField , the BaseFieldControl will work.

using System;

using System.Collections.Generic;

using System.Text;

using Microsoft.SharePoint.WebControls;

using System.Web.UI.WebControls;

using Microsoft.SharePoint;

namespace Sample.FieldType

{

public class CountryStateControl : BaseFieldControl,IDesignTimeHtmlProvider

{

protected DropDownList _country;

protected DropDownList _StateSelector;

protected Literal _StateSelectorLiteral;

public override object Value {

get

{

EnsureChildControls();

CountryStateValue field = new CountryStateValue();

if (_country == null || _StateSelector == null )

{

field.Country = String.Empty;

field.State = String.Empty;

}

else

{

// set country value

if (_country.SelectedIndex == 0)

field.Country = String.Empty;

else

field.Country = _country.SelectedValue;

// set State value

if (_StateSelector.SelectedIndex == 0)

field.State = String.Empty;

else

field.State = _StateSelector.SelectedValue;

}

return field;

}

set

{

EnsureChildControls();

if (value != null && !string.IsNullOrEmpty(value.ToString()))

{

CountryStateValue field = new CountryStateValue(value.ToString());

_country.SelectedValue = field.Country;

if (_country.SelectedIndex > 0)

_StateSelector.SelectedValue = field.State;

SetStateControlVisibility(_country.SelectedIndex);

}

}

}

private void SetStateControlVisibility(int countrySelectedIndex)

{

switch (countrySelectedIndex)

{

case 0: // if none selected

_StateSelector.Visible = false;

_StateSelectorLiteral.Visible = false;

break;

default: sss

_StateSelector.Visible = true;

_StateSelectorLiteral.Visible = true;

break;

}

}

protected void Country_SelectedIndexChanged(object sender, EventArgs e)

{

EnsureChildControls();

//ADDstatesdependsonCountry(_country.SelectedIndex);

SetStateControlVisibility(_country.SelectedIndex);

}

protected void ADDstatesdependsonCountry(int countrySelectedIndex)

{

_StateSelector.Items.Clear();

//Code for Adding items to State dropdown depends on contry

}

void AddItesmsForContry()

{

//code for adding items to country dropdown

}

protected override void CreateChildControls()

{

if (this.Field == null || this.ControlMode == SPControlMode.Display ||this.ControlMode == SPControlMode.Invalid)

return;

base.CreateChildControls();

// get reference to Country selector

_country = new DropDownList();

_country.SelectedIndexChanged += new EventHandler(Country_SelectedIndexChanged);

_country.AutoPostBack = true;

//AddItesmsForContry()

_StateSelector = new DropDownList();
_StateSelectorLiteral = new Literal();

//Add country ,state Selector and State Literal to control collection

this.Controls.Add(_country);

this.Controls.Add(_StateSelectorLiteral);

this.Controls.Add(_StateSelector);

}

}

}