Skip to main content

Go Search
Home
Surveys
Badges
  

Bloggings by PlanetParker > Posts > SharePoint Data View: Dynamically Grouping People Columns
SharePoint Data View: Dynamically Grouping People Columns

Okay, so hopefully you've found this post quickly and with minimal effort, because I couldn't imagine anyone going through the pure XSL hell that I just did these last 2 days. Yes, that's correct—two days I spent trying to figure out how to get a data view to dynamically group on a people-type column. When I say dynamically, I mean not by applying a static grouping through SharePoint Designer (although that too has its own issues), I'm talking about the nifty toolbar you can add to your data view to allow users to perform sorting, grouping, and filtering of your custom view. This is absolutely critical unless you want to spend you days and nights copying and modifying individual views to accommodate every possible sort and grouping scenario your users might come up with. At any rate, it sounds like it should be really simply, huh? Perhaps a built-in feature even, eh? Or at a minimum just using the sorting and grouping dialog correctly, right? Pffftt…yeah, I thought so too. image

(diagram above shows normal behavior when working with views within SharePoint’s end-user interface)

Here's what happens: In SharePoint designer, you first try to apply static grouping to your data view. Sure, it adds the need grouping headers, but unfortunately every entry is displayed within its own "group", which is obviously completely pointless. Here’s what it looks like:

clip_image002

Through some quick research you'll find that these people columns actually output a whole slew of data that's not actually rendered on the screen. Here's an example:

You see this: Doe, John

Sharepoint is hiding this: "<nobr><span><A HREF="/cl/XY/XYpeople/_layouts/userdisp.aspx?ID=231">Doe, John</A><img border="0" height="1" width="3" src="/_layouts/images/blank.gif"/><a href='javascript:' onclick='IMNImageOnClick();return false;' class='ms-imnlink'><img name='imnmark' title='' border='0' height='12' width='12' src='/_layouts/images/blank.gif' alt='No presence information' sip='John.Doe@Anycorp.com' id='imn_522,type=sip'/></a></span></nobr>"

 

Aside from being information overload for most purposes, it creates the very thing hated by the Group function: Uniqueness. If you look closely at the information, you see that there is a unique number embedded. What does it do? I have no idea, nor do I care. All I know is that by making each individual entry unique, my grouping won't work. So yes, don't worry, there is an easy way to truncate it so that you end up with a value that will not necessarily be unique, so you can get some grouping action going on.

No, it's not the usual "disable-output-escaping" statement…UGH!! That only fixes the display of the field in your html—it does nothing to fix the grouping problem.

Okay, so it's actually a really easy substring statement that you may have already found in your Google searches because you're better than me. If not, it looks like this:

<xsl:value-of select="substring-before(substring-after(substring-after(@ContactPerson, '?ID='), '&gt;'), '&lt;')" />

Which returns this:

"<nobr><span><A HREF="/cl/XY/XYpeople/_layouts/userdisp.aspx?ID=231">Doe, John

Notice that the id=imn_522 isn't there, only repeatable data that can easily be grouped together now. Sure, you can substring it even more to get just "Doe, John" returned, but after two days of banging my head against the keyboard trying to solve the grouping problem, I didn't bother. I'm fairly certain you could find about 2,000 other blogs with this information if you're interested.

 

Okay, so we have unique values and we're ready to watch SharePoint do some killer grouping, right!?? BUZZZ Wrong. This next part is really the key, and was the thing that eluded me for two days because it's just not documented anywhere that I could find. Now I'm sure as soon as I say that, I'll get 30 comments with links to everyone's blog with clear and easy instructions that have been out there for 2 years. Sure, maybe's it's out there. Heck, with as little sleep I've gotten lately, I'd probably miss it in my searches even if my wife posted a note on the fridge with the code. Okay, just in case you DON'T have the answer, Smarty-Pants, here it is:

Within your xsl, there is a section that deals specifically with evaluating the row data and grouping it. The problem, is that for some wholly ungodly reason, there is nothing in the code to deal with the people data type, so it just treats it as regular data and and it reads the entire string of the people column, which means that unique identifier slips in an ruins our grouping.

