Wow!!! SharePoint 2013 includes Like and Rating functionality out of the box. Just navigate to List/Library Settings -> Rating settings and set it up. It is that easy :-).
However, you can only like/unlike or rate a item/page in the “All Items” view of the list/library. So, If you want to show this flashy “Like” functionality to your users on different publishing pages of your site, there is no out of the box way to do it. In this post, I will explain a simple way to add a custom like button to your publishing pages by using SharePoint’s built in Javascript methods. I will also give pointers on how to add a rating button to your page.
(In the image above, I have changed the image for the Like Button to display a Thumbs up instead of a smiley.)
In a nutshell, the process goes like this. Create/modify the page layout/add a content editor used for the content pages of your site to add a little html. Then enable the liking settings on the library (mostly Pages Library) where the content/publishing pages are stored. Reference a small Javascript code in your masterpage/page layout and add some css to style your Like button. Finally, deploy the custom javascript file to SharePoint.
Now, let us understand the process in detail.
1. Create/modify the page layout or add :
Page Layout provides an excellent way to maintain a consistent and desirable look and feel for your content pages in the site. Most of the publishing sites use custom page layouts. If you do not use custom Page Layouts, don’t worry. You can still do this by adding a simple content editor webpart/script editor to your pages and adding the same code inside that. Add the following html code to your Page layout/content editor.
<div class="LikeSection"><span class="likecount"></span><a href="#" onclick="LikePage()" class="LikeButton"></a></div>
Explanation : In the above html code, the anchor tag will be our Like/Unlike button and the span will display the no of likes for the current page. I have added classes to all these elements and enclosed them in a div so that you can give your own look and feel to the like section :-).
2. Enable liking settings on the library –
Navigate to library settings -> Rating Settings. Select the option “Yes” for “Allow items in this list to be rated” and select “Likes” for “Which voting/rating experience you would like to enable for this list”.
Explanation : Once you enable liking, SharePoint will add two columns to the list named “LikedBy” and “LikesCount”. As the names suggest, “LikedBy” will store the user identities who liked the item and “LikesCount” will store the no of likes respectively. This step builds the SP liking infrastructure for you.
3. Create the javascript file –
Create a javascript file named Like.js and paste the following code into it.
function LikePage() { var like = false; var likeButtonText = $("a.LikeButton").text(); if (likeButtonText != "") { if (likeButtonText == "Like") like = true; var aContextObject = new SP.ClientContext(); EnsureScriptFunc('reputation.js', 'Microsoft.Office.Server.ReputationModel.Reputation', function () { Microsoft.Office.Server.ReputationModel. Reputation.setLike(aContextObject, _spPageContextInfo.pageListId.substring(1, 37), _spPageContextInfo.pageItemId, like); aContextObject.executeQueryAsync( function () { //alert(String(like)); GetLikeCount(); }, function (sender, args) { //alert('F0'); }); }); } } function GetLikeCount() { var context = new SP.ClientContext(_spPageContextInfo.webServerRelativeUrl); var list = context.get_web().get_lists().getById(_spPageContextInfo.pageListId); var item = list.getItemById(_spPageContextInfo.pageItemId); context.load(item, "LikedBy", "ID", "LikesCount"); context.executeQueryAsync(Function.createDelegate(this, function (success) { // Check if the user id of the current users is in the collection LikedBy. var likeDisplay = true; var $v_0 = item.get_item('LikedBy'); var itemc = item.get_item('LikesCount'); if (!SP.ScriptHelpers.isNullOrUndefined($v_0)) { for (var $v_1 = 0, $v_2 = $v_0.length; $v_1 < $v_2; $v_1++) { var $v_3 = $v_0[$v_1]; if ($v_3.$1E_1 === _spPageContextInfo.userId) { //cb(true, item.get_item('LikesCount')); //alert("Liked by me"); likeDisplay = false; } } } ChangeLikeText(likeDisplay, itemc); }), Function.createDelegate(this, function (sender, args) { //alert('F1'); })); } function ChangeLikeText(like, count) { if (like) { $("a.LikeButton").text('Like'); } else { $("a.LikeButton").text('Unlike'); } var htmlstring = "<img alt="" src="/_layouts/15/images/LikeFull.11x11x32.png" />" + " " + String(count); if (count > 0) $(".likecount").html(htmlstring) else $(".likecount").html(""); } $(document).ready(function () { GetLikeCount(); $("a.LikeButton").click(function () { LikePage(); }); });
Explanation : In our Like.js JS file, we have 4 methods –
LikePage() – This function calls the out of the box SharePoint method named “Microsoft.Office.Server.ReputationModel.Reputation.setLike” present in the “Reputation.js” javascript file (present inside Layouts folder). To see the function clearly, open the readable version of the file called “Reputation.debug.js”. This setLike function takes the parameters – context, listId, itemId and like(bool). We get the current context very easily using the SP.ClientContext(). Then we use the properties of the magical variable “_spPageContextInfo” to get the list ID and item ID respectively. Finally we pass the 4th parameter which is boolean to like or unlike a page.
GetLikeCount() – This function queries the list to get the “LikesCount” for the current list item (in our case, current page). It also checks the field “LikedBy” to see if the current user’s id is present in it to determine whether the current user has liked the page or not. Then it passes these values to the ChangeLikeText function.
ChangeLikeText() – This function displays the total likes for the current page and changes the text of the anchor tag to Like or Unlike based on whether the current user has liked the page or not.
Finally, in the document ready function, we display the like count and add the click handler to the like button.
4. Reference JS and css files –
If you have many content pages, just reference the SharePoint JS files in your masterpage as shown below. You can also reference them in your Page Layout if you wish to.
<SharePoint:ScriptLink ID="ScriptLink6" name="SP.js" runat="server" ondemand="false" localizable="false" loadafterui="true" /> <SharePoint:ScriptLink ID="ScriptLink8" name="SP.Core.js" runat="server" ondemand="false" localizable="false" loadafterui="true" /> <SharePoint:ScriptLink ID="ScriptLink9" name="Reputation.js" runat="server" ondemand="false" localizable="false" loadafterui="true" /> <script src="/_layouts/15/InSite/Scripts/Like.js" type="text/javascript"></script>
As you can see, the last one is a link to our like.js file which will do all the magic for us.
Add the following css to your global css file or inside PageLayouts
.likecount { margin-right:5px; } .LikeSection { margin-bottom:15px; }
5. Deploy Like.js –
You can deploy this into any custom folder inside layouts folder or into a library. Accordingly, change the path to like.js file in our step 4.
Similarly, if you want to add rating control to your page, leverage the function “Microsoft.Office.Server.ReputationModel.Reputation.SetRating” instead of “SetLike” in out custom javascript file and change the logic slighly to display the rating stars instead of Like controls.
22 Comments
August 3, 2013 2:53 pm
Simply want to say your article is as amazing. The clarity in your post is simply spectacular and i can assume you are an expert on this subject. Well with your permission let me to grab your RSS feed to keep updated with forthcoming post. Thanks a million and please keep up the enjoyable work.
October 11, 2013 6:48 am
Thank you.
October 15, 2013 9:29 am
Really great article. Thanks for spreading the knowledge.
I’m trying to achieve the following functionality using your example above. Unfortunately I don’t have a lot of success so far so maybe you can help a bit?
– Send notification when someone clicks the “like” button. The notification should read the “LikedBy” field and send over the name of the person who liked the list item
– Limit the number of likes for an item. If likes number >3 then hide the “like” button.
Do you think this is possible through JS or workflows?
Thanks,
Emily
October 16, 2013 2:24 pm
Thanks Emillia. Glad to hear that you liked it. Please find my response to your questions below –
– To show a notification on the page on click of Like button, you can simply call the built in javascript method called “SP.UI.Notify.addNotification” with a suitable message. More details on SP notification – http://melick-rajee.blogspot.com/2013/07/sharepoint-status-notifications-and-pop.html. For notification like email , there is no clean way to do it. One way can be to insert items into a list on click of like button using javascript CSOM or REST API and have a workflow/event reciever on the list which sends an email on item addition. To find the current username who clicked the like button, use a REST call like this on click of “Like” –
function GetCurrentUser() {
var userid = _spPageContextInfo.userId;
var requestUri = _spPageContextInfo.webAbsoluteUrl + “/_api/web/getuserbyid(” + userid + “)”;
var requestHeaders = { “accept” : “application/json;odata=verbose” };
$.ajax({
url : requestUri,
contentType : “application/json;odata=verbose”,
headers : requestHeaders,
success : onSuccess,
error : onError
});
}
function onSuccess(data, request){
var loginName = data.d.LoginName.split(‘|’)[1];
alert(loginName);
}
function onError(error) {
alert(error);
}
– Limiting the no. of likes is easy. Check the value returned from GetLikeCount(). If it is > 3, simply hide the like section.
Feel free to ask more questions.
October 28, 2013 1:15 pm
Great article! Exactly what I need, but I can’t get it to work.
In step 4, I think you are supposed to show how you reference the JS files in your masterpage? I can’t see it (tried in several browsers).
I’ve tried do a reference to Reputation.js in my masterpage like this:
And for my Like.js like this:
The Like.js is “loaded”, and I’ll get an error in console saying:
“Uncaught TypeError: undefined is not a function” on row 29.
var context = new SP.ClientContext(_spPageContextInfo.webServerRelativeUrl);
I’ll appreciate your help!
Thanks,
Linus
October 28, 2013 2:14 pm
Hi Linus,
Thank you. Glad to hear that you liked it. I have updated the missing reference in step 4. Let me know if you still face any issues.
October 28, 2013 2:50 pm
Thank you!
Now it don’t complain about that anymore. But it still don’t seem to work.
If I debug the Like.js, it steps over row 35-54. Does it mean that executeQueryAsync is failing? What could I do then?
Since it don’t run, it never changes to text to Like/Unlike either, so I have nothing to push on.
Thanks
October 29, 2013 10:13 am
Found the problem. I use a custom Masterpage, when I changed back to seattle.master this script worked properly.
Now it’s just up to me
Thank you very much!
November 1, 2013 6:27 am
Hi, Can we add comments in a list item along with the rating? I know this feature is available in Social networking blogs but can we do in a custom list items as well?
November 2, 2013 8:09 pm
Hi Saurabh,
Commenting along with rating is not available out of the box. However, if you are building a rating control for a page layout (similar to like button that I described on my post), you can hook up some Jquery & REST calls to display a popup to capture comments and update it to a custom column (maybe name it as Comments).
However, if you are trying to use the OOTB rating control in AllItems.aspx view of a list/library, you may have to hookup additional JS function call the averageratingElemeent control to display a popup and store its values to a custom column.
November 20, 2013 12:13 pm
Is it possible to like a page from a news archive that lists title, preamble, image and date of a page? How can I get the _spPageContextInfo from a list item? For example:
Page layout:
Like.js:
$(“.LikeButtonImage”).click(function () {
var spPageContent = $(this).data(“_spPageContextInfo”);
LikePage();
}
Regards
Linus
November 23, 2013 12:10 am
Hi Linus,
Like functionality leverages the liking and rating infrastructure provided by SharePoint out of the box. So, if a list has like setting enabled, the AllItems list view automatically adds a column for liking a list item /view the no of likes. It will also enable you to add a custom like button on the page which can leverage the same liking infrastructure using REST calls.
_spPageContextInfo is a simple javascript object available in every SP2013 page and contains a bunch of useful properties. See the properties here – http://blah.winsmarts.com/2013-2-_sppagecontextinfo_is_your_new_best_friend.aspx
Feel free to ask more questions.
Narahari
December 17, 2013 3:02 pm
Am I missing something? Why don’t you just add an AverageRatingFieldControl and a SocialCommentControl to your page layouts?
http://weblogs.asp.net/bsimser/archive/2011/09/18/adding-ratings-and-comments-to-sharepoint-publishing-pages.aspx
December 21, 2013 9:55 pm
Hi Leon,
Rating control is for rating and SocialCommentControl is for posting comments. But this post explains about adding the Like functionality which is introduced in 2013 and there is no ‘Like’ control out of the box.
December 26, 2013 7:58 am
Thank you narahari.
i used this code as it is.but i am facing one problem.
problem is while i am clicking like or unlike my database is updating two times.
can you please provide me if you have any solution.
thanks
Saran
January 17, 2014 5:24 pm
Hi Saran, Do you face the same issue when you like the page from the All Items view of document library too?
January 16, 2014 12:59 am
Hey Narahari, have you seen anything that takes an item URL or other parameter rather than liking the current page? If not, I’m working on that now and I’ll post a follow up once I get it working.
January 17, 2014 5:23 pm
Hi Anthony, I haven’t seen anything that accepts URL or other parameters. Would be glad to see a post from you on that.
February 4, 2014 1:22 pm
Thank you very much, this article helped me a lot!
February 26, 2014 6:57 pm
and what about REST, is it possible ? Updates on like via REST service?
March 5, 2014 8:23 am
Hi Narahari,
Great article
But… 😉
I use your javascript “as is”, but facing there are 2 entries in my personal Newsfeed when I like from a custom page
But when I like from the Pages library there is only 1 entry.
Any ideas?
Kind regards
Mickey
March 24, 2014 8:58 am
var context;
var factory;
var appContextSite;
var listName = “MyList”;
context = new SP.ClientContext(appwebURL);
factory = new SP.ProxyWebRequestExecutorFactory(appwebURL);
context.set_webRequestExecutorFactory(factory);
appContextSite = new SP.AppContextSite(context, hostwebURL);
var web = appContextSite.get_web();
var list = web.get_lists().getByTitle(listName);
context.load(list);
context.executeQueryAsync(
Function.createDelegate(this, function () {
EnsureScriptFunc(‘reputation.js’, ‘Microsoft.Office.Server.ReputationModel.Reputation’, function () {
var listID = list.get_id();
Microsoft.Office.Server.ReputationModel.
Reputation.setLike(context,
listID.toString(),
item.id, like);
context.executeQueryAsync(SuccessHandler, FailureHandler);
});
}),
Function.createDelegate(this, function (sender, args) {
alert(“Did not determine a like. : ” + args.get_message());
}));.
From the FailureHandler I get the list is not found on the currently selected page, what causing that could you please help with this issue.
Thank you very much.