{"id":1175,"date":"2011-07-22T10:19:02","date_gmt":"2011-07-22T08:19:02","guid":{"rendered":"http:\/\/www.itidea.nl\/?p=1175"},"modified":"2015-09-08T20:49:48","modified_gmt":"2015-09-08T18:49:48","slug":"client-side-social-dashboard-with-sharepoint-2010-and-spservices","status":"publish","type":"post","link":"https:\/\/www.itidea.nl\/index.php\/client-side-social-dashboard-with-sharepoint-2010-and-spservices\/","title":{"rendered":"Client side social dashboard with SharePoint 2010 and SPServices"},"content":{"rendered":"<div>The article I wrote for DIWUG SharePoint eMagazine 4 now also online here:<\/div>\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<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>\n<div>\u00a0<\/div>\n<div>In Central Administration the page \u2018Manage Social Tags and Notes\u2019 is available to manage the users\u2019 social terms. Here social terms can be found and eventually deleted. To manage the users\u2019 social terms a user has to have sufficient permissions to Central Administration.<\/div>\n<div>\u00a0<\/div>\n<div>Besides using the \u2018Manage Social Tags and Notes\u2019 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>\n<div>\u00a0<\/div>\n<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>\n<div>\u00a0<\/div>\n<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>\n<h2>The social dashboard functionality<\/h2>\n<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>\n<div>\u00a0<\/div>\n<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>\n<div>\u00a0<\/div>\n<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>\n<div>\u00a0<\/div>\n<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>\n<div>\u00a0<\/div>\n<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>\n<div>\u00a0<\/div>\n<div>To give the employees some information on how they\u2019re 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>\n<div>\u00a0<\/div>\n<div>Additional information is available to managers and members of the board to stimulate persons even more.<\/div>\n<div>\u00a0<\/div>\n<div>A tabular overview of the functionality based on the role of the user:<\/div>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"top\">\n<div><strong>Functionality<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div><strong>Employee<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div><strong>Manager<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div><strong>Board member<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<div><strong>Tags of current user<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<div><strong>Most used tags<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<div><strong>Drill down to url<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<div><strong>Top active users<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<div><strong>Drill down to tag<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>X<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<div><strong>Activity of employees in own department<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>X<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<div><strong>Activity of employees in a selectable department<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>X<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>X<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td valign=\"top\">\n<div>V<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div>\n<div>\n<div>\u00a0<\/div>\n<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>\n<div>\u00a0<\/div>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n\r\n&lt;script src=&quot;\/jQueryLibrary\/jquery-1.4.4.min.js&quot; type=&quot;text\/javascript&quot;&gt;&lt;\/script&gt;\r\n&lt;script src=&quot; \/jQueryLibrary\/jquery.SPServices-0.5.8.min.js&quot; type=&quot;text\/javascript&quot;&gt;&lt;\/script&gt;\r\n&lt;script src=&quot; \/jQueryLibrary\/jquery.tmpl.js&quot; type=&quot;text\/javascript&quot;&gt;&lt;\/script&gt;\r\n\r\n<\/pre>\n<\/div>\n<\/div>\n<h3>Tags of current user<\/h3>\n<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 \u2018GetTagsOfUser\u2019 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>\n<div>\u00a0<\/div>\n<div>The SPServices library exposes a function to get the account name of the current logged in user, \u2018SPGetCurrentUser\u2019. The code to get the account name of the current user:<\/div>\n<div>\u00a0<\/div>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar currentUserAccount = $().SPServices.SPGetCurrentUser({\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fieldName: &quot;Name&quot;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n<\/pre>\n<div>The SPGetCurrentUser function does an AJAX call to grab \/_layouts\/userdisp.aspx?Force=True and \u2018scrapes\u2019 the values from the page based on the internal field name. The \u2018Name\u2019 field used in the code is the internal field name of the account name.<\/div>\n<div>\u00a0<\/div>\n<div>Since the fieldname \u2018Name\u2019 in the above code is the default option of the SPGetCurrentUser function, the call can be combined with the operation \u2018<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/websvcsocialdataservice.socialdataservice.gettagsofuser.aspx\">GetTagsOfUser<\/a>\u2019.<\/div>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n$().SPServices({\r\n\u00a0\u00a0\u00a0 operation: &quot;GetTagsOfUser&quot;,\r\n\u00a0\u00a0\u00a0 userAccountName: $().SPServices.SPGetCurrentUser(),\r\n\u00a0\u00a0\u00a0 completefunc: function (xData, Status) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(xData.responseXML).find(&quot;SocialTagDetail&quot;).each(function () {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tagName = $(&quot;Term&gt;Name&quot;, $(this)).text();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tagsofuser.push({ Tag: tagName, Count: 1 });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tagsofuser = uniqueTags(tagsofuser);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SortByCount(tagsofuser);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(&quot;#currentUserTagsText&quot;).show();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(&quot;#currentUserTags&quot;).html(&quot;&quot;);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(&quot;#tagsofuserTemplate&quot;).tmpl(tagsofuser)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 .appendTo(&quot;#currentUserTags&quot;);\r\n\u00a0\u00a0\u00a0 }\r\n});\r\n<\/pre>\n<div>The callback function gets the response of the web service. A part of the response is displayed here:\u00a0<\/div>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n\r\n&lt;?xml version=&quot;1.0&quot;?&gt;\r\n&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;\r\n\u00a0 &lt;soap:Body&gt;\r\n\u00a0\u00a0\u00a0 &lt;GetTagsOfUserResponse xmlns=&quot;http:\/\/microsoft.com\/webservices\/SharePointPortalServer\/SocialDataService&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;GetTagsOfUserResult&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;SocialTagDetail&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Url&gt;http:\/\/sp2010\/Lists\/Tasks\/AllItems.aspx&lt;\/Url&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Owner&gt;sp2010\\mark&lt;\/Owner&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;LastModifiedTime&gt;2010-12-19T13:28:09.437&lt;\/LastModifiedTime&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Title&gt;Tasks - All Tasks&lt;\/Title&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Term&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Id&gt;974a854f-31b4-431f-91cb-a6289f58c978&lt;\/Id&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Name&gt;I like it&lt;\/Name&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/Term&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;IsPrivate&gt;false&lt;\/IsPrivate&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/SocialTagDetail&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Rest of the SocialTagDetails are intentionally left out\ufffd\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/GetTagsOfUserResult&gt;\r\n\u00a0\u00a0\u00a0 &lt;\/GetTagsOfUserResponse&gt;\r\n\u00a0 &lt;\/soap:Body&gt;\r\n&lt;\/soap:Envelope&gt;\r\n\r\n<\/pre>\n<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:\u00a0<\/div>\n<div>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;div&gt;&lt;script id=&quot;tagsofuserTemplate&quot; type=&quot;text\/x-jquery-tmpl&quot;&gt;\r\n&lt;div&gt;\u00a0&lt;\/div&gt;\r\n&lt;div&gt;&lt;div style=&quot;float:left;width:40%&quot;&gt;\r\n&lt;div&gt;\u00a0&lt;\/div&gt;\r\n&lt;div&gt;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ${Tag}\r\n&lt;div&gt;\u00a0&lt;\/div&gt;\r\n&lt;div&gt;&lt;\/div&gt;\r\n&lt;div&gt;\u00a0&lt;\/div&gt;\r\n&lt;div&gt;&lt;div style=&quot;float:left;width:20%&quot;&gt;\r\n&lt;div&gt;\u00a0&lt;\/div&gt;\r\n&lt;div&gt;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ${Count}\r\n&lt;div&gt;\u00a0&lt;\/div&gt;\r\n&lt;div&gt;&lt;\/div&gt;&lt;br \/&gt;\r\n&lt;div&gt;\u00a0&lt;\/div&gt;\r\n&lt;div&gt;&lt;\/script&gt;\r\n&lt;div&gt;<\/pre>\n<\/div>\n<div>The tags of the current user are displayed as show in the figure below:<\/div>\n<div>\u00a0<a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_01.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1188 alignnone\" title=\"Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_01\" src=\"https:\/\/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\" srcset=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_01.jpg 339w, https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_01-300x87.jpg 300w\" sizes=\"auto, (max-width: 339px) 100vw, 339px\" \/><\/a><\/div>\n<div>Since detailed information of the tags is available at the users\u2019 profile page, a link is displayed to get there.\u00a0<\/div>\n<h3>Most used tags<\/h3>\n<div>The web service doesn\u2019t 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>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\n$().SPServices({\r\n\u00a0\u00a0\u00a0 operation: &quot;GetAllTagTerms&quot;,\r\n\u00a0\u00a0\u00a0 debug: false,\r\n\u00a0\u00a0\u00a0 completefunc: function (xData, Status) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(xData.responseXML).find(&quot;SocialTermDetail&quot;).each(function () {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 termName = $(&quot;Term&gt;Name&quot;, $(this)).text();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 termGuid = $(&quot;Term&gt;Id&quot;, $(this)).text();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 counter = $(&quot;Count&quot;, $(this)).text();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 terms.push({ Term: termName, Count: counter, TermGuid: termGuid });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SortByCount(terms);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 terms.length = 5;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(&quot;#showterms&quot;).html(&quot;&quot;);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(&quot;#termTemplate&quot;).tmpl(terms)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 .appendTo(&quot;#showterms&quot;);\r\n\u00a0\u00a0\u00a0 }\r\n});\r\n\r\n<\/pre>\n<div>In the above code the operation \u2018<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/websvcsocialdataservice.socialdataservice.getalltagterms.aspx\">GetAllTagTerms<\/a>\u2019 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>\n<div>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;div&gt;&lt;div style=&quot;float:left;width:40%&quot;&gt;\r\n&lt;div&gt;\u00a0&lt;\/div&gt;\r\n&lt;div&gt;\u00a0\u00a0\u00a0\u00a0 &lt;a href=&quot;#&quot; id=${TermGuid}&gt;\r\n&lt;div&gt;\u00a0&lt;\/div&gt;\r\n&lt;div&gt;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ${Term}\r\n&lt;div&gt;\u00a0&lt;\/div&gt;\r\n&lt;div&gt;\u00a0\u00a0\u00a0 &lt;\/a&gt;\r\n&lt;div&gt;\u00a0&lt;\/div&gt;\r\n&lt;div&gt;&lt;\/div&gt;\r\n&lt;div&gt;\u00a0&lt;\/div&gt;\r\n&lt;div&gt;&lt;div style=&quot;float:left;width:20%&quot;&gt;\r\n&lt;div&gt;\u00a0&lt;\/div&gt;\r\n&lt;div&gt;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ${Count}\r\n&lt;div&gt;\u00a0&lt;\/div&gt;\r\n&lt;div&gt;&lt;\/div&gt;\r\n&lt;div&gt;<\/pre>\n<\/div>\n<div>The most used tags are displayed as show in the figure below:<\/div>\n<div><a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_02.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1189 alignnone\" title=\"Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_02\" src=\"https:\/\/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>\n<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.\u00a0<\/div>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\n\u00a0\u00a0\u00a0 $().SPServices({\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 operation: &quot;GetAllTagUrls&quot;,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 termID: termId,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 debug: true,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 completefunc: function (xData, Status) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(xData.responseXML).find(&quot;SocialUrlDetail&quot;).each(function () {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 url = $(&quot;Url&quot;, $(this)).text();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 countUrl = $(&quot;Count&quot;, $(this)).text();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 urlsofterm.push({ Url: url, Count: countUrl });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0SortByCount(urlsofterm);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(&quot;#urlsoftermContainer&quot;).show();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(&quot;#showurlsofterm&quot;).html(&quot;&quot;);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(&quot;#urlTemplate&quot;).tmpl(urlsofterm)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 .appendTo(&quot;#showurlsofterm&quot;);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 });\r\n\r\n<\/pre>\n<div>The \u2018GetAllTagUrls\u2019 of the SPServices library is called with the termID as parameter. The result is displayed with another jQuery template:<br \/>\n<a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_03.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1190 alignnone\" title=\"Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_03\" src=\"https:\/\/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\" srcset=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_03.jpg 380w, https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_03-300x188.jpg 300w\" sizes=\"auto, (max-width: 380px) 100vw, 380px\" \/><\/a><\/div>\n<h3>Top active users<\/h3>\n<div>The SocialDataService web service doesn\u2019t 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. \u00a0\u00a0\u00a0The SPServices library allows a call to the operation \u2018<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms772702.aspx\">GetUserCollectionFromSite<\/a>\u2019, which the web service Users and Groups exposes.<\/div>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\n$().SPServices({\r\n\u00a0\u00a0\u00a0 operation: &quot;GetUserCollectionFromSite&quot;,\r\n\u00a0\u00a0\u00a0 completefunc: function (xData, Status) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(xData.responseXML).find(&quot;User&quot;).each(function () {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 userName = $(this).attr(&quot;LoginName&quot;);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 userNames.push({ UserName: userName });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GetTopTagsOfUsers(userNames);\r\n\u00a0\u00a0\u00a0 }\r\n});\r\n\r\n<\/pre>\n<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.\u00a0<\/div>\n<div>With the array of login names the operation \u2018GetTopTagsOfUsers\u2019 is called to count the tags used by each user and format the result in a clear way.<\/div>\n<div>\u00a0<\/div>\n<div>To count the tags used for a single user the SocialDataService web service provides the \u2018<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/websvcsocialdataservice.socialdataservice.counttagsofuser.aspx\">CountTagsOfUser<\/a>\u2019 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.\u00a0<\/div>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\nfunction CountTagsOfUser(useraccountname, f) {\r\n\u00a0\u00a0\u00a0 var tagCount = &quot;&quot;;\r\n\u00a0\u00a0\u00a0 var tagsofuser = &#x5B;];\r\n\u00a0\u00a0\u00a0 $().SPServices({\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 operation: &quot;CountTagsOfUser&quot;,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 userAccountName: useraccountname,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 debug: true,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 completefunc: function (xData, Status) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(xData.responseXML).find(&quot;CountTagsOfUserResult&quot;).each(function () {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tagCount = $(this).text();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tagsofuser.push({ Count: tagCount, UserAccountName: useraccountname });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SortByCount(tagsofuser);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (typeof f == &quot;function&quot;) f(tagsofuser);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return tagsofuser;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0 });\r\n}\r\n<\/pre>\n<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>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\nfunction GetTopTagsOfUsers(usernames) {\r\n\u00a0\u00a0\u00a0 var result = &#x5B;];\r\n\u00a0\u00a0\u00a0 $.each(usernames, function (key, value) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 CountTagsOfUser(value&#x5B;&quot;UserName&quot;], function (items) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $.each(items, function (i, n) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 result.push({ Count: n&#x5B;&quot;Count&quot;], UserAccountName: n&#x5B;&quot;UserAccountName&quot;] });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (usernames.length == result.length) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SortByCount(result);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 result.length = 5;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(&quot;#showcounttagsofuser&quot;).html(&quot;&quot;);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (isCEO || isManager) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(&quot;#counttagsofuserTemplate&quot;).tmpl(result)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 .appendTo(&quot;#showcounttagsofuser&quot;);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } else {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(&quot;#counttagsofuserTemplateForUser&quot;).tmpl(result)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 .appendTo(&quot;#showcounttagsofuser&quot;);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0 });\r\n}\r\n\r\n<\/pre>\n<div>The \u2018GetTopTagsOfUser\u2019 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>\n<div>When showing the results on the screen the first difference is made between a \u2018regular\u2019 employee and a manager\/board member.<\/div>\n<div>For a \u2018regular\u2019 employee a different template is used for rendering, because they aren\u2019t allowed to drill down on a user to see which tags these users did use.<\/div>\n<div>The template for a \u2018regular\u2019 employee:<\/div>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n\r\n&lt;script id=&quot;counttagsofuserTemplateForUser&quot; type=&quot;text\/x-jquery-tmpl&quot;&gt;\r\n&lt;div style=&quot;float:left;width:40%&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ${UserAccountName}\r\n&lt;\/div&gt;\r\n&lt;div style=&quot;float:left;width:20%&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ${Count}\r\n&lt;\/div&gt;\r\n&lt;\/script&gt;\r\n\r\n<\/pre>\n<div>The top active users part on the page for a \u2018regular\u2019 employee:<\/div>\n<div><a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_04.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1191 alignnone\" title=\"Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_04\" src=\"https:\/\/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>\n<div>And for a manager\/board member:<\/div>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n\r\n&lt;script id=&quot;counttagsofuserTemplate&quot; type=&quot;text\/x-jquery-tmpl&quot;&gt;\r\n&lt;div style=&quot;float:left;width:40%&quot;&gt;\r\n \u00a0\u00a0 &lt;a href=&quot;#&quot; id=${UserAccountName}&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ${UserAccountName}\r\n\u00a0\u00a0\u00a0 &lt;\/a&gt;\r\n&lt;\/div&gt;\r\n&lt;div style=&quot;float:left;width:20%&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ${Count}\r\n&lt;\/div&gt;\r\n&lt;\/script&gt;\r\n\r\n<\/pre>\n<div>The top active users part on the page for a manager\/ board member:<\/div>\n<div><a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_05.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1192 alignnone\" title=\"Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_05\" src=\"https:\/\/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\" srcset=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_05.jpg 206w, https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_05-150x150.jpg 150w\" sizes=\"auto, (max-width: 206px) 100vw, 206px\" \/><\/a><\/div>\n<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.\u00a0<\/div>\n<h4><em>What\u2019s the difference between a \u2018regular\u2019 employee, a manager and a board member?<\/em><\/h4>\n<div>The differences are stored in the profile properties of the user profile.<\/div>\n<div>\u00a0<\/div>\n<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 \u2018CEO\u2019 to know this user a not a regular manager, but a member of the board.<\/div>\n<div>\u00a0<\/div>\n<div>The following table lists some examples of user profiles, their properties and their roles:<\/div>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"166\" valign=\"top\">\n<div><strong>UserName<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"162\" valign=\"top\">\n<div><strong>Department<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"155\" valign=\"top\">\n<div><strong>Manager<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"136\" valign=\"top\">\n<div><strong>Role<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"166\" valign=\"top\">\n<div><strong>Alex<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"162\" valign=\"top\">\n<div>ICT<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"155\" valign=\"top\">\n<div>Andrew<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"136\" valign=\"top\">\n<div>Employee<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"166\" valign=\"top\">\n<div><strong>Andrew<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"162\" valign=\"top\">\n<div>ICT<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"155\" valign=\"top\">\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"136\" valign=\"top\">\n<div>Manager<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"166\" valign=\"top\">\n<div><strong>Anita<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"162\" valign=\"top\">\n<div>Marketing<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"155\" valign=\"top\">\n<div>Mark<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"136\" valign=\"top\">\n<div>Employee<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"166\" valign=\"top\">\n<div><strong>Chris<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"162\" valign=\"top\">\n<div>HR<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"155\" valign=\"top\">\n<div>Dave<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"136\" valign=\"top\">\n<div>Employee<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"166\" valign=\"top\">\n<div><strong>Dave<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"162\" valign=\"top\">\n<div>HR<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"155\" valign=\"top\">\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"136\" valign=\"top\">\n<div>Manager<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"166\" valign=\"top\">\n<div><strong>Jeff<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"162\" valign=\"top\">\n<div>Marketing<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"155\" valign=\"top\">\n<div>Mark<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"136\" valign=\"top\">\n<div>Employee<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"166\" valign=\"top\">\n<div><strong>Mark<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"162\" valign=\"top\">\n<div>Marketing<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"155\" valign=\"top\">\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"136\" valign=\"top\">\n<div>Manager<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"166\" valign=\"top\">\n<div><strong>Paul<\/strong><\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"162\" valign=\"top\">\n<div>CEO<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"155\" valign=\"top\">\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<td width=\"136\" valign=\"top\">\n<div>Board member<\/div>\n<div>\u00a0<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div>\n<div>\n<div>\u00a0<\/div>\n<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 \u2018regular\u2019 employee.\u00a0<\/div>\n<div>The role column lists the role of the user based on the previous columns.<\/div>\n<div>\u00a0<\/div>\n<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 \u2018<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/microsoft.office.server.userprofiles.userprofileservice.getuserprofilebyname.aspx\">GetUserProfileByName<\/a>\u2019 to get the properties \u2018Department\u2019 and \u2018Manager\u2019. This method expects a parameter \u2018AccountName\u2019, which is the currently logged in user.<\/div>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\nvar CEOdepartment = &quot;CEO&quot;;\r\n$().SPServices({\r\n \u00a0\u00a0 operation: &quot;GetUserProfileByName&quot;,\r\n\u00a0\u00a0\u00a0 AccountName: currentUserAccount,\r\n\u00a0\u00a0\u00a0 completefunc: function (xData, Status) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(xData.responseXML).find(&quot;GetUserProfileByNameResult&gt;PropertyData&quot;).each(function () {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/check for CEO department\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if ($(&quot;Name&quot;, $(this)).text().toUpperCase() == &quot;Department&quot;.toUpperCase()) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 departmentOfCurrentUser = $(&quot;Values&gt;ValueData&gt;Value&quot;, $(this)).text();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (departmentOfCurrentUser.toUpperCase() == CEOdepartment.toUpperCase()) {\r\n\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isCEO = true;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GetDepartmentsAndUsers();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 else if ($(&quot;Name&quot;, $(this)).text().toUpperCase() == &quot;Manager&quot;.toUpperCase()) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 managerName = $(&quot;Values&gt;ValueData&gt;Value&quot;, $(this)).text();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (managerName == &quot;&quot;) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (!isCEO) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 isManager = true;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GetDepartmentsAndUsers();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0 }\r\n});\r\n<\/pre>\n<\/div>\n<\/div>\n<div>The callback function gets the response of the web service. A part of the xml response looks like:<\/div>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n\r\n&lt;?xml version=&quot;1.0&quot;?&gt;\r\n&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;\r\n\u00a0 &lt;soap:Body&gt;\r\n\u00a0\u00a0\u00a0 &lt;GetUserProfileByNameResponse xmlns=&quot;http:\/\/microsoft.com\/webservices\/SharePointPortalServer\/UserProfileService&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;GetUserProfileByNameResult&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;PropertyData&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;IsPrivacyChanged&gt;false&lt;\/IsPrivacyChanged&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;IsValueChanged&gt;false&lt;\/IsValueChanged&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Name&gt;AccountName&lt;\/Name&gt;\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Privacy&gt;Public&lt;\/Privacy&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Values&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;ValueData&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Value xsi:type=&quot;xsd:string&quot;&gt;sp2010\\paul&lt;\/Value&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/ValueData&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/Values&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/PropertyData&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;PropertyData&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;IsPrivacyChanged&gt;false&lt;\/IsPrivacyChanged&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;IsValueChanged&gt;false&lt;\/IsValueChanged&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Name&gt;Department&lt;\/Name&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Privacy&gt;Public&lt;\/Privacy&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Values&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;ValueData&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Value xsi:type=&quot;xsd:string&quot;&gt;CEO&lt;\/Value&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/ValueData&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/Values&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/PropertyData&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/GetUserProfileByNameResult&gt;\r\n\u00a0\u00a0\u00a0 &lt;\/GetUserProfileByNameResponse&gt;\r\n\u00a0 &lt;\/soap:Body&gt;\r\n&lt;\/soap:Envelope&gt;\r\n<\/pre>\n<div>The current user in the response xml has the account name sp2010\\paul and is a member of the CEO department. \u00a0<\/div>\n<div>\u00a0<\/div>\n<div>The find method of the responseXML gets to the PropertyData in the xml and tries to find the \u2018Department\u2019 and \u2018Manager\u2019 properties. Once found the value of the property is retrieved and in this case the variable \u2018isCEO\u2019 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 \u2018GetDepartmentsAndUsers\u2019 is called for later use on other functionality.<\/div>\n<div>\u00a0<\/div>\n<div>The above code is used to determine the role of the current logged in user and the \u2018Top active users\u2019 part on the page will display itself differently based on this role.\u00a0<\/div>\n<div>\u00a0<\/div>\n<div>Worried about security?\u00a0<\/div>\n<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>\n<h3>Activity of employees in own or a selectable department<\/h3>\n<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>\n<div>\u00a0<\/div>\n<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>\n<div>\u00a0<\/div>\n<div>These two functionalities can be implemented in a single operation. The method \u2018GetDepartmentsAndUsers\u2019 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 \/>\n\u00a0<\/div>\n<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>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\nvar queryTextSQL = &quot;&lt;QueryPacket xmlns='urn:Microsoft.Search.Query' Revision='1000'&gt;&quot;\r\nqueryTextSQL += &quot;&lt;Query&gt;&quot;\r\nqueryTextSQL += &quot;&lt;Context&gt;&quot;\r\nqueryTextSQL += &quot;&lt;QueryText language='en-US' type='MSSQLFT'&gt;&quot;\r\nif (isCEO) {\r\n\u00a0\u00a0\u00a0 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;\r\n} else {\r\n\u00a0\u00a0\u00a0 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;\r\n}\r\nqueryTextSQL += &quot;&lt;\/QueryText&gt;&quot;\r\nqueryTextSQL += &quot;&lt;\/Context&gt;&quot;\r\nqueryTextSQL += &quot;&lt;\/Query&gt;&quot;\r\nqueryTextSQL += &quot;&lt;\/QueryPacket&gt;&quot;;\r\n$().ready(function () {\r\n\u00a0\u00a0\u00a0 var resultText = &quot;&quot;;\r\n\u00a0\u00a0\u00a0 $().SPServices({\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 operation: &quot;QueryEx&quot;,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 queryXml: queryTextSQL,\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 completefunc: function (xData, Status) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(xData.responseXML).find(&quot;RelevantResults&quot;).each(function (i) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 accountName = $(&quot;ACCOUNTNAME&quot;, $(this)).text();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 departments&#x5B;i] = $(&quot;DEPARTMENT&quot;, $(this)).text();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 users.push({ AccountName: accountName, Department: departments&#x5B;i] });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (isCEO) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $('#departmentContainer').show();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fillDepartmentsDropdown('#departmentSelection', $.unique(departments), &quot;Select department&quot;);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (isCEO || isManager) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $('#userContainer').show();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fillUsersDropdown('#userSelection', users, &quot;Select user&quot;);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 });\r\n});\r\n<\/pre>\n<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 \u2018departmentOfCurrentUser\u2019, are retrieved.<\/div>\n<div>\u00a0<\/div>\n<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\u2019 dropdown box.<\/div>\n<div>\u00a0<\/div>\n<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:\u00a0<\/div>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\nfunction fillUsersDropdown(dropdownName, arrayToUse, text) {\r\n\u00a0\u00a0\u00a0 $(dropdownName).html(&quot;&quot;);\r\n\u00a0\u00a0\u00a0 $.each(arrayToUse,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 function (key, value) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(dropdownName).append('&lt;option value=&quot;' + value&#x5B;&quot;AccountName&quot;] + '&quot;&gt;' + value&#x5B;&quot;AccountName&quot;] + '&lt;\/option&gt;');\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0 $(dropdownName).prepend(&quot;&lt;option value='0' selected='true'&gt;&quot; + text + &quot;&lt;\/option&gt;&quot;);\r\n\u00a0\u00a0\u00a0 $(dropdownName).find(&quot;option:first&quot;)&#x5B;0].selected = true;\r\n}\r\n<\/pre>\n<div>The id\u2019s departmentContainer and userContainer used in the code contain the markup:<\/div>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n\r\n\u00a0\u00a0\u00a0 &lt;div style=&quot;float: left; width: 100%; display: none;&quot; id=&quot;departmentContainer&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;div style=&quot;float: left; width: 15%&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Select department&lt;\/div&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;select id=&quot;departmentSelection&quot; style=&quot;float: left; width: 15%&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/select&gt;\r\n\u00a0\u00a0\u00a0 &lt;\/div&gt;\r\n\u00a0\u00a0\u00a0 &lt;br \/&gt;\r\n\u00a0\u00a0\u00a0 &lt;div id=&quot;userContainer&quot; style=&quot;float: left; width: 100%; display: none;&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;div style=&quot;float: left; width: 15%&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Select user&lt;\/div&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;select id=&quot;userSelection&quot; style=&quot;float: left; width: 15%&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/select&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;div style=&quot;clear: both; float: left; width: 25%&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;a href=&quot;#&quot; onclick=&quot;GetTagsOfSelection(userSelection.value, departmentSelection.value);return false&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Show tags of selection&lt;\/a&gt;&lt;\/div&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;h4 style=&quot;clear: both; float: left; display: none;&quot; id=&quot;showtagsofuserText&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Tags of selection:&lt;\/h4&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;div id=&quot;showtagsofuser&quot; style=&quot;clear: both;&quot;&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/div&gt;\r\n\u00a0\u00a0\u00a0 &lt;\/div&gt;\r\n<\/pre>\n<div>The page now looks like this when the current logged in user is a board member:<\/div>\n<div><a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_06.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1193 alignnone\" title=\"Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_06\" src=\"https:\/\/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\" srcset=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_06.jpg 330w, https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_06-300x53.jpg 300w\" sizes=\"auto, (max-width: 330px) 100vw, 330px\" \/><\/a><\/div>\n<div>And a manager:<\/div>\n<div><a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_07.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1194 alignnone\" title=\"Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_07\" src=\"https:\/\/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\" srcset=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_07.jpg 316w, https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_07-300x40.jpg 300w\" sizes=\"auto, (max-width: 316px) 100vw, 316px\" \/><\/a><\/div>\n<div>The cascading functionality is now easy:\u00a0<\/div>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\n$('select').change(function (e) {\r\n\u00a0\u00a0\u00a0 if (this.id == &quot;departmentSelection&quot;) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $('#userSelection option').each(function (i, option) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(option).remove();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 j = 0;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 childArray.length = 0;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (this&#x5B;this.selectedIndex].value != 0) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 departmentSelected = this&#x5B;this.selectedIndex].text;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/filter the users array on the selected department\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 filteredUsers = $.grep(users, function (filter) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return filter&#x5B;&quot;Department&quot;] == departmentSelected;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fillUsersDropdown('#userSelection', filteredUsers, &quot;Select user&quot;);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 else {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fillUsersDropdown('#userSelection', users, &quot;Select user&quot;);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n});\r\n<\/pre>\n<div>The code first empties the items in the users\u2019 dropdown box and fills it again based on the selected department.<\/div>\n<div>\u00a0<\/div>\n<div>The picture below shows the cascading functionality between departments and users:<\/div>\n<div><a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_08.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1196 alignnone\" title=\"Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_08\" src=\"https:\/\/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\" srcset=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_08.jpg 318w, https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_08-300x89.jpg 300w\" sizes=\"auto, (max-width: 318px) 100vw, 318px\" \/><\/a><a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_09.jpg\"><\/a><\/div>\n<div>After making a selection of a department and\/or a user \u2018Show tags of selection\u2019 can be selected. Selecting this fires the operation \u2018GetTagsOfSelection()\u2019 with the values of the selected department and\/or user as parameters.\u00a0<\/div>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\nfunction GetTagsOfSelection(userSelection, departmentSelection) {\r\n\u00a0\u00a0\u00a0 var result = &#x5B;];\r\n\u00a0\u00a0\u00a0 if (userSelection != 0) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GetTagsOfUser(userSelection, true, true);\r\n\u00a0\u00a0\u00a0 } else if (departmentSelection != 0) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $.each(filteredUsers, function (key, value) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GetTagsOfUser(value&#x5B;&quot;AccountName&quot;], false, true, false, function (items) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $.each(items, function (i, n) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 result.push({ Tag: n&#x5B;&quot;Tag&quot;], Count: 1 });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 result = uniqueTags(result);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SortByCount(result);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(&quot;#showtagsofuserText&quot;).show();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(&quot;#showtagsofuser&quot;).html(&quot;&quot;);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $(&quot;#tagsofuserTemplate&quot;).tmpl(result)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 .appendTo(&quot;#showtagsofuser&quot;);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/}\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0 }\r\n}\r\n<\/pre>\n<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\u2019 member of the selected department are retrieved, counted and sorted descending. The jQuery template is rendered with the results.<\/div>\n<div>\u00a0<\/div>\n<div>The page now looks like this when the current logged in user is a board member:<\/div>\n<div><a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_091.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1197 alignnone\" title=\"Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_09\" src=\"https:\/\/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\" srcset=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_091.jpg 429w, https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_091-300x95.jpg 300w\" sizes=\"auto, (max-width: 429px) 100vw, 429px\" \/><\/a><\/div>\n<div>And a manager:<br \/>\n<a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_10.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1198 alignnone\" title=\"Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_10\" src=\"https:\/\/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\" srcset=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_10.jpg 426w, https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_10-300x81.jpg 300w\" sizes=\"auto, (max-width: 426px) 100vw, 426px\" \/><\/a><\/div>\n<h3>The result<\/h3>\n<div>Grabbing all the functionality together the social dashboards look like:<\/div>\n<div>\u00a0<\/div>\n<div>For an employee:<\/div>\n<div><a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_11.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1199 alignnone\" title=\"Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_11\" src=\"https:\/\/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\" srcset=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_11.jpg 873w, https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_11-300x80.jpg 300w\" sizes=\"auto, (max-width: 786px) 100vw, 786px\" \/><\/a><\/div>\n<div>For a manager:<\/div>\n<div><a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_12.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1200 alignnone\" title=\"Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_12\" src=\"https:\/\/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\" srcset=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_12.jpg 874w, https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_12-300x88.jpg 300w\" sizes=\"auto, (max-width: 787px) 100vw, 787px\" \/><\/a><\/div>\n<div>For a board member:<\/div>\n<div><a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_13.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1201 alignnone\" title=\"Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_13\" src=\"https:\/\/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\" srcset=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_13.jpg 876w, https:\/\/www.itidea.nl\/wp-content\/uploads\/2011\/07\/Boerboom_Client_side_social_dashboard_with_SharePoint_2010_and_SPServices_13-300x98.jpg 300w\" sizes=\"auto, (max-width: 788px) 100vw, 788px\" \/><\/a><\/div>\n<div>This month the board member, Paul, wins the bottle of champagne, because he tagged the most content. Since this isn\u2019t the wanted outcome, employees have to win the bottle of course; Paul throws in two bottles of champagne for the winner next month.<\/div>\n<div>\u00a0<\/div>\n<div>This company just started to use the social aspects of SharePoint. The number of tags used isn\u2019t 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>\n<div>\u00a0<\/div>\n<h2>Summary<\/h2>\n<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>\n<div>\u00a0<\/div>\n<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>\n<div>\u00a0<\/div>\n<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\u2019s not the web service not being efficient; it\u2019s 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>\n","protected":false},"excerpt":{"rendered":"<p>The article I wrote for DIWUG SharePoint eMagazine 4 now also online here: \u00a0 \u00a0 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 &#8230; <a class=\"more-link\" href=\"https:\/\/www.itidea.nl\/index.php\/client-side-social-dashboard-with-sharepoint-2010-and-spservices\/\">Read More &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[11,42,33],"class_list":["post-1175","post","type-post","status-publish","format-standard","hentry","category-sharepoint-2010","tag-jquery","tag-sharepoint-2010","tag-spservices"],"_links":{"self":[{"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/posts\/1175","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/comments?post=1175"}],"version-history":[{"count":22,"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/posts\/1175\/revisions"}],"predecessor-version":[{"id":1215,"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/posts\/1175\/revisions\/1215"}],"wp:attachment":[{"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/media?parent=1175"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/categories?post=1175"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/tags?post=1175"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}