Provision lookup field using CAML

There are lots of blog posts about how to create a lookup SiteColumn using Declaratively and Programmatically but i found following two post very useful and point me in right direction.
http://blogs.msdn.com/b/joshuag/archive/2008/03/14/add-sharepoint-lookup-column-declaratively-through-caml-xml.aspx?PageIndex=2#comments
http://pholpar.wordpress.com/2010/05/14/declaratively-adding-a-lookup-field-to-a-list-schema-using-the-name-of-the-referenced-list/
Peter Holpar blog post explain how to create a Lookup Filed using Custom list Definition but in my case i don’t want to create a custom definition as i need to Create  lookup to list based on Custom List Definition and that’s where CustomSchema attribute which is only available in sharepoint 2010  comes into picture.you can read about it in more details from Stefan Stanev nice blog post from here
http://stefan-stanev-sharepoint-blog.blogspot.com/2010/03/sharepoint-2010-listinstance.html?showComment=1303912623484#c1919163525190422580
Alright now i want to Create two list called Product and Category based on Custom list Definition and Create a CategoryName column as lookup to Category list and use it in Product list.simple you can do it through UI but there is no fun in that and also its not good practice in deployment point of view so lets do it using features.

First Create Empty sharepoint Project in Visual Studio 2010 and Select Deploy as Sandbox Solutions in my case its LookupSiteColumn.Now add New Item called EmptyElement to create siteColumns and give it name Fields.Now open Elements.xml and write CAML to Create Columns you need. In my case i need Columns called CategoryID(Number),ProductID(Number) and CategoryName(Lookup to CategoryList).

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Field ID="{99C917A4-156E-46B9-9CAF-2FFC7FE7C5C3}"
       Name="CategoryID"
       StaticName="CategoryID"
       SourceID="http://schemas.microsoft.com/sharepoint/v3"
       DisplayName="CategoryID"
       Type="Number"
       Required="FALSE" ReadOnly="FALSE"
       Sealed="FALSE" Hidden="FALSE"
       Group="Custom Columns">
  </Field>
  <Field ID="{7E703095-633A-450C-968C-9C886FD9013E}"
     Name="ProductID"
     StaticName="ProductID"
     SourceID="http://schemas.microsoft.com/sharepoint/v3"
     DisplayName="ProductID"
     Type="Number"
     Required="FALSE" ReadOnly="FALSE"
     Sealed="FALSE" Hidden="FALSE"
     Group="Custom Columns">
  </Field>
  <Field ID="{67146805-10A0-473F-971C-1B41BD36C4C5}"
         Name="CategoryName"
         StaticName="CategoryName"
         Group="Custom Columns"
         Type="Lookup"
         DisplayName="CategoryName"
         List="Lists/Category"
         ShowField="Title"
         PrependId="TRUE">
 </Field>
</Elements>

Now add two new Items Called Content Type to Create Content type for Product and Category based on Item Content type in Solution.in my case its looks like this
Category ContentType

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <!-- Parent ContentType: Item (0x01) -->
  <ContentType ID="0x0100c0a87e97a5ba4d22a1231c05253d7014"
               Name="Category"
               Group="Custom Content Types"
               Description=""
               Inherits="TRUE"
               Version="0">
    <FieldRefs>
      <FieldRef ID="{99C917A4-156E-46B9-9CAF-2FFC7FE7C5C3}" Name="CategoryID" />
      <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" DisplayName="Category" />
    </FieldRefs>
  </ContentType>
</Elements>

Product ContentType

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <!-- Parent ContentType: Item (0x01) -->
  <ContentType ID="0x0100dabceef503684c479fd5c2ae7d2e747d"
               Name="Product"
               Group="Custom Content Types"
               Description=""
               Inherits="TRUE"
               Version="0">
    <FieldRefs>
      <FieldRef ID="{7E703095-633A-450C-968C-9C886FD9013E}" Name="ProductID" />
      <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" DisplayName="ProductName" />
      <FieldRef ID="{67146805-10A0-473F-971C-1B41BD36C4C5}" Name="CategoryName"/>
    </FieldRefs>
  </ContentType>
