Thursday, April 17, 2008

Rearranging SharePoint Fields

Ever wanted to rearrange those annoying fields in EditForm.aspx and NewForm.aspx, without having to modify the actual pages in SharePoint Designer (SPD)? If you did want to use SPD for this please see the following blog which explains very nicely how to do this (http://kalsing.blogspot.com/2006/11/create-custom-list-form-for-sharepoint.html). However there is a drawback to this approach as it is a post deploy approach - the site and list has to be already created - what happens when you need to include these field arrangements as part of a site template?

First of all lets start with the way you deploy your site columns (fields) and content types. Currently we deploy content types and site columns via features. There are lots of blogs out there and even just diving into the HIVE you can see how Microsoft does this out-of-the-box, so I won't go through this in detail (see C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\FEATURES\fields and C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\FEATURES\ctypes).

Firstly you define your fields:

<Field ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}"
Name="Title"
SourceID="http://schemas.microsoft.com/sharepoint/v3"
StaticName="Title"
Group="_Hidden"
Type="Text"
DisplayName="$Resources:core,Title;"
Required="TRUE"
FromBaseType="TRUE">
</Field>

<Field id="{fa564e0f-0c70-4ab9-b863-0177e6ddd249}"
Name="FirstTitle"
SourceID="http://schemas.microsoft.com/sharepoint/v3"
StaticName="FirstTitle"
Group="_Hidden"
Type="Text"
DisplayName="First Title"
Required="TRUE">
</Field>

Now you define your content type:

<ContentType ID="0x01"
Name="$Resources:Item"
Group="$Resources:List_Content_Types"
Description="$Resources:ItemCTDesc"
Version="0">
<FieldRefs>
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" Required="TRUE" ShowInNewForm="TRUE" ShowInEditForm="TRUE"/>
</FieldRefs>
</ContentType>

<ContentType ID="0x0101" Name="Child Content Type" Group="$Resources:List_Content_Types"
Description="Child Content Type"
Version="0">
<FieldRefs>
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd249}"
Name="FirstTitle" Required="TRUE" ShowInNewForm="TRUE" ShowInEditForm="TRUE"/>
</FieldRefs>
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd250}"
Name="SecondTitle" Required="TRUE" ShowInNewForm="TRUE" ShowInEditForm="TRUE"/>
</FieldRefs>
</ContentType>

Now if you bind the Child Content Type to say the Pages library. The fields for the EditForm.aspx and NewForm.aspx will be displayed in the following order:

Title
First Title
Second Title

How about if you want First Title to come "First"?

By simply changing the order of the fields you put inside your content types it will change the order of the way they appear in the EditForm.aspx and NewForm.aspx. So if you referenced Second Title first in the content type the order would change to:

Title
Second Title
First Title

That's pretty neat! However what if I wanted "First Title" to go on top of the "Title" field?

When your content type inherits from the base content types or even content types you've defined then the order in your EditForm.aspx and NewForm.aspx will always show the parents fields first followed by the childs fields.

How to get around this problem? Simple all you need to do is add the same inherited field into your child content type and arrange it the way you want, this includes the base hidden site columns from the OOB content types. You then would obviously need to bind your content type to the list you want and this should do the trick. So if I wanted to put the fields in the following order:

First Title
Title
Second Title

Then I would simply just reference the Title field in the child content type:
<ContentType ID="0x0101" Name="Child Content Type" Group="$Resources:List_Content_Types"
Description="Child Content Type"
Version="0">
<FieldRefs>
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd249}"
Name="FirstTitle" Required="TRUE" ShowInNewForm="TRUE" ShowInEditForm="TRUE"/>
</FieldRefs>
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" Required="TRUE" ShowInNewForm="TRUE" ShowInEditForm="TRUE"/>
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd250}"
Name="SecondTitle" Required="TRUE" ShowInNewForm="TRUE" ShowInEditForm="TRUE"/>
</FieldRefs>
</ContentType>

This doesn't seem to break the inheritance of the content types either - just the ordering.

Apologies for the crappy cut and paste job - someone needs to teach me how to cut and paste properly on this.

First Up Blog

My first ever posting - I already now feel a little more nerdy :S

Actually it's about Bloggin time that I finally got off my lazy butt and started bloggin all the things I've learnt and use as a reference just in case I need to do the same thing again, plus I could always just tell people oh I've done that before you should go read my "Blog" how nerdy eh?

And so the bloggin now begins....