Vladi Gubler
Vladi Gubler
September 22, 2011

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 meant for support. If you experiencing an issue, please open a support request.
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
In addition to our responsive support team, a wide variety of resources, documentations, tutorials, blogs and webinars is available to you
ULTIMATEforms is a complete platform that enables everyone to easily create and maintain Microsoft SharePoint-based business solutions without a single line of code
Powerful Forms
State-of-the-art responsive forms, complete with tabs, permissions, dynamic rules, repeating sections, electronic signatures and advanced validation, powered by our AI-assisted form generator
Powerful Automation
Replace complex workflows with simple, but powerful actions to create and update data inside SharePoint and in a variety of integrated applications and databases
Powerful Reporting
Transform data into actionable insights with detailed exportable reports, sophisticated dashboards, color-coded calendars and dynamic charts
100’s of Templates
Build and replicate business solutions with ease, selecting from our vast free library and creating your own custom templates, all installed with a single click
Dive deeper
Watch a short introductory video showcasing the different unique capabilities of UltimateForms.
Ready to get started?
Hands-on training is the best way to get proficient. That's why we've created three unique training offerings which will help you master ULTIMATEFORMS. Our interactive sessions are delivered via web meetings and conducted within personal virtual workspaces.
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
In addition to our responsive support team, a wide variety of resources, documentations, tutorials, blogs and webinars is available to you
Microsoft partner logo
© 2005-2024 Infowise Solutions Ltd. All rights reserved.
Privacy | Cookie Policy | Accessibility | Cloud SLA