Development
August 4, 2008

Developing a SharePoint custom field type for displaying CRM 4.0 data



Enlarge Image

Written by: Karine Bosch

Introduction

In this walkthrough you will learn how you can create a SharePoint custom field type that allows users to select an existing account from the CRM database. A download link to the c# source code is available at the end of the article.

SharePoint offers you out of the box a variety of field types that you can use in lists, site columns and content types. These are field types like text, number, choice, lookup, users and even business data. Besides these standard field types you can also develop your own custom field type. The primary function of a field type is storing information. But there are cases in which you want the field type do something more like data validation or application of business rules. You can also provide a custom field type with a more complex user interface. but you can also want a custom field providing a certain functionality or presentation.

What is a custom field?

A custom field type consists of many different parts. The hub of the custom field is the field type class. If the custom field needs to store data in a more complex way than For example.e. a string or a number, this class will contain a reference to a field value class. If the custom field offers a custom presentation, then this class will also contain a reference to a field control class. In this field control class you can choose to dynamically build your controls in code or refer to a RenderTemplate defined in a user control.

When your custom field is all laid out it can be compiled into a dllan assembly. To inform SharePoint about the existence of your custom control and its structure you have to create a field definition file that needs to be deployed to the C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\XML directory of SharePoint. This definition file contains CAML markup containing a reference to the assembly and the field type class.

When SharePoint starts up - after a boot of the server or an IISRESET - all field type definitions are loaded and users will be able to use your custom field as for a column in a list or as a site column.

As SharePoint is all about features, the best way to deploy custom fields is by working with a feature.

Why a CRM Custom Field Type? What this custom field offers?

The custom field that we are going to develop in this walkthrough will give the user the possibility to retrieve information about accounts stored in the CRM database. As we expect to have a lot of accounts in the database, the user will be required to fill out a part of the company name. After clicking the Search button, all accounts containing the specified part in their company name will be retrieved and listed in a dropdown list.
user can select CRM account

SharePoint Custom Field Type: user can select CRM account

The user is then able to select an account from the dropdown list, which triggers the custom field to display the address details of the selected account.

SharePoint custom field type displaying CRM Account data

SharePoint custom field type displaying CRM Account data

Behind the scenes the Business Data Catalog is used to retrieve the data from the CRM database.

The Business Data Catalog

In the real world, business data is stored in many different ways and in a variety of databases. The purpose of the Business Data Catalog is to make that business data available into SharePoint.

The application definition file, which you can download at the bottom of this article, has been developed by Patrick Tisseghem for his new book Inside Search. This book will appear in x. He used the Business Data Catalog Editor which was recently released by Microsoft as part of the latest version of the MOSS 2007 SDK.

Developing the user control

First of all we are going to create the visual user interface. As the custom field will be deployed as an feature assembly, it is a good idea to create a class library project in Visual Studio 2005 or Visual Studio 2008. Prepare also the folder structure that is required for a feature:
Visual Studio Project layout

Visual Studio Project layout

First of all we are going to create the visual user interface. Here you have two possibilities: you can create the necessary controls like labels, text boxes and buttons completely in code. But if your user interface is a bit more complex than just a label and a text box, it is a good idea to design a user control. When working the programmatic way, the user interface is compiled within the custom field assembly.

In this walkthrough the second technique is used. User controls must reside in the CONTROLTEMPLATES directory of SharePoint so add a file with the ascx extension to the corresponding sub folder you just created.

Add a reference to the SharePoint dll:

<%@ Assembly Name=”Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %><%@ Control Language=”C#” %><%@ Register Assembly=”Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c”Namespace=”Microsoft.SharePoint.WebControls” TagPrefix=”SharePoint” %>

User controls developed for use by SharePoint custom fields must contain one or more SharePoint RenderingTemplate controls to tell SharePoint how to render your control.

<SharePoint:RenderingTemplate ID=”CRMAccountControl” runat=”server”>

<Template>

<!-Add user interface here–>

</Template>

</SharePoint:RenderingTemplate>

All controls will reside in a HTML table for the ease of positioning the controls on the form.

<table class=”ms-form” width=”100%”>

<colgroup>

<col width=”100%” />

<!-add the controls here –>

</colgroup>

</table>

Now add the necessary controls:

- A label, textbox and button for the lookup of a filtered set of accounts

<tr>

<td>

Enter a company name or part of a company name:</td>

</tr>

<tr>

<td>

<asp:TextBox ID=”AccountTextBox” runat=”server”

