Friday, October 3, 2008

Adding Title(with menu) field for Document Library

Scenario:
Out-of-box SharePoint allow to have context menu for 'Name' column only. Now you want to have similar Context Menu for 'Title' field also.

Solution:
Add a new field of type 'Title(with menu)' using Object Model.

Code:

using Microsoft.SharePoint; 

public void AddNewTitleFieldWithMenu()
{
string fieldTitle = "Title";
Guid fieldId = Guid.NewGuid();

using (SPSite site = new SPSite("http://localhost")) {
using (SPWeb web = site.OpenWeb()) {

SPList list = web.Lists["Shared Documents"];

string fieldDef = @"<Field ID='" + (fieldId.ToString()) + @"' SourceID='http://schemas.microsoft.com/sharepoint/v3'
Name='" + fieldTitle + @"'
StaticName='" + fieldTitle + @"'
Group='Custom Fields'
ReadOnly='TRUE'
Type='Computed'
DisplayName='" + fieldTitle + @"'
DisplayNameSrcField='FileLeafRef'
Filterable='FALSE'
ClassInfo='Menu'
AuthoringInfo='(with menu v1)'><!-- _locID@DisplayName='camlionet75' _locComment=' ' --><!-- _locID@AuthoringInfo='115' _locComment=' ' -->
<FieldRefs>
<FieldRef ID='{fa564e0f-0c70-4ab9-b863-0177e6ddd247}' Name='Title'/>
<FieldRef ID='{687c7f94-686a-42d3-9b67-2782eac4b4f8}' Name='FileLeafRef'/>
<FieldRef ID='{3c6303be-e21f-4366-80d7-d6d0a3b22c7a}' Name='_EditMenuTableStart'/>
<FieldRef ID='{2ea78cef-1bf9-4019-960a-02c41636cb47}' Name='_EditMenuTableEnd'/>
<FieldRef ID='{9d30f126-ba48-446b-b8f9-83745f322ebe}' Name='LinkFilenameNoMenu'/>
<FieldRef ID='{687c7f94-686a-42d3-9b67-2782eac4b4f8}' Name='FileLeafRef'/>
<FieldRef ID='{30bb605f-5bae-48fe-b4e3-1f81d9772af9}' Name='FSObjType'/>
<FieldRef ID='{998b5cff-4a35-47a7-92f3-3914aa6aa4a2}' Name='Created_x0020_Date'/>
<FieldRef ID='{94f89715-e097-4e8b-ba79-ea02aa8b7adb}' Name='FileRef'/>
<FieldRef ID='{39360f11-34cf-4356-9945-25c44e68dade}' Name='File_x0020_Type'/>
<FieldRef ID='{03e45e84-1992-4d42-9116-26f756012634}' Name='ContentTypeId'/>
</FieldRefs>
<DisplayPattern>
<FieldSwitch>
<Expr><GetVar Name='FreeForm'/></Expr>
<Case Value='TRUE'><Field Name='LinkFilenameNoMenu'/></Case>
<Default>
<Field Name='_EditMenuTableStart'/>

<IfEqual>
<Expr1><LookupColumn Name='FSObjType'/></Expr1>
<Expr2>1</Expr2>
<Then>
<FieldSwitch><Expr><GetVar Name='RecursiveView'/></Expr>
<Case Value='1'>
<LookupColumn Name='FileLeafRef' HTMLEncode='TRUE'/>
</Case>
<Default>
<SetVar Name='UnencodedFilterLink'>
<SetVar Name='RootFolder'><HTML>/</HTML><LookupColumn Name='FileRef'/></SetVar>
<SetVar Name='FolderCTID'>
<FieldSwitch><Expr><ListProperty Select='EnableContentTypes'/></Expr>
<Case Value='1'><Column Name='ContentTypeId'/></Case>
</FieldSwitch>
</SetVar>
<FilterLink Default='' Paged='FALSE'/>
</SetVar>
<HTML><![CDATA[<A onfocus='OnLink(this)' HREF=']]></HTML>
<GetVar Name='UnencodedFilterLink' HTMLEncode='TRUE'/>
<HTML><![CDATA[' onclick='javascript:EnterFolder(']]></HTML>
<ScriptQuote NotAddingQuote='TRUE'><GetVar Name='UnencodedFilterLink'/></ScriptQuote>
<HTML><![CDATA[');javascript:return false;'>]]></HTML>
<LookupColumn Name='FileLeafRef' HTMLEncode='TRUE'/>
<HTML><![CDATA[</A>]]></HTML>
</Default>
</FieldSwitch>
</Then>
<Else>
<HTML><![CDATA[<A onfocus='OnLink(this)' HREF=']]></HTML>
<Field Name='EncodedAbsUrl'/>
<HTML><![CDATA[' onclick='DispDocItemEx(this,']]></HTML>
<ServerProperty Select='HtmlTransform'/>
<HTML><![CDATA[',']]></HTML>
<ServerProperty Select='HtmlTrAcceptType'><Column Name='File_x0020_Type'/></ServerProperty>
<HTML><![CDATA[',']]></HTML>
<ServerProperty Select='HtmlTrHandleUrl'><Column Name='File_x0020_Type'/></ServerProperty>
<HTML><![CDATA[',']]></HTML>
<ServerProperty Select='HtmlTrProgId'><Column Name='File_x0020_Type'/></ServerProperty>
<HTML><![CDATA[')'>]]></HTML>
<UrlBaseName HTMLEncode='TRUE'><LookupColumn Name='Title'/></UrlBaseName>
<HTML><![CDATA[</A>]]></HTML>
<IfNew Name='Created_x0020_Date'>
<HTML><![CDATA[<IMG SRC='/_layouts/1033/images/new.gif' alt=']]></HTML>
<HTML>$Resources:core,new_gif_alttext</HTML><HTML><![CDATA['>]]></HTML>
</IfNew>
</Else>
</IfEqual>
<Field Name='_EditMenuTableEnd'/>
</Default>
</FieldSwitch>
</DisplayPattern>
</Field>";

list.Fields.AddFieldAsXml(fieldDef, true, SPAddFieldOptions.AddToAllContentTypes);
}
}
}

32 comments:

Varonin Maksim January 9, 2009 at 10:37 AM  

This approach doesn't seem to work. The menu gets displayed but after clicking it always shows error message like this: "One or more field types are not installed properly. Go to the list settings page to delete these fields."

Sandeep K Nahta January 9, 2009 at 9:54 PM  

HI Varonin,

I just tested it again on my WSS VM. This works like charm without any issues. Make sure you are doing this for Document Library and u can call this code in a Console application.

steamroller February 5, 2009 at 3:04 PM  

This is exactly what I need to do but I could use some additional details - i.e. can this be done in sharepoint designer?

Sandeep K Nahta February 5, 2009 at 3:45 PM  

Unfortunatly this cant be done in SP Designer, this will only work if u can execute this code on the server.

steamroller February 5, 2009 at 4:07 PM  

Thank you for the quick response Sandeep. I have access to the server so I can definitely mod the code but am not familiar with using object model. I hae tried modifying the onet.xml file with no luck.

Sandeep K Nahta February 5, 2009 at 4:13 PM  

Its preety simple, create a new simple concole application and insert the code in .cs file. Add reference to Microsoft.Sharepoint.dll ( Windows SharePoint Services )and make changed to list name and the Url to the server and hit F5

steamroller February 5, 2009 at 4:18 PM  

Right on Sandeep - sounds good but a little over my head. Thanks for your responses though. I'll dissect your response and try to figure this out. Thanks for sharing your knowledge though.

steamroller February 5, 2009 at 5:20 PM  

Sandeep I was able to build the .cs file as stated above. One last question -is it possible to run the .cs file outside of visual studio. I have it on my pc but the server doesn't have a copy. I could download a trial but didn't find much after searching for this answer.

Sandeep K Nahta February 5, 2009 at 5:25 PM  

compile the solution and u will find the EXE file in the BIN folder .. which u can directly run in another machine by double clicking it...

CS --- >> EXE --> run in new environment

steamroller February 5, 2009 at 5:38 PM  

Thank you! I appreciate all of your help.

steamroller February 6, 2009 at 2:30 PM  

Sandeep, I opened a new .cs project and pasted your code in between the tags provided in vis studio. I believe I followed everything from your comments, referenced the sharepoint.dll and ended up with 'the type or namespace name SPSite could not be found.' Just wanted to touch base one last time and no sweat if you're not sure. You've already taken a lot of time.

steamroller February 6, 2009 at 3:38 PM  

Got the exe to run but am now wondering if I need to restart sharepoint server for changes to take effect.

Sandeep K Nahta February 6, 2009 at 3:47 PM  

You might need to add following line of code

-------------------
using Microsoft.SharePoint;
-------------------


at the top along with other namespaces

steamroller February 6, 2009 at 3:59 PM  

Dude - you are the man. It worked! Thanks for all of your help!!

Anders March 11, 2009 at 7:00 AM  

Thank you, great post! Much appreciated.

Anonymous,  June 10, 2009 at 9:56 PM  

Thanks. This is great post. I have a requirement wherein if a document doesnt have title, its name shouls be picked up. Is that easily possible?

Sandeep K Nahta June 10, 2009 at 10:13 PM  

Yes thats out of functionality.. if file is missing title it will show file name as Title

Anonymous,  June 12, 2009 at 5:43 PM  

Thanks Sandeep. This is great. I'm new to sharepoint and wonder where to learn these syntax details required. the fieldRefs and display patterns.. SharePoint has big learning curve :)

Sandeep K Nahta June 12, 2009 at 8:39 PM  

100% right, if after implementing sharepoint from last 3 yrs , i still learn everyday

Anonymous,  August 31, 2009 at 7:09 PM  

Hey Sandeep,
Thanks for this post. I tried this and seem there is a issue in rendering title when the title has multiple full stops. This seems to stop until it sees first space after first full stop. Is this correct behavior? I've a requirement where the title can be made up with 2/3 small sentenses. In such cases it gets truncated to first sentense and first word after it. Please let me know if there is any solution for this.
Thanks,
Paresh

Anonymous,  September 1, 2009 at 1:16 PM  

Sorry, its not the full stop (period) that causes issues but the "(" is the culprit I think. If the title looks like "This is test (X. Y. Test)" then it displays only "This is test (X.Y"
Thanks,
Paresh

Anonymous,  September 2, 2009 at 1:18 PM  

I made below changes to the HTML just above "Created_x0020_Date". Removed the HTMLEncode='TRUE' changed LookupColumn = 'Title' to Field Name='Title'

Now it seems to work well. Is there any risk/bug I've introduced with these changes? Please let me know, I'm novice to sharepoint and may not have done right thing.
Thanks,
Paresh

Sandeep K Nahta September 2, 2009 at 6:50 PM  

Paresh,

hmm.. if u can tell me why you wanted those changes then i can guide u..

Thanks
sandeep

Anonymous,  September 3, 2009 at 12:35 PM  

Please refer to my previous comments. The issue was when I had title of a doc like:
"This is a test.(X. Y. Test)"
This would get truncated to :
"This is a test. (X"
Thanks,
Paresh

Umakanth Nelige November 5, 2009 at 1:57 PM  

Hi Sandeep!

I cant believe.. it just happened in one single try! I had the exact requirement and this code worked like a charm. You da man!!

Thanks Buddy!
Umakanth!!

Umakanth Nelige November 5, 2009 at 1:58 PM  

Sandeep.. this worked like a charm in the first attempt itself.. You da man!!

-Umakanth

Sandeep K Nahta November 5, 2009 at 1:59 PM  

thats why i the most number of comments on the post .. this is my most popular post

cevans,  August 18, 2010 at 10:44 AM  

I hardly ever leave comments on websites - but I have to say this is AWESOME. worked right away and solved a problem that I was absolutely frustrated on. Thank you for posting this code online!!!!

Datastorage,  November 15, 2010 at 6:26 AM  

Hey Sandeep,I have tried the code but i can see title coulmn in document library but it does not have any content means all contents in under name coulm but not in title coulmn , I m using sharepoint2010 .Plz guide

Anonymous,  May 6, 2011 at 10:41 AM  

Hi, I also cant get this to work on Sp2010 - the field is attached to the list/view but the field always appears blank and the menu doesnt appear as expected - has the rendering of the drop down menu changing in SP2010 ?

Sandeep K Nahta May 6, 2011 at 12:41 PM  

I haven't testing it in SP2010. I will do so in weekend and will update the post if any change required.

Anonymous,  May 10, 2011 at 4:17 AM  

Hi, Further to the SP2010 rendering, i couldnt get this and other methods i found revolving around "_EditMenuTableStart2" to work - but have identified what appears to be a hidden field in SP2010 which does the job. Basically all you need to do is add the ListItemMenu="TRUE" attribute to the item in the list schema. For info I found it while watching how Designer managed updates to the lists when you format columns etc - in my case i noticed it added this field to the schema.

Thought you may be interested
Ed