So in order to fix it, we need to tell the XSL to do something differently when we encounted this particular people field so that we can strip out the uniqueness part, before the grouping happens.  To do this, you simply add an xsl:choose branch to tell it to deal with people columns in the fashion mentioned above (substringing it to remove the unique identifier). The section of code you need to find is the dvt_1.body template section. In it, you'll find this block of code:

<xsl:variable name="NewGroup_adhoc">

<xsl:choose>

        <xsl:when test="$dvt_groupfield">

<xsl:value-of select="ddwrt:NameChanged(string(*[name()=$dvt_groupfield] | @*[name()=$dvt_groupfield] | current()[name(.) = $dvt_groupfield]), 0)" /></xsl:otherwise>    

        <xsl:otherwise></xsl:otherwise>

    </xsl:choose>

</xsl:variable>

 

Replace it with this block:

 

<xsl:variable name="NewGroup_adhoc">

<xsl:choose>

        <xsl:when test="$dvt_groupfield">

            <xsl:choose>

                <xsl:when test="contains($dvt_groupfield, 'ContactPerson')"> <xsl:value-of select="ddwrt:NameChanged(string(substring-before(@ContactPerson,'&lt;/A&gt;')), 0)"/></xsl:when>

                <xsl:otherwise><xsl:value-of select="ddwrt:NameChanged(string(*[name()=$dvt_groupfield] | @*[name()=$dvt_groupfield] | current()[name(.) = $dvt_groupfield]), 0)" /></xsl:otherwise>    

            </xsl:choose>

        </xsl:when>

        <xsl:otherwise></xsl:otherwise>

    </xsl:choose>

</xsl:variable>

 

WAIT!! There's one little tweak you need to make, and it's only because I'm a hack. Yes, that's right, I had to hard-code <crowd gasp> the contains criteria to distinguish the specific people field from other normal fields. I'm certain there is a way around this to make it more generic and reusable, and I actually intend to track that down later, so I'll certainly pass it along when I figure it out. For now though, in hopes that I can save you some frustration, just replace the word 'IT' in the code above with something that resembles the people field name that you're trying to group on. In my case, the actual field name was @ContactPerson. Okay, okay, it's a hack…I already said that…geez. But, it works for now, and that's all that matters.

 

image

 

Okay, I'm done here—just wanted to pass this along while it was fresh in my mind (and before I got too lazy to bother posting it). Hope it helps.

 

 

 

 

Like this post?  Why not RE Tweet this and we'll automatically tweet about it on your behalf!

Comments

Thank you!

Worked like a charm!!!!  Thank you for posting this!
at 8/13/2009 5:34 PM

Working well

thanks for ur help!!!
at 1/25/2010 8:03 AM

wow

thank you very much for such interesting post, though I have a question, is it possible to group multiple columns without actually nesting them, cause its been bothering me using ddwrt:NameChanged(string(@xxx), id) specially setting the id for multiple columns.

thanx again,
Zafer
at 2/8/2010 2:22 PM

Problem getting count to work on AssignedTo

I am grouping my ServiceRequest by AssignedTo in my dataview, but count is not working properly. When AssignedTo is empty, or equals a group name, I get an accurate count, but when AssignedTo is a person, I get '0'. The nodeset value in 'dvt_1.groupheader0' looks like this:


<xsl:with-param name="nodeset" select="msxsl:node-set($dvt_Rows)/root//Row[((@AssignedTo)=$groupheader0 or ((not(@AssignedTo) or @AssignedTo='') and $groupheader0=' '))]" />

Any thoughts on what I am doing wrong?

Randy
randell.schmidt@trak-1.com
at 3/2/2010 3:00 PM

Problem getting count to calculate correctly

I'm having the same issue as Randy.  If the column is any data type other than 'user' it calculates correctly, but when it contains a user value it is always zero (0).  Any assistance would be appreciated.
at 3/30/2010 5:21 PM

Grouping works, no count

I can group and sort all day long, but as soon as I try to count or sum by Contact Person, my count is always 0 too. I've been searching the web and not finding any answers. Anyone have any ideas?
at 5/7/2010 8:38 AM