<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>IT-Idea</title>
	<atom:link href="http://www.itidea.nl/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.itidea.nl</link>
	<description>All about SharePoint</description>
	<lastBuildDate>Wed, 08 Feb 2012 11:14:37 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Empty tooltip in refinement panel</title>
		<link>http://www.itidea.nl/index.php/empty-tooltip-in-refinement-panel/</link>
		<comments>http://www.itidea.nl/index.php/empty-tooltip-in-refinement-panel/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 11:13:13 +0000</pubDate>
		<dc:creator>Anita</dc:creator>
				<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[xslt]]></category>

		<guid isPermaLink="false">http://www.itidea.nl/?p=1352</guid>
		<description><![CDATA[Sometimes when hovering over a fieldvalue in the refinementpanel the tooltip displays only &#8216;Refine By:&#8217; without displaying any value.

While another displays an actual value:
Actual term in a tree

or just a &#8216;parent&#8217; term

Why?
When the fieldvalue is less than 19 characters the tooltip stays empty. Well empty.. it displays &#8216;Refine By:&#8217;. Every fieldvalue with more than 19 [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes when hovering over a fieldvalue in the refinementpanel the tooltip displays only &#8216;Refine By:&#8217; without displaying any value.<br />
<a href="http://www.itidea.nl/wp-content/uploads/2012/02/EmptyTooltipRefinementPanel01.png"><img class="alignnone size-full wp-image-1353" title="EmptyTooltipRefinementPanel" src="http://www.itidea.nl/wp-content/uploads/2012/02/EmptyTooltipRefinementPanel01.png" alt="EmptyTooltipRefinementPanel" width="140" height="157" /></a></p>
<p>While another displays an actual value:<br />
Actual term in a tree<br />
<a href="http://www.itidea.nl/wp-content/uploads/2012/02/EmptyTooltipRefinementPanel02.png"><img class="alignnone size-full wp-image-1354" title="Actual term in a tree" src="http://www.itidea.nl/wp-content/uploads/2012/02/EmptyTooltipRefinementPanel02.png" alt="Actual term in a tree" width="248" height="163" /></a></p>
<p>or just a &#8216;parent&#8217; term<br />
<a href="http://www.itidea.nl/wp-content/uploads/2012/02/EmptyTooltipRefinementPanel03.png"><img class="alignnone size-full wp-image-1355" title="Parent term" src="http://www.itidea.nl/wp-content/uploads/2012/02/EmptyTooltipRefinementPanel03.png" alt="Parent term" width="501" height="168" /></a></p>
<h3>Why?</h3>
<p>When the fieldvalue is less than 19 characters the tooltip stays empty. Well empty.. it displays &#8216;Refine By:&#8217;. Every fieldvalue with more than 19 characters is displayed in the tooltip. A &#8216;parent&#8217; term or a whole path.</p>
<h3>How to solve?</h3>
<p>This behavior can be solved by adjusting the xslt.</p>
<p>Original xslt:</p>
<pre class="brush: xml;">
&lt;a href=&quot;{$SecureUrl}&quot; title=&quot;{$RefineByHeading}: {$UrlTooltip}&quot;&gt;
&lt;xsl:value-of select=&quot;Value&quot;/&gt;
&lt;/a&gt;
</pre>
<p>Adjusted xslt:</p>
<pre class="brush: xml;">
&lt;xsl:variable name=&quot;UrlTooltipAdjusted&quot;&gt;
 &lt;xsl:call-template name=&quot;format-tooltip&quot;&gt;
 &lt;xsl:with-param name=&quot;tooltip&quot; select=&quot;$UrlTooltip&quot; /&gt;
 &lt;xsl:with-param name=&quot;string&quot; select=&quot;Value&quot; /&gt;
 &lt;/xsl:call-template&gt;
&lt;/xsl:variable&gt;

&lt;a href=&quot;{$SecureUrl}&quot; title=&quot;{$RefineByHeading}: $UrlTooltipAdjusted}&quot;&gt;
&lt;xsl:value-of select=&quot;Value&quot;/&gt;
&lt;/a&gt;

&lt;xsl:template name=&quot;format-tooltip&quot;&gt;
 &lt;xsl:param name=&quot;tooltip&quot; /&gt;
 &lt;xsl:param name=&quot;string&quot; /&gt;
 &lt;xsl:choose&gt;
 &lt;xsl:when test=&quot;$tooltip != ''&quot;&gt;
 &lt;xsl:value-of select=&quot;$tooltip&quot; /&gt;
 &lt;/xsl:when&gt;
 &lt;xsl:otherwise&gt;
 &lt;xsl:value-of select=&quot;$string&quot; /&gt;
 &lt;/xsl:otherwise&gt;
 &lt;/xsl:choose&gt;
&lt;/xsl:template&gt;
</pre>
<p>The &#8216;format-tooltip&#8217; template checks if the tooltip is empty and replaces the tooltip value with the actual fieldvalue if so.<br />
By doing this the tooltip will never be empty and will always show the value of the fieldvalue.<br />
<a href="http://www.itidea.nl/wp-content/uploads/2012/02/EmptyTooltipRefinementPanel04.png"><img class="alignnone size-full wp-image-1356" title="Tooltip shows value" src="http://www.itidea.nl/wp-content/uploads/2012/02/EmptyTooltipRefinementPanel04.png" alt="Tooltip shows value" width="198" height="153" /></a></p>
<h3>Summary</h3>
<p>Besides the fieldvalues also the tooltip values suffer from a character limitation. The values of the refinement panel have a 19 character display limit, the tooltip doesn&#8217;t display the value when the fieldvalue is less than 19 characters.<br />
This and the <a href="http://www.itidea.nl/index.php/refinement-panel-character-display-limitation/">previous post</a> solve these issues by making minor adjustments to the OOTB xslt.</p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.itidea.nl/index.php/empty-tooltip-in-refinement-panel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Refinement panel character display limitation</title>
		<link>http://www.itidea.nl/index.php/refinement-panel-character-display-limitation/</link>
		<comments>http://www.itidea.nl/index.php/refinement-panel-character-display-limitation/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 14:51:39 +0000</pubDate>
		<dc:creator>Anita</dc:creator>
				<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[xslt]]></category>

		<guid isPermaLink="false">http://www.itidea.nl/?p=1333</guid>
		<description><![CDATA[Search refiners can contain managed metadata fields to refine the results. Sometimes the display mode of the values look a bit weird in the refinement panel.
Suppose a sitecolumn of a library is a managed metadata column bound to a global termset. The termset is the parent of a few terms and all of these terms [...]]]></description>
			<content:encoded><![CDATA[<p>Search refiners can contain managed metadata fields to refine the results. Sometimes the display mode of the values look a bit weird in the refinement panel.</p>
<p>Suppose a sitecolumn of a library is a managed metadata column bound to a global termset. The termset is the parent of a few terms and all of these terms have one or more children itself. A termtree.<br />
The display format of the column is set to &#8216;Display the entire path to the term in the field&#8217;.<br />
<a href="http://www.itidea.nl/wp-content/uploads/2012/02/MMDRefiner01.png"><img class="alignnone size-full wp-image-1338" title="Managed metadata column" src="http://www.itidea.nl/wp-content/uploads/2012/02/MMDRefiner01.png" alt="Managed metadata column" width="414" height="397" /></a></p>
<p>A few documents are uploaded to the library and the metadata column is set to one of the terms.<br />
A full crawl is completed and the refinement panel shows the metadata refiner.<br />
The refinement panel now looks like this:<br />
<a href="http://www.itidea.nl/wp-content/uploads/2012/02/MMDRefiner02.png"><img class="alignnone size-full wp-image-1340" title="Refinement panel with child terms" src="http://www.itidea.nl/wp-content/uploads/2012/02/MMDRefiner02.png" alt="Refinement panel with child terms" width="166" height="147" /></a></p>
<p>As can be seen, not the whole fieldvalue is displayed. That&#8217;s weird. How do I know which one to use if not the whole value can be seen?<br />
Maybe it&#8217;s a css issue or the left column of the screen isn&#8217;t wide enough? Starting up Firebug and checking out the value:<br />
<a href="http://www.itidea.nl/wp-content/uploads/2012/02/MMDRefiner03.png"><img class="alignnone size-full wp-image-1341" title="Firebug shows value" src="http://www.itidea.nl/wp-content/uploads/2012/02/MMDRefiner03.png" alt="Firebug shows value" width="697" height="171" /></a></p>
<p>The whole value isn&#8217;t present as text to display in the panel! I was seriously surprised!<br />
SharePoint returns only the first 19 characters and three dots&#8230;</p>
<p>But&#8230; hover over de terms and the whole path is displayed. But that&#8217;s not a satisfactory solution, the values have to be displayed properly!</p>
<p>Ok, I agree displaying the whole term tree path isn&#8217;t that useful in this case, but it&#8217;s needed somewhere else in the site, so the display format of the site column has to stay &#8216;Display the entire path to the term in the field&#8217;.<br />
It would be great to have on option to show only the last term value despite the column display format. An excellent configuration place would be an extra attribute in the filter categories definition xml.</p>
<h3>Displaying the last term value</h3>
<p>The xslt of the refinementpanel can be adjusted to display the last term value now we know the tooltip does know the whole value.</p>
<p>Original xslt:</p>
<pre class="brush: xml;">
 &lt;a href=&quot;{$SecureUrl}&quot; title=&quot;{$RefineByHeading}: {$UrlTooltip}&quot;&gt;
  &lt;xsl:value-of select=&quot;Value&quot;/&gt;
 &lt;/a&gt;
</pre>
<p>The new xslt looks a little bit different than that.<br />
First the fieldvalue has to be analyzed if it contains &#8216;:&#8217;. The &#8216;:&#8217; means the value is a child term and the whole tree path is displayed.<br />
From the value which contains the whole tree path the last term is filtered by a recursive xslt template Â´substring-after-lastÂ´.<br />
Then a check has to be performed if the last term value contains the three dots. If it does, the last term value should be taken from the tooltip value, because the xslt Value doesn&#8217;t contain this value. Confusing, isn&#8217;t it?</p>
<pre class="brush: xml;">
&lt;xsl:variable name=&quot;PartOfValue&quot;&gt;
 &lt;xsl:call-template name=&quot;substring-after-last&quot;&gt;
  &lt;xsl:with-param name=&quot;string&quot; select=&quot;Value&quot; /&gt;
  &lt;xsl:with-param name=&quot;delimiter&quot; select=&quot;':'&quot; /&gt;
 &lt;/xsl:call-template&gt;
&lt;/xsl:variable&gt;

&lt;xsl:variable name=&quot;PartOfTooltip&quot;&gt;
 &lt;xsl:call-template name=&quot;substring-after-last&quot;&gt;
  &lt;xsl:with-param name=&quot;string&quot; select=&quot;$UrlTooltip&quot; /&gt;
  &lt;xsl:with-param name=&quot;delimiter&quot; select=&quot;':'&quot; /&gt;
 &lt;/xsl:call-template&gt;
&lt;/xsl:variable&gt;

&lt;xsl:choose&gt;
 &lt;xsl:when test=&quot;($FilterCategoryType = 'Microsoft.Office.Server.Search.WebControls.TaxonomyFilterGenerator') and ($PartOfValue != '')&quot;&gt;
  &lt;xsl:if test=&quot;not(contains($PartOfValue, 'â€¦'))&quot;&gt;
   &lt;xsl:value-of select=&quot;$PartOfValue&quot;/&gt;
  &lt;/xsl:if&gt;
  &lt;xsl:if test=&quot;contains($PartOfValue, 'â€¦')&quot;&gt;
   &lt;xsl:value-of select=&quot;$PartOfTooltip&quot;/&gt;
  &lt;/xsl:if&gt;
 &lt;/xsl:when&gt;
 &lt;xsl:otherwise&gt;
  &lt;xsl:value-of select=&quot;Value&quot;/&gt;
 &lt;/xsl:otherwise&gt;
&lt;/xsl:choose&gt;
</pre>
<p>If the fieldvalue contains less than 19 characters, no dots are displayed and the value can be used, but in that case the urltooltip is empty&#8230; To solve an empty tooltip, check out <a href="http://www.itidea.nl/index.php/empty-tooltip-in-refinement-panel/">my next post</a>.</p>
<p>After the xslt has been implemented the refinementpanel looks like the picture below<br />
<a href="http://www.itidea.nl/wp-content/uploads/2012/02/MMDRefiner041.png"><img class="alignnone size-full wp-image-1345" title="Adjusted refinementpanel" src="http://www.itidea.nl/wp-content/uploads/2012/02/MMDRefiner041.png" alt="Adjusted refinementpanel" width="148" height="148" /></a></p>
<p>And the tooltip displays the whole term tree:<br />
<a href="http://www.itidea.nl/wp-content/uploads/2012/02/MMDRefiner06.png"><img class="alignnone size-full wp-image-1346" title="Tooltip" src="http://www.itidea.nl/wp-content/uploads/2012/02/MMDRefiner06.png" alt="Tooltip" width="256" height="148" /></a></p>
<p>SharePoint returns only the first 19 characters, so what happens when a term itself exists of 19 or more characters?<br />
<a href="http://www.itidea.nl/wp-content/uploads/2012/02/MMDRefiner05.png"><img class="alignnone size-full wp-image-1343" title="Refinement panel with long term" src="http://www.itidea.nl/wp-content/uploads/2012/02/MMDRefiner05.png" alt="Refinement panel with long term" width="201" height="148" /></a></p>
<p>On the one hand it&#8217;s great the 19 character limitation of displaying a whole termtree isn&#8217;t applied to this term, on the other hand, it doesn&#8217;t look very nice when the text continues outside the refinement panel.</p>
<h3>Summary</h3>
<p>The values of the refinement panel have a 19 character display limit. When displaying a whole termtree it&#8217;s likely this limitation will be exceeded. Just a few xslt adjustments are necessary to display the fieldvalues correct again.</p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.itidea.nl/index.php/refinement-panel-character-display-limitation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ever tried to update a user subtype from code?</title>
		<link>http://www.itidea.nl/index.php/ever-tried-to-update-a-user-subtype-from-code/</link>
		<comments>http://www.itidea.nl/index.php/ever-tried-to-update-a-user-subtype-from-code/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 12:57:31 +0000</pubDate>
		<dc:creator>Anita</dc:creator>
				<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>

		<guid isPermaLink="false">http://www.itidea.nl/?p=1324</guid>
		<description><![CDATA[User subtypes are one of the many new and nice things in SharePoint 2010.
The other day I was editing user profiles and changed the subtype for this profile in code. After changing the user subtype Commit() was called and I thought I was done.
But then it just started, because the user profile wasn&#8217;t updated at [...]]]></description>
			<content:encoded><![CDATA[<p>User subtypes are one of the many new and nice things in SharePoint 2010.<br />
The other day I was editing user profiles and changed the subtype for this profile in code. After changing the user subtype Commit() was called and I thought I was done.<br />
But then it just started, because the user profile wasn&#8217;t updated at all. No exception, no message at all, just the old user subtype.<br />
The used code:</p>
<pre class="brush: csharp;">
ProfileSubtypeManager psubm = ProfileSubtypeManager.Get(context);
ProfileSubtype newSubtype = psubm.GetProfileSubtype(newSubtypeName);
currentUserProfile.ProfileSubtype = newSubtype;
currentUserProfile.Commit();
</pre>
<p>Changing the user subtype in the UI really updated the setting, so it was time to debug the SharePoint UserProfiles assembly.<br />
The short version of what the debugging session(s) told me:<br />
A UserProfileUpdateWrapper was created with the following xml</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
&lt;MSPROFILE&gt;
 &lt;PROFILE ProfileName=&quot;UserProfile&quot;&gt;
 &lt;USER NewUser=&quot;0&quot; NTAccount=&quot;account&quot; UserID=&quot;3db01e67-abb0-4946-8fa8-85943768cb79&quot;&gt;
</pre>
<p>The next step is iterating through the user profile fields to check if the value &#8216;IsDirty&#8217; aka the value has been changed. This is the only trigger to actually update a user profile.<br />
When adjusting the user subtype from the UI a few properties are updated, even when they&#8217;re not changed. The final XML looks like the following:</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
&lt;MSPROFILE&gt;
 &lt;PROFILE ProfileName=&quot;UserProfile&quot;&gt;
 &lt;USER NewUser=&quot;0&quot; NTAccount=&quot;account&quot; UserID=&quot;3db01e67-abb0-4946-8fa8-85943768cb79&quot;&gt;
 &lt;PROPERTY PropertyName=&quot;Assistant&quot; Privacy=&quot;1&quot; PropertyValue=&quot;&quot; /&gt;
 &lt;PROPERTY PropertyName=&quot;PictureURL&quot; Privacy=&quot;1&quot; PropertyValue=&quot;&quot; /&gt;
 &lt;PROPERTY PropertyName=&quot;SPS-TimeZone&quot; Privacy=&quot;1&quot; PropertyValue=&quot;&quot; /&gt;
 &lt;/USER&gt;
 &lt;/PROFILE&gt;
&lt;/MSPROFILE&gt;
</pre>
<p>and a real update of the user profile occurred.</p>
<p>To make the update work from code appearently another property has to be updated together with the change of subtype. After a test with an update of a random property, the user subtype was updated too.</p>
<h3>Summary</h3>
<p>Changing only the user subtype from code, does trigger the Commit() method, but doesn&#8217;t call the update profile, because no user profile property was changed. Use a dummy property to update every time the user subtype has changed.</p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.itidea.nl/index.php/ever-tried-to-update-a-user-subtype-from-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to delete crawled properties</title>
		<link>http://www.itidea.nl/index.php/how-to-delete-crawled-properties/</link>
		<comments>http://www.itidea.nl/index.php/how-to-delete-crawled-properties/#comments</comments>
		<pubDate>Sun, 20 Nov 2011 16:42:56 +0000</pubDate>
		<dc:creator>Anita</dc:creator>
				<category><![CDATA[SharePoint 2010]]></category>

		<guid isPermaLink="false">http://www.itidea.nl/?p=1311</guid>
		<description><![CDATA[You all know by now how to delete crawled properties and that you&#8217;re not able to delete a single crawled property. When deleting crawled properties, all unmapped properties from a single category get deleted.

In Central Administration select &#8216;Manage service applications&#8217;
Select the Search Service Application
Select &#8216;Metadata properties&#8217;
Select &#8216;Categories&#8217;
Edit the category of your choice
Select &#8216;Delete all unmapped [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.itidea.nl/wp-content/uploads/2011/11/CrawledPropertiesDatabase.png"></a>You all know by now how to delete crawled properties and that you&#8217;re not able to delete a single crawled property. When deleting crawled properties, all unmapped properties from a single category get deleted.</p>
<ol>
<li>In Central Administration select &#8216;Manage service applications&#8217;</li>
<li>Select the Search Service Application</li>
<li>Select &#8216;Metadata properties&#8217;</li>
<li>Select &#8216;Categories&#8217;</li>
<li>Edit the category of your choice</li>
<li>Select &#8216;Delete all unmapped crawled properties&#8217;</li>
<li>Select &#8216;Ok&#8217;</li>
</ol>
<p>First thing to notice here: it deletes only <em>unmapped</em> crawled properties. So if your crawled property is still mapped, remove this first.</p>
<p>Second thing: make sure the crawled property isn&#8217;t included in the index!</p>
<p>First there are two crawled properties in the SharePoint category (well, there are more, I selected two to see the difference&#8230;) :<br />
<a href="http://www.itidea.nl/wp-content/uploads/2011/11/CrawledPropertiesBothPresent.png"><img class="alignnone size-full wp-image-1312" title="CrawledPropertiesBothPresent" src="http://www.itidea.nl/wp-content/uploads/2011/11/CrawledPropertiesBothPresent.png" alt="" width="570" height="77" /></a></p>
<p>One is included in the index, the other isn&#8217;t.<br />
Next step is to clear the SharePoint category by following all the steps above. The result:<br />
<a href="http://www.itidea.nl/wp-content/uploads/2011/11/CrawledPropertiesOnePresent.png"><img class="alignnone size-full wp-image-1313" title="CrawledPropertiesOnePresent" src="http://www.itidea.nl/wp-content/uploads/2011/11/CrawledPropertiesOnePresent.png" alt="" width="570" height="55" /></a></p>
<p>The crawled property included in the index is still present! Even if a full index reset has been performed and the category has beenÂ cleaned up, theÂ crawled properties doesn&#8217;t get deleted when &#8216;Included in index&#8217; is set to &#8216;Yes&#8217;.</p>
<h3>Summary</h3>
<p>Besides unmapping a crawled property, deselect &#8216;Included in index&#8217; in the crawled property&#8217;s properties to delete a crawled property.</p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/11/CrawledPropertiesIncludeInIndexSetting.png"><img class="alignnone size-full wp-image-1314" title="CrawledPropertiesIncludeInIndexSetting" src="http://www.itidea.nl/wp-content/uploads/2011/11/CrawledPropertiesIncludeInIndexSetting.png" alt="" width="640" height="174" /></a></p>
<p>This is a valid and working solution for the most of the crawled properties and certainly your custom ones.</p>
<p>When you&#8217;re going to test this youself, you&#8217;ll notice some of the OOTB unmapped and not include in the indexÂ crawled properties will still be present after performing the steps above. This is the case because SharePointÂ uses some hidden managed properties which are mapped to these crawled properties. Steve Curran explains this<a href="http://vspug.com/smc750/2008/10/10/unable-to-delete-unmapped-crawled-properties-in-sharepoint-search/"> in his post </a><a href="http://www.itidea.nl/wp-content/uploads/2011/11/CrawledPropertiesDatabase.png"></a>which was written for MOSS 2007, but the same principle is still valid for SharePoint 2010:</p>
<p>In table MSSCrawledProperties ows_BaseName can be found with CrawledPropertyId 192.<br />
In table MSSSchemaPropertyMappings CrawledPropertyId 192 is mapped to PID 2147418032.<br />
In table MSSManagedProperties PID 2147418032 is mapped to property TempTitle with &#8216;Hidden&#8217; and &#8216;NoDelete&#8217; set to 1:</p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/11/CrawledPropertiesDatabase2.png"><img class="alignnone size-full wp-image-1317" title="CrawledPropertiesDatabase" src="http://www.itidea.nl/wp-content/uploads/2011/11/CrawledPropertiesDatabase2.png" alt="" width="828" height="32" /></a><a href="http://www.itidea.nl/wp-content/uploads/2011/11/CrawledPropertiesDatabase1.png"></a></p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.itidea.nl/index.php/how-to-delete-crawled-properties/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerShell Foreach vs ForEach-Object</title>
		<link>http://www.itidea.nl/index.php/powershell-foreach-vs-foreach-object/</link>
		<comments>http://www.itidea.nl/index.php/powershell-foreach-vs-foreach-object/#comments</comments>
		<pubDate>Tue, 08 Nov 2011 16:46:57 +0000</pubDate>
		<dc:creator>Anita</dc:creator>
				<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.itidea.nl/?p=1303</guid>
		<description><![CDATA[There are two variants of &#8216;for each&#8217; in PowerShell:
Foreach statement: iterates over a collection of objects
ForEach-Object: obtains its entries from the pipeline
At first they both seemed to do the job, but there are some differences.
Let&#8217;s do a test with a simple array of items and loop through it using both foreach methods. To measure the [...]]]></description>
			<content:encoded><![CDATA[<p>There are two variants of &#8216;for each&#8217; in PowerShell:<br />
Foreach statement: iterates over a collection of objects<br />
ForEach-Object: obtains its entries from the pipeline</p>
<p>At first they both seemed to do the job, but there are some differences.<br />
Let&#8217;s do a test with a simple array of items and loop through it using both foreach methods. To measure the time elapsed to loop the array the Measure-Command is used.</p>
<pre class="brush: powershell;">

$items = 1,2,3,4,5,6,7,8,9,0,10,12,13,14,15,52,58,41,59,841,5,4,1

Write-Host &quot;ForEach-Object: &quot;
(Measure-Command {Â  `
Â $items | ForEach-Object { `
Â Â &quot;Item: $_&quot; `
Â }}).totalmilliseconds

Write-Host &quot;Foreach: &quot;
(Measure-Command {Â  `
Â Foreach ($item in $items) { `
Â Â &quot;Item: $element&quot; `
Â }}).totalmilliseconds
</pre>
<p>MultipleÂ results:<br />
<a href="http://www.itidea.nl/wp-content/uploads/2011/11/ForEach.png"><img class="alignnone size-full wp-image-1306" title="ForEach" src="http://www.itidea.nl/wp-content/uploads/2011/11/ForEach.png" alt="" width="130" height="407" /></a></p>
<p>The results differ a lot!</p>
<h3>
When to use which method?</h3>
<p>When the items of the array are known at forehand, like in the test, foreach is the better approach because of the speed. This kind of speed can only be reached when all the objects are already known and stored in a variable.</p>
<p>ForEach-Object is a different story. When the items have to be collected before the loop starts and this can take a while: use ForEach-Object.<br />
This method processes the objects collected in the array directly when available and doesn&#8217;t wait until all objects are collected.</p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.itidea.nl/index.php/powershell-foreach-vs-foreach-object/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SPHttpUtility vs HTTPUtility</title>
		<link>http://www.itidea.nl/index.php/sphttputility-vs-httputility/</link>
		<comments>http://www.itidea.nl/index.php/sphttputility-vs-httputility/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 09:07:45 +0000</pubDate>
		<dc:creator>Anita</dc:creator>
				<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>

		<guid isPermaLink="false">http://www.itidea.nl/?p=1280</guid>
		<description><![CDATA[Comparison between SPHttpUtility and HTTPUtility &#8211; encoding and decoding
There are different ways of encoding and decoding querystring parameters, for example by using SPHttpUtility or HttpUtility.
While programming SharePoint I always tend to use the SPHttpUtility class, but I didn&#8217;t know exactly why. Until I accidentally used the HttpUtility and SPHttpUtility at the same time:Â I noticed some [...]]]></description>
			<content:encoded><![CDATA[<h3>Comparison between SPHttpUtility and HTTPUtility &#8211; encoding and decoding</h3>
<p>There are different ways of encoding and decoding querystring parameters, for example by using SPHttpUtility or HttpUtility.<br />
While programming SharePoint I always tend to use the SPHttpUtility class, but I didn&#8217;t know exactly why. Until I accidentally used the HttpUtility and SPHttpUtility at the same time:Â I noticed some differences.Â Â </p>
<h3>Encode</h3>
<p>SharePoint has a Utilities namespace, Microsoft.SharePoint.Utilities, which provides the SPHttpUtility class. One of the methods in this class is UrlKeyValueEncode with several overloads.<br />
The description of the methodÂ </p>
<pre class="brush: csharp;">UrlKeyValueEncode(string keyOrValueToEncode)</pre>
<p>is &#8216;Encodes the specified URL query string key or value&#8217;.Â </p>
<p>The HttpUtility class in the namespace System.Web contains a method UrlEnode, also with overloads. The description of</p>
<pre class="brush: csharp;">UrlEncode(string str)</pre>
<p>is &#8216;Encodes a URL string&#8217;.<br />
The HttpUtility class doesn&#8217;t have a method to encode a query string key or value as UrlKeyValueEncode, but this is the best match.Â Â </p>
<p>Let&#8217;s encode a space:<br />
The result while encoding with HttpUtility is &#8216;+&#8217;, encoding with SPHttpUtility results in a &#8216;%20&#8242;.</p>
<p>One of the major differences is the casing of the encoded characters. SPHttpUtility encodes the characters uppercase, HttpUtility lowercase.<br />
Another difference can be seen in the picture below: HttpUtility doesn&#8217;t encode all characters, SPHttpUtility does:Â Â </p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/11/Encoding01.png"><img class="alignnone size-full wp-image-1283" title="Encoding01" src="http://www.itidea.nl/wp-content/uploads/2011/11/Encoding01.png" alt="" width="642" height="219" /></a>Â Â </p>
<h3>Decode</h3>
<p>To decode charactersÂ the SPHttpUtility class provides the method</p>
<pre class="brush: csharp;">UrlKeyValueDecode(string keyOrValueToDecode)</pre>
<p>The couterpart of the UrlEncode method in the HttpUtility class is</p>
<pre class="brush: csharp;">UrlDecode(string str)</pre>
<p>While encoding results in different outcome, decoding doesn&#8217;t.<br />
As can be seen in the picture of the encoded characters above, HttpUtility doesn&#8217;t encode e.g. &#8216;(&#8216;, &#8216;!&#8217;, &#8216;*&#8217;. When decoding these (unencoded) characters with SPHttpUtility the results stay &#8216;(&#8216;, &#8216;!&#8217;, &#8216;*&#8217;. Check the pictures below.<br />
Encoded with HttpUtility, decoded these characters:Â Â </p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/11/Encoding021.png"><img class="alignnone size-full wp-image-1284" title="Encoding021" src="http://www.itidea.nl/wp-content/uploads/2011/11/Encoding021.png" alt="" width="638" height="218" /></a></p>
<p>SPHttpUtility encodes characters &#8216;(&#8216;, &#8216;!&#8217; and &#8216;*&#8217; as &#8216;%28&#8242;, &#8216;%21&#8242; and &#8216;%2A&#8217;. When decoding these characters with SPHttpUtility, but also with HttpUtility, the results are the same:Â Â </p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/11/Encoding022.png"><img class="alignnone size-full wp-image-1285" title="Encoding022" src="http://www.itidea.nl/wp-content/uploads/2011/11/Encoding022.png" alt="" width="644" height="222" /></a>Â Â </p>
<h3>Summary</h3>
<p>Since decoding gives the same results with SPHttpUtility and HttpUtility, why bother the encoding method?Â Â </p>
<p>Well, something inside me tells me SharePoint is using it somewhere internally. I didn&#8217;t figure out where, but why is the SPHttpUtility implemented if SharePoint easily could use HttpUtility?<br />
Besides some feelings, the SPHttpUtility doesn&#8217;t use HttpUtility internally. When checking out the SPHttpUtility.UrlKeyValueEncode with ILSpy, the encoded values, uppercase(!), are listed is the readonly string array s_crgstrUrlHexValue.</p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/11/EncodingILSpy.png"><img class="alignnone size-full wp-image-1286" title="EncodingILSpy" src="http://www.itidea.nl/wp-content/uploads/2011/11/EncodingILSpy.png" alt="" width="605" height="498" /></a>Â Â </p>
<p>Wikipedia has a definition of percent encoding (<a href="http://en.wikipedia.org/wiki/Percent-encoding">http://en.wikipedia.org/wiki/Percent-encoding</a>) :<br />
&#8216;Percent-encoding, also known as URL encoding, is a mechanism for encoding information in a Uniform Resource Identifier (URI) under certain circumstances&#8217;Â Â </p>
<p>According to this article reserved characters (Reserved characters are those characters that sometimes have special meaning) must be encoded&#8230;<br />
According to RFC 3986 reserved characters are:</p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/11/EncodingRFC3986.png"><img class="alignnone size-full wp-image-1287" title="EncodingRFC3986" src="http://www.itidea.nl/wp-content/uploads/2011/11/EncodingRFC3986.png" alt="" width="388" height="59" /></a></p>
<p>And encoded:<br />
<a href="http://www.itidea.nl/wp-content/uploads/2011/11/EncodingRFC3986Encoded.png"><img class="alignnone size-full wp-image-1288" title="EncodingRFC3986Encoded" src="http://www.itidea.nl/wp-content/uploads/2011/11/EncodingRFC3986Encoded.png" alt="" width="677" height="91" /></a>Â Â </p>
<p>So HttpUtility doesn&#8217;t encode the first five characters, SPHttpUtility encodes all reserved characters.Â Â </p>
<p>To be compatible with 3986 standard it seems SPHttpUtility is the best option to use.</p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.itidea.nl/index.php/sphttputility-vs-httputility/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to retrieve document set version history</title>
		<link>http://www.itidea.nl/index.php/how-to-retrieve-document-set-version-history/</link>
		<comments>http://www.itidea.nl/index.php/how-to-retrieve-document-set-version-history/#comments</comments>
		<pubDate>Sun, 21 Aug 2011 09:48:30 +0000</pubDate>
		<dc:creator>Anita</dc:creator>
				<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.itidea.nl/?p=1265</guid>
		<description><![CDATA[Document set versions are slightly different than item versions. Document sets can be managed by a separate ribbon tab called Document Set and group called Manage.

To create a version of a document set the action Capture Version in this part of the ribbon has to be selected. When selecting the following screen will be shown:

To [...]]]></description>
			<content:encoded><![CDATA[<p>Document set versions are slightly different than item versions. Document sets can be managed by a separate ribbon tab called Document Set and group called Manage.<br />
<a href="http://www.itidea.nl/wp-content/uploads/2011/08/DocSetHistory01Ribbon.png"><img class="alignnone size-full wp-image-1272" title="DocSetHistory01Ribbon" src="http://www.itidea.nl/wp-content/uploads/2011/08/DocSetHistory01Ribbon.png" alt="" width="467" height="137" /></a></p>
<p>To create a version of a document set the action Capture Version in this part of the ribbon has to be selected. When selecting the following screen will be shown:<br />
<a href="http://www.itidea.nl/wp-content/uploads/2011/08/DocSetHistory02Version.png"><img class="alignnone size-full wp-image-1273" title="DocSetHistory02Version" src="http://www.itidea.nl/wp-content/uploads/2011/08/DocSetHistory02Version.png" alt="" width="613" height="377" /></a></p>
<p>To use versioning of a document set (and items) versioning has to be enabled on the library.Â Â Â Â </p>
<p>After selecting a version option (when major/minor enabled), adding some comment and selecting the Ok button a document set version is created. To view the versions of the document set the action Version History can be selected in the ribbon.<br />
<a href="http://www.itidea.nl/wp-content/uploads/2011/08/DocSetHistory03VersionHistory.png"><img class="alignnone size-full wp-image-1274" title="DocSetHistory03VersionHistory" src="http://www.itidea.nl/wp-content/uploads/2011/08/DocSetHistory03VersionHistory.png" alt="" width="508" height="374" /></a></p>
<p>In this screen the first column displayed is No. This is not the regular version column of the library, but a totally different one. When creating a document set version the version column of the library doesn&#8217;t change, only the No value.Â Â Â Â </p>
<p>That&#8217;s nice, but where is the version of the document set actually stored?Â Â Â Â </p>
<p>The version(s) of a document set are stored in the propertybag of the item itself.Â Â Â Â </p>
<p>To analyze settings I always start up PowerShell first to check on things. Just because it&#8217;s quick and easy. When I get what I want from PowerShell it&#8217;s easily turned into C# code. I followed the same procedure to get to the storage of document set versions. Since I couldn&#8217;t find the version anywhere in the UI, my first guess was checking the propertybag keys.Â Â Â Â </p>
<pre class="brush: powershell;">
$site=Get-SPSite &quot;http://sp2010dev&quot;
$docList = $site.RootWeb.Lists.TryGetList(&quot;Documents&quot;);
$item = $docList.Items.GetItemById(2)
$prop = $item.Properties
</pre>
<p>Often I use PowerGui Script Editor which gives an excellent overview of variables:Â Â Â Â </p>
<p>The keys:<br />
<a href="http://www.itidea.nl/wp-content/uploads/2011/08/DocSetHistory04ItemKeys.png"><img class="alignnone size-full wp-image-1275" title="DocSetHistory04ItemKeys" src="http://www.itidea.nl/wp-content/uploads/2011/08/DocSetHistory04ItemKeys.png" alt="" width="522" height="406" /></a></p>
<p>And the values:<br />
<a href="http://www.itidea.nl/wp-content/uploads/2011/08/DocSetHistory05ItemValues.png"><img class="alignnone size-full wp-image-1276" title="DocSetHistory05ItemValues" src="http://www.itidea.nl/wp-content/uploads/2011/08/DocSetHistory05ItemValues.png" alt="" width="648" height="344" /></a></p>
<p>While scrolling through the property keys I noticed a key named snapshots. By checking out the value of that key I knew I found it!Â Â Â Â </p>
<p>The following PowerShell command can be used to get the value of the snapshot key:Â Â Â Â </p>
<pre class="brush: powershell;">
$item.Properties.get_Item(&quot;snapshots&quot;)
</pre>
<p>The version history is stored in xml:Â Â Â Â </p>
<pre class="brush: xml;">
&lt;SnapshotCollection NextSnapshotNumber=&quot;3&quot; NextInternalId=&quot;1&quot;&gt;
  &lt;Items /&gt;
  &lt;Snapshots&gt;
    &lt;Snapshot Label=&quot;2&quot; Major=&quot;True&quot; Created=&quot;08/21/2011 07:50:56&quot; By=&quot;username&quot;&gt;
      &lt;Comments&gt;Another version of the document set.&lt;/Comments&gt;
      &lt;Fields&gt;
        &lt;Field Id=&quot;8553196d-ec8d-4564-9861-3dbe931050c8&quot;&gt;Document set name&lt;/Field&gt;
        &lt;Field Id=&quot;fa564e0f-0c70-4ab9-b863-0177e6ddd247&quot;&gt;Document set name&lt;/Field&gt;
        &lt;Field Id=&quot;cbb92da4-fd46-4c7d-af6c-3128c2a5576e&quot;&gt;Add a description here.&lt;/Field&gt;
      &lt;/Fields&gt;
      &lt;SnapshotItems /&gt;
    &lt;/Snapshot&gt;
    &lt;Snapshot Label=&quot;1&quot; Major=&quot;True&quot; Created=&quot;08/21/2011 07:50:20&quot; By=&quot;username&quot;&gt;
      &lt;Comments&gt;This is the first version of this document set.&lt;/Comments&gt;
      &lt;Fields&gt;
        &lt;Field Id=&quot;8553196d-ec8d-4564-9861-3dbe931050c8&quot;&gt;Document set name&lt;/Field&gt;
        &lt;Field Id=&quot;fa564e0f-0c70-4ab9-b863-0177e6ddd247&quot;&gt;Document set name&lt;/Field&gt;
        &lt;Field Id=&quot;cbb92da4-fd46-4c7d-af6c-3128c2a5576e&quot; /&gt;
      &lt;/Fields&gt;
      &lt;SnapshotItems /&gt;
    &lt;/Snapshot&gt;
  &lt;/Snapshots&gt;
&lt;/SnapshotCollection&gt;
</pre>
<p>Â Â Â </p>
<p>The Snapshot element with Label attribute 1 is the first version. The comment is displayed and the fields and values of the document set.Â Â Â Â </p>
<p>The Snapshot element with Label attribute 2 is the second version. The same items are displayed with the addition of the value of the description â€˜Add a description hereâ€™. Thatâ€™s what I changed before creating the second version.Â Â Â Â </p>
<p>The attribute NextSnapshotNumber holds the value of the version number that will be created when creating another version, 3 in this case.Â Â Â Â </p>
<h3>SummaryÂ Â </h3>
<p>Document set versions are different than regular item versions. The version history of a document set is stored in the propertybag of the document set itself as xml.</p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.itidea.nl/index.php/how-to-retrieve-document-set-version-history/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerShell &#8211; Choose between colored host text or write to an output file? Not anymore!</title>
		<link>http://www.itidea.nl/index.php/powershell-choose-between-colored-host-text-or-write-to-an-output-file-not-anymore/</link>
		<comments>http://www.itidea.nl/index.php/powershell-choose-between-colored-host-text-or-write-to-an-output-file-not-anymore/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 13:06:10 +0000</pubDate>
		<dc:creator>Anita</dc:creator>
				<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.itidea.nl/?p=1228</guid>
		<description><![CDATA[In PowerShell multiple Write statements are available. The two statements I want to address are Write-Host and Write-Output.Â 
What do these two do?
Write-Host: Writes customized output to a host
Write-Output: Sends the specified objects to the next command in the pipeline. If the command is the last command in the pipeline, the objects are displayed in the [...]]]></description>
			<content:encoded><![CDATA[<p>In PowerShell multiple Write statements are available. The two statements I want to address are Write-Host and Write-Output.Â </p>
<p>What do these two do?<br />
<em>Write-Host</em>: Writes customized output to a host<br />
<em>Write-Output</em>: Sends the specified objects to the next command in the pipeline. If the command is the last command in the pipeline, the objects are displayed in the consoleÂ </p>
<p>An example of Write-Host</p>
<pre class="brush: powershell;">
Write-Host &quot;Write-Host statement...&quot;
</pre>
<p>The result displayed in the hostÂ </p>
<p>Â <a href="http://www.itidea.nl/wp-content/uploads/2011/07/PSWrite0.png"><img class="size-full wp-image-1230 alignnone" title="PSWrite0" src="http://www.itidea.nl/wp-content/uploads/2011/07/PSWrite0.png" alt="" width="199" height="41" /></a></p>
<p>An example of Write-Output</p>
<pre class="brush: powershell;">
Write-Output &quot;Write-Output statement...&quot;
</pre>
<p>The result displayed in the host</p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/07/PSWrite00.png"><img class="size-full wp-image-1231 alignnone" title="PSWrite00" src="http://www.itidea.nl/wp-content/uploads/2011/07/PSWrite00.png" alt="" width="215" height="44" /></a>Â </p>
<p>At this point there is no difference in the result of these two statements.Â </p>
<h3>Write-Host with ForegroundColorÂ </h3>
<p>A nice parameter of Write-Host is -ForegroundColor. Using this parameter with a color, the text displayed in the host has the color specified. I find this very useful to quickly see if a script hasÂ succeeded or failed. I always display the success message in green, the failed message in red.Â Â Â </p>
<p>To show this the existence of a SPList will be checked. If it doesnÂ´t exist, it will be created using the following statement:Â Â Â </p>
<pre class="brush: powershell;">
$sampleListName = &quot;PS List&quot;
$siteUrl=http://sp2010dev
$site = Get-SPSite $siteUrl
$web = $site.RootWeb&lt;/pre&gt;

function CreateList($listName){
  $web.Lists.Add($listName, &quot;Description for list&quot;, [Microsoft.SharePoint.SPListTemplateType]::GenericList)
}

function CheckIfListExists(){
$currentList = $web.Lists.TryGetList($sampleListName)
  if($currentList -ne $null){
    Write-Host &quot;List exists&quot; -ForegroundColor Green
  }
  else{
    Write-Host &quot;List doesn't exist, creating now...&quot; -ForegroundColor Red
    CreateList $sampleListName
    Write-Host &quot;Check if list exist...&quot;
    CheckIfListExists
  }
}

Write-Host &quot;Calling CheckIfListExists ...&quot;
CheckIfListExists
</pre>
<p>If the list exists a message with green colored text will appear: &#8216;List exists&#8217;, else a message with red colored text will appear: &#8216;List doesn&#8217;t exist, creating now&#8230;&#8217;, followed by the actualÂ creation of the list. After this the existence of the list is check again. As you can see if the list creation fails the code will be stuck in an infinite loop, so donÂ´t use this as production code&#8230;Â Â Â </p>
<p>Outcome when the list doesnÂ´t exist and is created:</p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite01.png"><img class="alignnone size-full wp-image-1244" title="PSWrite01" src="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite01.png" alt="" width="310" height="78" /></a></p>
<p>Outcome when the list already exists:&lt;picture PSWrite02&gt;</p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite02.png"><img class="alignnone size-full wp-image-1245" title="PSWrite02" src="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite02.png" alt="" width="252" height="34" /></a></p>
<h3>Write-Output with output to fileÂ Â Â </h3>
<p>A nice option of Write-Output is the possibility to write the output to a file on the filesystem.Â Â Â </p>
<pre class="brush: powershell;">
$file = &quot;C:\_Tools\OutputFile.txt&quot;
Write-Output &quot;Write-Output statement...&quot;
Write-Output &quot;Write-Output statement...&quot; | Out-File $file
</pre>
<p>The first Write-Output statement writes the output to the host, the second to the file (but not to the host).Â Â Â </p>
<h3>Best of both worlds?Â Â Â </h3>
<p>Ofcourse Write-Host as well as Write-Output has a lot more options to use, but I want to point out something here.<br />
Write-Host can write colored messages to the host, but it can&#8217;t write output to a file.<br />
Write-Output can&#8217;t write colored messages to the host, but it can write output to a file.Â Â Â </p>
<p>What if I want to:Â Â Â </p>
<p>write colored messages to the host if I decide to output to the host AND<br />
write messages to a file just by using &#8216;| Out-File $file&#8217;</p>
<p>With the current possibilities of both operations I have to choose between:<br />
1. colored messages (and nothing written to the output file) or put the output to a file and host, but no colored messages displayed in the hostÂ<br />
2. write double statements; Write-Host with -ForeGroundColor to write the colored output to the host and Write-Output to write the output to a file when using &#8216;| Out-File $file&#8217;.Â Â Â </p>
<p>Let me clarify the second option with an example.</p>
<pre class="brush: powershell;">
Write-Output &quot;Write-Output statement...&quot; | Out-File $file
Write-Host &quot;Write-Host statement...&quot; -ForegroundColor Blue
</pre>
<p>Write-Output writes the message to the file specified in $file and is not written to the host.<br />
Write-Host writes the message to the host in the color blue.<br />
Just as expected and just want I wanted. But I have to write the messages twice.</p>
<p>Another option:Â Â Â </p>
<pre class="brush: powershell;">
Write-Output &quot;Write-Output statement...&quot;
Write-Host &quot;Write-Host statement...&quot; -ForegroundColor Blue
</pre>
<p>The code above is saved in a file and called by:Â Â Â </p>
<pre class="brush: powershell;">

PS C:\_Tools&gt; .\PSScriptFile.ps1
</pre>
<p>Result: messages appear twice in the host.</p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite031.png"><img class="alignnone size-full wp-image-1254" title="PSWrite03" src="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite031.png" alt="" width="209" height="38" /></a></p>
<p>Output it to a file:Â Â Â </p>
<pre class="brush: powershell;">

PS C:\_Tools&gt; .\PSScriptFile.ps1 | Out-File $file
</pre>
<p>Result: No message in the host, but a message in the file!<br />
Still, the messages have to be written twice in the file: Write-Host and Write-Output&#8230;<br />
Do I really have to write all the messages twice to show them colored in the host and write them to an output file?<br />
Actually, there is no possibility to make Write-Host write to an output file.<br />
But the host itself can be accessed to change its text color (and more) and use Write-Output to write to the host (in color!) and to an output file.</p>
<p>The host itself can be accessed by $Host.Â Â Â </p>
<pre class="brush: powershell;">

$Host.Name
</pre>
<p>When using PowerGUI Script Editor the results of the above statement is: PowerGUIScriptEditorHost<br />
Executing the same statement in the console the result is: ConsoleHost</p>
<p>That&#8217;s awesome, $Host knows who he is! <img src='http://www.itidea.nl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Let&#8217;s try to get the text color of the host:</p>
<pre class="brush: powershell;">

$currentColor = $Host.UI.RawUI.ForegroundColor
</pre>
<p>PowerGUI Script Editor:</p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite04.png"><img class="alignnone size-full wp-image-1248" title="PSWrite04" src="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite04.png" alt="" width="249" height="23" /></a></p>
<p>Console:</p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite05.png"><img class="alignnone size-full wp-image-1249" title="PSWrite05" src="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite05.png" alt="" width="621" height="45" /></a></p>
<p>So what about changing the text color of the host?Â Â Â </p>
<pre class="brush: powershell;">

function WriteCustomOutput($message, [System.ConsoleColor]$foregroundcolor)
{
  currentColor = $Host.UI.RawUI.ForegroundColor
  $Host.UI.RawUI.ForegroundColor = $foregroundcolor
  if ($message)
  {
    Write-Output $message
  }
  $Host.UI.RawUI.ForegroundColor = $currentColor
}

WriteCustomOutput -message &quot;WriteColoredOutput statement...&quot; -foregroundcolor Green
</pre>
<p>And the result in the host:</p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite06.png"><img class="alignnone size-full wp-image-1250" title="PSWrite06" src="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite06.png" alt="" width="271" height="41" /></a>Â Â Â </p>
<p>Let&#8217;s save the code to a file and call the file from the console:</p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite07.png"><img class="alignnone size-full wp-image-1251" title="PSWrite07" src="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite07.png" alt="" width="321" height="43" /></a>Â </p>
<p>And will the output be written to an output file when using the statement:</p>
<pre class="brush: powershell;">

.\PSWriteCustomOutput.ps1 | Out-File OutputFile.txt
</pre>
<p>Yes it is written to the file:</p>
<p><a href="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite08.png"><img class="alignnone size-full wp-image-1252" title="PSWrite08" src="http://www.itidea.nl/wp-content/uploads/2011/08/PSWrite08.png" alt="" width="282" height="77" /></a>Â Â Â </p>
<h3>Summary</h3>
<p>Write-Host and Write-Output are very simple and useful statements. Sometimes the best of both is wished for.<br />
With some creativity you can have both. Use WriteCustomOutput!</p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.itidea.nl/index.php/powershell-choose-between-colored-host-text-or-write-to-an-output-file-not-anymore/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>To &#8216;this&#8217; or not to &#8216;this&#8217; with the Client Object model</title>
		<link>http://www.itidea.nl/index.php/to-this-or-not-to-this-with-the-client-object-model/</link>
		<comments>http://www.itidea.nl/index.php/to-this-or-not-to-this-with-the-client-object-model/#comments</comments>
		<pubDate>Sun, 24 Jul 2011 11:01:41 +0000</pubDate>
		<dc:creator>Anita</dc:creator>
				<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[Sandboxed Solutions]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>

		<guid isPermaLink="false">http://www.itidea.nl/?p=1216</guid>
		<description><![CDATA[Recently I developed a CustomAction on a list with some client script in the CommandAction. Nothing fancy or new.
I put a .js file in the _layouts folder and referenced the file by a CustomAction with Location &#8216;ScriptLink&#8217; and ScriptSrc. Put some code in the file to get some data I needed and called executeQueryAsync with [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I developed a CustomAction on a list with some client script in the CommandAction. Nothing fancy or new.<br />
I put a .js file in the _layouts folder and referenced the file by a CustomAction with Location &#8216;ScriptLink&#8217; and ScriptSrc. Put some code in the file to get some data I needed and called executeQueryAsync with two delegates like this:</p>
<pre class="brush: jscript;">
clientContext.executeQueryAsync(Function.createDelegate(this, this.OnSucceeded), Function.createDelegate(this, this.OnFailed));
</pre>
<p>Deployed as a Farm solution on the environment and everything went well so far.</p>
<p>After this, minds changed and it had to become a sandboxed solution. Ok, let&#8217;s do it.<br />
1. Set the Sandboxed Solution property to True on the project<br />
2. Removed the CustomAction with Location=&#8217;ScriptLink&#8217;<br />
3. Put the code from the js file from the _layouts folder in the CommandUIHandler&#8217;s attribute CommandAction<br />
4. Deployed the sandboxed solution</p>
<p>I always use FireFox when programming and all of a sudden I received the following error:<br />
<strong>b is undefined</strong></p>
<p><img class="aligncenter size-full wp-image-1222" title="Client object model this FireFox" src="http://www.itidea.nl/wp-content/uploads/2011/07/Blog-item-client-object-model-this-FireFox-msg-small.png" alt="Client object model this FireFox" width="599" height="46" /></p>
<p>and things stopped working. While in the Farm solution the CustomAction worked as expected and the OnSucceeded and OnFailed were executed.</p>
<p>I put in some alert statements to see where the code broke and it seemed the OnSucceeded and the OnFailed methods weren&#8217;t executed at all.<br />
By removing the &#8216;this&#8217; keyword in the createDelegate everything went well again:</p>
<pre class="brush: jscript;">
clientContext.executeQueryAsync(Function.createDelegate(this, OnSucceeded), Function.createDelegate(this, OnFailed));
</pre>
<p>This behaviour seems a bit strange to me. When putting the code in a separate js file and deploying it to the _layouts folder the &#8216;this&#8217; keyword can be used, but putting the exact same code in the CommandAction of CommandUIHandler the OnSucceeded and OnFailed methods can&#8217;t be found anymore using the &#8216;this&#8217; keyword.</p>
<p>By the way, in IE you will receive the following error:<br />
<strong>&#8216;b&#8217; is null or not an object</strong></p>
<p><img class="aligncenter size-full wp-image-1224" title="Client object model this IE" src="http://www.itidea.nl/wp-content/uploads/2011/07/Blog-item-client-object-model-this-IE-msg1.png" alt="Client object model this IE" width="553" height="200" /></p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.itidea.nl/index.php/to-this-or-not-to-this-with-the-client-object-model/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Client side social dashboard with SharePoint 2010 and SPServices</title>
		<link>http://www.itidea.nl/index.php/client-side-social-dashboard-with-sharepoint-2010-and-spservices/</link>
		<comments>http://www.itidea.nl/index.php/client-side-social-dashboard-with-sharepoint-2010-and-spservices/#comments</comments>
		<pubDate>Fri, 22 Jul 2011 08:19:02 +0000</pubDate>
		<dc:creator>Anita</dc:creator>
				<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[SPServices]]></category>

		<guid isPermaLink="false">http://www.itidea.nl/?p=1175</guid>
		<description><![CDATA[The article I wrote for DIWUG SharePoint eMagazine 4 now also online here:
Â 
Â 
One of the new features of SharePoint 2010 is tagging. Users can tag several items within SharePoint, such as pages and list items. The tags a user used can be viewed in a tag cloud on their profile page.
Â 
In Central Administration the page [...]]]></description>
			<content:encoded><![CDATA[<div>The article I wrote for DIWUG SharePoint eMagazine 4 now also online here:</div>
<div>Â </div>
<div>Â </div>
<div>One of the new features of SharePoint 2010 is tagging. Users can tag several items within SharePoint, such as pages and list items. The tags a user used can be viewed in a tag cloud on their profile page.</div>
<div>Â </div>
<div>In Central Administration the page â€˜Manage Social Tags and Notesâ€™ is available to manage the usersâ€™ social terms. Here social terms can be found and eventually deleted. To manage the usersâ€™ social terms a user has to have sufficient permissions to Central Administration.</div>
<div>Â </div>
<div>Besides using the â€˜Manage Social Tags and Notesâ€™ page, the SocialDataService web service can be used to retrieve information about tagging. This web service exposes a lot of operations to get all kinds of information about social data in SharePoint 2010. To retrieve the list of operations <a href="http://site/_vti_bin/SocialDataService.asmx">http://Site/_vti_bin/SocialDataService.asmx</a> can be called within a SharePoint site. When a specific operation is selected from the list the expected request xml is displayed and the response xml the web service returns.</div>
<div>Â </div>
<div>The jQuery library SPServices abstracts SharePoint&#8217;s Web Services and makes them easier to use. A list of implemented web services within SPServices can be found at CodePlex: <a href="http://spservices.codeplex.com/wikipage?title=$().SPServices&amp;referringTitle=Documentation">http://spservices.codeplex.com</a></div>
<div>Â </div>
<div>The SPServices library can be used fully client side and is an ideal solution to accomplish the goal of this article: creating a client side dashboard of some social analytics within SharePoint 2010. Marc D. Anderson has developed the SPServices library and is very open to community requests for enhancements as well as to help with any bugs, questions, or issues. You can contact him through the Discussions on the CodePlex site at any time.</div>
<h2>The social dashboard functionality</h2>
<div>Imagine an intranet portal at a certain company. The intranet portal is setup with SharePoint 2010 and the board wants to promote the social aspects of SharePoint, especially tagging, to the employees of the company.</div>
<div>Â </div>
<div>At every company a lot of things are said between employees during a visit to the coffee machine or water cooler. To help discover how employees really interact and how the organization functions as a whole social interaction within SharePoint is really helpful. The board wants to give the employees a voice and thereby uncover what they find most important.</div>
<div>Â </div>
<div>Besides this, the use of tagging will expose hidden knowledge in the organization. When an employee decides to move on to another company SharePoint keeps this information from being lost.</div>
<div>Â </div>
<div>The SharePoint search will also benefit by the use of tagging. Often tagged content will have a positive effect on the contents search result ranking.</div>
<div>Â </div>
<div>Unfortunately, adaptation of this new feature is currently poor in the organization and the use of tagging has to be stimulated in a way. Since people always like to be rewarded for their effort, the board decided to give away a bottle of champagne every month to the user who tags the most content.</div>
<div>Â </div>
<div>To give the employees some information on how theyâ€™re doing related to their colleagues, some statistics about tagging will be published on a page within SharePoint which is accessible to all employees. To make this page attractive, not only the most active users are displayed, but also the most used tags and the tags the current user used already.</div>
<div>Â </div>
<div>Additional information is available to managers and members of the board to stimulate persons even more.</div>
<div>Â </div>
<div>A tabular overview of the functionality based on the role of the user:</div>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top">
<div><strong>Functionality</strong></div>
<div>Â </div>
</td>
<td valign="top">
<div><strong>Employee</strong></div>
<div>Â </div>
</td>
<td valign="top">
<div><strong>Manager</strong></div>
<div>Â </div>
</td>
<td valign="top">
<div><strong>Board member</strong></div>
<div>Â </div>
</td>
</tr>
<tr>
<td valign="top">
<div><strong>Tags of current user</strong></div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
</tr>
<tr>
<td valign="top">
<div><strong>Most used tags</strong></div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
</tr>
<tr>
<td valign="top">
<div><strong>Drill down to url</strong></div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
</tr>
<tr>
<td valign="top">
<div><strong>Top active users</strong></div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
</tr>
<tr>
<td valign="top">
<div><strong>Drill down to tag</strong></div>
<div>Â </div>
</td>
<td valign="top">
<div>X</div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
</tr>
<tr>
<td valign="top">
<div><strong>Activity of employees in own department</strong></div>
<div>Â </div>
</td>
<td valign="top">
<div>X</div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
</tr>
<tr>
<td valign="top">
<div><strong>Activity of employees in a selectable department</strong></div>
<div>Â </div>
</td>
<td valign="top">
<div>X</div>
<div>Â </div>
</td>
<td valign="top">
<div>X</div>
<div>Â </div>
</td>
<td valign="top">
<div>V</div>
<div>Â </div>
</td>
</tr>
</tbody>
</table>
<div>
<div>
<div>Â </div>
<div>All the code displayed in the article is based on jQuery or html. With references to jQuery, the SPServices library and the jQuery template plugin all the code can be pasted in a Content Editor web part on a SharePoint page.</div>
<div>Â </div>
<pre class="brush: xml;">

&lt;script src=&quot;/jQueryLibrary/jquery-1.4.4.min.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot; /jQueryLibrary/jquery.SPServices-0.5.8.min.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot; /jQueryLibrary/jquery.tmpl.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
</pre>
</div>
</div>
<h3>Tags of current user</h3>
<div>To determine the tags a certain user used, one call to the SocialDataService web service with the help of SPServices will do. SPServices exposes an operation called â€˜GetTagsOfUserâ€™ which expects the parameter user account name. In this case the user account name is the account name of the currently logged in user.</div>
<div>Â </div>
<div>The SPServices library exposes a function to get the account name of the current logged in user, â€˜SPGetCurrentUserâ€™. The code to get the account name of the current user:</div>
<div>Â </div>
<pre class="brush: jscript;">
var currentUserAccount = $().SPServices.SPGetCurrentUser({
Â Â Â Â Â Â Â Â Â Â Â  fieldName: &quot;Name&quot;
Â Â Â Â Â Â Â  });
</pre>
<div>The SPGetCurrentUser function does an AJAX call to grab /_layouts/userdisp.aspx?Force=True and â€˜scrapesâ€™ the values from the page based on the internal field name. The â€˜Nameâ€™ field used in the code is the internal field name of the account name.</div>
<div>Â </div>
<div>Since the fieldname â€˜Nameâ€™ in the above code is the default option of the SPGetCurrentUser function, the call can be combined with the operation â€˜<a href="http://msdn.microsoft.com/en-us/library/websvcsocialdataservice.socialdataservice.gettagsofuser.aspx">GetTagsOfUser</a>â€™.</div>
<pre class="brush: jscript;">
$().SPServices({
Â Â Â  operation: &quot;GetTagsOfUser&quot;,
Â Â Â  userAccountName: $().SPServices.SPGetCurrentUser(),
Â Â Â  completefunc: function (xData, Status) {
Â Â Â Â Â Â Â  $(xData.responseXML).find(&quot;SocialTagDetail&quot;).each(function () {
Â Â Â Â Â Â Â Â Â Â Â  tagName = $(&quot;Term&gt;Name&quot;, $(this)).text();
Â Â Â Â Â Â Â Â Â Â Â  tagsofuser.push({ Tag: tagName, Count: 1 });
Â Â Â Â Â Â Â  });
Â Â Â Â Â Â Â  tagsofuser = uniqueTags(tagsofuser);
Â Â Â Â Â Â Â  SortByCount(tagsofuser);
Â Â Â Â Â Â Â  $(&quot;#currentUserTagsText&quot;).show();
Â Â Â Â Â Â Â  $(&quot;#currentUserTags&quot;).html(&quot;&quot;);
Â Â Â Â Â Â Â  $(&quot;#tagsofuserTemplate&quot;).tmpl(tagsofuser)
Â Â Â Â Â Â Â Â Â Â Â  .appendTo(&quot;#currentUserTags&quot;);
Â Â Â  }
});
</pre>
<div>The callback function gets the response of the web service. A part of the response is displayed here:Â </div>
<pre class="brush: xml;">

&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;soap:Envelope xmlns:soap=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;
Â  &lt;soap:Body&gt;
Â Â Â  &lt;GetTagsOfUserResponse xmlns=&quot;http://microsoft.com/webservices/SharePointPortalServer/SocialDataService&quot;&gt;
Â Â Â Â Â  &lt;GetTagsOfUserResult&gt;
Â Â Â Â Â Â Â  &lt;SocialTagDetail&gt;
Â Â Â Â Â Â Â Â Â  &lt;Url&gt;http://sp2010/Lists/Tasks/AllItems.aspx&lt;/Url&gt;
Â Â Â Â Â Â Â Â Â  &lt;Owner&gt;sp2010\mark&lt;/Owner&gt;
Â Â Â Â Â Â Â Â Â  &lt;LastModifiedTime&gt;2010-12-19T13:28:09.437&lt;/LastModifiedTime&gt;
Â Â Â Â Â Â Â Â Â  &lt;Title&gt;Tasks - All Tasks&lt;/Title&gt;
Â Â Â Â Â Â Â Â Â  &lt;Term&gt;
Â Â Â Â Â Â Â Â Â Â Â  &lt;Id&gt;974a854f-31b4-431f-91cb-a6289f58c978&lt;/Id&gt;
Â Â Â Â Â Â Â Â Â Â Â  &lt;Name&gt;I like it&lt;/Name&gt;
Â Â Â Â Â Â Â Â Â  &lt;/Term&gt;
Â Â Â Â Â Â Â Â Â  &lt;IsPrivate&gt;false&lt;/IsPrivate&gt;
Â Â Â Â Â Â Â  &lt;/SocialTagDetail&gt;
Â Â Â Â Â Â Â  Rest of the SocialTagDetails are intentionally left outï¿½
Â Â Â Â Â  &lt;/GetTagsOfUserResult&gt;
Â Â Â  &lt;/GetTagsOfUserResponse&gt;
Â  &lt;/soap:Body&gt;
&lt;/soap:Envelope&gt;
</pre>
<div>The term name is stored in an array of objects. The Count is set to one, because this tag is default present one time. When the duplicates are removed in the uniqueTags method the Count of the Tag is adjusted if the tag is present more than once. Since this is a helper method it is not showed here. Afterwards the tags are sorted descending by the number stored in the variable Count. A jQuery template, tagsofuserTemplate, is used to show the results on the page. The template is rendered with the data and appended to a div with the id currentUserTags. The template uses the objects in the array:Â </div>
<div>
<pre class="brush: xml;">
&lt;div&gt;&lt;script id=&quot;tagsofuserTemplate&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
&lt;div&gt;Â &lt;/div&gt;
&lt;div&gt;&lt;div style=&quot;float:left;width:40%&quot;&gt;
&lt;div&gt;Â &lt;/div&gt;
&lt;div&gt;Â Â Â Â Â Â Â  ${Tag}
&lt;div&gt;Â &lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;Â &lt;/div&gt;
&lt;div&gt;&lt;div style=&quot;float:left;width:20%&quot;&gt;
&lt;div&gt;Â &lt;/div&gt;
&lt;div&gt;Â Â Â Â Â Â Â  ${Count}
&lt;div&gt;Â &lt;/div&gt;
&lt;div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div&gt;Â &lt;/div&gt;
&lt;div&gt;&lt;/script&gt;
&lt;div&gt;</pre>
</div>
<div>The tags of the current user are displayed as show in the figure below:</div>
<div>Â <a href="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_01.jpg"><img class="size-full wp-image-1188 alignnone" title="Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_01" src="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_01.jpg" alt="" width="339" height="99" /></a></div>
<div>Since detailed information of the tags is available at the usersâ€™ profile page, a link is displayed to get there.Â </div>
<h3>Most used tags</h3>
<div>The web service doesnâ€™t provide an operation to get the most used tags, but only an operation to get all the tags. Therefor all the tags terms have to be retrieved and afterwards counted and sorted to get the most used ones.</div>
<pre class="brush: jscript;">

$().SPServices({
Â Â Â  operation: &quot;GetAllTagTerms&quot;,
Â Â Â  debug: false,
Â Â Â  completefunc: function (xData, Status) {
Â Â Â Â Â Â Â  $(xData.responseXML).find(&quot;SocialTermDetail&quot;).each(function () {
Â Â Â Â Â Â Â Â Â Â Â  termName = $(&quot;Term&gt;Name&quot;, $(this)).text();
Â Â Â Â Â Â Â Â Â Â Â  termGuid = $(&quot;Term&gt;Id&quot;, $(this)).text();
Â Â Â Â Â Â Â Â Â Â Â  counter = $(&quot;Count&quot;, $(this)).text();
Â Â Â Â Â Â Â Â Â Â Â  terms.push({ Term: termName, Count: counter, TermGuid: termGuid });
Â Â Â Â Â Â Â  });
Â Â Â Â Â Â Â  SortByCount(terms);
Â Â Â Â Â Â Â  terms.length = 5;
Â Â Â Â Â Â Â  $(&quot;#showterms&quot;).html(&quot;&quot;);
Â Â Â Â Â Â Â  $(&quot;#termTemplate&quot;).tmpl(terms)
Â Â Â Â Â Â Â Â Â Â Â  .appendTo(&quot;#showterms&quot;);
Â Â Â  }
});
</pre>
<div>In the above code the operation â€˜<a href="http://msdn.microsoft.com/en-us/library/websvcsocialdataservice.socialdataservice.getalltagterms.aspx">GetAllTagTerms</a>â€™ of the SPServices library is used. This operation gets all the tag terms. The name, id and the counter of each term are retrieved from the returned xml. The tag terms are sorted by the Count variable and the number of items returned is minimized to the top 5 most used tag terms. The result is displayed on the page by a jQuery template:</div>
<div>
<pre class="brush: xml;">
&lt;div&gt;&lt;div style=&quot;float:left;width:40%&quot;&gt;
&lt;div&gt;Â &lt;/div&gt;
&lt;div&gt;Â Â Â Â  &lt;a href=&quot;#&quot; id=${TermGuid}&gt;
&lt;div&gt;Â &lt;/div&gt;
&lt;div&gt;Â Â Â Â Â Â Â  ${Term}
&lt;div&gt;Â &lt;/div&gt;
&lt;div&gt;Â Â Â  &lt;/a&gt;
&lt;div&gt;Â &lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;Â &lt;/div&gt;
&lt;div&gt;&lt;div style=&quot;float:left;width:20%&quot;&gt;
&lt;div&gt;Â &lt;/div&gt;
&lt;div&gt;Â Â Â Â Â Â Â  ${Count}
&lt;div&gt;Â &lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;</pre>
</div>
<div>The most used tags are displayed as show in the figure below:</div>
<div><a href="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_02.jpg"><img class="size-full wp-image-1189 alignnone" title="Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_02" src="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_02.jpg" alt="" width="208" height="105" /></a></div>
<div>To drill down on a tag the method <a href="http://msdn.microsoft.com/en-us/library/websvcsocialdataservice.socialdataservice.getalltagurls.aspx">GetAllTagUrls</a> with the parameter this.id, in this case the guid of the term selected, is called when a user selects one of the tags.Â </div>
<pre class="brush: jscript;">

Â Â Â  $().SPServices({
Â Â Â Â Â Â Â  operation: &quot;GetAllTagUrls&quot;,
Â Â Â Â Â Â Â  termID: termId,
Â Â Â Â Â Â Â  debug: true,
Â Â Â Â Â Â Â  completefunc: function (xData, Status) {
Â Â Â Â Â Â Â Â Â Â Â  $(xData.responseXML).find(&quot;SocialUrlDetail&quot;).each(function () {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  url = $(&quot;Url&quot;, $(this)).text();
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  countUrl = $(&quot;Count&quot;, $(this)).text();
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  urlsofterm.push({ Url: url, Count: countUrl });
Â Â Â Â Â Â Â Â Â Â Â  });
Â Â Â Â Â Â Â Â Â Â  Â SortByCount(urlsofterm);
Â Â Â Â Â Â Â Â Â Â Â  $(&quot;#urlsoftermContainer&quot;).show();
Â Â Â Â Â Â Â Â Â Â Â  $(&quot;#showurlsofterm&quot;).html(&quot;&quot;);
Â Â Â Â Â Â Â Â Â Â Â  $(&quot;#urlTemplate&quot;).tmpl(urlsofterm)
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  .appendTo(&quot;#showurlsofterm&quot;);
Â Â Â Â Â Â Â  }
Â Â Â  });
</pre>
<div>The â€˜GetAllTagUrlsâ€™ of the SPServices library is called with the termID as parameter. The result is displayed with another jQuery template:<br />
<a href="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_03.jpg"><img class="size-full wp-image-1190 alignnone" title="Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_03" src="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_03.jpg" alt="" width="380" height="239" /></a></div>
<h3>Top active users</h3>
<div>The SocialDataService web service doesnâ€™t provide an operation to get the top active users either. To determine the top active users in the site collection first all the available users have to be retrieved. Â Â Â The SPServices library allows a call to the operation â€˜<a href="http://msdn.microsoft.com/en-us/library/ms772702.aspx">GetUserCollectionFromSite</a>â€™, which the web service Users and Groups exposes.</div>
<pre class="brush: jscript;">

$().SPServices({
Â Â Â  operation: &quot;GetUserCollectionFromSite&quot;,
Â Â Â  completefunc: function (xData, Status) {
Â Â Â Â Â Â Â  $(xData.responseXML).find(&quot;User&quot;).each(function () {
Â Â Â Â Â Â Â Â Â Â Â  userName = $(this).attr(&quot;LoginName&quot;);
Â Â Â Â Â Â Â Â Â Â Â  userNames.push({ UserName: userName });
Â Â Â Â Â Â Â  });
Â Â Â Â Â Â Â  GetTopTagsOfUsers(userNames);
Â Â Â  }
});
</pre>
<div>In the code above the request to the web service is made and the result, the login names of all the users, is stored in an array.Â </div>
<div>With the array of login names the operation â€˜GetTopTagsOfUsersâ€™ is called to count the tags used by each user and format the result in a clear way.</div>
<div>Â </div>
<div>To count the tags used for a single user the SocialDataService web service provides the â€˜<a href="http://msdn.microsoft.com/en-us/library/websvcsocialdataservice.socialdataservice.counttagsofuser.aspx">CountTagsOfUser</a>â€™ operation. The operation is called with the account name of the user as parameter. The result is formatted in an array of objects to store the account name and the number of tags of the user.Â </div>
<pre class="brush: jscript;">

function CountTagsOfUser(useraccountname, f) {
Â Â Â  var tagCount = &quot;&quot;;
Â Â Â  var tagsofuser = [];
Â Â Â  $().SPServices({
Â Â Â Â Â Â Â  operation: &quot;CountTagsOfUser&quot;,
Â Â Â Â Â Â Â  userAccountName: useraccountname,
Â Â Â Â Â Â Â  debug: true,
Â Â Â Â Â Â Â  completefunc: function (xData, Status) {
Â Â Â Â Â Â Â Â Â Â Â  $(xData.responseXML).find(&quot;CountTagsOfUserResult&quot;).each(function () {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  tagCount = $(this).text();
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  tagsofuser.push({ Count: tagCount, UserAccountName: useraccountname });
Â Â Â Â Â Â Â Â Â Â Â  });
Â Â Â Â Â Â Â Â Â Â Â  SortByCount(tagsofuser);
Â Â Â Â Â Â Â Â Â Â Â  if (typeof f == &quot;function&quot;) f(tagsofuser);
Â Â Â Â Â Â Â Â Â Â Â  return tagsofuser;
Â Â Â Â Â Â Â  }
Â  });
}
</pre>
<div>A callback function is necessary to use the CountTagsForUser in the function GetTopTagsOfUsers and returns the result array when the counting of the tags of the specified user has finished.</div>
<pre class="brush: jscript;">

function GetTopTagsOfUsers(usernames) {
Â Â Â  var result = [];
Â Â Â  $.each(usernames, function (key, value) {
Â Â Â Â Â Â Â  CountTagsOfUser(value[&quot;UserName&quot;], function (items) {
Â Â Â Â Â Â Â Â Â Â Â  $.each(items, function (i, n) {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  result.push({ Count: n[&quot;Count&quot;], UserAccountName: n[&quot;UserAccountName&quot;] });
Â Â Â Â Â Â Â Â Â Â Â  });
Â Â Â Â Â Â Â Â Â Â  if (usernames.length == result.length) {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  SortByCount(result);
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  result.length = 5;
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  $(&quot;#showcounttagsofuser&quot;).html(&quot;&quot;);
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  if (isCEO || isManager) {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  $(&quot;#counttagsofuserTemplate&quot;).tmpl(result)
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  .appendTo(&quot;#showcounttagsofuser&quot;);
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  } else {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  $(&quot;#counttagsofuserTemplateForUser&quot;).tmpl(result)
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  .appendTo(&quot;#showcounttagsofuser&quot;);
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  }
Â Â Â Â Â Â Â Â Â Â Â  }
Â Â Â Â Â Â Â  });
Â Â Â  });
}
</pre>
<div>The â€˜GetTopTagsOfUserâ€™ function retrieves for every user present in the site collection the number of tags and stores the result in an array of objects. Once this function completes, the number of usernames are equal to the tagcount result, the results are sorted descending to get the most active user on top and the number of results is limited to the top five users.</div>
<div>When showing the results on the screen the first difference is made between a â€˜regularâ€™ employee and a manager/board member.</div>
<div>For a â€˜regularâ€™ employee a different template is used for rendering, because they arenâ€™t allowed to drill down on a user to see which tags these users did use.</div>
<div>The template for a â€˜regularâ€™ employee:</div>
<pre class="brush: xml;">

&lt;script id=&quot;counttagsofuserTemplateForUser&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
&lt;div style=&quot;float:left;width:40%&quot;&gt;
Â Â Â Â Â Â Â  ${UserAccountName}
&lt;/div&gt;
&lt;div style=&quot;float:left;width:20%&quot;&gt;
Â Â Â Â Â Â Â  ${Count}
&lt;/div&gt;
&lt;/script&gt;
</pre>
<div>The top active users part on the page for a â€˜regularâ€™ employee:</div>
<div><a href="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_04.jpg"><img class="size-full wp-image-1191 alignnone" title="Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_04" src="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_04.jpg" alt="" width="198" height="108" /></a></div>
<div>And for a manager/board member:</div>
<pre class="brush: xml;">

&lt;script id=&quot;counttagsofuserTemplate&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
&lt;div style=&quot;float:left;width:40%&quot;&gt;
 Â Â  &lt;a href=&quot;#&quot; id=${UserAccountName}&gt;
Â Â Â Â Â Â Â  ${UserAccountName}
Â Â Â  &lt;/a&gt;
&lt;/div&gt;
&lt;div style=&quot;float:left;width:20%&quot;&gt;
Â Â Â Â Â Â Â  ${Count}
&lt;/div&gt;
&lt;/script&gt;
</pre>
<div>The top active users part on the page for a manager/ board member:</div>
<div><a href="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_05.jpg"><img class="size-full wp-image-1192 alignnone" title="Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_05" src="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_05.jpg" alt="" width="206" height="205" /></a></div>
<div>The GetTagsOfUser operation used to drill down on a user is the same method used by displaying the tags of the current user mentioned in the beginning of the article.Â </div>
<h4><em>Whatâ€™s the difference between a â€˜regularâ€™ employee, a manager and a board member?</em></h4>
<div>The differences are stored in the profile properties of the user profile.</div>
<div>Â </div>
<div>The user profiles of all the people present in the company are set up with the Department field filled and/or the Manager field filled. The Department field of the board has to be filled with â€˜CEOâ€™ to know this user a not a regular manager, but a member of the board.</div>
<div>Â </div>
<div>The following table lists some examples of user profiles, their properties and their roles:</div>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="166" valign="top">
<div><strong>UserName</strong></div>
<div>Â </div>
</td>
<td width="162" valign="top">
<div><strong>Department</strong></div>
<div>Â </div>
</td>
<td width="155" valign="top">
<div><strong>Manager</strong></div>
<div>Â </div>
</td>
<td width="136" valign="top">
<div><strong>Role</strong></div>
<div>Â </div>
</td>
</tr>
<tr>
<td width="166" valign="top">
<div><strong>Alex</strong></div>
<div>Â </div>
</td>
<td width="162" valign="top">
<div>ICT</div>
<div>Â </div>
</td>
<td width="155" valign="top">
<div>Andrew</div>
<div>Â </div>
</td>
<td width="136" valign="top">
<div>Employee</div>
<div>Â </div>
</td>
</tr>
<tr>
<td width="166" valign="top">
<div><strong>Andrew</strong></div>
<div>Â </div>
</td>
<td width="162" valign="top">
<div>ICT</div>
<div>Â </div>
</td>
<td width="155" valign="top">
<div>Â </div>
<div>Â </div>
</td>
<td width="136" valign="top">
<div>Manager</div>
<div>Â </div>
</td>
</tr>
<tr>
<td width="166" valign="top">
<div><strong>Anita</strong></div>
<div>Â </div>
</td>
<td width="162" valign="top">
<div>Marketing</div>
<div>Â </div>
</td>
<td width="155" valign="top">
<div>Mark</div>
<div>Â </div>
</td>
<td width="136" valign="top">
<div>Employee</div>
<div>Â </div>
</td>
</tr>
<tr>
<td width="166" valign="top">
<div><strong>Chris</strong></div>
<div>Â </div>
</td>
<td width="162" valign="top">
<div>HR</div>
<div>Â </div>
</td>
<td width="155" valign="top">
<div>Dave</div>
<div>Â </div>
</td>
<td width="136" valign="top">
<div>Employee</div>
<div>Â </div>
</td>
</tr>
<tr>
<td width="166" valign="top">
<div><strong>Dave</strong></div>
<div>Â </div>
</td>
<td width="162" valign="top">
<div>HR</div>
<div>Â </div>
</td>
<td width="155" valign="top">
<div>Â </div>
<div>Â </div>
</td>
<td width="136" valign="top">
<div>Manager</div>
<div>Â </div>
</td>
</tr>
<tr>
<td width="166" valign="top">
<div><strong>Jeff</strong></div>
<div>Â </div>
</td>
<td width="162" valign="top">
<div>Marketing</div>
<div>Â </div>
</td>
<td width="155" valign="top">
<div>Mark</div>
<div>Â </div>
</td>
<td width="136" valign="top">
<div>Employee</div>
<div>Â </div>
</td>
</tr>
<tr>
<td width="166" valign="top">
<div><strong>Mark</strong></div>
<div>Â </div>
</td>
<td width="162" valign="top">
<div>Marketing</div>
<div>Â </div>
</td>
<td width="155" valign="top">
<div>Â </div>
<div>Â </div>
</td>
<td width="136" valign="top">
<div>Manager</div>
<div>Â </div>
</td>
</tr>
<tr>
<td width="166" valign="top">
<div><strong>Paul</strong></div>
<div>Â </div>
</td>
<td width="162" valign="top">
<div>CEO</div>
<div>Â </div>
</td>
<td width="155" valign="top">
<div>Â </div>
<div>Â </div>
</td>
<td width="136" valign="top">
<div>Board member</div>
<div>Â </div>
</td>
</tr>
</tbody>
</table>
<div>
<div>
<div>Â </div>
<div>To give an example on how to read the table: Jeff is an employee and member of the Marketing department. His manager is Mark. This makes Jeff a â€˜regularâ€™ employee.Â </div>
<div>The role column lists the role of the user based on the previous columns.</div>
<div>Â </div>
<div>The information about the department and manager of a person is stored in their User Profile. The SPServices library supports a lot of operations on the UserProfileService web service. The one needed here is â€˜<a href="http://msdn.microsoft.com/en-us/library/microsoft.office.server.userprofiles.userprofileservice.getuserprofilebyname.aspx">GetUserProfileByName</a>â€™ to get the properties â€˜Departmentâ€™ and â€˜Managerâ€™. This method expects a parameter â€˜AccountNameâ€™, which is the currently logged in user.</div>
<pre class="brush: jscript;">

var CEOdepartment = &quot;CEO&quot;;
$().SPServices({
 Â Â  operation: &quot;GetUserProfileByName&quot;,
Â Â Â  AccountName: currentUserAccount,
Â Â Â  completefunc: function (xData, Status) {
Â Â Â Â Â Â Â  $(xData.responseXML).find(&quot;GetUserProfileByNameResult&gt;PropertyData&quot;).each(function () {
Â Â Â Â Â Â Â Â Â Â Â  //check for CEO department
Â Â Â Â Â Â Â Â Â Â Â  if ($(&quot;Name&quot;, $(this)).text().toUpperCase() == &quot;Department&quot;.toUpperCase()) {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  departmentOfCurrentUser = $(&quot;Values&gt;ValueData&gt;Value&quot;, $(this)).text();
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  if (departmentOfCurrentUser.toUpperCase() == CEOdepartment.toUpperCase()) {
Â  Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â isCEO = true;
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  GetDepartmentsAndUsers();
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  }
Â Â Â Â Â Â Â Â Â Â Â  }
Â Â Â Â Â Â Â Â Â Â Â  else if ($(&quot;Name&quot;, $(this)).text().toUpperCase() == &quot;Manager&quot;.toUpperCase()) {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  managerName = $(&quot;Values&gt;ValueData&gt;Value&quot;, $(this)).text();
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  if (managerName == &quot;&quot;) {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  if (!isCEO) {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  isManager = true;
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  GetDepartmentsAndUsers();
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  }
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  }
Â Â Â Â Â Â Â Â Â Â Â  }
Â Â Â Â Â Â Â  });
Â Â Â  }
});
</pre>
</div>
</div>
<div>The callback function gets the response of the web service. A part of the xml response looks like:</div>
<pre class="brush: xml;">

&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;soap:Envelope xmlns:soap=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;
Â  &lt;soap:Body&gt;
Â Â Â  &lt;GetUserProfileByNameResponse xmlns=&quot;http://microsoft.com/webservices/SharePointPortalServer/UserProfileService&quot;&gt;
Â Â Â Â Â  &lt;GetUserProfileByNameResult&gt;
Â Â Â Â Â Â Â  &lt;PropertyData&gt;
Â Â Â Â Â Â Â Â Â  &lt;IsPrivacyChanged&gt;false&lt;/IsPrivacyChanged&gt;
Â Â Â Â Â Â Â Â Â  &lt;IsValueChanged&gt;false&lt;/IsValueChanged&gt;
Â Â Â Â Â Â Â Â Â  &lt;Name&gt;AccountName&lt;/Name&gt;
 Â Â Â Â Â Â Â Â  &lt;Privacy&gt;Public&lt;/Privacy&gt;
Â Â Â Â Â Â Â Â Â  &lt;Values&gt;
Â Â Â Â Â Â Â Â Â Â Â  &lt;ValueData&gt;
Â Â Â Â Â Â Â Â Â Â Â Â Â  &lt;Value xsi:type=&quot;xsd:string&quot;&gt;sp2010\paul&lt;/Value&gt;
Â Â Â Â Â Â Â Â Â Â Â  &lt;/ValueData&gt;
Â Â Â Â Â Â Â Â Â  &lt;/Values&gt;
Â Â Â Â Â Â Â  &lt;/PropertyData&gt;
Â Â Â Â Â Â Â  &lt;PropertyData&gt;
Â Â Â Â Â Â Â Â Â  &lt;IsPrivacyChanged&gt;false&lt;/IsPrivacyChanged&gt;
Â Â Â Â Â Â Â Â Â  &lt;IsValueChanged&gt;false&lt;/IsValueChanged&gt;
Â Â Â Â Â Â Â Â Â  &lt;Name&gt;Department&lt;/Name&gt;
Â Â Â Â Â Â Â Â Â  &lt;Privacy&gt;Public&lt;/Privacy&gt;
Â Â Â Â Â Â Â Â Â  &lt;Values&gt;
Â Â Â Â Â Â Â Â Â Â Â  &lt;ValueData&gt;
Â Â Â Â Â Â Â Â Â Â Â Â Â  &lt;Value xsi:type=&quot;xsd:string&quot;&gt;CEO&lt;/Value&gt;
Â Â Â Â Â Â Â Â Â Â Â  &lt;/ValueData&gt;
Â Â Â Â Â Â Â Â Â  &lt;/Values&gt;
Â Â Â Â Â Â Â  &lt;/PropertyData&gt;
Â Â Â Â Â  &lt;/GetUserProfileByNameResult&gt;
Â Â Â  &lt;/GetUserProfileByNameResponse&gt;
Â  &lt;/soap:Body&gt;
&lt;/soap:Envelope&gt;
</pre>
<div>The current user in the response xml has the account name sp2010\paul and is a member of the CEO department. Â </div>
<div>Â </div>
<div>The find method of the responseXML gets to the PropertyData in the xml and tries to find the â€˜Departmentâ€™ and â€˜Managerâ€™ properties. Once found the value of the property is retrieved and in this case the variable â€˜isCEOâ€™ is set to true, because Paul is a member of the CEO department. The department of the current user is stored in the variable departmentOfCurrentUser and the operation â€˜GetDepartmentsAndUsersâ€™ is called for later use on other functionality.</div>
<div>Â </div>
<div>The above code is used to determine the role of the current logged in user and the â€˜Top active usersâ€™ part on the page will display itself differently based on this role.Â </div>
<div>Â </div>
<div>Worried about security?Â </div>
<div>All information is gathered by calls to web services. Calls on the web services make everything security trimmed, so the approach is secure.</div>
<h3>Activity of employees in own or a selectable department</h3>
<div>Managers are allowed to view the activity of all the employees which are a member of their department. The account names of these employees are displayed in a dropdown box on the page.</div>
<div>Â </div>
<div>Besides viewing the activity of a single user, the board wants to view the activity within a whole department. The departments are listed in a dropdown box cascading the users of the selected department.</div>
<div>Â </div>
<div>These two functionalities can be implemented in a single operation. The method â€˜GetDepartmentsAndUsersâ€™ is called in the previous code. This operation is responsible to provide the values to set up the cascading functionality between departments and account names of the users. This method is only called when the current logged in user is a manager of a CEO.<br />
Â </div>
<div>To retrieve all the departments and account names the <a href="http://msdn.microsoft.com/en-us/library/search.queryservice.queryex(v=office.12).aspx">Search web service</a> is called. One call is made to the web service to get the departments and the account names by formatting the query to return these properties in the result. The SQL syntax is used and the scope is set to the People scope.</div>
<pre class="brush: jscript;">

var queryTextSQL = &quot;&lt;QueryPacket xmlns='urn:Microsoft.Search.Query' Revision='1000'&gt;&quot;
queryTextSQL += &quot;&lt;Query&gt;&quot;
queryTextSQL += &quot;&lt;Context&gt;&quot;
queryTextSQL += &quot;&lt;QueryText language='en-US' type='MSSQLFT'&gt;&quot;
if (isCEO) {
Â Â Â  queryTextSQL += &quot;SELECT Title, Rank, Size, Description, Write, Path, AccountName, Department FROM scope() WHERE ( (\&quot;SCOPE\&quot; = 'People') ) ORDER BY \&quot;Rank\&quot; DESC&quot;
} else {
Â Â Â  queryTextSQL += &quot;SELECT Title, Rank, Size, Description, Write, Path, AccountName, Department FROM scope() WHERE ( (\&quot;SCOPE\&quot; = 'People') ) AND (CONTAINS (Department,'&quot; + departmentOfCurrentUser + &quot;')) ORDER BY \&quot;Rank\&quot; DESC&quot;
}
queryTextSQL += &quot;&lt;/QueryText&gt;&quot;
queryTextSQL += &quot;&lt;/Context&gt;&quot;
queryTextSQL += &quot;&lt;/Query&gt;&quot;
queryTextSQL += &quot;&lt;/QueryPacket&gt;&quot;;
$().ready(function () {
Â Â Â  var resultText = &quot;&quot;;
Â Â Â  $().SPServices({
Â Â Â Â Â Â Â  operation: &quot;QueryEx&quot;,
Â Â Â Â Â Â Â  queryXml: queryTextSQL,
 Â Â Â Â Â Â  completefunc: function (xData, Status) {
Â Â Â Â Â Â Â Â Â Â Â  $(xData.responseXML).find(&quot;RelevantResults&quot;).each(function (i) {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  accountName = $(&quot;ACCOUNTNAME&quot;, $(this)).text();
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  departments[i] = $(&quot;DEPARTMENT&quot;, $(this)).text();
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  users.push({ AccountName: accountName, Department: departments[i] });
Â Â Â Â Â Â Â Â Â Â Â  });
Â Â Â Â Â Â Â Â Â Â Â  if (isCEO) {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  $('#departmentContainer').show();
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  fillDepartmentsDropdown('#departmentSelection', $.unique(departments), &quot;Select department&quot;);
Â Â Â Â Â Â Â Â Â Â Â  }
Â Â Â Â Â Â Â Â Â Â Â  if (isCEO || isManager) {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  $('#userContainer').show();
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  fillUsersDropdown('#userSelection', users, &quot;Select user&quot;);
Â Â Â Â Â Â Â Â Â Â Â  }
Â Â Â Â Â Â Â  }
Â Â Â  });
});
</pre>
<div>Dependent if the user is a manager or board member different queries are fired. When a manager only the users which are member of the department, set earlier in the variable â€˜departmentOfCurrentUserâ€™, are retrieved.</div>
<div>Â </div>
<div>When the response is retrieved the departments are stored in an array of strings and the users are stored in an array of objects. The object contains the account name of the user and the department which the user is a member of. The department of the user is needed to accomplish the cascading dropdown between departments and account names. The department dropdown is only filled and showed when the current logged in user is member of the CEO department. If the user is a manager of another department only the users of that department are shown in the usersâ€™ dropdown box.</div>
<div>Â </div>
<div>There are two different methods to fill the dropdown boxes for departments and users, because the users are stored in an array of objects, only the account name is used to fill the box:Â </div>
<pre class="brush: jscript;">

function fillUsersDropdown(dropdownName, arrayToUse, text) {
Â Â Â  $(dropdownName).html(&quot;&quot;);
Â Â Â  $.each(arrayToUse,
Â Â Â Â Â Â Â  function (key, value) {
Â Â Â Â Â Â Â Â Â Â Â  $(dropdownName).append('&lt;option value=&quot;' + value[&quot;AccountName&quot;] + '&quot;&gt;' + value[&quot;AccountName&quot;] + '&lt;/option&gt;');
Â Â Â Â Â Â Â  });
Â Â Â  $(dropdownName).prepend(&quot;&lt;option value='0' selected='true'&gt;&quot; + text + &quot;&lt;/option&gt;&quot;);
Â Â Â  $(dropdownName).find(&quot;option:first&quot;)[0].selected = true;
}
</pre>
<div>The idâ€™s departmentContainer and userContainer used in the code contain the markup:</div>
<pre class="brush: xml;">

Â Â Â  &lt;div style=&quot;float: left; width: 100%; display: none;&quot; id=&quot;departmentContainer&quot;&gt;
Â Â Â Â Â Â Â  &lt;div style=&quot;float: left; width: 15%&quot;&gt;
Â Â Â Â Â Â Â Â Â Â Â  Select department&lt;/div&gt;
Â Â Â Â Â Â Â  &lt;select id=&quot;departmentSelection&quot; style=&quot;float: left; width: 15%&quot;&gt;
Â Â Â Â Â Â Â  &lt;/select&gt;
Â Â Â  &lt;/div&gt;
Â Â Â  &lt;br /&gt;
Â Â Â  &lt;div id=&quot;userContainer&quot; style=&quot;float: left; width: 100%; display: none;&quot;&gt;
Â Â Â Â Â Â Â  &lt;div style=&quot;float: left; width: 15%&quot;&gt;
Â Â Â Â Â Â Â Â Â Â Â  Select user&lt;/div&gt;
Â Â Â Â Â Â Â  &lt;select id=&quot;userSelection&quot; style=&quot;float: left; width: 15%&quot;&gt;
Â Â Â Â Â Â Â  &lt;/select&gt;
Â Â Â Â Â Â Â  &lt;div style=&quot;clear: both; float: left; width: 25%&quot;&gt;
Â Â Â Â Â Â Â Â Â Â Â  &lt;a href=&quot;#&quot; onclick=&quot;GetTagsOfSelection(userSelection.value, departmentSelection.value);return false&quot;&gt;
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  Show tags of selection&lt;/a&gt;&lt;/div&gt;
Â Â Â Â Â Â Â  &lt;h4 style=&quot;clear: both; float: left; display: none;&quot; id=&quot;showtagsofuserText&quot;&gt;
Â Â Â Â Â Â Â Â Â Â Â  Tags of selection:&lt;/h4&gt;
Â Â Â Â Â Â Â  &lt;div id=&quot;showtagsofuser&quot; style=&quot;clear: both;&quot;&gt;
Â Â Â Â Â Â Â  &lt;/div&gt;
Â Â Â  &lt;/div&gt;
</pre>
<div>The page now looks like this when the current logged in user is a board member:</div>
<div><a href="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_06.jpg"><img class="size-full wp-image-1193 alignnone" title="Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_06" src="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_06.jpg" alt="" width="330" height="59" /></a></div>
<div>And a manager:</div>
<div><a href="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_07.jpg"><img class="size-full wp-image-1194 alignnone" title="Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_07" src="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_07.jpg" alt="" width="316" height="43" /></a></div>
<div>The cascading functionality is now easy:Â </div>
<pre class="brush: jscript;">

$('select').change(function (e) {
Â Â Â  if (this.id == &quot;departmentSelection&quot;) {
Â Â Â Â Â Â Â  $('#userSelection option').each(function (i, option) {
Â Â Â Â Â Â Â Â Â Â Â  $(option).remove();
Â Â Â Â Â Â Â  });
Â Â Â Â Â Â Â  j = 0;
Â Â Â Â Â Â Â  childArray.length = 0;
Â Â Â Â Â Â Â  if (this[this.selectedIndex].value != 0) {
Â Â Â Â Â Â Â Â Â Â Â  departmentSelected = this[this.selectedIndex].text;
Â Â Â Â Â Â Â Â Â Â Â  //filter the users array on the selected department
Â Â Â Â Â Â Â Â Â Â Â  filteredUsers = $.grep(users, function (filter) {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  return filter[&quot;Department&quot;] == departmentSelected;
Â Â Â Â Â Â Â Â Â Â Â  });
Â Â Â Â Â Â Â Â Â Â Â  fillUsersDropdown('#userSelection', filteredUsers, &quot;Select user&quot;);
Â Â Â Â Â Â Â  }
Â Â Â Â Â Â Â  else {
Â Â Â Â Â Â Â Â Â Â Â  fillUsersDropdown('#userSelection', users, &quot;Select user&quot;);
Â Â Â Â Â Â Â  }
Â Â Â  }
});
</pre>
<div>The code first empties the items in the usersâ€™ dropdown box and fills it again based on the selected department.</div>
<div>Â </div>
<div>The picture below shows the cascading functionality between departments and users:</div>
<div><a href="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_08.jpg"><img class="size-full wp-image-1196 alignnone" title="Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_08" src="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_08.jpg" alt="" width="318" height="95" /></a><a href="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_09.jpg"></a></div>
<div>After making a selection of a department and/or a user â€˜Show tags of selectionâ€™ can be selected. Selecting this fires the operation â€˜GetTagsOfSelection()â€™ with the values of the selected department and/or user as parameters.Â </div>
<pre class="brush: jscript;">

function GetTagsOfSelection(userSelection, departmentSelection) {
Â Â Â  var result = [];
Â Â Â  if (userSelection != 0) {
Â Â Â Â Â Â Â  GetTagsOfUser(userSelection, true, true);
Â Â Â  } else if (departmentSelection != 0) {
Â Â Â Â Â Â Â  $.each(filteredUsers, function (key, value) {
Â Â Â Â Â Â Â Â Â Â Â  GetTagsOfUser(value[&quot;AccountName&quot;], false, true, false, function (items) {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  $.each(items, function (i, n) {
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  result.push({ Tag: n[&quot;Tag&quot;], Count: 1 });
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  });
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  result = uniqueTags(result);
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  SortByCount(result);
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  $(&quot;#showtagsofuserText&quot;).show();
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  $(&quot;#showtagsofuser&quot;).html(&quot;&quot;);
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  $(&quot;#tagsofuserTemplate&quot;).tmpl(result)
Â Â Â Â Â Â Â Â Â Â Â  .appendTo(&quot;#showtagsofuser&quot;);
Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  //}
Â Â Â Â Â Â Â Â Â Â Â  });
Â Â Â Â Â Â Â  });
Â Â Â  }
}
</pre>
<div>When a single user is selected the operation GetTagsOfUser() is used again. When a single department is selected the tags of all the usersâ€™ member of the selected department are retrieved, counted and sorted descending. The jQuery template is rendered with the results.</div>
<div>Â </div>
<div>The page now looks like this when the current logged in user is a board member:</div>
<div><a href="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_091.jpg"><img class="size-full wp-image-1197 alignnone" title="Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_09" src="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_091.jpg" alt="" width="429" height="136" /></a></div>
<div>And a manager:<br />
<a href="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_10.jpg"><img class="size-full wp-image-1198 alignnone" title="Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_10" src="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_10.jpg" alt="" width="426" height="116" /></a></div>
<h3>The result</h3>
<div>Grabbing all the functionality together the social dashboards look like:</div>
<div>Â </div>
<div>For an employee:</div>
<div><a href="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_11.jpg"><img class="size-full wp-image-1199 alignnone" title="Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_11" src="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_11.jpg" alt="" width="786" height="212" /></a></div>
<div>For a manager:</div>
<div><a href="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_12.jpg"><img class="size-full wp-image-1200 alignnone" title="Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_12" src="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_12.jpg" alt="" width="787" height="233" /></a></div>
<div>For a board member:</div>
<div><a href="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_13.jpg"><img class="size-full wp-image-1201 alignnone" title="Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_13" src="http://www.itidea.nl/wp-content/uploads/2011/07/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_13.jpg" alt="" width="788" height="259" /></a></div>
<div>This month the board member, Paul, wins the bottle of champagne, because he tagged the most content. Since this isnâ€™t the wanted outcome, employees have to win the bottle of course; Paul throws in two bottles of champagne for the winner next month.</div>
<div>Â </div>
<div>This company just started to use the social aspects of SharePoint. The number of tags used isnâ€™t very high yet. The search results ranking within SharePoint will not benefit from this tagging; neither the hidden knowledge in the organization is stored in SharePoint yet. When the stimulation of the use of tagging continues, employees will embed the use of tagging in their daily work and it will not take long to see the positive effects of it.</div>
<div>Â </div>
<h2>Summary</h2>
<div>The SocialDataService web service is a good starting point on retrieving and displaying social information like tagging on a page. To use the service fully client side the library SPServices is an excellent solution.</div>
<div>Â </div>
<div>To display information as shown in this article the SocialDataService web service does not provide all the necessary information and other web services have to be used. Other web services used here are the Users and Groups, the UserProfile and the Search web services. With the use of all these services and additional jQuery the goal of creating a client side dashboard of some social analytics is accomplished.</div>
<div>Â </div>
<div>Performance wise the solutions are not always the most optimal. For example when the most active users are gathered. First it grabs all the users from the site collection, counts the tags for all of these users and then it is limited to show the top 5 of highest tag counts. Itâ€™s not the web service not being efficient; itâ€™s the lack of the availability of a function to get the highest tags counts without the need to make the count on a specific user.</div>
 ]]></content:encoded>
			<wfw:commentRss>http://www.itidea.nl/index.php/client-side-social-dashboard-with-sharepoint-2010-and-spservices/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

