Monday, June 7, 2010

Creating custom field in SharePoint 2007 – Part 1

Hi All,

Many times the most common requirement is such that we have to build custom field in SharePoint and hence I though of sharing information on how we can create custom fields.

I am going to break this series of creating custom filed in to parts because there is so much fun in it to learn so many techniques while creating custom field.

Hence we are going to start with very basic text box control which will validate if the entered address starts with http or ftp or not.

Before diving more into coding part, first let me give you highlight on what all files are necessary for this.

1) Control ascx file - This is required for the field that we are going to develop; this will actually play a role while assigning field to the actual type (textbox, drop down etc).
2) Control xml file - This will define the type of the field and register to the SharePoint to make it understand that there is some field type that needs to be rendered at the time of creating field. We can define much more here. We will see them in upcoming series.
3) Control cs file – Coding related to the control which tells SharePoint about getting and setting the value of field and also to assign properties to the control in the code.
4) Field file – To validate the value entered in the field and throw the exception if validation fails. This will prevent item being added in the list. At the end, if we do not want any validation to happen, this file can return the value which is entered in the field.


Now let us start our journey of creating simple and basic text box custom field. Thank God I am not starting with Hello World.

Open Visual Studio and create a project with appropriate name to you. Now add one file and its extension should be .ascx. Make sure that you reference System.Web and Microsoft SharePoint assembly in the project.

Type in below code in that.

<%@Control Language="C#" Debug="true"%>
<%@Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@Register TagPrefix="SharePoint" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" namespace="Microsoft.SharePoint.WebControls"%>
<SharePoint:RenderingTemplate ID="SPKingsTextbox" runat="server">
<Template>
<asp:TextBox ID="txtTextBox" runat="server" />
</Template>
</SharePoint:RenderingTemplate>


You can give your own ID to the rendering template and your own ID to textbox control.

Now add one more file. Call it as an xml file. And then type in the following code in it.

<?xml version="1.0" encoding="utf-8" ?>
<FieldTypes>
<FieldType>
<Field Name="TypeName">SPKings Textbox</Field>
<Field Name="TypeDisplayName">SPKings Textbox</Field>
<Field Name="TypeShortDescription">SPKings Textbox</Field>
<Field Name="ParentType">Text</Field>
<Field Name="FieldTypeClass">SharePointKings.CustomControls.SPKingsTextBoxField, SharePointKings.CustomControls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ed861ccbb4ad6887</Field>
<Field Name="Sortable">TRUE</Field>
<Field Name="Filterable">TRUE</Field>
</FieldType>
</FieldTypes>


Now let me explain you each tag here. We will explore more and more tag in upcoming series. First the Type Name is the name that you want to give to this field. Type Display Name is the name of the field that will appear when you add the column to the list. Type Short Description as a name suggest is the description about this field. Parent Type is also an interesting value. We will see more on this in upcoming series. As of now we have taken it as Text. FieldTypeClass is the entire assembly reference with the field class name. We are going to add field class soon. SPKingsTextBoxField is the name of the field class in my project. Sortable true means you are allowing your end user to sort this column in list view web part and on AllItems and EditItems page. If this is false, they cannot sort this field. Filterable means filter can appear in that field column. If specified false, then you cannot filter on that column.

Change the appropriate references for your project assembly wherever it applies.

Add one more class and name it according to your choice. And paste the following code in it. I have demonstrated whole class file with namespace. This class is Control class for our custom field. Change your references accordingly. Make sure that your default template name should be equal to the rendering template id that you have in the ascx file. And your protected textbox ID should be equal to the textbox id that you gave in ascx file.

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.WebControls;

namespace SharePointKings.CustomControls
{
public class SPKingsTextboxControl : BaseFieldControl
{
protected TextBox txtTextBox;

/// <summary>
/// setting template name
/// </summary>
protected override string DefaultTemplateName
{
get
{
return @"SPKingsTextbox";
}
}


/// <summary>
/// get set value
/// </summary>
public override object Value
{
get
{
EnsureChildControls();
return txtTextBox.Text.Trim();
}

set
{
EnsureChildControls();
txtTextBox.Text = (string)this.ItemFieldValue;
}
}


/// <summary>
/// create child control
/// </summary>
protected override void CreateChildControls()
{
if (Field == null) return;
base.CreateChildControls();
}

}
}


