• images
  • 8:33 am
  • images
  • 22 Comments.

Using Like and Rating functionality in SharePoint 2013 Pages (and SP2013 Custom like button)

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 :-).

Library Settings

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.

Like Button

(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 &lt; $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 &gt; 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

metin2

August 3, 2013 2:53 pm Reply

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.

admin

October 11, 2013 6:48 am Reply

Thank you.

Emillia

October 15, 2013 9:29 am Reply

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

    admin

    October 16, 2013 2:24 pm Reply

    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.

Linus

October 28, 2013 1:15 pm Reply

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

    admin

    October 28, 2013 2:14 pm Reply

    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.

      Linus

      October 28, 2013 2:50 pm Reply

      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

        Linus

        October 29, 2013 10:13 am Reply

        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!

Saurabh

November 1, 2013 6:27 am Reply

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?

    admin

    November 2, 2013 8:09 pm Reply

    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.

Linus

November 20, 2013 12:13 pm Reply

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

    admin

    November 23, 2013 12:10 am Reply

    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

Leon Zandman (@leonzandman)

December 17, 2013 3:02 pm Reply

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

    admin

    December 21, 2013 9:55 pm Reply

    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.

saran

December 26, 2013 7:58 am Reply

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

    admin

    January 17, 2014 5:24 pm Reply

    Hi Saran, Do you face the same issue when you like the page from the All Items view of document library too?

Anthony Rubalcaba

January 16, 2014 12:59 am Reply

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.

    admin

    January 17, 2014 5:23 pm Reply

    Hi Anthony, I haven’t seen anything that accepts URL or other parameters. Would be glad to see a post from you on that.

Willian Fakri Bratkauskas

February 4, 2014 1:22 pm Reply

Thank you very much, this article helped me a lot!

mauricio

February 26, 2014 6:57 pm Reply

and what about REST, is it possible ? Updates on like via REST service?

Mickey

March 5, 2014 8:23 am Reply

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

Tshepo

March 24, 2014 8:58 am Reply

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.

Leave a Comment