Width=”70%” />&nbsp;&nbsp;&nbsp;

<asp:Button ID=”SearchButton” runat=”server” Width=”26%”

Text=”Search” />

</td>

</tr>

- A warning label

<tr>

<td style=”color: Red”>

<asp:Literal ID=”WarningLabel” runat=”server” Visible=”false”

Text=”Please, fill out the name or a part of the name of the account you are looking for.” />

</td>

</tr>

- A dropdown list that will be populated with company names matching the search criterium:

<tr>

<td>Select CRM Account:</td>

</tr>

<tr>

<td>

<asp:DropDownList ID=”AccountDropDownList” runat=”server”

AutoPostBack=”true” CssClass=”ms-RadioText”

Width=”100%” Enabled=”false”>

<asp:ListItem>Select an account…</asp:ListItem>

</asp:DropDownList>

<asp:TextBox ID=”CompanyNameTextBox” runat=”server” Width=”100%”

Enabled=”false” Visible=”false” />

<asp:TextBox ID=”AccountIdTextBox” runat=”server” Visible=”false” />

</td>

</tr>

The company name text box is there for editing purposes and stays hidden when a SharePoint list item is created.

- The literals and text boxes for the display of the account details. These controls stay hidden until an account is selected from the dropdown list.

<tr>

<td>

<asp:Literal ID=”AddressLiteral” runat=”server” Visible=”false”

Text=”Address details:” />

</tr>

<tr>

<td>

<asp:TextBox ID=”AddressTextBox” runat=”server” Visible=”false”

Width=”100%” Enabled=”false” />

</td>

</tr>

<tr>

<td>

<asp:TextBox ID=”PostalCodeTextBox” runat=”server” Visible=”false”

Width=”30%” Enabled=”false” />&nbsp;&nbsp;&nbsp;<asp:TextBox

ID=”CityTextBox” runat=”server” Visible=”false” Width=”67%”

Enabled=”false” />

</td>

</tr>

<tr>

<td>

<asp:TextBox ID=”CountryTextBox” runat=”server” Visible=”false”

Width=”100%” Enabled=”false” />

</td>

</tr>

Developing the Field Value Class

Now we can start the development of the different classes. Add a reference to the System.Web.dll and to the Microsoft.SharePoint.dll.

The first class we will develop is the Field Value class. This class is only needed in case of complex custom fields, meaning that they cannot be derived from SharePoint types like SPFieldText, SPFieldNumber or SPFieldBoolean. The Field Value class defines the structure in which the data must be stored.

Add a class to the root of the Visual Studio project. This class must derive from the SharePoint base class SPFieldMultiColumnValue. This class is an internal class and is not visible to users. Our custom data structure will contain values for the AccountId, CompanyName, Address, PostalCode, City and Country.

In this class we need to override two constructors. The first constructor is the default constructor with no parameters. You have to pass the number of fields in this field value class to the base constructor. Additionally the properties are initialized to an empty string. The second constructor to override accepts a string value as parameter, which must also be passed to the base constructor. The parameter is an initial value of the field. Internally it is split into an array.

Then 6 properties are defined. The property returns or stores a value from a certain position in the internal array. In this custom field all properties are of type string but they can also be of other data types like integer, decimal, etc. Only the AccountId property is shown in the code sample but the complete definition can be found in the source code.

class CRMAccountFieldValue : SPFieldMultiColumnValue

{

private const int NUMBER_FIELDS = 6;

public CRMAccountFieldValue()

: base(NUMBER_FIELDS)

{

AccountId = string.Empty;

CompanyName = string.Empty;

Address = string.Empty;

PostalCode = string.Empty;

City = string.Empty;

Country = string.Empty;

}

public CRMAccountFieldValue(string value)

: base(value)

{

}

public string AccountId

{

get { return this[0]; }

set { this[0] = value; }

}

//other properties are omitted for brievety

}

Developing the Field Control Class

Next step is developing the Field Control class. This class is responsible for the rendering and proper functioning of the user interface. It will hide and show controls when necessary, it will add event handlers to the buttons and execute the code behind these event handlers.

Add a second class to the root of the Visual Studio project and let it derive from BaseFieldControl. This internal class renders the field on a form page.

Override the DefaultTemplateName property and pass it the value in the ID attribute of the RenderingTemplate control from the ascx control.

protected override string DefaultTemplateName

{

get { return “CRMAccountControl”; }

}

With this value SharePoint will look into all control templates located in the 12\TEMPLATE\CONTROLTEMPLATES folder and render the corresponding control template.

