The OOTB discussion board in SharePoint 2013 has a ‘+ new discussion’ link at the top of the list as shown below.
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(); } }
This is exactly what I’m looking to do, thank you! Does the code go in a Script Editor web part?
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.
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
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.