Pages

Wednesday, November 4, 2009

Step by Step Tutorial for How to create and implement custom field type in SharePoint 2007

Hi Everyone


What is Custom field Type in SharePoint ? Why we need Custom field type?


We have sometime instances where our business data does not fit to the field types included in Windows SharePoint Services or some situations where we need to further customize those general field types. Windows SharePoint Services enables you to create custom field types. These custom fields can include custom data validation and custom field rendering. You can also customize the way that variable properties of your custom field types are processed and rendered when users set property variables and create new columns that are based on your custom field type.


Example:


We need Country and State Columns in SharePoint List and when user selects Country we need to populate states according to that, How to implement this functionality If we need to use Country and State drop down again and again in number of places in SharePoint lists then we need to use Custom Field Type and add that Custom Field in SharePoint List.

Today I’ll show you how to 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.
  9. 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” / >

<HTML> <![CDATA[;]]></HTML>

< 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);

}

}

}

Happy Coding :)

9 comments:

  1. Hi,
    We see an interface when we select for example a choice column out of the box.
    How can we achieve this with custom field.
    Thanks
    Ramakrishna

    ReplyDelete
  2. Hello Disha,
    I have some doubts during creation plz send you mail id if possible........
    Regards,
    Rudresh

    ReplyDelete
    Replies
    1. Hi Rudy

      Please post your any doubt here!!!! I will reply!!!

      Thanks
      Disha Shah

      Delete
  3. Hi Disha,

    I am new to SharePoint can you suggest me some links from where i can learn SharePoint. I have used lists, libraries, sites and sub-sites. now i was trying to create a custom page but i am completely lost how to do that if you can help me with some links it would be more helpful for me. I am using a free version of Windows SharePoint services 3.0.

    ReplyDelete
  4. Hi Disha,
    i have created project i need to add the project dll to gac i have given the comment as show below
    gacutil.exe /i [/r <...>] [/f]
    but i am getting an error access denied

    ReplyDelete
    Replies
    1. Hi Asha

      Open c:\windows\Assembly as "Administrator" and Install your DLL to GAC!!!

      How to open "windows Explorer" as Administrator.
      1> Open cmd.exe as "Administrator" , right click on cmd and select that option
      2> Run Explorer.exe and "c:\windows\Assembly"
      3> Same way open the folder as "Administraor" where DLL reside.
      4> Drag and Drop

      Hope this helps!!!
      Thanks

      Delete
  5. thank you disha,

    Disha can you help me how to add the ascx page to aspx page which i can implement in sharepoint

    ReplyDelete
    Replies
    1. Hi Asha

      You can write an sharePoint Webpart and use LoadControl method to load the ascx page as webpart.

      Please check this link which provides good example.
      http://jcapka.blogspot.com/2009/01/i-was-explaining-my-technique-of-using.html

      Hope this helps!!
      Disha Shah

      Delete
  6. Hi Disha,

    I want to create a custom Color field (choice).
    Can you please help me on this?

    ReplyDelete