Linking a Multi-Select Lookup Column (XSLT Solution)

The Problem

A common issue in SharePoint 2010 is dealing with linking 2 lists via a look-up column. That’s easy-peasy.

But, what happens when you want to display a view of a record in the main list? By default, you get a semi-colon delimited list of the items from the look-up list, each linked to their record in the look-up list.

Here’s what the standard behavior looks like:

The standard behavior - opening the related item's display form.
The standard behavior – opening the related item’s display form.

That might be fine in some instances, but what if you want to do something a bit more user-friendly? For example, what if you want to link each look-up item to a page that displays the look-up item’s data and some related data?

Well, you could do that by customizing the standard display page of the look-up table. But, if you do that, you’ll still get the edit ribbon for the look-up item. I’m not a huge fan of the edit ribbon.

I’d rather my users have a more standard web experience. So, I want to link each look-up item to a custom web part page, that pulls in data based on the ID of the item.

The Solution

The best way that I’ve found to do this is to create a custom XSL template, and apply it to the output of your multi-select look-up column in a Data View Web Part. There are a couple of things to understand about how multi-select look-up columns work.

  • For each column of this type, there are 2 data fields returned in a DVWP datasource. One of the fields includes the links to the item’s display form. The other field does not.
  • The field you want to use with the custom XSL Template below is the one that does not already contain links.
  • The field you want will always be the field name with a period (.) appended to the end.
  • This field will contain data that looks like so: ID;Title – where the ID is the numeric ID of the item and Title is the actual title of the item. (or whichever field you used for the look-up).

The always helpful Marc Anderson already had a great sample template out there for handling a similar problem. I just took his template 1 step further.

Here’s the code:


<xsl:template name="MultiSelectDisplay">
<xsl:param name="MultiSelectValue"/>
<xsl:param name="MultiSelectDelimiter"/>
<xsl:param name="MultiSelectSeparator"/>
<xsl:param name="Link"/>
<xsl:param name="ThisID" select="0" />
<xsl:choose>
<xsl:when test="contains($MultiSelectValue, $MultiSelectDelimiter)">
<xsl:variable name="before" select="substring-before($MultiSelectValue, $MultiSelectDelimiter)"/>
<xsl:choose>
<!-- if we have a number, pass it back, but don't display anything -->
<xsl:when test= "string(number($before))!='NaN'">
<a>
<xsl:attribute name="href">
<xsl:value-of select="$Link"/><xsl:value-of select="$before"/>
</xsl:attribute>
<xsl:call-template name="MultiSelectDisplay">
<xsl:with-param name="MultiSelectValue" select="substring-after($MultiSelectValue, $MultiSelectDelimiter)"/>
<xsl:with-param name="MultiSelectDelimiter" select="$MultiSelectDelimiter"/>
<xsl:with-param name="MultiSelectSeparator" select="$MultiSelectSeparator"/>
<xsl:with-param name="Link" select="$Link"/>
<xsl:with-param name="ThisID" select="$before"/>
</xsl:call-template>
</a><br/>
</xsl:when>
<!--Otherwise, display and then pass back -->
<xsl:otherwise>
<xsl:value-of select="concat($before, $MultiSelectSeparator)" disable-output-escaping="yes"/>
<xsl:call-template name="MultiSelectDisplay">
<xsl:with-param name="MultiSelectValue" select="substring-after($MultiSelectValue, $MultiSelectDelimiter)"/>
<xsl:with-param name="MultiSelectDelimiter" select="$MultiSelectDelimiter"/>
<xsl:with-param name="MultiSelectSeparator" select="$MultiSelectSeparator"/>
<xsl:with-param name="Link" select="$Link"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<!-- Display the last item in the list -->
<xsl:otherwise>
<xsl:value-of select="$MultiSelectValue"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

Or, in a pretty picture, because WordPress doesn’t do code includes very well:

Image Version of the Template - pretty colors!
Image Version of the Template – pretty colors!

To call the code, in your DVWP, include this bit, passing in the relevant parameters:

<xsl:call-template name="MultiSelectDisplay">
<xsl:with-param name="MultiSelectValue" select="@Audience1."/>
<xsl:with-param name="MultiSelectDelimiter" select="';#'"/>
<xsl:with-param name="MultiSelectSeparator" select="'<br />'"/>
<xsl:with-param name="Link">/tools/wnepresources/SitePages/Resources%20by%20Audience.aspx?AudienceID=</xsl:with-param>
</xsl:call-template>

And, again – the pretty picture of the code version:

How to call the XSLT from within your DVWP.
How to call the XSLT from within your DVWP.

When you include the “MultiSelectDisplay” template in the DVWP’s stylesheet, and call it, you will get output like so:

Finished Solution - 1 item per line, linked to a custom page.
Finished Solution – 1 item per line, linked to a custom page.

Happy Coding!

Advertisement

7 thoughts on “Linking a Multi-Select Lookup Column (XSLT Solution)

  1. I tried to use this code but wouldn’t work, How are you calling the XSL, You have 2 sections were do you put those exactly?

    1. So, in your web part page, you’ve got a dataviewwebpart, right? And, in that dataview webpart, you’re outputting your multi-select look up column, right? So, anywhere in your xsl stylesheet tags (but outside any other tags) you include the custom template “MultiSelectDisplay.” Then, where you were just calling an xsl:value-of for your multi-select lookup column, instead call the second bit of xsl (the call-template). Does that make sense?

    2. I think an issue is we are using sfilter=sid1, the sid1 is the ID in your version. We use a Sid plus a number. we call the column @RelatedServices_x003a_serviceID,

      Thanks
      Jay

      1. Actually the column is maybe this @serviceID, this column is the id that needs to be at the end of the link, ex: pgView.aspx?sfilter=@serviceID, which is sid20, or sid21 and so on.

      2. So, are you saying that you’re having trouble figuring out how to link to your secondary page? In this snippet, you need to customize the variables to fit your environment:

        <xsl:with-param name="MultiSelectSeparator" select="'
        '"/>
        /tools/wnepresources/SitePages/Resources%20by%20Audience.aspx?AudienceID=

        So, the with-param link should be customized to the page you need it to go to (pgView.aspx?sfilter=, it looks like from what you posted). If you’re not using just the ID of the item (like I’m doing) then you’ll need to customize the MultSelectDisplay template to generate whatever you actually want to pass along.

        Make sense?

      3. Ya that makes sense. We keep getting an error. We placed the template piece in the section of the webpart then placed the call template in a text file and then in the web part properties linked it but get an error doing that. Do you have other screen shots on how you did it?

        Thanks for all the help

      4. I’ve never been able to get SPD to play nicely with XSLT includes. They always error for me, even when they “should” work. I’ll email you the full code from the webpart.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s