Make PDP Read-only for certain users or groups

Requirement

There is a particular PDP (say, financial information) which should only be editable by PMO and rest (including PM) should see it in read-only mode.

 

Solution

There were some solutions available on other blogs (see alternative solutions section) but i wanted to have a simpler solution. Its relatively easy to disable the input fields using JavaScript. The interesting part was to do it for certain users (anyone other then PMO) only. I used SharePoint Web part Audience Targeting feature to execute the disabling script only for limited users. Here is the summary of the solution

 

1- On the PDP, add a content editor webpart, render a DIV element with special ID (i used “hiddendiv” as ID)

2- Set Audience of this webpart as a PMO (in my case PMO was a SharePoint Group, but you could use Active Directory group or even compile custom Audience). Using Audience property, “hiddendiv” will only render when someone from PMO will come to the PDP

3- Add another Content Editor Webpart on PDP, check if “hiddendiv” element is present on PDP. If so, don’t do any thing. Otherwise disable all input fields on PDP.

4- To protect fields from being changed in Project Professional, fields behaviour should be defined as “Behavior controlled by workflow”.

 

The solution has been tested in Project Server 2013 on premises but should also work in Project Online. Full Code for both Content Editor Web Parts is provided below

 

Script

 

CEWP 1:

<div id="hiddenDiv">&#160;</div>

 

CEWP 2:

<strong class="ms-rteForeColor-9" style="text-decoration: underline">Note</strong><span class="ms-rteForeColor-9">: Only PMO Administrators can edit the fields on this page</span><script>
function  hiddenDivPresent()
    {
        var hiddenDivID ="hiddenDiv";
        var hiddenDiv = document.getElementById(hiddenDivID);
        if (hiddenDiv != null)
            return true;
        return false;
    }
    function MakeReadOnly()
    {
        try {
            var allProjectFieldWebparts = document.getElementsByName("WPClass:ProjectFieldPart");
            for (var h = 0; h < allProjectFieldWebparts.length; h++)
            {
                var arrInput = allProjectFieldWebparts[h].getElementsByTagName('input');
                for (var i = 0; i < arrInput.length; i++)
                {
                    arrInput[i].disabled=true;
                }
                var arrbtn = allProjectFieldWebparts[h].getElementsByTagName('button');
                for (var j = 0; j < arrbtn.length; j++) {
                    arrbtn[j].disabled=true;
                }
                var arrtxtArea = document.getElementsByTagName('textarea');
                for (var k = 0; k < arrtxtArea.length; k++)
                {
                    if(arrtxtArea[k].title == 'Description')
                    {
                        arrtxtArea[k].disabled=true;
                    }
                    else
                    {
                        var divID=arrtxtArea[k].id+'_div';
                        var txtAreaDiv =document.getElementById(divID);
                        if(txtAreaDiv!=null)
                        {
                            txtAreaDiv.disabled=true;
                            txtAreaDiv.removeAttribute("contentEditable");
                        }
                    }
                }
            }
        }
catch(e){
alert('An error has occurred: '+e.message)
}
    }
    function runAfterEverythingElse(){
        SP.SOD.executeOrDelayUntilScriptLoaded(function () {

            var InEditMode = SP.Ribbon.PageState.Handlers.isInEditMode();
            if (!InEditMode)
            {
                if (hiddenDivPresent())
                {
                    // User belongs to Audience so Do Nothing
                }
                else
                {
                    // Hide All Fields in this page
                    MakeReadOnly();
                }
            }
        }, "sp.ribbon.js");

    }
_spBodyOnLoadFunctionNames.push("runAfterEverythingElse");</script>

 

 

Alternative Solutions

1- InfoPath based solution by Andrew Lavinsky

2- Custom Webpart based solution by epmxperts

2 comments:

Hammad Arif said...

Thanks Martin :)

Khurram Jamshed said...

JavaScript is the name of a game when you have to play around with PDPs ...

Post a Comment