Wednesday, November 7, 2012

Branding

5 PowerShell snippets for SharePoint branders

Just as I wrote in my last blog post I like to collect pieces of code snippets. Sooner or later I’ll found them useful and they could save time and other efforts. My intention with this post is just to share a couple of my snippets and I hope that you’ll found something useful here.
PowerShell is a command-line scripting tool that provides an administrator full access to applicable application programming interfaces (APIs), along with the ability to unlock the capability to interact directly with SharePoint 2010 Products to manipulate Web applications, site collections, sites, lists and much more. So what’s a useful thing to do with PowerShell as a SharePoint brander or a front end developer? Well, there are a lot of different types of tasks you can use PowerShell to, for example populate a list with a large amount of objects when you need to performance test your Data View Web Part or if you need to apply a theme to let’s say some site in the structure including its sub sites or if you need to batch update properties of a collection page layouts.
Maybe you see something that can be written more efficient or if you have some cool snippets of your own you like to share, please drop this in a comment. Take these snippets as they are, try them first in your developer or test environment and feel free to use them and modify in the way you want.
Running PowerShell scripts is easy and you will find many resources out there if you never used PowerShell before, when you know the basics it’s just to go ahead and try these out. This stuff is written for SharePoint 2010 but most of this can be used in SharePoint 2013 as it is.

1. Change Master Page for all sites in the collection

In this example I’ll apply a customer master to all the sites in the site collection, this can be rewritten specific for SharePoint foundation, where PowerShell is much useful for such task. In this snippet I have set V4.master, so have to change the name of the master page file if apply a custom master page.
01# ----- For publishing sites and non publishing sites
02$site = Get-SPSite http://intranet
03foreach ($web in $site.AllWebs) {
04$web; $web.CustomMasterUrl = "/_catalogs/masterpage/V4.master";
05$web.Update(); $web.CustomMasterUrl;
06$web.Dispose()
07}
08foreach ($web in $site.AllWebs) {
09$web; $web.MasterUrl = "/_catalogs/masterpage/v4.master";
10$web.Update(); $web.MasterUrl;
11$web.Dispose()
12}
13$site.Dispose()
14write-host "Complete! V4.master is now applied";

2. Set alternate CSS

In this way you can set a custom CSS file as an alternate CSS at the top site of your site collection, publishing sub sites will inherit the alternate CSS by default.
1$web = Get-SPWeb http://intranet
2$web.AlternateCssUrl = "/Style Library/MyStyles/main.css"
3$web.AllProperties["__InheritsAlternateCssUrl"] = $True
4$web.Update()

3. Set a site logo