</Elements>

Now Lets Create two New List Instance item to Create List Instance for Product and Category list based on Custom list Definition.in my case i give them name called Product and Category.Now right click on Category list and add new xml file called schema.xml and set it Deployment Type Property to ElementFile and do same step for Product.
Category LisInstance Elements.xml looks like this

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <ListInstance Title="Category"
                OnQuickLaunch="FALSE"
                TemplateType="100"
                FeatureId="00bfea71-de22-43b2-a848-c05709900100"
                Url="Lists/Category"
                Description="A list to store Category for Products." 
                CustomSchema="Category\schema.xml">
  </ListInstance>
</Elements>

Category list schema.xml file looks like this

<?xml version="1.0" encoding="utf-8"?>
<List xmlns:ows="Microsoft SharePoint" Title="Category" EnableContentTypes="TRUE" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/Category" BaseType="0" xmlns="http://schemas.microsoft.com/sharepoint/">
  <MetaData>
    <ContentTypes>
      <ContentType ID="0x0100c0a87e97a5ba4d22a1231c05253d7014" Name="Category" Group="Custom Content Types" Description="" Inherits="TRUE" Version="0">
        <FieldRefs>
          <FieldRef ID="{99C917A4-156E-46B9-9CAF-2FFC7FE7C5C3}" Name="CategoryID" />
          <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" DisplayName="Category" />
        </FieldRefs>
      </ContentType>
    </ContentTypes>
    <Fields>
      <Field ID="{99c917a4-156e-46b9-9caf-2ffc7fe7c5c3}" Name="CategoryID" StaticName="CategoryID" SourceID="http://schemas.microsoft.com/sharepoint/v3" DisplayName="CategoryID" Type="Number" Required="FALSE" ReadOnly="FALSE" Sealed="FALSE" Hidden="FALSE" Group="Custom Columns">
      </Field>
      <Field ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" DisplayName="Category" Type="Text" />
    </Fields>
    <Views>
      <View BaseViewID="0" Type="HTML" MobileView="TRUE" TabularView="FALSE">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="LinkTitleNoMenu">
          </FieldRef>
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="Modified" Ascending="FALSE">
            </FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="AddNewAnnouncement" Location="Resource(wss,addnewitem)" />
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_ONET_HOME)" />
        </ParameterBindings>
      </View>
      <View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;" DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" Url="AllItems.aspx">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="CategoryID"></FieldRef>
          <FieldRef Name="LinkTitle" DisplayName="Category"></FieldRef>
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="ID">
            </FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_DEFAULT)" />
        </ParameterBindings>
      </View>
    </Views>
    <Forms>
      <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
    </Forms>
  </MetaData>
</List>

Now most import thing as per Josh Gaffey’s Blog(first link at starting of post) is that in order for lookup Column to work, the URL specified in your schema.xml file MUST MATCH the List attribute on all your Field references in fields.xml and schema.xml. If these don’t match, it will not work.So as per my example Url Property from schema.xml file match with Url Property in List Instance and List Property in lookup column definition.

Product LisInstance Elements.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <ListInstance Title="Product"
                OnQuickLaunch="FALSE"
                TemplateType="100"
                FeatureId="00bfea71-de22-43b2-a848-c05709900100"
                Url="Lists/Product"
                Description="A list to store Products Information"
                CustomSchema="Product\schema.xml" >
  </ListInstance>
</Elements>

Product LisInstance schema.xml

