Hiding New discussion link on SharePoint 2013 discussion board for read-only users

The OOTB discussion board in SharePoint 2013 has a ‘+ new discussion’ link at the top of the list as shown below.

1 New Discussion

This link however is shown even for read-only users. When a read-only user clicks this link, they get the error message “Sorry, this site hasn’t been shared with you.”. This user experience is not ideal. It doesn’t happen on other list types, and may be a MS bug. I tested this on June 2014 CU and it is still an issue.

So, to fix this issue we can use JSLink to invoke a custom JavaScript when this view loads. Our JavaScript would use JSOM to check the permissions of the user, and then use JQuery to hide the link if required.

Below is the code for our JavaScript. Review the in-code comment.

//The function that actually does the work
var BNH = BNH || {};
BNH.DiscussionListSubjectView = (function () {
	return {
		removeNewDiscussionLinkForReadOnlyUsers: function (ctx) {
			/** The approach we are taking is actually to hide the link first, then use JSOM to check the user's permissions,
			and then unhide it if they have permissions. This is because it takes 0.5-1 second to check the user's
			permissions. If we do thing the opposite order, i.e. check permission first then hide, then the user might
			see the link when the page loads, and then see it disappears, which is not a nice user experience.
			*/
			var newDiscussionLinkSelector = "div.ms-comm-forumContainer div.ms-comm-heroLinkContainer";

			//Ensure that JQuery is loaded on the page, e.g. via the master page.
			$(newDiscussionLinkSelector).hide();

			var list;
			SP.SOD.executeOrDelayUntilScriptLoaded(showNewDiscussionLinkForCreateUsers, 'sp.js');

			function showNewDiscussionLinkForCreateUsers() {
				var clientContext = new SP.ClientContext.get_current();

				list = clientContext.get_web().get_lists().getByTitle(ctx.ListTitle);
				clientContext.load(list, 'EffectiveBasePermissions');
				clientContext.executeQueryAsync(onSuccess, onFailure);
			}

			function onSuccess() {
				var userPermissions = list.get_effectiveBasePermissions();
				if (userPermissions.has(SP.PermissionKind.addListItems)) {
					$(newDiscussionLinkSelector).show();
				}
			}

			function onFailure() {
				alert('We are sorry but something has gone wrong while loading this view. Please contact your system administrator.');
			}
		}
	};
})();

//This function registers our JS with the view rendering.
(function () {
	var templateOverrideInfo = {};
	templateOverrideInfo.Templates = {};

	//This registers our JS to run after the view has been rendered. I ran into some issues creating the ClientContext
	//in JSOM when the JS was registered on OnPreRender.
	templateOverrideInfo.Templates.OnPostRender = BNH.DiscussionListSubjectView.removeNewDiscussionLinkForReadOnlyUsers;

	//Details of the OOTB Subject view that we want to target.
	templateOverrideInfo.BaseViewID = 3;
	templateOverrideInfo.ListTemplateType = 108;

	SPClientTemplates.TemplateManager.RegisterTemplateOverrides(templateOverrideInfo);
})();

And below is the code to update the Subject view with our JSLink. One thing to note is that the OOTB Subject view already has a value in its JSLink property. Therefore, we will have to append the location of our custom script to this property and use the separator ‘|’ to ensure that both scripts will be loaded.

using (var site = new SPSite("http://myServer"))
			{
				using (var web = site.OpenWeb())
				{
					var list = web.Lists["Discussions"];
					var view = list.Views["Subject"];
					view.JSLink = view.JSLink + "|~sitecollection/location_to_our_custom_script.js";
					view.Update();
				}
			}
Advertisements

About Bernado

Based in Australia, I am a freelance SharePoint and Dynamics CRM developer. I love developing innovative solutions that address business and everyday problems. Feel free to contact me if you think I can help you with your SharePoint or CRM implementation.
This entry was posted in JSLink, SharePoint 2013. Bookmark the permalink.

4 Responses to Hiding New discussion link on SharePoint 2013 discussion board for read-only users

  1. Elle says:

    This is exactly what I’m looking to do, thank you! Does the code go in a Script Editor web part?

    • Bernado says:

      Hi Elle,

      This approach uses the JSLink approach, so no the code doesn’t go into a Script Editor web part. The JavaScript goes into a JS file, which you upload to a location within the site. You then use the C# code to update the Subject view of the Discussion list to reference the JS file.

      I haven’t tried the Script Editor approach, but that may work too. The JavaScript code will need to be adapted slightly though.

      Hope that helps.

  2. rohitnsk says:

    Hi,

    I have discussionboard and want to show only 5 recent items on recent selection.I am trying to ms-pivotControl-surfacedOpt-selected class but it gives empty in postrender method.

    Please help

  3. Rao says:

    Send JSLink for Subject View is causing issues.. When I debug the page I am getting “Syntax error” because Java Script file is not allowing me to use using…. Please suggest me.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s