This post is just another example about JSLink you can find on web. This post is about show follow/Unfollow Document link in List-view. The solution is simple. Add a text column on the List (Say FollowLink) and hide this column in forms. Include the column in Listview. Link the following JSLink code in Listview webpart.
var SPOFieldCustomizations = window.SPOFieldCustomizations || {}; SPOFieldCustomizations.CustomizeFollowLinkFieldRendering = function () { var fieldJsLinkOverride = {}; fieldJsLinkOverride.Templates = {}; fieldJsLinkOverride.OnPostRender = postRenderHandler; fieldJsLinkOverride.Templates.Fields = { // Make sure the Priority field view gets hooked up to the GetPriorityFieldIcon method defined below // we have to update the column name here 'FollowLink': { 'View': SPOFieldCustomizations.GetFollowLinkFieldMarkup } }; // Register the rendering template SPClientTemplates.TemplateManager.RegisterTemplateOverrides(fieldJsLinkOverride); }; SPOFieldCustomizations.GetFollowLinkFieldMarkup = function (ctx) { var followLinkMarkup = ""; if (ctx.CurrentItem.FSObjType === "0") { followLinkMarkup = '<a class="ms-profile-followLink ms-heroCommandLink" href="javascript:;">' + '<span class="ms-profile-followHeroImageParent">' + '<img data-toggle="tooltip" data-placement="right" title="" id="Img' + ctx.CurrentItem.ID + '" src="/_layouts/15/images/gears_anv4.gif?rev=35" class="ms-profile-followHeroImage" ></img>' + '</span>' + '</a>'; SPOFieldCustomizations.isFollowed('/' + ctx.CurrentItem.FileRef, 'Img' + ctx.CurrentItem.ID); } return followLinkMarkup; }; SPOFieldCustomizations.isFollowed = function (documentUrl, imgid) { window.Utilities.Social.REST.LoadIsFollowed(documentUrl, _spPageContextInfo.webAbsoluteUrl, 1, function (responseData) { jsonObject = JSON.parse(responseData.body); if (jsonObject.d.IsFollowed === true) { $('#' + imgid).attr("title", "Click to Unfollow").attr('data-followed', '1') .attr('src', '/_layouts/15/images/socialcommon.png?rev=33') .addClass("unFollow") } else { $('#' + imgid).attr("title", "Click to Follow").attr('data-followed', '0') .attr('src', '/_layouts/15/images/socialcommon.png?rev=33') .removeClass("unFollow"); } $('#' + imgid).click(function () { var FollowStatus = $(this).attr('data-followed'); var url = ''; if (FollowStatus === '1') url = _spPageContextInfo.webAbsoluteUrl + '/_api/social.following/stopfollowing'; else if (FollowStatus === '0') url = _spPageContextInfo.webAbsoluteUrl + '/_api/social.following/follow'; if (url !== '') { SPOFieldCustomizations.toggleFollow(url, documentUrl, imgid, FollowStatus); } }); }, function (s, a, errMsg) { $('#' + imgid).text(errMsg); }); }; SPOFieldCustomizations.toggleFollow = function (url, documentUrl, imgid, FollowStatus) { window.Utilities.Social.REST.ToggleFollow(url, documentUrl, _spPageContextInfo.webAbsoluteUrl, 1, function (responseData) { var jsonObject = JSON.parse(responseData.body); var isfollowed = jsonObject.d.Follow; var stoppedFollowing = jsonObject.d.StopFollowing; if (isfollowed !== undefined) { $('#' + imgid).attr('title', 'Click to Unfollow').attr('data-followed', '1') .addClass("unFollow"); } else { $('#' + imgid).attr('title', 'Click to Follow').attr('data-followed', '0') .removeClass("unFollow"); } }, function (s, a, errMsg) { $('#' + imgid).text(errMsg); }); } function postRenderHandler(ctx) { // code to execute after view render } // Call the function. SPOFieldCustomizations.CustomizeFollowLinkFieldRendering();
There are few utility function calls inside this JSLink code to follow/unfollow documents. The code looks like
function LoadAndExecuteSodFunction(scriptKey, fn) { if (!ExecuteOrDelayUntilScriptLoaded(fn, scriptKey)) { LoadSodByKey(NormalizeSodKey(scriptKey)); } } RegisterSod('/_layouts/15/sp.requestexecutor.js'); window.Utilities = window.Utilities || {}; window.Utilities.Social = window.Utilities.Social || {}; window.Utilities.Social.REST = window.Utilities.Social.REST || function () { var LoadIsFollowed = function (documentOrSiteUrl, siteurl, actortype, successcallback, failcallback) { var requestinfo = { url: siteurl + '/_api/social.following/isfollowed', method: "POST", body: JSON.stringify({ "actor": { "__metadata": { "type": "SP.Social.SocialActorInfo" }, "ActorType": actortype, "ContentUri": documentOrSiteUrl, "Id": null } }), headers: { "accept": "application/json;odata=verbose", "content-type": "application/json;odata=verbose" }, success: function (responseData) { successcallback(responseData); }, error: function (s, a, errMsg) { failcallback(s, a, errMsg); } }; LoadAndExecuteSodFunction('sp.requestexecutor.js', function () { var executor = new SP.RequestExecutor(siteurl); executor.executeAsync(requestinfo); }); }; var ToggleFollow = function (url, documentOrSiteUrl, siteurl, actortype, successcallback, failcallback) { var requestinfo = { url: url, method: "POST", body: JSON.stringify({ "actor": { "__metadata": { "type": "SP.Social.SocialActorInfo" }, "ActorType": actortype, "ContentUri": documentOrSiteUrl, "Id": null } }), headers: { "accept": "application/json;odata=verbose", "content-type": "application/json;odata=verbose" }, success: function (responseData) { successcallback(responseData); }, error: function (s, a, errMsg) { failcallback(s, a, errMsg); } }; LoadAndExecuteSodFunction('sp.requestexecutor.js', function () { var executor = new SP.RequestExecutor(siteurl); executor.executeAsync(requestinfo); }); }; return { LoadIsFollowed: LoadIsFollowed, ToggleFollow: ToggleFollow}; }();