Add the necessary using statements:

using System.Web.UI.WebControls;

using Microsoft.SharePoint;

using Microsoft.SharePoint.WebControls;

Each control defined in the ascx control will also be defined in this class:

protected TextBox AccountTextBox;

protected Button SearchButton;

protected Literal WarningLabel;

protected DropDownList AccountDropDownList;

protected Literal AddressLiteral;

protected TextBox AccountIdTextBox;

protected TextBox CompanyNameTextBox;

protected TextBox AddressTextBox;

protected TextBox CityTextBox;

protected TextBox CountryTextBox;

protected TextBox PostalCodeTextBox;

You also need to override the CreateChildControl method:

protected override void CreateChildControls()

{

if (this.Field == null

|| this.ControlMode == SPControlMode.Display

|| this.ControlMode == SPControlMode.Invalid)

return;

base.CreateChildControls();

// get a reference to the different controls in the control template

AccountTextBox = TemplateContainer.FindControl(”AccountTextBox”) as TextBox;

if (AccountTextBox == null)

throw new ArgumentException(”Account text box not found. ”

+ “Please check if your control template is valid.”);

SearchButton = TemplateContainer.FindControl(”SearchButton”) as Button;

if (SearchButton == null)

throw new ArgumentException(”Search button not found. ”

+ “Please check if your control template is valid.”);

// add an event handler to this control

SearchButton.Click += new EventHandler(SearchButton_Click);

WarningLabel = TemplateContainer.FindControl(”WarningLabel”) as Literal;

if (WarningLabel == null)

throw new ArgumentException(”Warning label not found.” +

+ “Please check if your control template is valid.”);

AccountDropDownList =

TemplateContainer.FindControl(”AccountDropDownList”) as DropDownList;

if (AccountDropDownList == null)

throw new ArgumentException(”Account dropdown list not found. ”

+ “Please check if your control template is valid.”);

// add an event handler to this control

AccountDropDownList.SelectedIndexChanged +=

new EventHandler(AccountDropDownList_SelectedIndexChanged);

AddressLiteral = TemplateContainer.FindControl(”AddressLiteral”) as Literal;

if (AddressLiteral == null)

throw new ArgumentException(”AddressLiteral literal not found. ”

+ “Please check if your control template is valid.”);

// The rest of the controls is omitted for brievety.

// …

}

The first statement is a validation of the display mode of the field. When a new item is created, the display mode of the field is New. When an item is viewed, the display mode of the field is Display. When an item is edited, its display mode is Edit. In this sample the rendering of the user control will only take place when the field is in Edit or Display mode. This specific rendering will also only take place when the list item containing a column of this type is created or edited. How the field is rendered when in display mode will explained later in this article.

Then each control is looked up in the user control. The TemplateContainer property, which is a member of the BaseFieldControl base class, contains a reference to the RenderingTemplate control. Use the FindControl method to get the instance of each control. If the instance of a control cannot be found, throw an exception.

The code sample also adds a Click event handler to the Search button and a SelectedIndexChanged event handler to the account dropdown list. The implementation of these event handlers will be explained a bit later in this section.

Another property to override is the Value property. It gets or sets the value of the field in the user interface.

public override object Value

{

get

{

EnsureChildControls();

CRMAccountFieldValue field = new CRMAccountFieldValue();

// set the account value

bool fillout = false;

if (AccountDropDownList != null && AccountDropDownList.SelectedIndex > 0)

{

fillout = true;

field.CompanyName = AccountDropDownList.SelectedItem.Text;

field.AccountId = AccountDropDownList.SelectedValue;

}

else if (CompanyNameTextBox.Visible && CompanyNameTextBox.Text.Length > 0

&& AccountIdTextBox.Text.Length > 0)

{

fillout = true;

field.CompanyName = CompanyNameTextBox.Text;

field.AccountId = AccountIdTextBox.Text;

}

if (fillout)

{

field.Address = AddressTextBox.Text;

field.City = CityTextBox.Text;

field.Country = CountryTextBox.Text;

field.PostalCode = PostalCodeTextBox.Text;

}

return field;

}

set

{

EnsureChildControls();

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

{

CRMAccountFieldValue field =

new CRMAccountFieldValue(value.ToString());

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

{

AccountIdTextBox.Text = field.AccountId;

CompanyNameTextBox.Text = field.CompanyName;

AddressTextBox.Text = field.Address;

CityTextBox.Text = field.City;

CountryTextBox.Text = field.Country;

PostalCodeTextBox.Text = field.PostalCode;

}

SetControlVisibility(field.AccountId);

}

else

{

SetControlVisibility(Guid.Empty.ToString());

}

}

}

