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>

78 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!

    Reply
    • 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.

      Reply
    • 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.

      Reply
      • 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

        Reply
        • 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.

          Reply
  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
    …….

    Reply
    • 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.

      Reply
      • 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

        Reply
        • 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.

          Reply
  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

    Reply
  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

    Reply
    • 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

      Reply
        • 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.

          Reply
          • 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.

            Reply
            • 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>
              
              Reply
  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.

    Reply
    • 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?

      Reply
      • 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….

        Reply
        • 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.

          Reply
          • 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!

            Reply
  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.

    Reply
  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!!

    Reply
    • 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.

      Reply
      • 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.

        Reply

Leave a Reply