Custom field nada mais é que um campo customizado para ser adicionado nas listas do sharepoint.
Por exemplo, eu tenho o campo “Pessoas ou grupos” no sharepoint, porém, por padrão, ele não tem uma opção para trazer automaticamente o usuário logado preenchido nesse campo, ao carregar “novo item” . Pesquisando sobre isso achei algumas soluções com java script e outras utilizando o custom field. Na minha opinião as soluções com custom field são melhores, uma vez que vc pode criar um campo específico para o que deseja. Já nas soluções com java script você precisa editar a webpart newform.aspx depois de inserida. Bom não vou entrar em detalhes sobre a solução com java script, a idéia aqui é falar um pouco da solução com o custom field.
Como criar um Custom Field
Inicialmente precisamos criar um XML , esse XML é o responsável por garantir que esse novo tipo de campo aparecerá para o usuário quando for criar uma nova coluna.
Exemplo de xml:
<?xml version="1.0" encoding="utf-8" ?>
<FieldTypes>
<FieldType>
<Field Name="TypeName">CurrentUserField</Field>
<Field Name="ParentType">User</Field>
<Field Name="TypeDisplayName">Current User</Field>
<Field Name="TypeShortDescription">Person or Group (Current user is default)</Field>
<Field Name="UserCreatable">TRUE</Field>
<Field Name="ShowInListCreate">TRUE</Field>
<Field Name="ShowInSurveyCreate">TRUE</Field>
<Field Name="ShowInDocumentLibraryCreate">TRUE</Field>
<Field Name="ShowInColumnTemplateCreate">TRUE</Field>
<Field Name="FieldTypeClass"> Test.Portal.TEMPLATE.CONTROLTEMPLATES.CurrentUserField.CurrentUserField, Test.Portal, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e4f816fa35933333</Field>
<Field Name="FieldEditorUserControl">/_controltemplates/UserFieldEditor.ascx</Field>
<PropertySchema>
</PropertySchema>
</FieldType>
</FieldTypes>
Explicando um pouco sobre as Tags acima:
· TypeName: Nome do tipo;
· ParentType: Todo custom field criado é baseado em um campo já esxistente;
· TypeDisplayName: Nome que será mostrado ao usuario quando criar uma coluna nova;
· TypeShortDescription: Descrição que será mostrada ao usuario quando criar uma nova coluna;
· FieldTypeClass: indica a dll e a classe para controle do custom field criado.
· FieldEditorUserControl: indica o ascx de edição para o custom field. Obs.: Nesse caso específico usamos um ascx já existente no sharepoint.
Ainda no XML, podemos adicionar recursos prontos do próprio sharepoint, como por exemplo esse custom field que vamos criar. Não muda nada em relação ao ascx que exibe o campo para editar ou visualizar, então podemos adicionar o código ao xml para indicar as paginas já existentes. Ficando dessa forma o XML:
<?xml version="1.0" encoding="utf-8" ?>
<FieldTypes>
<FieldType>
<Field Name="TypeName">CurrentUserField</Field>
<Field Name="ParentType">User</Field>
<Field Name="TypeDisplayName">Current User</Field>
<Field Name="TypeShortDescription">Person or Group (Current user is default)</Field>
<Field Name="UserCreatable">TRUE</Field>
<Field Name="ShowInListCreate">TRUE</Field>
<Field Name="ShowInSurveyCreate">TRUE</Field>
<Field Name="ShowInDocumentLibraryCreate">TRUE</Field>
<Field Name="ShowInColumnTemplateCreate">TRUE</Field>
<Field Name="FieldTypeClass">Test.Portal.TEMPLATE.CONTROLTEMPLATES.CurrentUserField.CurrentUserField, Test.Portal, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e4f816fa35933333</Field>
<Field Name="FieldEditorUserControl">/_controltemplates/UserFieldEditor.ascx</Field>
<PropertySchema>
</PropertySchema>
<RenderPattern Name="HeaderPattern">
<Switch>
<Expr>
<PresenceEnabled/>
<HTML>-</HTML>
<Property Select="ShowFieldImnHeader"/>
<GetVar Name="FileDialog"/>
</Expr>
<Default>
<Switch>
<Expr>
<Property Select="Sortable"/>
</Expr>
<Case Value="FALSE">
<Property Select='DisplayName' HTMLEncode="TRUE"/>
</Case>
<Default>
<Switch>
<Expr>
<Property Select='Filterable'/>
</Expr>
<Case Value="FALSE"> </Case>
<Default>
<Switch>
<Expr>
<GetVar Name='Filter'/>
</Expr>
<Case Value='1'>
<HTML><![CDATA[<SELECT ID="diidFilter]]></HTML>
<Property Select='Name'/>
<HTML> <![CDATA[" TITLE=]]></HTML>
<HTML>"$Resources:core,501;</HTML>
<Property Select='DisplayName' HTMLEncode='TRUE'/>
<HTML><![CDATA[" OnChange='FilterField("]]></HTML>
<GetVar Name="View"/>
<HTML><![CDATA[",]]></HTML>
<ScriptQuote>
<Property Select='Name' URLEncode="TRUE"/>
</ScriptQuote>
<HTML><![CDATA[,this.options[this.selectedIndex].value, this.selectedIndex);' dir="]]></HTML>
<Property Select="Direction" HTMLEncode="TRUE"/>
<HTML><![CDATA[">]]></HTML>
<FieldFilterOptions BooleanTrue="$Resources:core,fld_yes;" BooleanFalse="$Resources:core,fld_no;" NullString="$Resources:core,fld_empty;" AllItems="$Resources:core,fld_all;"></FieldFilterOptions>
<HTML><![CDATA[</SELECT><BR>]]></HTML>
</Case>
</Switch>
</Default>
</Switch>
<Switch>
<Expr>
<Property Select='Sortable'/>
</Expr>
<Case Value="FALSE">
<Property Select='DisplayName' HTMLEncode="TRUE"/>
</Case>
<Default>
<Switch>
<Expr>
<GetVar Name='SortDisable'/>
</Expr>
<Case Value='TRUE'>
<Property Select='DisplayName' HTMLEncode="TRUE"/>
</Case>
<Default>
<HTML><![CDATA[<A ID="diidSort]]></HTML>
<Property Select='Name'/>
<HTML> <![CDATA[" onfocus="OnFocusFilter(this)" TITLE=]]></HTML>
<HTML>"$Resources:core,500;</HTML>
<Property Select='DisplayName' HTMLEncode='TRUE'/>
<HTML><![CDATA[" HREF="javascript:" OnClick="javascript:return OnClickFilter(this,event);" ]]></HTML>
<HTML><![CDATA[ SORTINGFIELDS="]]></HTML>
<FieldSortParams HTMLEncode="TRUE"/>
<HTML><![CDATA[">]]></HTML>
<Property Select='DisplayName' HTMLEncode="TRUE"/>
<HTML><![CDATA[<img src="/_layouts/images/blank.gif" class="ms-hidden" border=0 width=1 height=1 alt="]]></HTML>
<HTML>$Resources:OpenMenuKeyAccessible;</HTML>
<HTML><![CDATA[">]]></HTML>
<HTML><![CDATA[</A><IMG SRC="]]></HTML>
<FieldSortImageURL/>
<HTML><![CDATA[" ALT="]]></HTML>
<Switch>
<Expr>
<GetVar Name='SortDir'/>
</Expr>
<Case Value='Asc'>
<HTML>$Resources:core,150;</HTML>
</Case>
<Case Value='Desc'>
<HTML>$Resources:core,151;</HTML>
</Case>
<Default>
<HTML></HTML>
</Default>
</Switch>
<HTML><![CDATA[" BORDER=0>]]></HTML>
</Default>
</Switch>
</Default>
</Switch>
<HTML><![CDATA[<IMG SRC="]]></HTML>
<FieldFilterImageURL/>
<HTML><![CDATA[" BORDER=0 ALT="">]]></HTML>
</Default>
</Switch>
</Default>
<Case Value="TRUE-TRUE">
<Switch>
<Expr>
<Property Select="Filterable"/>
</Expr>
<Case Value="FALSE">
<HTML><![CDATA[<table cellpadding=0 cellspacing=0 dir="]]></HTML>
<Property Select="Direction" HTMLEncode="TRUE"/>
<HTML><![CDATA["><tr><td style="padding-right: 2px;"><img border="0" valign="middle" height="12" width="12" altbase="]]><![CDATA[$Resources:idPresEnabled;]]><![CDATA[" src="/_layouts/images/blank.gif" onload="IMNRegisterHeader()" id="imnhdr]]></HTML>
<Counter/>
<HTML><![CDATA["></td><td nowrap class="ms-vh">]]></HTML>
<Property Select="DisplayName" HTMLEncode="TRUE"/>
</Case>
<Default>
<Switch>
<Expr>
<Property Select='Filterable'/>
</Expr>
<Case Value="FALSE"> </Case>
<Default>
<Switch>
<Expr>
<GetVar Name='Filter'/>
</Expr>
<Case Value='1'>
<HTML><![CDATA[<SELECT ID="diidFilter]]></HTML>
<Property Select='Name'/>
<HTML> <![CDATA[" TITLE=]]></HTML>
<HTML>"$Resources:core,501;</HTML>
<Property Select='DisplayName' HTMLEncode='TRUE'/>
<HTML><![CDATA[" OnChange='FilterField("]]></HTML>
<GetVar Name="View"/>
<HTML><![CDATA[",]]></HTML>
<ScriptQuote>
<Property Select='Name' URLEncode="TRUE"/>
</ScriptQuote>
<HTML><![CDATA[,this.options[this.selectedIndex].value, this.selectedIndex);' dir="]]></HTML>
<Property Select="Direction" HTMLEncode="TRUE"/>
<HTML><![CDATA[">]]></HTML>
<FieldFilterOptions BooleanTrue="$Resources:core,fld_yes;" BooleanFalse="$Resources:core,fld_no;" NullString="$Resources:core,fld_empty;" AllItems="$Resources:core,fld_all;"></FieldFilterOptions>
<HTML><![CDATA[</SELECT><BR>]]></HTML>
</Case>
</Switch>
</Default>
</Switch>
<HTML><![CDATA[<table cellpadding=0 cellspacing=0 dir="]]></HTML>
<Property Select="Direction" HTMLEncode="TRUE"/>
<HTML><![CDATA["><tr><td style="padding-right: 2px;"><img border="0" valign="middle" height="12" width="12" altbase="]]><![CDATA[$Resources:idPresEnabled;]]><![CDATA[" src="/_layouts/images/blank.gif" onload="IMNRegisterHeader()" id="imnhdr]]></HTML>
<Counter/>
<HTML><![CDATA["></td><td nowrap class="ms-vh">]]></HTML>
<Switch>
<Expr>
<Property Select='Sortable'/>
</Expr>
<Case Value="FALSE">
<Property Select='DisplayName' HTMLEncode="TRUE"/>
</Case>
<Default>
<Switch>
<Expr>
<GetVar Name='SortDisable'/>
</Expr>
<Case Value='TRUE'>
<Property Select='DisplayName' HTMLEncode="TRUE"/>
</Case>
<Default>
<HTML><![CDATA[<A ID="diidSort]]></HTML>
<Property Select='Name'/>
<HTML> <![CDATA[" onfocus="OnFocusFilter(this)" TITLE=]]></HTML>
<HTML>"$Resources:core,500;</HTML>
<Property Select='DisplayName' HTMLEncode='TRUE'/>
<HTML><![CDATA[" HREF="javascript:" OnClick="javascript:return OnClickFilter(this,event);" ]]></HTML>
<HTML><![CDATA[ SORTINGFIELDS="]]></HTML>
<FieldSortParams HTMLEncode="TRUE"/>
<HTML><![CDATA[">]]></HTML>
<Property Select='DisplayName' HTMLEncode="TRUE"/>
<HTML><![CDATA[<img src="/_layouts/images/blank.gif" class="ms-hidden" border=0 width=1 height=1 alt="]]></HTML>
<HTML>$Resources:OpenMenuKeyAccessible;</HTML>
<HTML><![CDATA[">]]></HTML>
<HTML><![CDATA[</A><IMG SRC="]]></HTML>
<FieldSortImageURL/>
<HTML><![CDATA[" ALT="]]></HTML>
<Switch>
<Expr>
<GetVar Name='SortDir'/>
</Expr>
<Case Value='Asc'>
<HTML>$Resources:core,150;</HTML>
</Case>
<Case Value='Desc'>
<HTML>$Resources:core,151;</HTML>
</Case>
<Default>
<HTML></HTML>
</Default>
</Switch>
<HTML><![CDATA[" BORDER=0>]]></HTML>
</Default>
</Switch>
</Default>
</Switch>
<HTML><![CDATA[<IMG SRC="]]></HTML>
<FieldFilterImageURL/>
<HTML><![CDATA[" BORDER=0 ALT="">]]></HTML>
</Default>
</Switch>
<HTML><![CDATA[</td></tr></table>]]></HTML>
</Case>
</Switch>
</RenderPattern>
<RenderPattern Name="DisplayPattern">
<FieldSwitch>
<Expr>
<Property Select="FieldRef"/>
</Expr>
<Case Value="">
<Switch>
<Expr>
<Column/>
</Expr>
<Case Value="">
<FieldSwitch>
<Expr>
<Property Select="SuppressNameDisplay"/>
</Expr>
<Case Value="TRUE">
<HTML><![CDATA[<table cellpadding=0 cellspacing=0 dir="]]></HTML>
<Property Select="Direction" HTMLEncode="TRUE"/>
<HTML><![CDATA["><tr><td style="padding-right: 3px;">]]></HTML>
<HTML><![CDATA[ <img border="0" valign="middle" height="12" width="12" src="/_layouts/images/blank.gif" > </td></tr></table>]]></HTML>
</Case>
</FieldSwitch>
</Case>
<Default>
<FieldSwitch>
<Expr>
<Property Select="LookupType"/>
</Expr>
<Case Value="Computed">
<LookupColumn/>
</Case>
<Default>
<LookupColumn HTMLEncode="TRUE"/>
</Default>
</FieldSwitch>
</Default>
</Switch>
</Case>
<Default>
<LookupColumn HTMLEncode="TRUE"/>
</Default>
</FieldSwitch>
</RenderPattern>
<RenderPattern Name="EditPattern">
<HTML><![CDATA[<SCRIPT>fld = new Field(frm,]]></HTML>
<ScriptQuote>
<Property Select="Name"/>
</ScriptQuote>
<HTML>,</HTML>
<ScriptQuote>
<Property Select="DisplayName"/>
</ScriptQuote>
<HTML><![CDATA[);</SCRIPT>]]></HTML>
<HTML><![CDATA[<SELECT TABINDEX=1 NAME="]]></HTML>
<FieldPrefix/>
<Property Select="Name"/>
<HTML><![CDATA[">]]></HTML>
<Switch>
<Expr>
<Property Select="Required"/>
</Expr>
<Case Value="TRUE">
</Case>
<Default>
<HTML><![CDATA[<OPTION Value="">]]></HTML>
<HTML>$Resources:core,onetfldtypes03;</HTML>
<HTML><![CDATA[</OPTION>]]></HTML>
</Default>
</Switch>
<SelectOptions Len="100" MoreText="..."/>
<HTML><![CDATA[</SELECT>]]></HTML>
</RenderPattern>
<RenderPattern Name="NewPattern" DisplayName="NewPattern">
<HTML><![CDATA[<SCRIPT>fld = new Field(frm,]]></HTML>
<ScriptQuote>
<Property Select="Name"/>
</ScriptQuote>
<HTML>,</HTML>
<ScriptQuote>
<Property Select="DisplayName"/>
</ScriptQuote>
<HTML><![CDATA[);</SCRIPT>]]></HTML>
<HTML><![CDATA[<SELECT TABINDEX=1 NAME="]]></HTML>
<FieldPrefix/>
<Property Select="Name"/>
<HTML><![CDATA[" TITLE="]]></HTML>
<Property Select="Name"/>
<HTML><![CDATA[">]]></HTML>
<Switch>
<Expr>
<Property Select="Required"/>
</Expr>
<Case Value="TRUE">
</Case>
<Default>
<HTML><![CDATA[<OPTION Value="">]]></HTML>
<HTML>$Resources:core,onetfldtypes03;</HTML>
<HTML><![CDATA[</OPTION>]]></HTML>
</Default>
</Switch>
<SelectOptions Len="100" MoreText="..."/>
<HTML><![CDATA[</SELECT>]]></HTML>
</RenderPattern>
<RenderPattern Name="PreviewDisplayPattern">
<HTML><![CDATA[["]]></HTML>
<Property Select="DisplayName" HTMLEncode="TRUE"/>
<HTML>"$Resources:core,fldtypes011;</HTML>
</RenderPattern>
<RenderPattern Name="PreviewEditPattern">
<Switch>
<Expr>
<Property Select="Format"/>
</Expr>
<Case Value="RadioButtons">
<HTML><![CDATA[<table cellpadding="0" cellspacing="1">]]></HTML>
<SetVar Name="_ChoiceDefault">
<Property Select="Default"/>
</SetVar>
<ForEach Select="CHOICES/CHOICE">
<HTML><![CDATA[<tr><td vAlign="top"> <input type="radio"]]></HTML>
<IfEqual>
<Expr1>
<Property Select="."/>
</Expr1>
<Expr2>
<GetVar Name="_ChoiceDefault"/>
</Expr2>
<Then>
<HTML><![CDATA[ checked]]></HTML>
</Then>
</IfEqual>
<HTML><![CDATA[></td><td class="ms-RadioText" vAlign="top">]]></HTML>
<Property Select="." HTMLEncode="TRUE"/>
<HTML><![CDATA[</td></tr>]]></HTML>
</ForEach>
<Switch>
<Expr>
<Property Select="FillInChoice"/>
</Expr>
<Case Value="TRUE">
<HTML><![CDATA[<tr><td vAlign="top"> <input type="radio"></td><td class="ms-RadioText" vAlign="top">]]></HTML>
<HTML>$Resources:core,fldtypes018;</HTML>
<HTML><![CDATA[</td></tr><tr><td vAlign="top"></td><td class="ms-RadioText" vAlign="top"> <input class="ms-input" value=""></td></tr>]]></HTML>
</Case>
</Switch>
<HTML><![CDATA[</table>]]></HTML>
</Case>
<Default>
<Switch>
<Expr>
<Property Select="FillInChoice"/>
</Expr>
<Case Value="TRUE">
<HTML><![CDATA[<table><tr><td vAlign="top"> <input type="radio"></td><td class="ms-RadioText" vAlign="top">]]></HTML>
<HTML><![CDATA[<select><option selected>"]]></HTML>
<Property Select="DisplayName" HTMLEncode="TRUE"/>
<HTML>"$Resources:core,fldtypes012;</HTML>
<HTML><![CDATA[</option></select>]]></HTML>
<HTML><![CDATA[</td></tr>]]></HTML>
<HTML><![CDATA[<tr><td vAlign="top"> <input type="radio"></td><td class="ms-RadioText" vAlign="top">]]></HTML>
<HTML>$Resources:core,fldtypes018;</HTML>
<HTML><![CDATA[</td></tr><tr><td vAlign="top"></td><td class="ms-RadioText" vAlign="top"> <input class="ms-input" value=""></td></tr></table>]]></HTML>
</Case>
<Default>
<HTML><![CDATA[<select><option selected>"]]></HTML>
<Property Select="DisplayName" HTMLEncode="TRUE"/>
<HTML>"$Resources:core,fldtypes012;</HTML>
<HTML><![CDATA[</option></select>]]></HTML>
</Default>
</Switch>
</Default>
</Switch>
</RenderPattern>
<RenderPattern Name="PreviewNewPattern">
<Switch>
<Expr>
<Property Select="Format"/>
</Expr>
<Case Value="RadioButtons">
<HTML><![CDATA[<table cellpadding="0" cellspacing="1">]]></HTML>
<SetVar Name="_ChoiceDefault">
<Property Select="Default"/>
</SetVar>
<ForEach Select="CHOICES/CHOICE">
<HTML><![CDATA[<tr><td vAlign="top"> <input type="radio"]]></HTML>
<IfEqual>
<Expr1>
<Property Select="."/>
</Expr1>
<Expr2>
<GetVar Name="_ChoiceDefault"/>
</Expr2>
<Then>
<HTML><![CDATA[ checked]]></HTML>
</Then>
</IfEqual>
<HTML><![CDATA[></td><td class="ms-RadioText" vAlign="top">]]></HTML>
<Property Select="." HTMLEncode="TRUE"/>
<HTML><![CDATA[</td></tr>]]></HTML>
</ForEach>
<Switch>
<Expr>
<Property Select="FillInChoice"/>
</Expr>
<Case Value="TRUE">
<HTML><![CDATA[<tr><td vAlign="top"> <input type="radio"></td><td class="ms-RadioText" vAlign="top">]]></HTML>
<HTML>$Resources:core,fldtypes018;</HTML>
<HTML><![CDATA[</td></tr><tr><td vAlign="top"></td><td class="ms-RadioText" vAlign="top"> <input class="ms-input" value=""></td></tr>]]></HTML>
</Case>
</Switch>
<HTML><![CDATA[</table>]]></HTML>
</Case>
<Default>
<Switch>
<Expr>
<Property Select="FillInChoice"/>
</Expr>
<Case Value="TRUE">
<HTML><![CDATA[<table><tr><td vAlign="top"> <input type="radio"></td><td class="ms-RadioText" vAlign="top">]]></HTML>
<HTML><![CDATA[<select><option selected>"]]></HTML>
<Property Select="DisplayName" HTMLEncode="TRUE"/>
<HTML>"$Resources:core,fldtypes012;</HTML>
<HTML><![CDATA[</option></select>]]></HTML>
<HTML><![CDATA[</td></tr>]]></HTML>
<HTML><![CDATA[<tr><td vAlign="top"> <input type="radio"></td><td class="ms-RadioText" vAlign="top">]]></HTML>
<HTML>$Resources:core,fldtypes018;</HTML>
<HTML><![CDATA[</td></tr><tr><td vAlign="top"></td><td class="ms-RadioText" vAlign="top"> <input class="ms-input" value=""></td></tr></table>]]></HTML>
</Case>
<Default>
<HTML><![CDATA[<select><option selected>"]]></HTML>
<Property Select="DisplayName" HTMLEncode="TRUE"/>
<HTML>"$Resources:core,fldtypes012;</HTML>
<HTML><![CDATA[</option></select>]]></HTML>
</Default>
</Switch>
</Default>
</Switch>
</RenderPattern>
</FieldType>
</FieldTypes>
Terminado o XML, ainda não definimos como o custom field irá automaticamente mostrar o nome do usuário logado. Vocês devem ter reparado que nesse xml ele cita uma classe. No trecho abaixo:
<Field Name="FieldTypeClass"> Test.Portal.TEMPLATE.CONTROLTEMPLATES.CurrentUserField.CurrentUserField, Test.Portal, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e4f816fa35974913</Field>
O “FieldTypeclass” informa qual a classe do controle. Assim podemos trabalhar as informações do nosso custom field. Como no exemplo abaixo nossa classe irá buscar o usuário logado.
using Microsoft.SharePoint;
namespace Test.Portal.TEMPLATE.CONTROLTEMPLATES.CurrentUserField
{
public class CurrentUserField : SPFieldUser
{
#region Constructors
public CurrentUserField(SPFieldCollection fields, string fieldName)
: base(fields, fieldName)
{
}
public CurrentUserField(SPFieldCollection fields, string typeName, string displayName)
: base(fields, typeName, displayName)
{
}
#endregion
#region SPFieldUser
public override string DefaultValue
{
get
{
using (SPWeb web = SPContext.Current.Web)
{
//Busco o usuário logado.
SPUser user = web.CurrentUser;
//cria a string com o nome do usuário corrente.
string defaultValue = string.Format("{0};#{1}", user.ID.ToString(), user.Name);
//Verifica usuário e permissão
if (this.SelectionGroup > 0)
{
SPGroup group = web.Groups[this.SelectionGroup];
if ((group != null) && (group.ContainsCurrentUser))
{
return defaultValue;
}
}
else
{
return defaultValue;
}
}
return string.Empty;
}
set
{
base.DefaultValue = value;
}
}
#endregion
}
}
Pronto!!! nosso custom field está finalizado. Agora só fazer o Deploy. Para quem faz o deploy manual seguir os passos abaixo:
1. Copiar o XML para a pasta: “C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\xml”
2. Copiar as dlls para o GAC.
3. Dar um iisreset.
Agora é só utilizar o custom field.
No próximo post vou ensinar como criar uma lista e utilizar o custom field, tanto direto pelo sharepoint como por uma feature.