The getter executes a call to the EnsureChildControls. This method checks if the child controls are already created. If not it creates the child controls. A new object of type CRMAccountFieldValue is created and all fields are filled out based on values in the account dropdown list or the company name text box. If the control is in New mode the account dropdown list will be visible. If an account is selected, the values for the other properties can be set. If the control is in Edit mode the company name text box is visible. If a company is filled out the values for the other properties can be set.

The setter also calls the EnsureChildControls method. Then the validation of the incoming value takes place. If the value is not null or empty, an object of type CRMAccountFieldValue is created and the incoming value is passed in. If a value comes in, it means that the list item is in Edit mode. In that case a certain number of text boxes are filled out. The visibility of the different controls is handled in the private method SetControlVisibility and is based on the value of the account id and whether the item is in Edit mode or in New mode.

private void SetControlVisibility(string accountID)

{

if (accountID == Guid.Empty.ToString())

{

// this means that no account is selected

AccountDropDownList.Visible = true;

CompanyNameTextBox.Visible = false;

AddressLiteral.Visible = false;

AddressTextBox.Visible = false;

CityTextBox.Visible = false;

CountryTextBox.Visible = false;

PostalCodeTextBox.Visible = false;

}

else

{

switch (this.ControlMode)

{

case SPControlMode.New:

// this means another country is selected

PopulateCRMAccountDetails(accountID);

AccountDropDownList.Visible = true;

CompanyNameTextBox.Visible = false;

break;

case SPControlMode.Edit:

AccountDropDownList.Visible = false;

CompanyNameTextBox.Visible = true;

break;

}

AddressLiteral.Visible = true;

AddressTextBox.Visible = true;

CityTextBox.Visible = true;

CountryTextBox.Visible = true;

PostalCodeTextBox.Visible = true;

}

}

If the account id is empty, the account dropdown list is made visible and the address detail controls are hidden. If the account id contains a value all address detail controls are made visible. Additionally if the control is in New mode, account details are looked up in the CRM database via the Business Data Catalog. The account dropdown list is kept visible and the company name text box is hidden. If the control is in Edit mode, the account dropdown list is hidden and the company name text box is shown.

Next implement the Click event handler for the Search button. If the user filled out a value in the account text box, all accounts containing that string in their company name are returned and listed in the account dropdown list. For this purpose the private method PopulateCRMAccounts is called. This method will be explained in detail in a moment. If the account text box is empty, no lookup in the CRM database can be performed and a warning is displayed.

void SearchButton_Click(object sender, EventArgs e)

{

if (AccountTextBox.Text.Length > 0)

{

WarningLabel.Visible = false;

AccountDropDownList.Enabled = true;

PopulateCRMAccounts(AccountTextBox.Text);

}

else

{

WarningLabel.Visible = true;

AccountDropDownList.Enabled = false;

}

SetControlVisibility(Guid.Empty.ToString());

}

Now implement the event handler for the SelectedIndexChanged event of the account dropdown list. This method ensures that the child controls are created and calls the SetControlVisibility method passing the selected account to it.

void AccountDropDownList_SelectedIndexChanged(object sender, EventArgs e)

{

EnsureChildControls();

SetControlVisibility(AccountDropDownList.SelectedValue);

}

The PopulateCRMAccounts method accepts one argument containing a company name or part of a company name. This method uses the Business Data Catalog object model to populate the account dropdown list. Therefore you need to add a reference to the Microsoft.Office.Server.dll and the Microsoft.SharePoint.Portal.dll. Both assemblies are located in the 12\ISAPI folder of SharePoint. Add also the following using statements at the top of this class file.

using Microsoft.Office.Server.ApplicationRegistry.Infrastructure;

using Microsoft.Office.Server.ApplicationRegistry.MetadataModel;

using Microsoft.Office.Server.ApplicationRegistry.SystemSpecific.Db;

using Microsoft.Office.Server.ApplicationRegistry.Runtime;

The Business Data Catalog is instantiated and the method GetAccounts method on the Account entity is executed. More detailed information on the BDC object model can be found in Chapter 6 of Patrick Tisseghems book Inside Search.

private void PopulateCRMAccounts(string partName)

