dinsdag 12 januari 2010

Custom people field in SharePoint 2007

Some time ago I needed to create a people field which had to have a default value. The default value had to be the current user. This is not possible out of the box so I needed to create a custom field type for this. Because there was very little information on creating a custom people field on the net, I will explain the method in this post.

1. Create the custom field xml
This file needs to go in 12/TEMPLATE/XML. Make sure it starts with 'fldtypes_'. I will call it 'fldtypes_customPeopleField'.

Here is the xml. It will describe some properties of this field like the type name, displayname and the class which will take care of the actual logics.

   1: <?xml version="1.0" encoding="utf-8"?>



   2: <FieldTypes>



   3: <FieldType>



   4: <Field Name="TypeName">CurrentUserAsDefault</Field>



   5: <Field Name="ParentType">User</Field>



   6: <Field Name="TypeDisplayName">Current User</Field>



   7: <Field Name="TypeShortDescription">People field with current user as default value</Field>



   8: <Field Name="UserCreatable">TRUE</Field>



   9: <Field Name="ShowInListCreate">TRUE</Field>



  10: <Field Name="ShowInSurveyCreate">TRUE</Field>



  11: <Field Name="ShowInDocumentLibrary">TRUE</Field>



  12: <Field Name="ShowInColumnTemplateCreate">TRUE</Field>



  13: <Field Name="FieldTypeClass">MyProject.ContentTypes.CurrentUserField, MyProject.ContentTypes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f443cebe7d24f267</Field>



  14: <Field Name="FieldEditorUserControl">/_controltemplates/UserFieldEditor.ascx</Field>



  15: <Field Name="Sortable">TRUE</Field>



  16: <Field Name="Filterable">TRUE</Field>



  17: <RenderPattern Name="DisplayPattern">



  18: <FieldSwitch>



  19: <Expr>



  20: <Property Select="FieldRef"/>



  21: </Expr>



  22: <Case Value="">



  23: <Switch>



  24: <Expr>



  25: <Column/>



  26: </Expr>



  27: <Case Value="">



  28: <FieldSwitch>



  29: <Expr>



  30: <Property Select="SuppressNameDisplay"/>



  31: </Expr>



  32: <Case Value="TRUE">



  33: <HTML><![CDATA[<table cellpadding=0 cellspacing=0 dir="]]></HTML>



  34: <Property Select="Direction" HTMLEncode="TRUE"/>



  35: <HTML><![CDATA["><tr><td style="padding-right: 3px;">]]></HTML>



  36: <HTML><![CDATA[ <img border="0" valign="middle" height="12" width="12" src="/_layouts/images/blank.gif" > </td></tr></table>]]></HTML>



  37: </Case>



  38: </FieldSwitch>



  39: </Case>



  40: <Default>



  41: <FieldSwitch>



  42: <Expr>



  43: <Property Select="LookupType"/>



  44: </Expr>



  45: <Case Value="Computed">



  46: <LookupColumn/>



  47: </Case>



  48: <Default>



  49: <LookupColumn HTMLEncode="TRUE"/>



  50: </Default>



  51: </FieldSwitch>



  52: </Default>



  53: </Switch>



  54: </Case>



  55: <Default>



  56: <LookupColumn HTMLEncode="TRUE"/>



  57: </Default>



  58: </FieldSwitch>



  59: </RenderPattern>



  60: </FieldType>



  61: </FieldTypes>







2. Create the logic


For the actual logics, I will create a class which inherits from SPFieldUser and I will override the 'DefaultValue' property.









   1: namespace MyProject.ContentTypes



   2:  



   3: {



   4:  



   5: public class CurrentUserField : SPFieldUser



   6: {



   7:  



   8: public CurrentUserField(SPFieldCollection fields, string fieldName, string displayname) : base(fields, fieldName, displayname){}



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



  10:  



  11: public override string DefaultValue



  12: {



  13:  



  14: get



  15: {



  16:  



  17: SPWeb web = SPContext.Current.Web;



  18:  



  19: SPUser user = web.CurrentUser;



  20:  



  21: string defaultValue = string.Format("{0};#{1}", user.ID.ToString(), user.Name);



  22:  



  23: if (this.SelectionGroup > 0)



  24: {



  25:  



  26: SPGroup group = web.Groups[this.SelectionGroup];



  27:  



  28: if ((group != null) && (group.ContainsCurrentUser))



  29:  



  30:    return defaultValue;



  31:  



  32: }



  33: else



  34: {



  35:  



  36:    return defaultValue;



  37:  



  38: }



  39:  



  40:    return string.Empty;



  41:  



  42: }



  43:  



  44: set



  45: {



  46:  



  47:    base.DefaultValue = value;



  48:  



  49: }



  50:  



  51: }



  52:  



  53: }



  54:  



  55: }








What it will do is set the current user as the default value. The setter we will leave untouched and therefore we just use the one from SPFieldUser.





3. Using the custom field


You can now use this custom field to create a custom column:









   1: <Field



   2:     Type="CurrentUserAsDefault"



   3:     DisplayName="My Custom User Field"



   4:     List="UserInfo"



   5:     ShowField="ImnName"



   6:     UserSelectionMode="0"



   7:     UserSelectionScope="0"



   8:     Group="Custom"



   9:     ID="{0ab09806-9434-4e11-bedd-d232614089b2}"



  10:     SourceID="{ac48197d-8e5a-4207-bf24-6615f4bb857f}"



  11:     StaticName="CurrentUserAsDefault"



  12:     Name="CurrentUserAsDefault"



  13: />





4. Deployment


Just create a wsp solution file and make sure the field xml is placed in the correct folder. Normally this field type should also popup in the GUI when you want to create a new site column.





5. Sidenotes


I have understood that this custom field (and possibly all custom fields) are not supported by Colligo, an offline tool for SharePoint. By not supported I mean I wasn't able to update this field. It was just read-only. Just so you know :) .

5 opmerkingen: