Displaying a Multi-Select Column "Nicely"

UPDATE 2010-08-26: I’ve added this template to the SPXSLT project on Codeplex. There’s a bit more explanation there.

UPDATE 2010-04-27: Shalin Parmar pointed out in a comment below that I had  a bug in the template where the separator would only be displayed between the first and second values.  I’ve made a change to the template to fix this as well as to allow markup in the separator.  Thanks, Shalin!

Here’s another little utility piece of XSL which I have used from time to time.  It takes as its parameters the multi-select column’s value and a separator string.  The template will replace every occurrence of the semi-colon (;) in the multi-select value with the separator string.  This is another example of what you can pull off with recursion in your XSL templates.

Instead of seeing something like this:

value1;value2;value3

if you pass in ‘ | ‘ as the separator, you’ll see

value1 | value2 | value3

<xsl:template name="MultiSelectDisplay">
  <xsl:param name="MultiSelectValue"/>
  <xsl:param name="MultiSelectSeparator"/>
  <xsl:choose>
    <xsl:when test="contains($MultiSelectValue, ';')">
      <xsl:value-of select="concat(substring-before($MultiSelectValue, ';'), $MultiSelectSeparator)" disable-output-escaping="yes"/>
      <xsl:call-template name="MultiSelectDisplay">
        <xsl:with-param name="MultiSelectValue" select="substring-after($MultiSelectValue, ';')"/>
        <xsl:with-param name="MultiSelectSeparator" select="$MultiSelectSeparator"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$MultiSelectValue" disable-output-escaping="yes"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

Similar Posts

