in

SharePoint Blogs

The Best Place for SharePoint-related Blogs

Tech MOSS Team

SharePoint Programmatically: Provisioning Lookup Fields

Provisioning Content Type’s fields is quite straight forward when using Solutions: using Element Manifests you can define your own Content Types and their properties among which fields. Unfortunately there is one serious con to the solution Microsoft has offered: you simply cannot provision any Lookup Field using the Element Manifest.

Lookup Fields obtain their values from an existing list. Each Lookup Field is being linked to its list using the list’s ID. As the ID’s are being generated after creating the instances there is no way to provision a Lookup Field linked to a newly created list during Solution deployment. That’s when Feature Receivers are useful. Feature Receivers are nothing more than custom code you can attach to events triggered by a feature. Provisioning a custom field programmatically works exactly the same as doing it using the GUI: first you need to create a Site Column and then you need to attach it to the Content Type of your choice.

Assuming you have a solution with a feature called ContentDefinition responsible for deploying List Templates, provisioning List Instances and creating Site Columns and Content Types. It would look something close to:

<Feature Id="GUID"
              Title="Content Definition"
              Description="Configures content definition"
              Version="1.0.0.0"
              Scope="Site"
              Hidden="FALSE"
              xmlns="http://schemas.microsoft.com/sharepoint/">
       <ElementManifests>
              <ElementManifest Location="SiteColumns\SiteColumns.xml"/>
              <ElementManifest Location="ContentTypes\ContentTypes.xml"/>
 
              <!-- Lists -->
 
              <!-- Custom List -->
              <ElementFile Location="CustomList\schema.xml"/>
              <ElementFile Location="CustomList\AllItems.aspx"/>
              <ElementFile Location="CustomList\DispForm.aspx"/>
              <ElementFile Location="CustomList\EditForm.aspx"/>
              <ElementFile Location="CustomList\NewForm.aspx"/>
              <ElementManifest Location="CustomList\Elements.xml"/>
       </ElementManifests>
</Feature>

First of all you provision your Site Columns and Content Types. Then you deploy a custom List Definition and using Elements.xml you create a new instance of that list.

To make use of Feature Receivers you need to extend the Feature element with two attributes: ReceiverClass en ReceiverAssembly:

<Feature Id="GUID"
              Title="Content Definition"
              Description="Configures content definition"
              Version="1.0.0.0"
              Scope="Site"
              Hidden="FALSE"
              xmlns="http://schemas.microsoft.com/sharepoint/"

              ReceiverAssembly="Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=keytoken"
              ReceiverClass="Assembly.ContentDefinitionFeatureReceiver">

Now you can proceed to create the ContentDefinitionFeatureReceiver class. First of all inherit from the Microsoft.SharePoint.SPFeatureReceiver class. Then override the event you want to use: as for Fields provisioning you should use the FeatureActivated synchronous event.

As I have already mentioned you need to complete two steps in order to provision a Lookup Field: you have to create a new Site Column and then add it to the desired Content Type. The best approach is to create separate methods to complete both tasks as you might need to provision multiple Lookup Fields.

public static SPFieldLookup CreateLookupField(string fieldName, string group, bool required, bool allowMultipleValues, SPWeb w, SPList lookupList, string lookupField)
{
       w.Fields.AddLookup(fieldName, lookupList.ID, lookupList.ParentWeb.ID, required);
       SPFieldLookup lookup = (SPFieldLookup)w.Fields[fieldName];
       lookup.AllowMultipleValues = allowMultipleValues;
       lookup.LookupField = lookupField;
       lookup.Group = group;
       lookup.Update(true);
       return lookup;
}

You can use this method like this:

SPFieldLookup lookup = CreateLookupField("CustomLookup", "Custom fields", false, false, SPContext.Current.Site.RootWeb, SPContext.Current.Site.AllWebs["MyWeb"].Lists["CustomList"], "Title");

The next step is to link the created Lookup Field to the existing Content Type:

public static void LinkFieldToContentType(SPWeb web, string contentType, SPField field)
{
       SPContentType ct = web.ContentTypes[contentType];
       ct.FieldLinks.Add(new SPFieldLink(field));
       ct.Update();
}

As we have just created a method returning the created Lookup Field all we have to do is to call the LinkFieldToContentType method with the created field passed as parameter:

LinkFieldToContentType(SPContext.Current.Site.RootWeb, "MyContentType", (SPField)lookup);

It is important you pass the root web as the web parameter: it’s the web containing the definitions of your Content Types.

And that’s all. As both of the methods are static you could incorporate them in a Utility class and make use of them in any of your receiver classes.

Comments

 

Links (9/6/2007) « Steve Pietrek’s SharePoint Stuff said:

Pingback from  Links (9/6/2007) &laquo; Steve Pietrek&#8217;s SharePoint Stuff

September 6, 2007 7:29 PM
 

Driebier.net said:

Strong-typed provisioning of custom lists in Sharepoint 2007

October 13, 2007 7:08 AM
 

Antoine Pichot said:

Great Job Waldek,

I've also discussed about an association between a lookup field a a list, via a feature.

If you please, you can go there

apichot.blogspot.com/.../sharepoint-2007-create-field-lookup-and.html

November 23, 2007 2:35 PM
 

Manas R Moharana said:

it was a greate post. and it is working perfectly but one problem is when we select multiple value from lookup field the result  always defferent .mean some time it take 2 value some time it is taking 3 .and it is taking value on its own.

plz tell me why it is happning . and can we do it by using  xml file.

ok

thanks once again for this post.

can

January 11, 2008 2:32 AM
 

Manas R Moharana said:

in the preveous comment  ,bymistake i have specify wrong mail id.as ( mmoharana@leveernt.com)

thecorrect one is mmoharana@leverent.com

January 11, 2008 2:37 AM
 

TimR said:

On www.it-dev.pl/.../SharePoint_DSL_ToolKit.aspx there is a DSL addin to Visual Studio to model CAML schema including lookups, but there is little information except screencast. I asked about demo and I'm waiting.

April 18, 2008 6:22 PM
 

Creating Lookup Columns Using Features in SharePoint 2007 « Rusty’s SharePoint Blog said:

Pingback from  Creating Lookup Columns Using Features in SharePoint 2007 &laquo; Rusty&#8217;s SharePoint Blog

July 8, 2008 7:08 PM
 

david said:

you can also look at infowise product - Infowise Connected Fields - its also a manipulation of MOSS lookup fields

www.infowise.co.il/Product_ConnectedFields_2007.aspx

August 31, 2008 8:57 AM

Leave a Comment

(required )  
(optional )
(required )  
Add

About Waldek Mastykarz

Waldek Mastykarz is a Dutch SharePoint 2007 developer specialized in Web Content Management solutions in Microsoft Office SharePoint Server 2007, web standards and accessibility.

Need SharePoint Training? Attend a SharePoint Bootcamp!

Posts (c) their respective authors. Everything else (c) 2007 SharePoint Experts