With this one you can associate a logo with all sites in the site collection by entering the URL to an image file.
1(get-spsite http://intranet).AllWebs | foreach {
2$_.SiteLogoUrl = "/Style%20Library/MyClient/Images/ClientLogo.png";

4. Set regional setting/locale

This one can be handy when you need to specify the way the site displays numbers, dates, and time. In this example I set locale to Swedish (1053).
1$site = Get-SPSite http://intranet
2foreach ($web in $site.AllWebs) {
3$web; $web.Locale = 1053;
4$web.Update(); $web.Locale;
5$web.Dispose()
6}
7$site.Dispose()

5. Set a theme

This one will set a theme to all sites in the site collection. This script is originally written by my friend MVP Yaroslav Pentsarskyy
01$SiteUrl = "http://intranet"
02$NewTheme = "Azure"
03# Loading Microsoft.SharePoint.PowerShell
04$snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'}
05if ($snapin -eq $null) {
06Write-Host "Loading SharePoint Powershell Snapin"
07Add-PSSnapin "Microsoft.SharePoint.Powershell"
08}
09# Setting site themes on sites and sub sites
10$SPSite = Get-SPSite | Where-Object {$_.Url -eq $SiteUrl}
11if($SPSite -ne $null)
12{
13$themes = [Microsoft.SharePoint.Utilities.ThmxTheme]::GetManagedThemes($SiteUrl);
14foreach ($theme in $themes)
15{
16if ($theme.Name -eq $NewTheme)
17{
18break;
19}
20}
21foreach ($SPWeb in $SPSite.AllWebs)
22{
23$theme.ApplyTo($SPWeb, $true);
24Write-Host "Set" $NewTheme "at :" $SPWeb.Title "(" $SPWeb.Url ")"
25}
26}
27Write-Host "Themes updated at:" $SPSite.Url -foregroundcolor Green

More

If you’re a truly SharePoint Designer guy, why not use PowerShell to check if you allowed to do your branding stuff before fire it up…
1Get-SPDesignerSettings -webapplication http://intranet
There’s lot of blogs about using PowerShell in SharePoint but here’s a pic of a few cool scripts that somehow are related to this topic.
N8Design Stefan Bauer – Hide fields from list forms using PowerShell
MSDN Samples Stefan Bauer – version cleanup in SharePoint
Gary Lapointe – Reset Theme
Finally I’d like to give thanks to MVP Cathy Dew for inspiring discussions about this topic; PowerShell from a brander’s perspective as well as I’d like to thanks Falak Mahmood for general discussions and suggestions for the use of PowerShell.
Stay in tune!
Christian
September 27, 2012

10 jQuery snippets for SharePoint 2010

I like to collect pieces of code snippets, sooner or later I’ll found them useful and they could save time and other efforts. My intention with this post is just to share a couple of my snippets and I hope that you’ll found something useful here.
Maybe you see something that can be written more efficient or if you have some cool snippets of your own you like to share, please drop this in a comment. These snippets are all plugin independent and should be easy to follow and modify and they can be used in SharePoint Designer 2010, Visual Studio or be included in a text file in SharePoint linked from a content editor. Don’t forget to create a reference to latest jQuery in the master page or into the text file.
1. Text manipulation
In this example I replace ‘All site content’ with help of the each function.

1/* --- Doc ready ---*/
2$(document).ready(function() {
3$('.ms-splinkbutton-text').each(function(i){ $(this).text($(this).text().replace('All Site Content','More stuff here..'))
4})
2. Check the URL
If the URL contains ‘news’, let’s do something conditionally with JS.
1if(document.URL.indexOf("news") != -1){
2alert("News site");
3} else{
4alert("Not the news site");
5}
Another way is to getting a URL parameter and maybe their values and to something based on a condition with help of jQuery. Let’s give the background different colors depending if the view are sorted by Desc or Asc
01var url = window.location.href;
02/* --- Doc ready ---*/
03$(document).ready(function() {
04if (url.search("&SortDir=Asc") > 0) {
05$(".ms-viewheadertr").css('background-color','lime');
06};
07else if (url.search("&SortDir=Desc") > 0) {
08$(".ms-viewheadertr").css('background-color','yellow');
09};
10/* --- End doc ready ---*/
11});
3. Timestamp
If each page you create needs to have a unique name, you can set a time stamp when it creates. In this example I’ve used year to milliseconds and a random number at the end. This may be useful for a news site with many pages.

01// create a timestamp with random
02var now = new Date();
03var year = now.getFullYear();
04var month = now.getMonth();
05var day = now.getDay();
06var hours = now.getHours();
07var minutes = now.getMinutes();
08var seconds = now.getSeconds();
09var milliseconds = now.getMilliseconds();
10var rand = Math.floor((Math.random()*1000000)+1);
11var pageID = ('ID-')
12var CustomInput = pageID + '' + year + '' + month + '' + day + '' + hours + '' + minutes + '' + seconds + '' + milliseconds + '' + rand;
13 
14/* --- Doc ready ---*/
15$(document).ready(function() {
16$("input[name='ctl00$PlaceHolderMain$nameInput']").val(CustomInput);
17/* --- End doc ready ---*/
18});
If you only want this function for let’s say a news site, you can use an If statement and identify the URL. But don’t forget that URL can be changed.
1/* --- Doc ready ---*/
2$(document).ready(function() {
3if(document.URL.indexOf("news") != -1) {
4// Unique page title
5$("input[name='ctl00$PlaceHolderMain$nameInput']").val(CustomInput);
6} else{}
7/* --- End doc ready ---*/
8});
4. Change the attribute
Let’s say you want to change for example the title tag for the ‘I Like It’ button, you can do like this to set a custom attribute.

1/* --- Doc ready ---*/
2$(document).ready(function() {
3$(".ms-socialNotif-Container > a").attr({
4title: "Click the button if you like this page",
5});
6/* --- End doc ready ---*/
7});
5. Change CSS
Let’s change the header text to red if the name is Link.
1/* --- Doc ready ---*/
2$(document).ready(function() {
3$(".ms-WPTitle span:contains('Links')").css("color", "red");
4});
Another way is to use a condition and a variable for this, if the web part header is equal to Shared Documents set the color to green, if the text is eq to Link set a border around the web part and set the text to red color. Normally I set the CSS into a CSS file, and you can use addClass to set the class as an option to set the CSS inline the script if you like.

01/* --- Doc ready ---*/
02$(document).ready(function() {
03var WPtitle = $('.ms-WPTitle span');
04for (var i = 0; i <= WPtitle.length; i++) {
05if ($(WPtitle[i]).text() == 'Links') {
06$(WPtitle[i]).css({'color': 'red'});
07$(WPtitle[i]).parents().eq(10).css({'border': '1px black solid!important'});
08}
09else if ($(WPtitle[i]).text() == 'Shared Documents') {
10$(WPtitle[i]).css({'color': 'green'});
11}}
12/* --- End doc ready ---*/
13});
6. Add expand / collapse web parts
The following code will get expand/collapse for all standard web parts.

01/* --- Doc ready ---*/
02$(document).ready(function() {
03$(function($) {
04$('.s4-wpTopTable').find('tr:first h3').append('<a class=\'min\' style=\'float:left; margin-right:5px\'><img src=\'/_layouts/images/collapse.gif\'/></a>');
05var Collapse = "/_layouts/images/collapse.gif";
06var Expand = "/_layouts/images/expand.gif";
07$('.min').click(function(){     
08var img = $(this).children();
09$(this).closest('.s4-wpTopTable').find('tr:first').next().toggle().is(":visible") ? img.attr('src',Collapse) : img.attr('src',Expand );
10});
11});
12});
7. Modify form field
jQuery can be used in many ways for standard list forms in SharePoint and this fist example shows how to set read only, a color and a specific width for the title field in edit mode.

1/* --- Doc ready ---*/
2$(document).ready(function() {
3$("input[title='Title']").attr("readonly","true").css('background-color','#ccc').width(70);
4/* --- End doc ready ---*/
5});
Next example shows how to set a field limit and add a counter that shows number of characters left

01// Show Nr of Characters left in a common list field
02(function($){ 
03$.fn.fieldLimit = function(options) { 
04return this.each(function() { 
05var characters = 30;
06$(this).keyup(function(){
07if($(this).val().length > characters){
08$(this).val($(this).val().substr(0, characters));
09}  
10var remaining = characters - $(this).val().length;
11$(options.result).html(remaining + " characters left");        
12});
13}); 
14}; 
15})(jQuery);
16 
17/* --- Doc ready ---*/
18$(document).ready(function() {
19$('.ms-formtable').prepend("<div class='CharactersLeft'></div>");
20$('input[title$=Title]').fieldLimit({
21result:".CharactersLeft",
22});
23/* --- End doc ready ---*/
24});
8. Check site template
If you need to do something based on which site template a site has been created from, you can identify this with help of the site template ID. I have only covered a few templates below.
01/* --- Doc ready ---*/
02$(document).ready(function(){
03CurrentTemplate = g_wsaSiteTemplateId;
04TeamSite = 'STS#0'
05EnterpriseWiki = 'ENTERWIKI#0';
06PublishingSite = 'CMSPUBLISHING#0';
07if (CurrentTemplate == TeamSite){
08alert('Im a Team site');}
09else if (CurrentTemplate == EnterpriseWiki){
10alert('Im a Enterprise Wiki');}
11else if (CurrentTemplate == PublishingSite){
12alert('Im a Publishing Site');}
13else {
14alert('Sitetemplate not defined yet..');}
15/* --- End doc ready ---*/
16});
9. Welcome message
This example shows how to work with variables. You’ll also find some plain old good JS date stuff that can be useful when you need to check times.

01/* --- Doc ready ---*/
02$(document).ready(function(){
03var WelcomeMenuContent = $('.ms-welcomeMenu > a.ms-menu-a > span');
04var UserName = WelcomeMenuContent.text();
05var FirstName = UserName.split(" ")[0];
06var Display;
07var Digital = new Date()
08var Hours = Digital.getHours()
09Morning = 'Good morning' + " " + FirstName;
10Lunch = 'Lunch time' + " " + FirstName;
11Evening = 'Good evening' + " " + FirstName;
12Night = 'Time to go home' + " " + FirstName;
13TimeElse = 'Welcome' + " " + FirstName;
14if (Hours >= 5 && Hours <= 11)
15WelcomeMenuContent.text(Morning);
16else if (Hours == 12)
17WelcomeMenuContent.text(Lunch);
18else if (Hours >= 13 && Hours <= 17)
19WelcomeMenuContent.text(Evening);
20else if (Hours >= 18 && Hours <= 23)
21WelcomeMenuContent.text(Night);
22else
23WelcomeMenuContent.text(TimeElse); 
24/* --- End doc ready ---*/
25});
10. Append today’s date
While we’re talking about get date with JS, let’s see how you can use this to display current date somewhere at the page like this.

1var d = new Date();
2var month = d.getMonth();
3var date = d.getDate();
4var year = d.getFullYear();
5/* --- Doc ready ---*/
6$(document).ready(function() {
7$('.s4-pagedescription').append("<div style='float:right'>" + month + "/" + date + "/" + year + "</div>");
8});
Stay in tune!
/ Christian Ståhl
August 31, 2012

Use jQuery & cookies in SharePoint 2010

In this article I’ll show you how to use Cookies in jQuery for your SharePoint Designer 2010 no code applications.
With help of a cookie you can write information to the user’s computer and this can be useful if you need to store stuff like visitors preferences, for example if the user has checked a check box or not at some page. Cookies can be very useful in many ways, but in some situations you need to write such information to the server like a database instead, cookies should not be used for critical information or any kind of sensitive information especially at a public faced site. However a cookie can be a great choice for many tasks in your front end development.
Some examples of the usefulness of a cookie
  • Change color schemes
  • Hide / Show elements at the page
  • Resizing fonts, scale up or down
  • Form, auto save inputs in fields, selected check box or radio button
  • Accordion / tabs, remember last state of collapsed/opened
  • Navigation, remember the last location
  • Welcome message, for example if you want to show a popup only once at specific date at the start page.
jQuery doesn’t support cookies natively but you can use a super small plugin called ‘jquery.cookie.js’  that contains all kind of basic functions and options you’ll need for your scripting. This plugin is also included in jQuery UI development-bundle.
Jquery.cookies gives a couple of options like:
  • Expires
    The lifetime for the cookie. You can use a number of days or a specific date. If omitted, the cookie is a session cookie
  • Path
    Where the cookie is valid. If you want it to be valid at every site in the site collection, just use a slash /, if you want it to be valid at let’s say only the news site set e.g /news/

Get going

Let’s start with a simple example just to get going, the following example will set the top row to a red or green background color depending of which link you click. Let’s say you clicked at green one and then reload the page, the green background color will remain. If you restart the browser, the top row will be white again. This script do not have any expired date, therefore, the cookie will expire automatically when you close the browser.
Let’s try this out:
Download jquery.cookies.js and create a reference to this file in your custom master, don’t forget to include an reference to latest jQuery API as well.
HTML
Put this somewhere in your custom master page
1<!-- Session -->
2<div class="Wrapper">
3    <div class="Red">Red</div>
4    <div class="Pipe">|</div>
5    <div class="Green">Green</div>
6</div>
jQuery
Put this in an external JS file referenced from your master page
01$(document).ready(function() {
02 
03// Click red
04$('.Red').click(function() {
05$('.Wrapper').css("background-color","red");
06$.cookie('Wrapper', 'red');
07});
08 
09// Click green
10$('.Green').click(function() {
11$('.Wrapper').css("background-color","green");
12$.cookie('Wrapper', 'green');
13});
14 
15// Cookies
16var Wrapper = $.cookie('Wrapper');
17if (Wrapper == 'red') {
18$('.Wrapper').css("background-color","red");
19};
20if (Wrapper == 'green') {
21$('.Wrapper').css("background-color","green");
22};
23 
24});
CSS
Put this in an external CSS file referenced from your master page
01.Wrapper{
02width:100%;height:16px;
03background-color:#fff;color:#000;
04}
05.Red{
06cursor:pointer;padding-left:5px;
07float:left;
08}
09.Green{
10cursor:pointer;float:left;
11}
12.Pipe{
13float:left;padding:0px 5px 0px 5px
14}
Maybe you want to set the cookie to a life span of 2 days, take a look at the jQuery script and the part where you set the name and the property:
1$.cookie('Wrapper-', 'Green-');
Just add a path and a value; a number or a specific date, this will create the cookie

1$.cookie('Wrapper-', 'Green-', {path: '/', expires: 2});
Take a look at the cookie in your disk, if you are using IE, you will find it through this path

1C:\Users\...\AppData\Local\Microsoft\Windows\Temporary Internet Files
The file will contain the name of the cookie, the property and the path like this

1Wrapper-Green-ecmtest67/108815182001923024639810215318430245996*

How to use cookies in a Data View web part

If we take this a step further and try to use cookies in a typical news roller DVWP. In this example, If you click at the icon next to the header for a news item that section will disappear, a kind of ‘I Have Read This’ function. At the bottom of the web part there’s a reset link that will delete the cookie.

The HTML part of the DVWP, it’s important to use @ID for the id, classes and href as the script shows
01<div class="NewsRow {@ID}">
02<div class="NewsContentContainer">           
03<div class="NewsTitle">
04<div class="NewsHider"><a href="{@ID}" id="{@ID}"><img alt="" src="/Style%20Library/Custom/Images/IhaveReadThis.png" width="22" height="22" /></a></div>
05<div class="NewsTitleInner"><a href="/news/Pages/{@LinkFilename}"><xsl:value-of select="@Title" /></a></div>
06<div class="GeneralClearBoth"></div>
07</div>       
08</div>
09<div class="NewsAuthorCreatedWrap">
10<span class="NewsAuthor">By <xsl:value-of select="@PublishingContact.title" />,</span> <span class="NewsCreated"><xsl:value-of select="@ArticleStartDate" /></span>
11</div>
12<div class="NewsContent">
13<xsl:call-template name="FirstNWords">
14<xsl:with-param name="TextData" select="$DescText"/>
15<xsl:with-param name="WordCount" select="15"/>
16<xsl:with-param name="MoreText" select="'...'"/>
17</xsl:call-template>
18</div>
19</div>
The jQuery goes here
01jQuery(function ($) {
02var removedLinks = 'removedLinks'
03,Options = {
04expires: 7,
05path: '/news'
06},
07c=$.cookie(removedLinks)||'#DebuggingCode'
08$(c).remove();
09$(".NewsHider a").click(function (e) {
10e.preventDefault();
11var LinkClass = '.'+ $(this).attr('id'),
12removeLinksClasses=c.split(',')
13$(LinkClass).remove()
14removeLinksClasses.push(LinkClass)
15c=removeLinksClasses.join(',')
16$.cookie(removedLinks, c, Options)
17});
18$('#NewsResetCookie').click(function(){
19$.cookie(removedLinks,'',{expires:-1,path:'/news'})
20})
21});
If you prefer to use this in the ItemStyle.xsl and use it as a format for the Content Query web part, it works fine as well. If you want to take a look at a video of this, take a look here: http://youtu.be/kKEE_yktk8c
Hopes this give some ideas or inspiration for your cookie scripting adventures!
/ Christian
July 18, 2012

Comment functionality for news pages – Part II

This article is the last one of two describing how to implement comment functionality into the news pages in SharePoint Server 2010. You’ll find Part I here. If you followed the examples in the Part II and have implemented the comment functionality it’s time to create one or more news rollup web part:
  • A web part that display the latest news pages and the number of related comments
  • A web part that display recently commented news pages
  • A web part that display the Display most commented news pages

First step – create a news rollup DVWP

When Lists and libraries are connected with a lookup you have the possibility to join content from both sources into a single Data View Web Part (joined sub view). This is useful if you want to create a news rollup that shows the latest news including the number of comments for each news item. In my examples I use the Page library in the root like the custom list NewsComments. You can use this in a sub site for news if you prefer.
I wanted to strip out HTML from the body text and limited body text by a number of words, so I used the strip HTML and the Count Word templates; a Codeplex project called SPXSLT created by my friend Marc D Anderson.
  • Open SPD and create a new folder direct in the root level and give it the name ’SPD-WebParts’.
  • Create a new ASPX page and give it the name RollupNews.aspx, check it out and open this with SPD.
  • Paste all the content from my file with the same name, you’ll find the download link at the end of this blog post.
  • Save the file and hit F12 for preview.
  • Check in and publish the file.
  • You can save this DVWP to the site gallery or to your disc if you want to implement the web part with the browser.

Next step – create a recently comments DVWP

This web part displays the most recent commented news pages. If the comment is created today, ‘New!’ will be displayed otherwise not.

  • Create a new ASPX page, save into the folder SPD-WebParts and give it the name LatestCommentedNews.aspx, check it out and open it up.
  • Paste all the content from my file with the same name, you’ll find the download link at the end of this blog post.
  • Save the file and hit F12 for preview. Check in and publish the file.
  • You can save this DVWP to the site gallery or to your disc if you want to implement the web part with the browser.

Next step – create a most comments DVWP

This web part display the most commented news pages. In order to group this, I have used the PageID column for the grouping. Furthermore I want to sort the web part by number of Items but of some reason I haven’t yet found the perfect way to accomplish this in XSLT, so I leave this as an open question to you readers! If you found a pure XSLT way for this I’ll update this blog post. In the meantime I’ll go for the jQuery TableSorter plugin. This plug is useful in different scenarios when you need client side sorting with all kind of data and it a works great if you need secondary ‘hidden’ sorting or for example just sorting a table without page refresh. You’ll find the file included in the download, see the link at the end of this blog post.

  • Create a new ASPX page, save it save into the folder SPD-WebParts and give it the name MostCommentedNews.aspx, check it out and open it up.
  • Paste all the content from my file with the same name, you’ll find the download link at the end of this blog post.
  • Save the file and hit F12 for preview. Check in and publish the file.
  • You can save this DVWP to the site gallery or to your disc if you want to implement the web part with the browser.
To activate the sort order, add a reference in your custom master page to the tablesorter file and add the following line of script into an external JS file or into the head section of your master page:
1<script type="text/javascript">
2$(document).ready(function() {
3// Custom sort DVWP news sort by most comments
4$('.tablesorter').tablesorter({sortList:[[0,0]] });
5});
6</script>

Download the files

If you got questions about this or maybe ideas for more functions or web parts related to this, pleas drop a comment.
Download my example files here
Thanks!
/ C
June 30, 2012

Comment functionality for news pages – Part I

If you want to implement comment functionality into the news pages in SharePoint Server 2010, a no code solution with Data Views and portion of jQuery could be a perfect option for you. Alternative you can use the OOTB Note board web part or even use a blog site to get comment functionality but these options limits you if you need to customize such solution in comparison to data views powered with XSLT, jQuery and CSS.

My concept for this is basically to use two connected lists. In the following example I’ll use the Page library in the root site and a custom list called NewsComments. The NewsComments lists have a lookup column (PageID) that connects the ID column in the Pages library. You can do this at a news sub site as well if you prefer.
I am using a data view form web part for the comment textbox in a page layout that sends the comment text, the current page ID, the page title and the page URL to the NewsComments list. Into this Page layout that serves as a template for the news pages, I have created a DVWP that displays all comments related to the current page. Do get this relation I use a parameter with a server variable and a XSL filter that matches current page name to the column in NewsComments list that stores the page names. I do also use some jQuery to grab and populate information on the page and the list.
When you connecting lists with a lookup it gives you the possibility to join content from both lists in a Data View Web Part (joined subview), this can also be useful if you want to create a news rollup that shows the latest news including the number of comments per news item. I’ll write more about such web parts in the next blog.

First step – create the list and a page layout

  • Create a list in the root site of the site collection by the type of Custom List named NewsComments. Create following columns:
    • A column named PageID by the type Lookup. Select Pages in ’Get information from’ and select ID for ’In this column’. Set it to required and click OK.
    • A column named PageTitle by the type Single Line of Text and click OK.
    • A column named Comments by the type multiple lines of text with 5 rows, specify this as Plain text and click OK.
  • Open SPD and create a new page layout and give it the name ’NewsPages’. Don’t forget to give the file a Title. You can copy an existing page layout. Open the page and add or remove the content fields you like the page to have, you can use just Page Content and Title. Add some additional markup; give the elements class names that the jQuery functions needs. Download my example files down below and copy the markup. In my example I have created a Page layout based on the Article Page layout, if you are using a content type like the Enterprise Wiki you have to add tag prefix in the top of the page layout that match the fields you put on the page.
  • Save and publish the file in _catalogs > masterpage folder at the root site. Make sure that it’s available at the root site as a selectable page layout so you can specify this page layout when you create a new page in the root site.
  • Now use the browser and create some pages at the root site, for example name the first on to test1 and the URL will be /Pages/test1.aspx. Use your new page layout as template.

Next step – create a comment in the list

Open the NewsComments list and create a new item, type the URL name of one of the pages you have created in the tile field, for example test1.aspx. Type the filename of the page in the Title field, select the ID of this page, type the title of the page in the PageTitle column and create a comment. You’ll need to do this just to make sure the comments can be connected.

You have now created the basics and were now move the two DVWPs that will display the comments for the pages and make the comment box available. Download my example files if you get stuck, you can just copy the DVWPs and the jQuery and paste them in your page layout.

Next step – create a Data View Web Part that only display comments related to the current news page.

  • Open SPD and the page layout that you just created with SharePoint Designer. Create a DVWP (display Item Form) that get the information from the NewsComments list. Add this DVWP at the bottom of the page just below the last content field. Use no paging, show all objects and show only the column Comments.
  • Create a new parameter as in the image below. The parameter is required to match the current page’s URL name to what caught up in NewsComments list’s Title field.
  • Change the dsQueryRespoinse/Rows variable. If you have a language other than English don’t forget to change name of Pages. Locate the following line:
    1<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>
    change to:

    1<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row[@Title=substring-after($ReferPageURL, 'Pages/')]"/>
  • Save the page and verify that only the comments appear per page according to what you entered in the NewsComments list.
  • Clean up the DVWP, och add the some markup for presentation.
  • Verify that everything works so far.

Next step – create a form web part

  • Add a DFWP (New Item Form) below the other data view, that get the information from the NewsComments list.
  • Use only following columns: PageID, PageTitle, Title and Comments
Clean the DFWP and give it some markup. As for the other DVWP, it’s important that you use the appropriate markup when jQuery and CSS makes use of class names.

Next step – create the jQuery you need for the comment box in the page layout

The purpose of the following jQuery is to get the page’s ID populated in the dropdown and to populate the Page’s title and URL into the select fields. I have also included a function that show characters left and set a limit to 140 characters.
01<script type="text/javascript">
02// Limit characters
03function limitChars(textid, limit, infodiv){
04var text = $('#'+textid).val();   
05var textlength = text.length;
06if(textlength > limit) {
07$('#' + infodiv).html(''+limit+' limit reached');
08$('#'+textid).val(text.substr(0,limit));
09return false;
10}
11else {
12$('#' + infodiv).html(''+ (limit - textlength) +' characters left');
13return true;
14}}
15$(function(){
16$(".FormFieldNewsComments > span > textarea[title='Comments']").keyup(function(){
17limitChars(".FormFieldNewsComments > span > textarea[title='Comments']", 140, "LimitInfo");
18})
19});
20     
21$(document).ready(function() {
22var loc = window.location.href.substr(window.location.href.lastIndexOf("/")+1); // Get the page filename
23var PageTitle = $('.PageTitleDiv').html(); // Get the page title
24$(".FormFieldNewsTitle > span > input[title='Title']").val(loc); // insert page filename in a CSS hidden formfield
25$(".FormFieldPageTitle > span > input[title='PageTitle']").val(PageTitle);    // insert pages title in a CSS hidden formfield
26var HiddenInput = $("input[title='PageID']").attr("optHid"); // Lagrar ID till attributet optHid
27$("select[title='PageID']").val(_spPageContextInfo.pageItemId); // If less than 20 items i Pages bibl, lägger in ID nr som en selected i DD
28$("input[title='PageID']").val(_spPageContextInfo.pageItemId);  // If 20 or more items in Pages lib
29$("input[id='" + HiddenInput +"']").attr("value",(_spPageContextInfo.pageItemId)) // Set ID as selected if 20 or more items in Pages lib
30});
31</script>

Next step – add a few more functions

I added a few additional functions in this example which I think may be helpful and that is the ability to remove own comments and to show number of comments for the page. If you download my example files, this is already included in the DVWPs.
Show the number of comments

1<xsl:if test="count($Rows) = 0">No comments yet..</xsl:if>
2<xsl:if test="count($Rows) = 1"><xsl:value-of select="$dvt_RowCount" /> Comment</xsl:if>
3<xsl:if test="count($Rows) &gt;= 2"><xsl:value-of select="$dvt_RowCount" /> Comments</xsl:if>
Add the following parameter to your XSL style sheet

1<xsl:param name="UserID" />
Create these parameter for the rowview template

1<xsl:param name="KeyField">ID</xsl:param>
2<xsl:param name="KeyValue" select="ddwrt:EscapeDelims(string(@ID))"/>
3<xsl:param name="Mode">view</xsl:param>
Match the author to the logged in user

1<xsl:if test="@Author.title = $UserID">
2<a href="javascript: {ddwrt:GenFireServerEvent(concat('__cancel;__delete={',$KeyField,'=',$KeyValue,'};__commit'))}">DELETE</a>
3</xsl:if>
If you want to create a link to the comment list that only administrators should see you can use the DDWRT:IfHasRights() function with an appropriate value

1<xsl:if test="ddwrt:IfHasRights(33554432)"><a href="/Lists/NewsComments/AllItems.aspx"><img src="/Style Library/Branding/Images/EditIcon.gif" alt="" /></a></xsl:if>

Next step – branding

The functions for this are now completed and it’s time to give this some visual awesomeness! Download my example files where you find CSS and an image that should get you going.

More to do

There are a lot of things to keep in mind to get this up and I hope you can take this as a base for your own solution and find inspiration. There are many ways to extend this and maybe I’ll publish this to Codeplex for the support and possibilities to further extensions. Maybe it could be an idea to integrate this function with my friend Marc D Anderson’s SPservices SocialDataServices

Download the files

Download my example files here

Part II

In the next blog I’ll show you how to create a news rollup out of this, a joined DVWP that displays the latest news and the number of related comments.
See Part II

Stay in tune!
News comments
News comments
May 23, 2012

Branding the Quick launch in SharePoint 2010 – Part II

This post is the last one of two articles about some branding tips and tricks for the Quick launch in SharePoint 2010. In this article I’ll show you a simple way to add rounded corners with help of two background images at the top and bottom. Take a look at the first article here.

Let’s go – Example 1

Open your custom master page with SharePoint Designer and find the Sharepoint:SPNavigationManager control. Add the following DIV just above this control.
1<div id="QLtopwrapper"></div>
When you complete this find the end tag of the </Sharepoint:SPNavigationManager> and add the following DIV just above this control.
1<div id="QLbottomwrapper"></div>
Now you have everything in place in your custom master page as needed, so now it’s time to add some CSS. Copy the following CSS code and paste it into your external CSS file. As you can see I have used two background images. Make your own or download the Images I have used here. I have included my example master page in the download if you find it difficult to locate where you should place the top and bottom div.
01/* |--------- Quicklaunch -----------| */
02.ms-quickLaunch {padding-top:0px}
03#s4-leftpanel-content{
04background-color:transparent!important;
05}
06#s4-leftpanel-content {
07border:0px!important;
08background-color:transparent!important;
09}
10.s4-ql {
11background-color:#fff;
12margin-bottom:0px!important;
13}
14/* Inner nav element */
15.menu-vertical {
16padding:0px!important;
17}
18/* top rounded */
19#QLtopwrapper {
20background:url('/Style%20Library/Branding/Images/QLtop.png') repeat-x;
21height:19px;
22width:220px;
23}
24/* bottom rounded */
25#QLbottomwrapper {
26background:url('/Style%20Library/Branding/Images/QLbottom.png') repeat-x;
27height:19px;
28width:220px;
29}
30.menu-vertical > ul.root > li.static > .menu-item{
31border-bottom:1px #929292 solid!important;
32padding-left:0px;
33color:#fff;
34font-family:Arial;
35font-size:11px;
36font-weight:bold;
37background-color:#8c8c8c!important;
38background-color:#8C8C8C!important;
39}
40/* Selected */
41.s4-ql a.selected {
42background-color:transparent;
43background-image:none;
44border:1px transparent solid!important;
45color:#fff!important;
46}
47/* no border in teamsites */
48.s4-ql,.s4-specialNavLinkList{
49border:0px!important;
50}
51.menu-vertical > ul.root > li.static {
52padding:0px!important; margin:0px!important;
53}
54/* headers */
55.menu-vertical > ul.root > li.static > a.menu-item {
56padding:10px 4px 10px 5px;
57border-bottom:1px #ccc solid;
58}
59/* headers selected for publishing sites */
60.menu-vertical > ul.root > li.static > a.selected {
61padding:10px 4px 10px 3px;!important;
62padding-left:4px!important;
63background-color:#777!important;
64}
65/* Subitem container */
66.menu-vertical > ul.root > li.static > ul {
67margin-bottom:0px;
68padding-top:0px;
69padding-bottom:0px;
70}
71/* SubItems wrap */
72.menu-vertical > ul.root > li.static > ul.static > li.static > a  {
73font-family:Arial, Helvetica, sans-serif;
74font-size:11px;
75padding:10px 4px 10px 8px;
76color:#ccc!important;
77}
78/* SubItems  */
79.menu-vertical > ul.root > li.static > ul.static > li.static > a > span > span {
80color:#333;
81text-decoration:none!important;
82}
83/* SubItems hover */
84.menu-vertical > ul.root > li.static > ul.static > li.static a:hover {
85text-decoration:none!important;
86}
87/* Selected SubItems  */
88.menu-vertical > ul.root > li.static > ul.static > li.selected > a.selected {
89background-color:#fff;
90border:1px transparent solid!important;
91padding-left:10px!important;
92}
93/* Selected SubItems  */
94.menu-vertical > ul.root > li.static > ul.static > li.selected > a.selected > span > span {
95color:#000;
96}
97.menu-vertical > ul.root > li.static > ul.static > li {
98border-bottom:1px #8C8C8C solid!important;
99}

