1

I'm creating custom field type - lets name it 'MyCustomType'. I need to change its column title in List View. I tried to use xslt-transform in my fldtypes_MyCustomType.xsl with no luck - nothing changes.

I tried the following code:

<xsl:template name="FieldRef_MyCustomType_header" ddwrt:dvt_mode="header" 
              match="FieldRef[@Type='MyCustomType']" mode="header" priority="9">
  <th class="ms-vh-icon" nowrap="nowrap" scope="col" onmouseover="OnChildColumn(this)">
  <xsl:call-template name="dvt_headerfield">
     <xsl:with-param name="fieldname">MyCustomType</xsl:with-param>
     <xsl:with-param name="fieldtitle">This value I want to change</xsl:with-param>
     <xsl:with-param name="displayname">MyCustomType</xsl:with-param>
     <xsl:with-param name="fieldtype">MyCustomType</xsl:with-param>
  </xsl:call-template>
  </th>
</xsl:template>

I copied this code from Sharepoint fldtypes.xsl, 'FieldRef_Attachments_header' template.

Please help me to make it works.

  • have a look into this example: sharepoint.stackexchange.com/questions/109277/… – Supermode Aug 19 '15 at 1:01
  • This example is cool, but it manipulates with List View of entire List. I need to modify only my filed title, because my field can be added to any list via code or UI. So I can't predict what kind of list will use my field, and what columns there will be. – Olga Golubeva Aug 19 '15 at 5:56
1

I'd almost forget about this problem, but accidently I'd found the way to solve it.

The main difference between SP2013 and SP2010 - is javascript rendering! In 2013 - javascript is everywhere, and XsltListViewWebParts (classic list view) by default are rendering on client too. That's why Xslt-transformations for header working, but not visible! To see it, go to the List View Page -> "Change Page" -> "Change XsltListViewWebPart properties" -> find checkBox "Render on server" -> Save. XsltListViewWebPart will render at 2010-style and you will see your header from Xslt.

But how to do my custom header in 2013-style, with client render? The answer is - Javascript. You'll have to override javascript header rendering. You can find it in clienttemplates.js

So, full solution is:

  1. When you creating your custom field type, you have to override JS-link for your field:

    public class MyCustomType: SPFieldLookup
    {        
       private const string JSLinkUrl = "~site/_layouts /15/MyCustomType/MyCustomType.js";
    
       public override string JSLink
       {
           get { return JSLinkUrl; }
           set { base.JSLink = value; }
       }
    
      //constructors and other logic
    } 
    

    In file /_layouts /15/MyCustomType/MyCustomType.js you will make all javascript transformations for your field.

  2. Create MyCustomType/MyCustomType.js in the LAYOUTS folder. And there, override renderHeader field of spMgr object:

    (function () {
       spMgr.RenderHeader = function (renderCtx, field) {
            //...
            //you'll have to copy all SPMgr functions from clientTemplates.js 
            //if you want render other fields headers propertly.
            //Simply find string 'function SPMgr() {' and grab this function fully
            //then add you header rendering
            //...
            if (field.Name == 'SelectedFlag')
                return RenderSelectedFlagHeader(renderCtx, field);
            else if (field.Name == 'Checkmark')
                return RenderCheckmarkHeader(renderCtx, field);
            var fieldHeaderRenderMap = {
                Attachments: RenderAttachmentsHeader,
                Computed: RenderComputedHeader,
                CrossProjectLink: RenderCrossProjectLinkHeader,
                Recurrence: RenderRecurrenceHeader,
                DateTime: RenderDateTimeHeader
            };
            var headerRenderer = fieldHeaderRenderMap[field.Type];
    
            if (field.FieldType == 'MyCustomType')
                return RenderMyCustomHeader(renderCtx, field); //this is our rendering!
            else {
                if (headerRenderer != null)
                    return headerRenderer(renderCtx, field);
                return RenderDefaultHeader(renderCtx, field);
            }        
        }
    })(); 
    function RenderMyCustomHeader(renderCtx, field) {
        var iStr = '<th scope="col" onmouseover="OnChildColumn(this)" style="max-width: 500px;" class="ms-vh2" onmousedown="ListHeaderMenu_OnMouseDown(this);">';   
        iStr += "My field -my header from js";
        iStr += '</th>';
        return iStr;
    }
    

Unfortunately, I hadn't find the solution without full overriding SPMgr function from clienttemplates.js. If someone will find it - please add it here!

Update:

And here is the correct XSLT-rendering (fldtypes_MyCustomType.xsl) for Server-side rendering in SP2010-style:

  <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" >
      <xsl:output method="html" indent="no"/>

      <xsl:template name="FieldRef_MyCustomType_header" 
                    match="FieldRef[@FieldType='MyCustomType']" 
                    ddwrt:dvt_mode="header" mode="header" priority="9">
        <th class="ms-vh-icon" nowrap="nowrap" scope="col" onmouseover="OnChildColumn(this)">
          <xsl:attribute name="class">ms-vh2</xsl:attribute>
          <xsl:call-template name="dvt_headerfield">
            <xsl:with-param name="fieldname"><xsl:value-of select="@Name"/>
            </xsl:with-param>
            <xsl:with-param name="fieldtitle">
              MyCustomType from XSL 
            </xsl:with-param>
            <xsl:with-param name="displayname"><xsl:value-of select="@DisplayName"/></xsl:with-param>
            <xsl:with-param name="fieldtype">x:string</xsl:with-param>
          </xsl:call-template>
        </th>
      </xsl:template>

| improve this answer | |
0
<xsl:call-template name="dvt_headerfield">

I think you have a typo, it should be dvt.headerfield. Although I did see posts using the underscore, more authoritative posts like this one uses the dot.

You also write "nothing happens", are you positive that the template FieldRef_MyCustomType_header is ever called? you can check this by adding something like:

<xsl:comment>Hey, I hit my template!</xsl:comment>

at the top of the template, and then check the output.

| improve this answer | |
  • Not, it's not a typo. First, I've copied this piece of code from 15\TEMPLATE\LAYOUTS\XSL\fldtypes.xsl, from template FieldRef_Attachments_header. Second, If I use dvt.headerfield - I get an error 'could not load webpart' in list view. Also, my template is never called. – Olga Golubeva Sep 14 '15 at 7:23
  • @OlgaGolubeva, so you have the choice between template never called, and template name raising an error. You should search for what calls FieldRef_MyCustomType_header (if that is indeed currently not called), and analyze your way back step by step. – Abel Sep 14 '15 at 7:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.