SharePoint custom field XSLT rendering with custom properties
Vladi Gubler
Vladi Gubler
September 22, 2011 | Development

Hi,

For our new product, URL Plus Field, we needed to render a field value different depending on field settings. For instance, you can set to open links in a new window or replace the description text with an icon. In 2007, this is pretty easy, once you define your custom property as an attribute of field schema (do not use PropertySchema, you must set you custom values as attributes, you can do that by directly manipulating the underlying XML in your field class). In 2010, there is no way (as far as I can tell, please enlighten me) to know what the field values are in the XSLT rendering.

First we tried to fall back to old school CAML rendering by setting CAMLRendering property to true. That basically brought the whole list rendering down with an error, it is something specific to URL fields, as it works fine with text or number fields.

So I needed to come up with a way to get the property values and keep the XSLT rendering. After spending an entire day looking for a solution, approaching it from different angle and basically pulling my hair out, I still was nowhere near the solution.

The break came the next day, when I had an idea - if I cannot read the properties, maybe I can incorporate the property values as part of the item value (the URL itself). AND IT WORKED!!!

What I did was override the GetFieldValue method of my field class:

public override object GetFieldValue(string value) 
  {
          if (IsSharePoint2010)   
        {     
          if (string.IsNullOrEmpty(value)) 
                return value;
                 return value + string.Format(",{0},{1},{2},{3}", DisplayFormat, ShowAsIcon, IconUrl, OpenInNewWindow);   
       }  
          else     
           return base.GetFieldValue(value);  
       }

Here I'm basically checking if the current SharePoint version is 2010 (using a helper method that compare the build version of the local farm to 12, which is 2007), if not, I attach my additional property values to the URL itself. Now we are getting the property value in XSLT through the back door :)

So now we can use these values in our XSLT template.

Using the following two helper templates I can split my field value into parts and get value of each separate part:

This template split the value into sort of an array (in the XSL world):

<xsl:template name="IWURLPLUStokens">
    <xsl:param name="str" select="."/>
    <xsl:param name="splitString" select="','"/>
<xsl:choose>
      <xsl:when test="contains($str,$splitString)">
        <token>
          <xsl:value-of select="substring-before($str,$splitString)"/>
        </token>
        <xsl:call-template name="IWURLPLUStokens">
          <xsl:with-param name="str"    select="substring-after($str,$splitString)"/>
          <xsl:with-param name="splitString" select="$splitString"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <token>
          <xsl:value-of select="$str"/>
        </token>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

And this one will return value according to index:

  <xsl:template name="IWURLPLUSGetPartAtIndex">
    <xsl:param name="splits"/>
    <xsl:param name="index"/>
    <xsl:value-of select="msxsl:node-set($splits)/token[position()=$index]"/>
  </xsl:template>

So now we can split our value into the URL itself (index=1) and the property values (the other 4 parts in our example).