<?xml version="1.0" encoding="utf-8"?>
<List xmlns:ows="Microsoft SharePoint" Title="ProductList" EnableContentTypes="TRUE" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/Product" BaseType="0" xmlns="http://schemas.microsoft.com/sharepoint/">
  <MetaData>
    <ContentTypes>
      <ContentType ID="0x0100dabceef503684c479fd5c2ae7d2e747d" Name="Product" Group="Custom Content Types" Description="" Inherits="TRUE" Version="0">
        <FieldRefs>
          <FieldRef ID="{7E703095-633A-450C-968C-9C886FD9013E}" Name="ProductID" />
          <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" DisplayName="ProductName" />
          <FieldRef ID="{67146805-10A0-473F-971C-1B41BD36C4C5}" Name="CategoryName" />
        </FieldRefs>
      </ContentType>
    </ContentTypes>
    <Fields>
      <Field ID="{7e703095-633a-450c-968c-9c886fd9013e}" Name="ProductID" StaticName="ProductID" SourceID="http://schemas.microsoft.com/sharepoint/v3" DisplayName="ProductID" Type="Number" Required="FALSE" ReadOnly="FALSE" Sealed="FALSE" Hidden="FALSE" Group="Custom Columns">
      </Field>
      <Field ID="{67146805-10a0-473f-971c-1b41bd36c4c5}" Name="CategoryName" StaticName="CategoryName" Group="Custom Columns" Type="Lookup" DisplayName="CategoryName" List="Lists/Category" ShowField="Title" PrependId="TRUE">
      </Field>
    </Fields>
    <Views>
      <View BaseViewID="0" Type="HTML" MobileView="TRUE" TabularView="FALSE">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="LinkTitleNoMenu">
          </FieldRef>
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="Modified" Ascending="FALSE">
            </FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="AddNewAnnouncement" Location="Resource(wss,addnewitem)" />
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_ONET_HOME)" />
        </ParameterBindings>
      </View>
      <View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;" DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" Url="AllItems.aspx">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="LinkTitle"></FieldRef>
          <FieldRef Name="CategoryName"/>
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="ID">
            </FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_DEFAULT)" />
        </ParameterBindings>
      </View>
    </Views>
    <Forms>
      <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
    </Forms>
  </MetaData>
</List>

Now time to create features to deploy siteColumns,Content Types and list instances.In my case i have created three web scope features like this
1.CategoryList to deploy Category ListInstance.

<Feature xmlns="http://schemas.microsoft.com/sharepoint/" Title="CategoryList " Id="f07763e7-4b4a-48c7-9da5-0b06f0f2706e" Scope="Web">
  <ElementManifests>
    <ElementManifest Location="Category\Elements.xml" />
    <ElementFile Location="Category\schema.xml" />
  </ElementManifests>
</Feature>

2.FieldsContentTypes to deploy SiteColumns and Content types and activation dependency to Category list.

<Feature xmlns="http://schemas.microsoft.com/sharepoint/" Title="FieldsContentTypes" Id="344f18a5-4a18-4bf0-861d-caca7b17fe99" Scope="Web">
  <ActivationDependencies>
    <ActivationDependency FeatureId="f07763e7-4b4a-48c7-9da5-0b06f0f2706e" FeatureTitle="CategoryList " />
  </ActivationDependencies>
  <ElementManifests>
    <ElementManifest Location="Fields\Elements.xml" />
    <ElementManifest Location="CategoryCT\Elements.xml" />
    <ElementManifest Location="ProductCT\Elements.xml" />
  </ElementManifests>
</Feature>

3.ProductList to deploy Product ListInstance.

<Feature xmlns="http://schemas.microsoft.com/sharepoint/" Title="ProductList" Id="de1999ac-404d-4c1d-9d02-669d125765de" Scope="Web">
  <ActivationDependencies>
    <ActivationDependency FeatureId="f07763e7-4b4a-48c7-9da5-0b06f0f2706e" FeatureTitle="CategoryList " />
    <ActivationDependency FeatureId="344f18a5-4a18-4bf0-861d-caca7b17fe99" FeatureTitle="FieldsContentTypes" />
  </ActivationDependencies>
  <ElementManifests>
    <ElementManifest Location="Product\Elements.xml" />
    <ElementFile Location="Product\schema.xml" />
  </ElementManifests>
</Feature>

Now build and deploy.Please leave comments if you find any errors
Thanks
Ronak

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s