Let’s go – Example 2

In this example I’ll use a jQuery script to get a simple and basic expand and collapse function in a specific scenario. Let’s say you have the setting “Display only the navigation items below the current site” for some site and have added headings and link manually. You can then use jQuery to toggle the headings. This behavior the jQuery script gives with the current navigation settings may not be suitable for all sites in the collection for you; this example is just build for this specific case and you can use it locally just on a single page if you prefer to.

Here’s the jQuery
01$(".menu-vertical > ul.root > li.static > ul.static").css("display","none");
02$(".menu-vertical > ul.root > li.static").css("background","url('/_layouts/images/plus.gif') no-repeat 3px 12px");
03  
04toggle();
05function toggle() {
06$(".menu-vertical > ul.root > li.static > a").toggle(
07function () {
08$("> ul", $(this).parent()).show("fast");
09$($(this).parent()).css("background","url('/_layouts/images/minus.gif') no-repeat 3px 12px");
10},
11function () {
12$("> ul", $(this).parent()).hide("fast");
13$($(this).parent()).css("background","url('/_layouts/images/plus.gif') no-repeat 3px 12px");
14});
15}
16$sel = $('.menu-vertical > ul.root > li.static > ul.static > li.selected');
17if($sel.length) {
18$sel.parent().css("display", "block");
19$sel.parents().eq(1).css("background","url('/_layouts/images/minus.gif') no-repeat 3px 12px"); 
20}
Here’s the CSS
01/* |--------- Quicklaunch -----------| */
02.s4-ql A.selected {
03background-color:transparent;
04border:0px!important;
05}
06/* Inner nav element */
07.menu-vertical {padding:10px; padding-left:0px}
08 
09/* Headers */
10.menu-vertical > ul.root > li.static > a > span > span.menu-item-text {
11border-bottom:1px #ccc solid;
12padding-left:5px; color:#333;
13padding-bottom:5px; padding-top:5px;
14}
15/* Sublinks */
16.menu-vertical > ul.root ul > li > a {
17padding-left:15px; color:#333;
18}
19/* Sublinks hover */
20.menu-vertical > ul.root ul > li > a:hover{
21color:#009BA4; text-decoration: underline
22}
23/* Sublinks top and bottom */
24.menu-vertical > ul.root ul {
25margin-top:5px; margin-bottom:5px;
26}
27/* Sublinks selected */
28.menu-vertical > ul.root > li.static > UL.static > li.selected > a.menu-item > span.additional-background{
29margin-left:6px!important
30}
Thanks & stay in tune!
/ Christian
April 2, 2012