Using the regular XSLT template we can now use these values to produce the exact outcome that we need in any XSLT view!

 <xsl:template match="FieldRef[@FieldType='UrlPlusField']" mode="URL_body">
    <xsl:param name="thisNode" select="." />
    <xsl:variable name="thisValue" select="$thisNode/@*[name()=current()/@Name]"/>
    <xsl:variable name="url">
      <xsl:choose>
        <xsl:when test="contains($thisValue, ',')">
          <xsl:value-of select="substring-before($thisValue, ',')" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$thisValue" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:variable name="splits">
      <xsl:call-template name="IWURLPLUStokens">
        <xsl:with-param name="str" select="$thisValue"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="displayFormat">
      <xsl:if test="contains($thisValue, ',')">
        <xsl:call-template name="IWURLPLUSGetPartAtIndex">
          <xsl:with-param name="splits" select="$splits"/>
          <xsl:with-param name="index" select="2"/>
        </xsl:call-template>
      </xsl:if>
    </xsl:variable>
    <xsl:variable name="openInNewWindow">
      <xsl:if test="contains($thisValue, ',')">
        <xsl:call-template name="IWURLPLUSGetPartAtIndex">
          <xsl:with-param name="splits" select="$splits"/>
         <xsl:with-param name="index" select="5"/>
        </xsl:call-template>
      </xsl:if>    </xsl:variable>
    <xsl:variable name="showAsIcon">
      <xsl:if test="contains($thisValue, ',')">
        <xsl:call-template name="IWURLPLUSGetPartAtIndex">
          <xsl:with-param name="splits" select="$splits"/>
          <xsl:with-param name="index" select="3"/>
        </xsl:call-template>
      </xsl:if>
    </xsl:variable>
    <xsl:variable name="iconUrl">
      <xsl:if test="contains($thisValue, ',')">
        <xsl:call-template name="IWURLPLUSGetPartAtIndex">
          <xsl:with-param name="splits" select="$splits"/>
          <xsl:with-param name="index" select="4"/>
        </xsl:call-template>
      </xsl:if>
    </xsl:variable>

    <xsl:variable name="desc" select="$thisNode/@*[name()=concat(current()/@Name, '.desc')]" />
    <xsl:choose>
      <xsl:when test="$url=''">
      </xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="$displayFormat='Image'">
            <img src="{$url}" alt="{$desc}" />
          </xsl:when>
          <xsl:otherwise>
            <a href="{$url}" >
              <xsl:if test="$openInNewWindow='Always'">
                <xsl:attribute name="target">_new</xsl:attribute>
              </xsl:if>
              <xsl:choose>
                <xsl:when test="$showAsIcon='True'">
                  <img border="0">
                    <xsl:attribute name="alt">
                      <xsl:choose>
                        <xsl:when test="$desc=''">
                          <xsl:value-of select="$url"/>
                        </xsl:when>
                        <xsl:otherwise>
                          <xsl:value-of select="$desc"/>
                        </xsl:otherwise>
                      </xsl:choose>
                    </xsl:attribute>
                    <xsl:attribute name="src">
                      <xsl:choose>
                        <xsl:when test="$iconUrl='Link'">/_layouts/images/LINK.GIF</xsl:when>
                        <xsl:when test="$iconUrl='Help'">/_layouts/images/hhelp.gif</xsl:when>
                        <xsl:when test="$iconUrl='Warning'">/_layouts/images/WARN16.GIF</xsl:when>
                      </xsl:choose>
                    </xsl:attribute>
                  </img>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:choose>
                    <xsl:when test="$desc=''">
                      <xsl:value-of select="$url"/>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:value-of select="$desc"/>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:otherwise>
              </xsl:choose>
           </a>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

 

And that's it. Pretty easy, huh?!

Loading...

Add your comment

Comments are not designed to replace support calls. If you have a specific issue with one of our products, please send an email to support@infowisesolutions.com to open a support ticket.

UltimateForms

Build powerful business applications in SharePoint using only your browser.
100% No-Code Solution

It's never been easier, to create, innovate and share, all you need is your web browser!

Cost-effective

Address business process pain points immediately. Save time and money.

Fantastic Support Team

Facing difficulties installing the application? Contact our fantastic support team.

support@infowisesolutions.com

Related Topics

What is right for you?

Online Trial

Not ready to install yet? Create a trial site in our environment
  • Full control of the site and its settings
  • Optionally pre-install one of our solution templates
  • Site provisioned instantly
  • Automatically removed after 30 days
  • Available to everyone!

Error!

There was an error processing your request.
Please contact us for further details.

Installation

Install in your own environment, on Microsoft 365 and on premises
  • Start working with real users and data
  • Install online or on premises
  • Register for 30 day trial
  • Seemlessly convert to paid license
  • Requires administrator permissions

Success!

Download link has been emailed to .
If you do not receive it within 5 minutes, please check your spam.
The link is valid for 72 hours.
If you are having problems, please contact us.

Error!

There was an error processing your request.
Please contact us for further details.
Technical details:

Request a Live Demo

Book an appointment for a one-on-one with an ULTIMATEforms expert trainer.

Test drive the awesome power of ULTIMATEforms

Learn how to quickly and easily turn time-consuming business processes into automated, efficient workflows.

Have a strong start

Only thirty minutes of well-coached time can translate into great future savings in time and money. So, sit back and enjoy the ride.

It's Free

Learn how to address business process pain points immediately. Save time and money.