As you can see override Value method actually does the work of getting and setting the value of the field.

Now add one more class name it according to your choice. This is the field class for our custom field. And write down the following code. I have taken namespace and class of my project in this reference code. Change it to your own need.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;

namespace SharePointKings.CustomControls
{
public class SPKingsTextBoxField: SPFieldText
{
#region Contstructors

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

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

}

#endregion

public override string GetValidatedString(object value)
{
string strTxtValue = Convert.ToString(value).Trim();

if (!strTxtValue.ToUpper().StartsWith("HTTP") &&
!strTxtValue.ToUpper().StartsWith("FTP"))
{
throw new SPFieldValidationException("Web address does not start with HTTP or FTP");
}

return strTxtValue;
}
}
}


As you can see, the only interesting part in this file as of now is GetValidateString method which handles the entered value in the field. Here we are getting the value by converting it to the string and then checking against the http and ftp, if not then we are throwing SPFieldValidationException which is basically throws the message at the time of clicking on OK button on the form.

Now this is it. All we need to do is copy respective files at respective locations. First build the project and sign it with strong key. Deploy that DLL to the GAC and then see its property. Take out the public key token and modify it in your XML field file.

Now copy this DLL to GAC (which you have just done), copy XML file to the 12 hive XML directory and copy ascx file to the CONTROLTEMPLATES folder under 12 hives. Reset the IIS.

I have created one dummy list to show you the custom field in action. Create column, now when you click on create column, on the page where you land up, you will see one more field being added and which is SPKings TextBox in my case. Give field name WebSite and select SPKings TextBox field type and click on OK.



This will add WebSite column with our own field in the list. Go ahead and click on New to add the item in the list. Type in www.SharePointKings.com. And the moment after clicking OK button, our field validates the entered value with our own written logic and throws the exception with the message that we wrote in the code.



Now change the value to http://www.SharePointKings.com and click on OK. This time it passes the validation and value gets entered in the list. Open the same item for editing and see the value is in WebSite column. Try to modify that column again by removing http and click on OK, again it will validate the value and throws the exception.





So this is the end of my first part of this series. Hope that you have liked this post and look forward to read further interesting part. I will be back soon with part 2.

5 comments:

siva said...

do u have any idea how to deploy custom field type for specific site collection . ?

SharePoint Kings said...

siva,

thats not looks possible.

custom field will be available in all the farm. it's can not be restricted to one site or site collection.

atleast we don't think thats possible.

Tobbi said...

In order to get this to work with the usercontrol I created, I had to include an override of the property FieldRenderingControl

public override BaseFieldControl FieldRenderingControl

{

get

{

BaseFieldControl fieldControl = new customfieldcontrol();

fieldControl.FieldName = this.InternalName;

return fieldControl;

}

}

Kumar said...

How would you do this, if you wanted to add a drop down field instead of a text field?

SharePoint Kings said...

Kumar,

use dropdown instead of textbox.
change all the syntax accordingly.

give it a try

we will try to post for dropdown when we get time.

but it will take time.




Share your SharePoint Experiences with us...
As good as the SharePointKings is, we want to make it even better. One of our most valuable sources of input for our Blog Posts comes from ever enthusiastic Visitors/Readers. We welcome every Visitor/Reader to contribute their experiences with SharePoint. It may be in the form of a code stub, snippet, any tips and trick or any crazy thing you have tried with SharePoint.
Send your Articles to sharepointkings@gmail.com with your Profile Summary. We will Post them. The idea is to act as a bridge between you Readers!!!

If anyone would like to have their advertisement posted on this blog, please send us the requirement details to sharepointkings@gmail.com