SharePoint Server MVP 2012

I’m happy to announce that I have been selected again by Microsoft to receive the SharePoint Server MVP award for 2012 for the second time and I have now been awarded two years.
For me it’s really cool to receive this award, it’s motivates me to write more blogs & articles and other contributions to the SharePoint community. My goals for 2012 is to focus even more the area of branding and front end development in SharePoint. Besides my daily consulting work, I’ll also do more public speaking, to start with I’ll talk at TechDays in Sweden about branding & customize SharePoint online in Office 365. Later this year I’ll will speak at Konferenca SharePoint in Slovenia, SEF in Sweden and some more places, more about that later on.
MVP Award 2012
From the MVP site: “MVPs are recognized and awarded for their exceptional commitment to helping us improve our products and helping people around the world make the most of their Microsoft technology.”
Corey Artherholt Marketing, Events and Program Manager,
Community & Online Support, Microsoft
Read more about Microsoft MVP program at the Microsoft Most Valuable Professional site
Thanks a lot Microsoft, colleagues, friends and all great people out there in the world wide SharePoint communitys.
See you around and stay in tune for comming posts & articles .
March 27, 2012

Branding the Quick Launch in SharePoint 2010 – Part I

This post describes how to customize the standard Quick Launch in SharePoint by using SharePoint Designer 2010.
Branding the Quick Launch with only CSS could be a bit tricky and it takes a little while to become a friend with the markup of this navigation and have it to look the way you want. This first article in a series of two will show you how to create a simple custom look and feel with only CSS code. If you need to create a more advanced design for the Quick launch than you can do with just CSS, the alternatives is to manipulate the DOM with jQuery or using plain HTML with CSS and background images. Besides of this, CSS 3 comes with some exiting features like box shadow and border radius that lets you create stuff like boxes with curved corners but it’s not an option here because we need to render the master page in IE8 mode to get all functionalities intact in SharePoint 2010. I hope this post gives you some ideas and inspirations for branding the quick launch in the way you want.