85 Comments

  1. What if you want to do the opposite- that is, you have values that you WANT to delimit with a semicolon? I have a text string that is produced when an infopath form repeating table’s values are promoted to SharePoint. They are not delimited and I would like them to be. Thanks!

    1. Can you post an example of the values? As long as there’s *some* sort of delimiter (even spaces if they only occur at value breaks) you can make it work.

      M.

    1. Marja:

      Sure! The way the XSL template works, you can pass in anything you want for the MultiSelectSeparator parameter. To put each value on a new line, pass in

      <br>

      .

      As for the hyperlinks, you’d need to alter the template a little. What would you want the hyperlinks to be? If it’s something like http://servername/sitename/page.aspx?Value=thisValue (where thisValue is each multi-select value), then it’s easy. If the links would vary, then it probably would be hard.

      M.

      1. Marc,

        Works like a charm.

        Indeed my links would be a link back to the dispform od this value, just like in a listviewwebpart. When I put

        <a href="URLLookup('{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}', 'lookup_x0020_field', string(@Title))}" rel="nofollow">

        around it only works for the first lookupvalue. The second lookupvalue get the link from the first lookupvalue. How to solve this? Or is there some jquery or javascript that would make this work?

        For an example see http://www.potatopro.com/Lists/Conferences/DispForm.aspx?ID=82 under featured organizers.

        Thanks in advance
        Marja

        1. I’m not sure that you have enough information in the lookup column values to add the hyperlinks. You may need to lookup the values in the source list to get the information to build the hyperlinks correctly. In the link that you are building above, you’ll be passing the same vaue in for @Title every time, so the links will be a constant. Would it work to do this?

          <xsl:template name="MultiSelectDisplay">
            <xsl:param name="MultiSelectValue"/>
            <xsl:param name="MultiSelectSeparator"/>
            <xsl:choose>
              <xsl:when test="contains($MultiSelectValue, ';')">
                <xsl:value-of select="concat(substring-before($MultiSelectValue, ';'), $MultiSelectSeparator)"/>
                <xsl:call-template name="MultiSelectDisplay">
                  <xsl:with-param name="MultiSelectValue" select="substring-after($MultiSelectValue, ';')"/>
                </xsl:call-template>
              </xsl:when>
              <xsl:otherwise>
                <a href="URLLookup('{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}', 'lookup_x0020_field', string($MultiSelectValue))}" rel="nofollow">
              </xsl:otherwise>
            </xsl:choose>
          </xsl:template>

          M.

              1. If I want to implement this in a Custom Form in SharePoint Designer, where exactly would I place the 2 parts of code. Thanks for the help.

  2. Hi,

    I need a multi select in XSL in which user should be able to select multiple options and submit the form(FYI multiselect is a part in the page i was developing.) Data in XML looks like

    1
    Chinese

    2
    Japanese

    3
    English

    4
    French
    …….

    1. I would assume that you’ve then got a multi-select column defined for your list? Isn’t SharePoint rendering a multi-select control for you?

      M.

      1. Actually i was new to XSLT and was wondering how to define the XSL multi-select. I had never used the XSL multi select before. I am using it in JAVA to develop the webb application.

        Any instance into multi-select is highly appreciated.

        Kiran

        1. I think you may be working way too hard. Assuming that you are building a form to add items to a SharePoint list, all you need to do is define the column to be a multi-select, and SharePoint renders the right control for you. No Java, no XSL required.

          M.

  3. I want to replace all these check boxes with multi-select

    checkbox
    true
    bosnian

    true

    BOSNIAN

    checkbox
    true
    Chinese

    true

    CHINESE

    checkbox
    true
    english

    true

    ENGLISH

    Kiran

    1. Again, if you are putting the values into a list, you just need to change the column to be a multi-select, and SharePoint will render the right control for you.

      M.

  4. Marc,

    Great tip. I am trying to accomplish exactly this, except with a multi-select SharePoint lookup column, so my data looks like: 1;#Value1;2;#Value2;3;#Value3. I’m having trouble getting the XSL correct with the goal of removing the IDs. Can you help?

    Fred

    1. Hi Fred,

      I didnt get your question correctly, can you explain in detail. Upto my understanding you need multi-select with different values but without id’s right. In xslt in order to get the multi-select check boxes you need to assign all the values with same name. So that in javascript you call that name and assign it to an array and us that array either for further javascript funcionalities or can assign it to the URL(for submit button). In this case you no need assign the values with ID’s, you can invoke the value by calling the name like getELementByName(“”);

      If the above info doesn’t helps to solve your problem let me know with the exact issue.

      Kiran

    2. Fred:

      What type of column are you looking up into? I want to reproduce this on my end so that I can give you a good answer.

      M.

        1. Is the Single line of text also a lookup? When I set up a Lookup column to a Single line of text column, I get a value that looks like this:
          Washington;Alabama;Alaska;Alberta;Arizona;Arkansas;British Columbia;California;Colorado

          M.

          1. Marc: To recap, I have two lists. List “A” has a multi-select lookup column the source of which is the “Title” field of list “B”. When I display the multi-select lookup column in my DVWP, it renders like this: 1;#Value1;2;#Value2;3;#Value3. One detail that I didn’t mention previously is that I am using the SharePoint lists web service to retrieve the data since it resides in another site collection. Not sure why/if that would matter. Thanks.

            1. Aha! Yes, the Web Service access does matter, as the values are actually returned differently. I’ll try to reproduce and get back to you.

              M.

            2. After some back and forth in email, Fred and I agreed that he had posted his values incorrectly in his initial comment (I’ve corrected it). Here’s what the values coming back from the Lists Web Service for a multi-select column look like:

              247;#Miami;#1;#Abington;#2;#Acton;#3;#Acushnet;#4;#Adams;#5;#Agawam;#6;#Amesbury;#7;#Amherst;#8;#Amherst Center

              and here’s the XSL to format it “nicely”:

              <xsl:template name="MultiSelectDisplay">
                <xsl:param name="MultiSelectValue"/>
               <xsl:param name="MultiSelectSeparator"/>
                <xsl:choose>
                  <xsl:when test="contains($MultiSelectValue, ';#')">
                    <xsl:value-of select="concat(substring-before(substring-after($MultiSelectValue, ';#'), ';#'), $MultiSelectSeparator)"/>
                    <xsl:call-template name="MultiSelectDisplay">
                      <xsl:with-param name="MultiSelectValue" select="substring-after(substring-after($MultiSelectValue, ';#'), ';#')"/>
                    </xsl:call-template>
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="substring-after($MultiSelectValue, ';#')"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:template>
              
  5. Hey, this is exactly what I am looking for…but where do I put this code into Sharepoint? I have the Content Editor Web Part added to the bottom of the page, and I tried adding the code to the source editor…Sorry if this sounds stupid. I’m new to this.

    1. Bobby:

      This is an XSL template which you swould use in a Data View Web Part (DVWP), not in a Content Editor Web Part (CEWP). Can you explain what you are trying to accomplish?

      1. I have a check list called “Lead Status”. Lets pretend the choices are: Choice 1, Choice 2, Choice 3, Choice 4, and Choice 5.

        When the user has all of these choices selected, it shows up like this: Choice 1; Choice 2; Choice 3; Choice 4; Choice 5 (on the column view)

        ….which looks ugly, and not very user friendly when an employee is trying to quickly view the progress of the lead status of a particular company

        What I want, is just what your title says. To display a Multi-Select Column “Nicely”. But instead of putting the “|” as a replacement for the “;”…. I want to show them as an organized list:

        Choice 1
        Choice 2
        Choice 3
        Choice 4
        Choice 5

        ……..or in my case;

        Completed Initial Discussion and Fact Finding
        Identified Key Contacts
        Followed-up to Discuss Proposal
        etc….

        1. Bobby:

          OK, to use the template in this post, you’ll need to convert the List View Web Part (LVWP) to XSLT (which gives you a DVWP). The other option would be to use some script on the page which alters how the values are shown on page load.

          M.

          1. Yes, I was able to convert the list view to XSLT from within Sharepoint Designer. And, I see this code as default:

            Do I edit this? replace it with your code? Thanks for your help!

  6. Hi Mark,

    I am not able to get this working for my multi-select lookup column. I can easily put the “|” separator and it will work however, when I put ‘<br>’ for the separator it shows me value1value2 and so on….

    Also, the loojup column hyperlink is removed and shown as a plain text.

    Please help on how to get these two resolved.

    1. Shalin:

      To use the <br/> tag as your separator, you’d need to pass it in encoded and within single quotes, like so:

      <xsl:call-template name="MultiSelectDisplay">
        <xsl:with-param name="MultiSelectValue" select="@ColumnName"/>
        <xsl:with-param name="MultiSelectSeparator" select="'&lt;br/&gt;'"/>
      </xsl:call-template>
      

      Let me know if this works for you.

      I’m not sure what you mean by the lookup column not being a link.

      M.

      1. That is exactly what I am doing…..your comments section encoded my lt and gt to make it like . Still it shows me val1 val2 ……

        Regarding hyperlink, here is the case. By default the lookup column will render as hyperlink val1; val2; val3 each taking to their metadata page in the lookup list. However, once I call the template to relpace the ; character it shows as text and we can’t get to that metadata lookup page!

        1. Sounds like you want it to work a little differently then I did in the original post. I think you’ll just need to tweak the template to preserve the markup.

          M.

          1. Well I am trying to achive the following:

            – I have a multi-select look-up columns in a list
            – I want to use the recursive template that you created on that column so that my lookup values are rendered as
            val1
            val2
            val3
            instead of val1; val2; val3.

            Also, as this is a lookup column all the values are rendered as hyperlinks which is what I also want! This is how the elements are rendered on the page:

            Assembly Test Stage Planning PS; Component Test Stage Planning PS; Execute Test Stage PS; Global Systems Testing PS; Operational Readiness Test Stage Planning PS; Requirements Risk Assessment PS; Test Strategy PS; User Acceptance Test Stage Planning PS “

  7. <xsl:with-param name="MultiSelectSeparator" select="$MultiSelectSeparator"/>
    

    This needs to be added to the recursion while calling the template at second occurence for me to work the template. Otherhwise it will only show the replacing character after the first value and not after that.

    Also, even replacing ; with | also removes the hyperlinks and shows plain text!!

    1. Shalin:

      You are indeed correct! I’m sorry about that. I’m surprised no one has brought it to my attention before. I’ve updated the template, and I think it ought to work for you now. As for the links, they are not actually stored in the value; SharePoint adds them at render time. You could replicate this piece, but my template was never intended to do that.

      M.

      1. Hi Mark,

        The template does work now to have the lookups in new line. But the problem still remains on how the render them as links. Please let me know if you have any ideas on the same.

        1. You’re going to need to enhance the template to do a lookup into the reference list to get the right link for each value.

          M.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.