{

AccountDropDownList.Items.Clear();

AccountDropDownList.Items.Add(”Select an account…”);

//connect to the LobSystemInstance that represents the CRM business

// application in the BDC

NamedLobSystemInstanceDictionary instances =

ApplicationRegistry.GetLobSystemInstances();

LobSystemInstance instance = instances["CRM_Accounts_Instance"];

// Connect to the CRM account entity

Entity entity = instance.GetEntities()["Account"];

// Find and execute the method to get a set of accounts returned

Method method = entity.GetMethods()["GetAccounts"];

MethodInstance methodinstance =

method.GetMethodInstances()["GetAccountsInstance"];

FilterCollection filters = method.GetFilters(methodinstance);

WildcardFilter filter = (WildcardFilter)filters[0];

filter.Value = string.Format(”%{0}%”, AccountTextBox.Text);

DbEntityInstanceEnumerator accounts =

(DbEntityInstanceEnumerator)entity.FindFiltered(filters, instance);

// loop through the accounts and populate the accounts dropdown

while (accounts.MoveNext())

{

DbEntityInstance account = (DbEntityInstance)accounts.Current;

AccountDropDownList.Items.Add(

new ListItem(account.GetFormatted(”name”).ToString(),

account.GetFormatted(”accountid”).ToString()));

}

}

The PopulateCRMAccountDetails method accepts an account id as incoming argument. The account details are looked up via the BDC by executing the GetAccount method of the CRM Account entity.

private void PopulateCRMAccountDetails(string accountId)

{

// connect to the LobSystemInstance that represents the CRM Accounts

// business application in the BDC

NamedLobSystemInstanceDictionary instances =

ApplicationRegistry.GetLobSystemInstances();

LobSystemInstance instance = instances["CRM_Accounts_Instance"];

// Connect to the CRM Account entity

Entity entity = instance.GetEntities()["Account"];

// Find and execute the method to get the account details

Method method = entity.GetMethods()["GetAccount"];

MethodInstance methodinstance =

method.GetMethodInstances()["GetAccountInstance"];

Object[] args = methodinstance.GetMethod().CreateDefaultParameterInstances(

methodinstance);

args[0] = accountId;

DbEntityInstanceEnumerator accounts =

(DbEntityInstanceEnumerator)entity.Execute(methodinstance,

instance, ref args);

// As account id is used to find account details, you can be sure only one

// account is returned

accounts.MoveNext();

DbEntityInstance account = (DbEntityInstance)accounts.Current;

AddressTextBox.Text = account.GetFormatted(”address1_line1″).ToString();

PostalCodeTextBox.Text =

account.GetFormatted(”address1_postalcode”).ToString();

CityTextBox.Text = account.GetFormatted(”address1_city”).ToString();

CountryTextBox.Text = account.GetFormatted(”address1_country”).ToString();

}

Developing the Field Type Class

Now it is time to create the Field Type class, which is the coordinating class of the custom field. Add another class to the Visual Studio project and let it derive from SPFieldMultiColumn because the value of this field consist of more than one column.

Implement two constructors:

public CRMAccountField(SPFieldCollection fields, string fieldName)

: base(fields, fieldName)

{

}

public CRMAccountField(SPFieldCollection fields, string typeName,

string displayName)

: base(fields, typeName, displayName)

{

}

Then override the GetFieldValue method. This is necessary to make the custom field type aware that there is a Field Value class. If the incoming string is not null or empty an instance of type CRMAccountFieldValue is created.

public override object GetFieldValue(string value)

{

if (string.IsNullOrEmpty(value))

return null;

return new CRMAccountFieldValue(value);

}

Then override the FieldRenderingControl property and return a control of type CRMAccountFieldControl to indicate which control to render for this custom field type.

public override BaseFieldControl FieldRenderingControl

{

get

{

BaseFieldControl control = new CRMAccountFieldControl();

control.FieldName = this.InternalName;

return control;

}

}

Also override the GetValidatedString method. In this method you can check whether the user has set a column of this custom type as required. If so, the field should contain a value. If the column of this type contains a value, check that the value is of the correct type, i.e. CRMAccountFieldValue.

If the value is of the correct type and the column is defined as required, check that a company has been selected.

public override string GetValidatedString(object value)

{

if (value == null)

{

if (this.Required) throw new SPFieldValidationException(

“Invalid value for required field.”);

return string.Empty;

}

else

{

CRMAccountFieldValue field = value as CRMAccountFieldValue;

// if no value obtained, error in the field

if (field == null) throw new ArgumentException(”Invalid value.”);

// if the field is defined as required field

if (this.Required)

{

// make sure that a company is selected

if (string.IsNullOrEmpty(field.CompanyName))

throw new SPFieldValidationException(

“A CRM account is required.”);

}

return value.ToString();

}

}