Let’s go

Open SPD, create a custom master page and include a reference to an external CSS file. Paste the following CSS code in your custom CSS file. Save and publish the files and apply the master page to a site or your site collection. Use the browser and go to a site where you can see a Quick Launch to verify the changes. This first example uses a list style background image for the sub items. You can download the arrow icon here.

CSS

Add this CSS in your custom CSS file, don’t forget to change the path to the arrow icon to the folder where you put the image:
01/* |--------- Quicklaunch -----------| */
02.s4-ql ul.root ul {
03margin-bottom:5px;
04}
05/* Outher nav element */
06#s4-leftpanel-content{
07background-color:#fff!important;
08border:1px #d8d6d7 solid!important;
09border:0px!important
10}
11/* Inner nav element */
12.menu-vertical {
13padding-right:10px!important;
14padding-left:10px!important;
15}
16/* Inner Inner nav element */
17.menu-vertical > ul.root {
18padding-top:3px;
19}
20/* mainlinks */
21.menu-vertical > ul.root > li.static > .menu-item{
22border-bottom:1px #555 solid!important;
23padding:1px 1px 1px 0px!important;
24color:#333!important;
25}
26/* Sublinks */
27.menu-vertical > ul.root > li.static > ul.static  {
28margin-top:5px; margin-bottom:5px;
29}
30.menu-vertical > ul.root > li.static > ul.static > li.static > a > span > span {
31margin-top:2px
32}
33/* Selected */
34.menu-vertical > ul.root > li.selected > a {
35background-color:transparent!important;
36border:0px; margin:0px; padding:0px;
37}
38.menu-vertical > ul.root > li.static > ul.static > li > a.selected {
39background-image:none!important;
40background-color:transparent;
41color:green!important;
42border:0px; margin-top:1px;
43}
44/* no border for the QL when no links */
45.s4-specialNavLinkList {
46border:0px
47}
48/* Liststyle square */
49.s4-ql ul.root ul > li  {
50padding-top:0px;
51background-image:url('/Style Library/WordPress/Images/Arrow-Right.png');
52background-repeat:no-repeat;
53background-position:0.0em;
54}
55/* Liststyle square links */
56.s4-ql ul.root ul > li > a {
57display: inline-block!important;
58padding-top:0px;
59padding-bottom:0px!important;
60padding-left:0px!important;
61margin-left:16px;
62vertical-align:top!important;
63}

