Enabling ECB menu on a custom column in SharePoint 2010 (Part 2)
OK. In Part 1, I’ve explained the problem of “Edit in undefined” when you enable the ECB menu on a field in the document library. To workaround this problem, we have to go back to the way we used for MOSS. In MOSS, when we want to enable the ECB menu on a field, we have to define a custom field with the Computed field type and add references to two special fields, _EditMenuTableStart and _EditMenuTableEnd. We usually need to add another reference to a field from which the value of the custom field comes. So here in SharePoint 2010, let’s do the same thing.
The following is the definition of my custom field. I’ve highlighted the attributes and values which you may pay attention to. In this field, I want it to have the same value of Title so I add a reference to Title. Note in SharePoint 2010 now we use _EditMenuTableStart2 instead of _EditMenuTableStart. To make things simple, I also create a content type to use this custom field.
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="https://schemas.microsoft.com/sharepoint/">
<Field ID="{566F83FF-CCFE-4f7a-BE3C-332169E040B8}"
Group="Morpheus Columns"
ReadOnly="TRUE"
Type="Computed"
Name="TitleEx"
StaticName="TitleEx"
DisplayName="TitleEx"
DisplayNameSrcField="Title"
ClassInfo="Menu"
AuthoringInfo="(with edit menu)"
SourceID="https://schemas.microsoft.com/sharepoint/v3">
<FieldRefs>
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}"
Name="Title" />
<FieldRef ID="{1344423c-c7f9-4134-88e4-ad842e2d723c}"
Name="_EditMenuTableStart2" />
<FieldRef ID="{2ea78cef-1bf9-4019-960a-02c41636cb47}"
Name="_EditMenuTableEnd" />
</FieldRefs>
<DisplayPattern>
<FieldSwitch>
<Expr>
<GetVar Name="FreeForm"/>
</Expr>
<Case Value="TRUE">
<Field Name="Title"/>
</Case>
<Default>
<Field Name="_EditMenuTableStart2"/>
<Field Name="Title"/>
<Field Name="_EditMenuTableEnd"/>
</Default>
</FieldSwitch>
</DisplayPattern>
</Field>
<!-- Parent ContentType: Document (0x0101) -->
<ContentType ID="0x010100922fc480f3ae4beba09c8eb3aec9530a"
Name="TitleEx"
Group="Morpheus CTypes"
Description="A content type with an ECB menu enabled field. "
Inherits="TRUE"
Version="0">
<FieldRefs>
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}"
Name="Title" Required="TRUE" />
<FieldRef ID="{566F83FF-CCFE-4f7a-BE3C-332169E040B8}"
Name="TitleEx" Required="TRUE" />
</FieldRefs>
</ContentType>
</Elements>
Now if we deploy and use the content type in a document library, my field, TitleEx, is actually displayed as below. There is no value displayed, although there is a value in the Title field.
The reason why there is nothing in this field is the same as what I mentioned in my previous post: SharePoint 2010 now is using XSLT instead of <DisplayPattern> to render the field on the list view. Although I defined <DisplayPattern> for my field, it will never be used. We have to create a custom XSLT to render it.
The following is the XSLT stylesheet I used for my field.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:x="https://www.w3.org/2001/XMLSchema"
xmlns:d="https://schemas.microsoft.com/sharepoint/dsp"
version="1.0"
exclude-result-prefixes="xsl msxsl ddwrt"
xmlns:ddwrt="https://schemas.microsoft.com/WebParts/v2/DataView/runtime"
xmlns:asp="https://schemas.microsoft.com/ASPNET/20"
xmlns:__designer="https://schemas.microsoft.com/WebParts/v2/DataView/designer"
xmlns:xsl="https://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:SharePoint="Microsoft.SharePoint.WebControls"
xmlns:ddwrt2="urn:frontpage:internal">
<xsl:template match="FieldRef[@Name='TitleEx']" mode="Computed_body">
<xsl:param name="thisNode" select="." />
<xsl:param name="ShowAccessibleIcon" select="0"/>
<a onfocus="OnLink(this)" href="{$FORM_DISPLAY}&ID={$thisNode/@ID}"
onclick="GoToHistoryLink(this, {$thisNode/@_UIVersion});return false;"
target="_self">
<xsl:call-template name="LinkTitleValue">
<xsl:with-param name="thisNode" select="$thisNode"/>
<xsl:with-param name="ShowAccessibleIcon" select="$ShowAccessibleIcon"/>
</xsl:call-template>
</a>
<xsl:if test="$thisNode/@Created_x0020_Date.ifnew='1'">
<xsl:call-template name="NewGif">
<xsl:with-param name="thisNode" select="$thisNode"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Now there is a value shown in my field, and it is the same as the value of Title.
The final step is to edit TitleEx in SharePoint Design and enable Show List Item Menu on it. After that, we will be able to see the ECB menu on this field. The result is below. It shows the “Edit in Microsoft Word” correctly.
Comments
- Anonymous
October 03, 2010
Hi Chun! Thanx for your post. As I'm new in SP development, I'm not familiar where above XSLT code must be putted? Somewhere in list definiton file(if yes, where precisely?) or somewhere else?Also does <DisplayPattern> must be defined because of use XSLT? - Anonymous
October 04, 2010
The XSLT must be put in %ProgramFiles%Common FilesMicrosoft Sharedweb server extensions14TEMPLATELAYOUTSXSL. <DisplayPattern> is necessary if you want to show your field not only in list view but other forms like view properties form etc. XSLT just works for XSLTListViewWebPart. All other forms are still using the CAML defined by <DisplayPattern>. You can even force SharePoint to render your field with <DisplayPattern> only. Please refer to my previous post for details: blogs.msdn.com/.../rendering-a-field-with-the-custom-xslt-stylesheet.aspx. - Anonymous
October 04, 2010
I did as you said (modification of my field definition with your field spec, added ref in CType, added refs in list definition, added custom XSLT file,checked guids, reset of app pools) and NOTHING. I can't see any value in "TitleEx" in both cases (link to Title field or my custom field (which is final goal))As I develop this functionality just from code (with no assistance of SP Designer), can you maybe give me some hint on which I maybe forgotten? - Anonymous
October 06, 2010
Try the solution I attached. Thx. - Anonymous
December 16, 2010
Hi Chun, thanks for your post.I'm new to SP, is it possible to create a field with the function of your TitleEx field.I want this function can be used in everylistThanks - Anonymous
January 31, 2011
Good post, Chun. Is there a way to change the XSLT to render the link so that it opens up the document, and not the item properties? - Anonymous
April 20, 2011
Hello Chun,I like your post but I have a small problem, it works perfectly but for some stupid reasons I got a javascript error when I load a view which renders this custom fieldI located the source of the problem, it comes from the GoToHistoryLink(this, {$thisNode/@_UIVersion});return false;any idea on the problem ?thx - Anonymous
August 15, 2011
Chun,Thank you for the post. I am having an issue thought. I think I am not getting the right steps.I created the XML file (I am using 'DocumentTitle' as my field name) and put it in the following folder with the following name:C:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions14TEMPLATEXMLfldtypes_DocumentTitle.xmlThen I created my XSL file and put it in the following folder with the following nameC:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions14TEMPLATELAYOUTSXSLfldtypes_DocumentTitle.xslI restarted the IIS and I don't see where the new field should be. I am not sure what to do next, any thought?Any help would be greatly appreciated.Pearl - Anonymous
April 18, 2012
Chun,i added and deployed the solution. Then activated on my site. I can see the content type in my document library. But the two things are missing , the column "TitleEx" is blank and then context menu. - Anonymous
April 18, 2012
Chun,i added and deployed the solution. Then activated on my site. I can see the content type in my document library. But the two things are missing , the column "TitleEx" is blank and then context menu. - Anonymous
June 24, 2012
In the XSL, the link showing the Title will direct me to the page showing the properties (as the default behaviour for the title column in a list).<a onfocus="OnLink(this)" href="{$FORM_DISPLAY}&ID={$thisNode/@ID}" onclick="GoToHistoryLink(this, {$thisNode/@_UIVersion});return false;" target="_self"><xsl:call-template name="LinkTitleValue"> <xsl:with-param name="thisNode" select="$thisNode"/> <xsl:with-param name="ShowAccessibleIcon" select="$ShowAccessibleIcon"/> </xsl:call-template></a>However for a document library, i would like the default behaviour of opening the document with the client application or in a web browser. I browsed through the entire field rendering xsl code on the server but didn´t an example which code i need for rendering an edit document link. - Anonymous
March 05, 2013
Is there a way to do this using sandboxed solution since we can't deploy to _layouts?