All code has been written now. Sign your assembly and build it.

Creating the Field Type definition

The custom field type definition is an XML file that contains CAML markup to inform SharePoint about the existence of the custom field type.

Each time SharePoint loads it checks the 12\TEMPLATE\XML directory for XML files containing field type definitions. Field type definitions always start with the CAML element <FieldTypes>. Within that root element one or more <FieldType> elements can occur. The <Field> elements contain necessary information for SharePoint like the name of the field, the parent field type, the display name and a reference to the assembly and Field Type class.

The <RenderPattern> element in this example contains rendering information for the field when it is in display mode. Columns 1, 4 and 5 will be shown separated by a comma. Going back to the Field Type Value class you will see that these are the column numbers for the company name, the city and the country.

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

<FieldTypes>

<FieldType>

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

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

<Field Name=”TypeDisplayName”>CompanyName, city</Field>

<Field Name=”FieldEditorUserControl”>CRMAccountControl</Field>

<Field Name=”TypeShortDescription”>

CRM account custom field containing Company name and address information.

</Field>

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

<Field Name=”FieldTypeClass”>U2U.SharePoint.CRM.CustomFields.CRMAccountField, U2U.SharePoint.CRM.Account.CustomFields, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b014aa8fd23dd3de</Field>

<RenderPattern Name=”DisplayPattern”>

<Switch>

<Expr>

<Column />

</Expr>

<Case Value=”" />

<Default>

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

<HTML><![CDATA[,&nbsp;]]></HTML>

<Column SubColumnNumber=”4″ HTMLEncode=”TRUE” />

<HTML><![CDATA[,&nbsp;]]></HTML>

<Column SubColumnNumber=”5″ HTMLEncode=”TRUE” />

</Default>

</Switch>

</RenderPattern>

</FieldType>

</FieldTypes>

It is a good practice toAlways prefix the file name of your own custom field types with fldtypes_. For this custom field type I gave it the name fldtypes_crm_account.xml.

Deploying the custom field

Now it is time to deploy the custom field. There are 3 steps to perform:

- The assembly for the custom field needs to be deployed in the global assembly cache.

- The ascx control needs to be copied to the 12\TEMPLATE\CONTROLTEMPLATES directory.

- The fldtypes_crm_account.xml file needs to be copied to the 12\TEMPLATE\XML directory.

Perform an IISRESET because or recycleing the application pool will not be sufficient for SharePoint to load the new custom field into SharePoint.

Testing the custom field

Open your SharePoint site and create a new custom list. Add a field or two, and the CRM account custom field.

Add a new item to the list. Fill out part of a company name and click the Search button. Select an account from the dropdown list and the account details will be displayed.

display CRM data

SharePoint Custom Field: display CRM data

If you didn’t fill out part of a company name before clicking the Search button, you get a warning that the search could not be performed.

Fill out part of the company name

SharePoint custom field type: Fill out part of the company name

When the item is added and you are returned to the All Items view, you will see that the custom field displays company name, city and country, as you defined in the DisplayPattern of the field definition.

SharePoint List View

SharePoint List View

Try to edit the item. You will notice that all account details are filled out and that the company name is displayed in a text box. If you want to change the value of the custom field, you can simply fill out part of the new company name and execute a search. The account combo box will be shown populated with account, from where you can select another account.

Downloads

A zip file containing:

- Application definition file

- Source code

Download the Soure Code

This entry was posted on Monday, August 4th, 2008 at 1:01 pm and is filed under Development. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
About the Author

Boske

Ten years ago I started my career as Visual Basic developer but as soon as .NET came out I started developing in VB.NET and C#. In 2002 I started working for a Belgian company U2U, specialized in .NET and SharePoint training. I did some consultancy work on SharePoint 2003 but once SharePoint 2007 released I started working full time on WSS and MOSS.

Contact the author | Other Posts by Karine Bosch (3) | Author's Website

Viewing 9 Comments

 

Trackbacks

(Trackback URL)

close Reblog this comment
blog comments powered by Disqus


SharePoint Magazine

Support SharePoint Magazine

Technical

Everything You Need to Know about BDC: Part 3 of 8

Products

Visual Fusion Brings Location Intelligence to SharePoint

People

SharePoint Magazine chats with Paul Culmsee