Another example

If you want to display more levels in the Quick Launch you can set the display level to three, MaximumDynamicDisplayLevels=”3″ for the SharePoint Asp menu in the master page. Look for the menu control with the ID V4QuickLaunchMenu. In this example I have used list-style squares instead of the arrows.

Add this CSS in your custom CSS file:
01/* |--------- Quicklaunch -----------| */
02.s4-ql ul.root ul {
03margin-bottom:5px;
04}
05/* Outher nav element */
06#s4-leftpanel-content{
07background-color:#fff!important;
08border:1px #d8d6d7 solid!important;
09border:0px!important
10}
11/* Inner nav element */
12.menu-vertical {
13padding-right:10px!important;
14padding-left:10px!important;
15}
16/* Inner Inner nav element */
17.menu-vertical > ul.root {
18padding-top:3px;
19}
20/* mainlinks */
21.menu-vertical > ul.root > li.static > .menu-item{
22border-bottom:1px #555 solid!important;
23padding-left:0px!important;
24padding:1px!important;
25color:#333!important;
26}
27/* Sublinks margins */
28.menu-vertical > ul.root > li.static > ul.static  {
29margin-top:5px;
30margin-bottom:5px;
31}
32/* Selected */
33.menu-vertical > ul.root > li.selected > a {
34background-color:transparent!important;
35border:0px; margin:0px; padding:0px
36}
37.menu-vertical > ul.root > li.static > ul.static > li > a.selected {
38background-image:none!important;
39background-color:transparent;
40color:green!important;
41border:0px; margin-top:1px;
42}
43/* no border for the QL when no links */
44.s4-specialNavLinkList {
45border:0px
46}
47/* Liststyle square */
48.s4-ql ul.root ul > li  {
49list-style:square inside !important;
50list-style-position:outside !important;
51margin-left: 23px !important;
52padding-top:0px;
53}
54/* Liststyle square links */
55.s4-ql ul.root ul > li > a {
56display: inline-block!important;
57padding-top:0px;
58padding-bottom:5px!important;
59padding-left:0px!important;
60vertical-align:top!important;
61}
62/* If 3 lvl in QL */
63/* Wrapper for all Items in lvl 3 */
64.menu-vertical > ul.root > li.static > ul.static > li.static > ul.dynamic {
65position:relative;
66left:-8px!important;
67top:1px!important;
68padding-left:0px
69}
70/* Wrapp each Item in lvl 3 */
71.menu-vertical > ul.root > li.static > ul.static > li.static > ul.dynamic > li.dynamic {}
72.menu-vertical > ul.root > li.static > ul.static > li.static > ul.dynamic a:hover {}
73.menu-vertical > ul.root > li.static > ul.static > li.dynamic-children > a.dynamic-children > span.additional-background {
74background-image:none
75}
76/* Items in level 3*/
77.menu-vertical > ul.root > li > ul > li > ul > li > a.selected > span > span  {
78padding-left:5px!important
79}
80/* Item lvl 3 - get all subItems from the last available DOM defined selected Item */
81.menu-vertical > ul.root > li > ul > li.selected > ul > li > a > span > span {}
Read more about customizing the Quick Launch at MSDN library How to: Customize the Display of Quick Launch
In the next blog post I’ll show you some more examples how to customize the quick launch with stuff like rounded corner & borders and how to expand / collapse the Quick Launch with help of jQuery. Stay in tune!
/ Christian
February 11, 2012

