Uses of Custom Field Types
WSS 3.0 and MOSS have a rich set of field types that ship from Microsoft which can probably handle all of your needs. There comes a time when you just want a little more though. Allow me to introduce you to custom field types.
With custom field types you can do more than store text, numbers, dates, and even some HTML. You can store, display, and interact with information in a way that more closely fits your organization. Using custom field types can give you the opportunity to enforce data validation rules, interact with other data and systems, provide enhanced security, store custom data structures, and provide rich interfaces for viewing and editing information.
The Field Class
The first step in creating a custom field type is to create a new field class. This class derives from the SPField class directly or from another field type that derives from SPField – the next section lists the base field types in which your custom field types can derive. This class should be compiled into a signed assembly and referenced in the field type definition. This class will have any logic for working with properties and methods that are related to field configuration, value validation, and retrieval of the field’s value.
Base Field Types
All fields *MUST* must derive from the class Microsoft.SharePoint.SPField directly or through one of the following base field types:
- SPFieldBoolean – Represents a Boolean field type.
- SPFieldChoice – Represents a choice field type.
- SPFieldCurrency – Represents a currency field type.
- SPFieldDateTime – Represents a date-time field type.
- SPFieldLookup – Represents a lookup field. The field value for an SPFieldLookup object is contained in an SPFieldLookupValue object.
- SPFieldMultiChoice – Represents a multichoice field type. The field value for an SPFieldMultiChoice object is contained in an SPFieldMultiChoiceValue object.
- SPFieldMultiColumn – Represents a multicolumn field type. The field value for an SPFieldMultiColumn object is contained in an SPFieldMultiColumnValue object.
- SPFieldMultiLineText – Represents a multiline text field type.
- SPFieldNumber – Represents a number field type.
- SPFieldRatingScale – Represents a ratings field type. The field value for an SPFieldRatingScale object is contained in an SPFieldRatingScaleValue object.
- SPFieldText – Represents a single line text field type.
- SPFieldUrl – Represents a URL field type. The field value for an SPFieldUrl object is contained in an SPFieldUrlValue object.
- SPFieldUser – Represents a Windows SharePoint Services user.
* The list above was obtained from MSDN
All custom field types must have a field type definition in order to inform the platform how to configure and display the field type. Field type definitions reside in a set of files located in the C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\XML folder and file names beginning with fldtypes and ending with an .xml file extension. Examples for these files would include FLDTYPES.XML (default WSS) and fldtypes_myfield.xml.
Properties allow for the customization of how an instance of a field type behaves when added to a list. These are the items that you can configure on a column settings page. For example, a number field can set the number of decimal places to display or a choice field allows a list of choices to be entered. You can create properties that control how the data is validated, displayed, or in the case of the Business Data field, where the information resides.
Custom properties must be declared in the fldtypes.xml within the <PropertySchema> element. See PropertySchema Element (Field Types) on MSDN.
To work with the values from within the context of the field class the SPField.GetCustomProperty and SPField.SetCustomProperty methods can be used. As a best practice, I suggest that public properties are created in the field class in order to promote the internally available properties into publicly accessible properties for the field type.
When performing validation on the field, override the SPField.GetValidatedString method. You can think of this method as a data entry scrubber. Overriding the logic of this method can enable the field to strip out any unwanted information or throw an SPFieldValidationException to reject the entry and notify the user of any corrective action.
A RenderPattern element in the fldtypes*.xml file controls how the information is displayed and edited using a CAML syntax with an HTML mix. Each type of view has its own render pattern. If a render pattern is not specified, the pattern from the base class is used unless a custom control is specified by the SPField.FieldRenderingControl property of the field class.
Render patterns that can be specified in the field’s type definition using a CAML-based render pattern:
- HeaderPattern – list view column header
- DisplayPattern – rendering on view forms and list views
- EditPattern – rendering on edit forms
- NewPattern – rendering on new forms
- PreviewDisplayPattern – SPD display preview
- PreviewEditPattern – SPD edit preview
- PreviewNewPattern – SPD new preview
Server Controls and Control Templates
In addition to using CAML-based render patters, you can use any type of server control as long as it derives from Microsoft.SharePoint.WebControls.BaseFieldControl. This control can generate the presentation through logic contained within the control or use a template based control. Place the ASCX file that contains a control of type Microsoft.SharePoint.WebControls.RenderingTemplate into the …/12/TEMPLATE/CONTROLTEMPLATES folder. When the application starts, the contents of the files in this folder are read and made available as control templates. The BaseFieldControl class is a template based control class where the rendering template that is used can be specified at run-time by overriding the DefaultTemplateName and DisplayTemplateName properties. A custom control for editing the field’s properties can also be specified in the field type definition.
Using a Custom Value Class
The value class contains the object that represents a field’s value. This value type may be simple or have a custom data structure that is very complex. This class must be serializable in order to store the data unless the value is temporary in nature and does not need to be persisted.