jQuery Blogging Part Deux
Guest Author: Jason MacKenzie
Intelligence Among Us
This is a continuation of my previous post on enhancing the SharePoint Blog user interface with jQuery. In that sample I demonstrated how to use jQuery along with a customized Content Query Web Part in order to create a nice accordion effect for recent blog comments. In this example I will take things further and demonstrate:
- How to include the most recent blog posts using jQuery to create a nice scrolling effect
- Use the concepts introduced by Mark Miller for creating a Scripting Resource Center
- How to change the look and feel of your jQuery components by using jQuery themes
- Finally I will use the jQuery Dynamic List Filter and MOSS Filter web parts to create a dynamic page for searching posts and comments
- I’ll also use the ChartPart web parts and some SPD workflows to create some graphs to visualize information about the blog

The completed blog home page looks like the image below. Please check the following screen cast to see it in action. Note that some of the more dynamic effects aren’t visible in the video due to the fact that Camtasia Studio seems to consume a lot of resources. You can see them in the video attached to the previous blog post. http://www.screencast.com/users/JasonMacKenzie/folders/Default/media/7e067f8b-af00-4a69-aae0-59c2fc41a198

Blog Scrolling
The first effect I wanted to achieve was to create a scrolling list of recent blog posts. In order to achieve this I used the Content Query Web Part along with the Scrollable plugin from jQuery Tools. The vertical scrolling requires the HTML to be output in the following structure:
<div id="actions"> <a class="prevPage">« Back</a> <a class="nextPage">More pictures »</a> </div> <!-- root element for scrollable --> <div class="scrollable vertical"> <!-- root element for the items --> <div class="items"> <!-- first item. can contain anything --> <div> <!-- image --> <img src="http://farm1.static.flickr.com/_m.jpg" /> <!-- title --> <h3>1. Barcelona Pavilion</h3> <!-- content --> <p> The Pavilion was not only a pioneer ... </p> </div> <!-- second item (and so on) --> <div> ... </div> </div> </div>
So, as in the last post I’ll create a custom item template in ItemStyles.xsl in order to achieve this effect. I won’t go into to detail explaining this as you can read my previous post for the mechanics of it. I’ll post the template in it’s entirety for you to use:
<xsl:template name="ScrollableBlogPosts" match="Row[@Style='ScrollableBlogPosts']" mode="itemstyle"> <xsl:variable> <xsl:call-template> <xsl:with-param select="'ImageUrl'"/> </xsl:call-template> </xsl:variable> <xsl:variable> <xsl:call-template> <xsl:with-param select="'LinkUrl'"/> </xsl:call-template> </xsl:variable> <xsl:variable> <xsl:call-template> <xsl:with-param select="@Title"/> <xsl:with-param select="'LinkUrl'"/> </xsl:call-template> </xsl:variable> <xsl:variable> <xsl:if test="@OpenInNewWindow = 'True'" >_blank</xsl:if> </xsl:variable> <xsl:if test="count(preceding-sibling::*)=0"> <div></div> <style> <xsl:text disable-output-escaping="yes"> .vertical {position:relative; overflow:hidden; height: 665px; width: 650px; border-top:1px solid #ddd; } .items {position:absolute; height:20000em; margin: 0px;} .items div {margin:2px 0; padding:2px;} .items img {float:left;margin-right:20px; height:180px; width:240px;} .items h3 {margin:0 0 5px 0; font-size:16px;color:#456; font-weight:normal;} #actions {width:100%px;margin:30px 0 10px 0;} #actions a {font-size:11px; cursor:pointer; color:#666;} #actions a:hover {text-decoration:underline;color:#000;} .disabled {visibility:hidden;} .nextPage {float:right;} </xsl:text> </style> <div> <a>Previous</a> <a>More Blog Posts</a> </div> <a></a> <xsl:text disable-output-escaping="yes"> <!-- root element for scrollable --> <div> <!-- root element for the items --> <div> </xsl:text> </xsl:if> <div><div><strong><a style="font-size:medium;color:gray" href="{$SafeLinkUrl}" target="{$LinkTarget}" title="{@LinkToolTip}"> <xsl:value-of select="@Title"></xsl:value-of></a></strong></div><xsl:value-of select="@Body" disable-output-escaping="yes"></xsl:value-of> Posted at <xsl:value-of select="ddwrt:FormatDateTime(string(@PubDate) ,1033 ,'dd-MM-yyyy')" /> Posted By: <xsl:value-of select="@Author"></xsl:value-of> | <a style="font-size:x-small;color:black" href="{$SafeLinkUrl}#Comments" target="{$LinkTarget}" title="{@LinkToolTip}"> Comments</a> <hr style="color:white;border-bottom:1px solid black;"></hr> </div> <xsl:if test="count(following-sibling::*)=0"> <xsl:text disable-output-escaping="yes"> </div> </div> </xsl:text> </xsl:if> </xsl:template>
The next thing we’ll need to do is modify out CEWP to contain the jQuery to handle the scrolling. I will include all the script that is included in order to make our prototype function properly. The relevant script is in red. Note the easing function – for those that read my posts I’m sure you recognize that I did not come up with that on my own. All those algorithms are from the jQuery Easing plugin and you can simply copy and paste them in order to change the easing effect.
<script src="/sprc/Resources%20%20jQuery/jquery-1.3.2.min.js"></script> <script src="/sprc/Resources%20%20jQuery/jquery.tools.min.js"></script> <script src="/sprc/Resources%20%20jQuery/jquery-ui-1.7.1.min.js"></script> <link rel="stylesheet" href="/sprc/Resources%20%20jQuery/jquery-ui-themes-1.7.1/excite-bike/jquery-ui.css"> <h3> <script> $(document).ready(function(){ $("#accordion").accordion( { autoheight: false} ); // initialize scrollable $("div.scrollable").scrollable({ vertical:true, size: 1,easing: 'custom', speed: 1000 }) jQuery("#dialog").dialog({ bgiframe: true, autoOpen: false, modal: true, show: 'slide' }); $("#demo img[title]").tooltip('#demotip'); }); // custom easing called "custom" $.easing.custom = function (x, t, b, c, d) { if (t==0) return b; if (t==d) return b+c; if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; } function PopulateText(textToShow, title) { document.getElementById("dialog").innerHTML = textToShow; document.getElementById("dialog").title = title; } </script>
Scripting Resource Center
Following Mark’s advice I created a Scripting Resource Center to centrally host all jQuery related files as well as a wiki for all things SharePoint. I have download the latest versions of jQuery – 1.2.6 +, recent versions of jQuery UI, jQuery Tools as well as all the jQuery UI themes:

Changing Look and Feel
jQuery themes make it extremely easy to change the look of your jQuery components. See the screencast for the specific look but in a nutshell all you need to do is change the theme name in your CEWP. I’m quite pleased with the fact that the theme that works for me is called excite-bike. For some reason the name makes me happy.
<link rel=”stylesheet” href=”/sprc/Resources%20%20jQuery/jquery-ui-themes-1.7.1/excite-bike/jquery-ui.css”> to <link rel=”stylesheet” href=”/sprc/Resources%20%20jQuery/jquery-ui-themes-1.7.1/redmond/jquery-ui.css”>
Personalized View and Dynamic List Filtering
I added a page where a user can view all blog posts along with their own comments. This uses the Filter web parts that are part of MOSS Enterprise Edition. The important thing to note here is that you need to set the Select Value to Provide to SharePoint profile value for current name and then select “Name” from the drop down.

Adding dynamic filtering could not be easier thanks to Jaap Vossers solution. This requires jQuery 1.2.6 so I installed that into the Resource Center and then it’s just a matter of placing the script in a CEWP. In my view this dramatically improves the user experience.
Charting and Real-Time Data
For the last piece of the puzzle I want to provide some charts on the home page that would show in (near) real time some of the activity on the blog. For this I downloaded the ChartPart solution from CodePlex and begged my administrator to install it It is incredibly easy to configure and it renders really slick looking charts.
Everything else was accomplished with a few custom lists and a 2 step workflow called Activity Tracker on the Posts list.
I created 2 lists – Comment Counter and Post Comment Counter.
Comment Counter contains 3 columns – Title, Comment Poster (person) and Comment Count (number).
Post Comment Counter contains 2 columns – Post Subject and Comment Count (number).
Below is a shot of the workflow in SPD:

Both steps are essentially the same and the process goes like this:
- If the current user has a an entry already in the Comment Count list then get the current comment count, increment the count by 1 and then update their list item.
- If the user has no item in the Comment Count list then create a new item for them with a Comment Count of 1.
The second step is essentially the same except we are looking to see if an item with the same subject as the current post the user is commenting on exists. If so increment by 1, otherwise create a new item for that Blog Post with a Comment Count of 1.
We can then create views and easily hook the charts up to those views.
And that is it. Going through this process has been extremely educational for me as it relates to integrating jQuery with SharePoint and I can say with certainty that our users are very impressed by the new pizazz we’re adding to their intranet. It also made it clear how many resources there are available and what you can do when you combine them into a holistic solution.
Guest Author: Jason MacKenzie
Intelligence Among Us
Jason has been an IT professional for 12 years and has worked in a variety of roles from software development to managing business solutions for a large international automotive supplier. He has developed mission critical software solutions for the manufacturing industry and has experience in the government and educational fields as well.
Jason is a social networking enthusiast and is currently working as an independent SharePoint architect. Jason helps organizations with strategy and implementation guidance related to architecture, governance, processes as well as hand-holding and facilitating a good group cry every now and again. Jason’s goal is to actively participate in the community and share what he has learned in order to help people and business leverage their investment in this critical platform.
- JQuery and SharePoint Blogging Sample
- jQuery Blogging Part Deux