Create a Microblog for SharePoint 2010

This post is about how to create a Microblog with SharePoint Designer 2010 and the use of DVWPs, CSS and jQuery. A Microblog can be used for quick communication with team members in short sentences at the Intranet. This example works just like a SharePoint blog site, posts and comments are stored in separate lists that are linked by a lookup and team members can add posts and anyone can reply to posts. This Microblog is a basic no code solution and if you are looking for more advanced social features like hash tagging, direct messages, document uploading or integration of my site you should check out tools like NewsGator or Yammer among more. If you are looking for a basic comment function, maybe the OTB web part Note board could be an option. But let’s look into how you can use the DWVP for a Microblog.

Let’s try it out

  • Open the browser and create two custom lists in the root site of your Site Collection
    • Name it ListPosts
    • Name it ListComments
  • ListPosts
    • Create a column:
    • Name: Content – Multi lines of text with three lines for editing and plain text type.
    • Go to list settings, click the Created By column and change the presentation for this field to Name (with picture).
    • Add a new Item in the list with a title and a comment.
  • ListComments
    • Create two columns:
    • Name: PostsID – type Lookup. Get information from ListPosts in the ID column. Do not allow multiple values.
    • Name:  Comments – Multi lines of text with three lines for editing and plain text type.
    • Go to list settings, click the Created By column and change the presentation for this field to Name (with picture).
    • If you don’t use English language, rename the the (Title) column to Title, another way is just to set this column as optional if you prefer.
    • Add a new Item in the list with a title and a comment. Type a title, select PostID according to the ID from the ListPosts item you added and add a comment.

Create a Linked Data Source for the posts and comments lists

  • Open the root site with SPD and click at site objects in the left navigation at click Data Sources. Click at Linked Data Source in the ribbon. Give it the name MicroBlog in the General tab and click at configure Linked Source in the Source tab.
  • Select ListPosts and ListComments and add them to the right pane. If you can’t see the list you have to update SPD. Click at the next button and select Join and click at Finish and OK.
  • Open the root site with SPD and create a new folder named SPD-WebParts
  • Create a new ASPX page called MicroBlog and save it in the folder you created, open the page with SPD. IF you download my pages and will copy and paste you don’t need to do more now, but if you want to set this up by your self you can attach the page to your custom master page. Check it out, click at the Style tab in the ribbon, the button Attach and attach it as a custom master page. In the design view, click at the right arrow for the PlaceHolderMain place holder and click at create custom content.
  • Create a new ASPX page called MicroBlogForm and save it in the same folder as Microblog.aspx. Repeat the steps as you just did for the MicroBlog.aspx.

Create two ASPX pages

In the next step it’s time to create two DVWPs for MicroBlog.aspx, the first is for inserting posts and the second is for displaying current posts and their comments. If you want to build this by yourself you can just add a Display Item Form DVWP and use the Linked Sources and then insert field from the Comments as a Joined sub view. You will also have to create a New Item Form DVWP for the second page meant for inserting comments.
If I would describe all the steps from now including styling and jQuery this blog would be too long and for this reason I have prepared this so it’s just to download the pages and do some copy and paste. If you export or upload the DVWPs as web parts the CSS and the jQuery will not follow the web part. so cut the CSS from the MicroBlogForm page and paste this into an external CSS file. The same goes for the jQuery stuff in both pages, cut the scripts and paste them into the head section of your custom master or into an external JS file.
Read more about Linked data sources at the Microsoft Office SPD pages.
SPD-MicroBlog
SPD-MicroBlog

Insert the Dataviews into the ASPX pages

MicroBlog.txt

  • Open this page and copy the content into MicroBlog.aspx and save the page

MicroBlogForm.txt

  • Open this page and copy the content into MicroBlogForm.aspx and save the page

CSS

Copy this CSS into your custom CSS file
01/* --- MicroBlog --- */
02.PostBodyWrapper {width:100%;}
03.PostWrapper {margin-left:5px}
04.PostSeparator {border-bottom:1px #f1f1f1 solid; border-top:1px #fff solid; margin:5px 5px 5px 5px}
05.PostImg {float:left; width:50px; height:50px; padding-right:10px}
06.PostContentWrapper {background-color: #fff; height:50px;}
07.PostEditor {font-weight:bold; color: #0072bc}
08.PostContent {}
09.PostLink {}
10.PostComment {}
11.PostCreatePost {padding:10px}
12.FormFieldMicroBlogWrapper {margin-left:5px; width:100%; }
13.FormFieldMicroBlog > span > textarea {
14background-color: transparent; width:95%;
15border:1px solid #ccc;       
16overflow:hidden; overflow-y: hidden; overflow-x: hidden;  
17font-size:14px; color:#999;
18font-family:Arial, Helvetica, sans-serif;
19padding:10px 20px 0px 10px;
20margin-right:20px
21}
22.PostBtn {padding-right:3px; float:left}
23.PostBtn Input {
24width: auto;
25padding: 5px 10px 5px 10px;
26background: #617798;
27border: 0;
28font-size:13px;
29color: #fff;
30cursor: pointer!important;
31float:right
32}
33.CommentWrapper {margin-left:60px; margin-right:5px; background-color: #f7f7f7; padding:10px; border-bottom:1px #fff solid}
34.CommentImg {width:50px; float:left;}
35.CommentContentWrapper {}
36.CommentEditor {font-weight:bold; float:left}
37.CommentEnd {margin-left:60px; margin-right:5px; border-top:1px #ccc solid; border-bottom:1px #fff solid; margin-bottom:20px}
38.CommentContent {}
39.CommentLink {}
40.CommentNoComment {border-bottom:1px #fff solid; border-top:1px #fff solid; margin:0px 0px 15px 0px}
41/* --- End MicroBlog --- */

Jquery

Copy this jQuery into your custom master or into a referenced JS file
01$(document).ready(function() {
02$(function() {
03// Remove autofocus
04$("textarea[title='Content']").blur();
05// Set defaulttext
06var defaultText = 'What are you working on?';
07$("textarea[title='Content']"
08// Handle blur effect 
09.val(defaultText)
10.focus(function() {
11if ( this.value == defaultText ) this.value = ''
12})
13.blur(function() {
14if ( !$.trim( this.value ) ) this.value = defaultText
15});});
16});

Image Paths

If you not have activated the user profiles and my site, you have to change the image path in the MicroBlog file. You can create an image library in the root site and store the user images there if you want. Just name the images same as the Users ID. The path can looks like:
<img src=”/RootImages/{@Author.id}.jpg” alt=”" width=”50″ height=”50″ />

Ready to test

Finally it’s time to try this out, open your browser and to to the MicroBlog page

Behind the scenes

Some notes if you needs to change something
  • You have to reference the latest jQuery file in your custom master page
  • Save the two web parts into the web part gallery, or export them as files and you can use them at any page in the site collection, not only at the root site.
  • I have set a RowLimit variable to 5 In MicroBlog.aspx, change this as you prefer.
  • I changed the variable that Joins the list to get rid of the unwanted characters
    <xsl:variable name=”Rows” select=”../../../ListComments/Rows/Row[substring-before(@PostsID., ';#') = normalize-space($dvt_ParentRow/@ID)]“/>
  • The link ‘Reply’ sends the current posts ID as a query string over to the next page (the dialogue). I have used a bit jQuery go get this ID from the URL in order to prepopulate a hidden drop down (the lookup column), and as you may know if there are 20 or more items in a list and you use lookup to this list, the select drop down will be converted to an input drop down and this needs to be solved as well.
  • In the dialog I used a SharePoint:SaveButton as I think is an easy way to close a dialog when click the save button.
The jQuery used in the MicroBlogForm that sets the Post ID into the hidden dropdown.
1$(document).ready(function() {
2var loc = window.location.href.substr(window.location.href.lastIndexOf("/")).replace('/MicroBlogForm.aspx?CID=', '').replace('&IsDlg=1', '');
3var HiddenInput = $("input[title='PostsID']").attr("optHid");$("select[title='PostsID']").val(loc);
4$("input[title='PostsID']").val(loc);  
5$("input[id='" + HiddenInput +"']").attr("value",(loc))
6$('input[title="Title"]').val(loc);
7$(".FormFieldShow > span > textarea").focus();
8});

More to do

If someone’s profile picture should be broken or missing, you can use jQuery to replace a broken image with an shadow image:
1$(window).bind('load', function() {
2$('img.resizeme').each(function() {
3    if((typeof this.naturalWidth != "undefined" &&
4        this.naturalWidth == 0
5        || this.readyState == 'uninitialized' ) {
6        $(this).attr('src', '/_layouts/images/O14_person_placeHolder_32.png');
7    }
8});
9})
Enjoy, and drop a comment if you have something to ask
/ Christian
January 27, 2012

Customize the UI of web parts in SharePoint 2010

This post describes how to customize a standard Web Part in SharePoint by using SharePoint Designer 2010. Depending of the look and feel or factors such as accessibility, performance or cross browser stability it could be a challenge to bend the web part UI exactly in the way you want. The markup of the web parts in SharePoint contains a quite deep nested table structure and the elements do not always have an id or class.
When you need to create an advanced design for the web parts, the alternatives is to manipulate the DOM with jQuery or create custom web part control wrappers with code. Besides of this, CSS 3 comes with some interesting possibilities like box shadow and border radius that lets you create stuff like boxes with curved corners but it’s not an option here because we need to render the master page in IE8 mode to get all functionalities intact in SharePoint 2010.

So what can you do quick and easily then? The web part headers and all the cells in header row can easily be customized with CSS just like the borders around. I have made four examples with different colors you can download and use at the bottom of this page.
Using only CSS and images for rounded corners is the easiest approach where you don’t need plugins like CSS3 Pie or other htc solutions, fallback methods for different browsers or care about slow rendering when rewriting the already complex and nestled DOM. But when you reach the border of what is possible to do with just CSS and images it’s time to bend the DOM with our friend jQuery or fire up Visual Studio for write a control adapter. Take a look at this blog post from ‘All things SharePoint’ that describes how to use jQuery to adding classes and wrappers into the DOM so you can get a wrapper with rounded corners for the web parts, and take a look at Waldek Mastykars post about how to removing the web part tables with code.
Back to the basics, let’s see how you can customize the web part headers the easy way.
The following example, see the image above, applies background images for the corners and for the middle section. The left and right corners have dimensions of 7 x 33 pixels, and the middle image has dimensions of 14 x 33 pixels.

Let’s go

Download the images and put them into Style Library/BlogBranding/Images or change the path in the CSS below if you want to put the images in some other folder.
01/* WebPart headers */
02/* All tdS in the row */
03.ms-WPHeader > TD{
04background-image: url('/Style Library/BlogBranding/Images/WP-MidGreen.png');
05background-repeat:repeat-x;
06padding-left:1px; padding-right:1px; height:33px;
07border-bottom-style:none!important;border-bottom-color:inherit!important; border-bottom-width:0px!important;
08}
09/* Left cell */
10.ms-WPHeader td:first-child {
11width:5px;
12background-image:url('/Style Library/BlogBranding/Images/WP-LeftGreen.png')!important;
13background-repeat:no-repeat;
14}
15/* Right cell */
16.ms-wpTdSpace {
17width:7px;
18background-image:url('/Style Library/BlogBranding/Images/WP-RightGreen.png')!important;
19background-repeat:no-repeat;
20background-color:transparent;
21}
22/* Arrow */
23.ms-WPHeaderTdMenu{
24background-color:transparent;
25border:0px!important;
26}
27/* Web part title */
28.ms-WPTitle {
29padding-left:10px;
30font-family:Arial, Helvetica, sans-serif;
31color:#fff;
32font-weight:bold;
33margin-bottom:1px;
34font-size:14px;
35}
36/* linked title and visited */
37.ms-WPTitle a, .ms-WPTitle a:visited {
38color:#fff;
39text-decoration:none;
40}
41/* hover title */
42.ms-WPTitle a:hover {
43color:#333;
44text-decoration:none;
45}
46/* hover web part menu */
47.ms-WPHeaderTdMenu:hover{
48border-left:1px solid transparent;
49background-image: url('/Style Library/BlogBranding/Images/WP-MidGreen.png');
50}

More stuff you can do

If you want to do something special just for one single web part based on some condition or similar? Let’s say you want to have a different look and feel for some web part only if its header text is ‘Links’. I made up an example that makes the header title red and adds a border with a dropshadow filter older IEs and BoxShadow for modern browsers. Other web parts will not apply this look and feel.

Here’s the jQuery

01$(document).ready(function() {
02var WPtitle = $('.ms-WPTitle span');
03for (var i = 0; i <= WPtitle.length; i++) {
04    if ($(WPtitle[i]).text() == 'Links') {
05            $(WPtitle[i]).css({'color': 'red'});
06            $(WPtitle[i]).parents().eq(10).addClass("WebPartBorder");
07    }
08    else if ($(WPtitle[i]).text() == 'Shared Documents') {
09            $(WPtitle[i]).css({'color': 'blue'});
10    }
11}
12});

Here’s the CSS

01/* All TDs in the table row */
02.ms-WPHeader TD{
03background-color: #f7f7f7;
04filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb', endColorstr='#e2e2e2');
05background: -webkit-gradient(linear, left top, left bottom, from(#e2e2e2), to(#ebebeb));
06background: -moz-linear-gradient(top, #e2e2e2, #ebebeb);
07border-top:1px #cfcfcf solid; border-bottom:1px #e2e2e2 solid!important;
08padding:3px;
09}
10/* for css / jquery drop shadow */
11.WebPartBorder{
12border:1px #777 solid!important;
13-moz-box-shadow: 5px 5px 5px #ccc;
14-webkit-box-shadow: 5px 5px 5px #ccc;
15box-shadow: 5px 5px 5px #ccc;/* CSS3 */
16background-color:#fff;
17filter: progid:DXImageTransform.Microsoft.DropShadow(OffX=5, OffY=5, Color=#e9e9e9);   
18}
19.WebPartBorder > tbody {
20background-color:#f7f7f7!important
21}
22/* Border to the sides */
23.ms-WPHeader td:first-child {
24border-left:1px #e2e2e2 solid;
25border-right:0px;
26}
27.ms-wpTdSpace {
28border-right:1px #e2e2e2 solid;
29}
30/* Web part title */
31.ms-WPTitle {
32color: #333;
33font-weight:bold;
34}
35/* linked title and visited */
36.ms-WPTitle a, .ms-WPTitle a:visited {
37color: #333!important;
38text-decoration:none!important;
39}
40/* hover title */
41.ms-WPTitle a:hover {
42color:#0072bc!important;
43}
44/* hover web part menu */
45.ms-WPHeaderTdMenu:hover{
46 background-image:none;
47border-top:1px solid #ccc;
48border-right:1px solid transparent;
49border-left:1px solid transparent;
50background-color:#f7f7f7;
51}
52/* for the jQuery */
53.LinkTextColor {
54color:red;
55}
Hopes this gives you some ideas, and please feel free to drop a comment!
/ Christian

1 comment: