blog.atwork.at

news and know-how about microsoft, technology, cloud and more.

Project Online / Project Server: Project Detail Pages - Enhancements (Part 3) - Show/Hide a field based on the value of an internal field using REST

This is the third part of articles discussing Project Detail Page enhancements:

  1. Show/hide a field depending on the value of an internal field on the same page
  2. Show/hide a field depending on the value of an Enterprise Custom field on the same page
  3. Show/Hide a field based on the value of an internal field using REST
  4. Show/Hide a field based on the value of an Enterprise Custom Field without Lookup Table using REST
  5. Remove Time from Enterprise Custom Fields on Project Detail Pages
  6. Remove Prefix from Enterprise Custom Fields on Project Detail Pages
  7. Hide Impact Ratings on Project Detail Page "Strategic Impact"
  8. Disable "Project Owner" Button on Project Detail Page

For a description for preparation of a Project Detail Page for JavaScript, see General Preparation.

This time, we will show or hide a field depending on the value of an internal field not available on this page. To get the value, we will use REST API. There are two restrictions:

  1. This code will not work with Project Server 2013 (and below). Project Server 2013 does not provide internal field information using REST. You can make it work with OData, but I avoid this since it requires more permissions for Team Members than usually provided.
  2. This code will not work in delegate session in on premise environments. Within a delegate session, REST is not available per 2019-01-28 in Project Server 2013, 2016 and 2019. To test, open a delegate session and enter "http(s)://<SERVER>/PWA/_api/ProjectServer/Projects" as address in browser. You will get the following result:
    image


In this sample, Enterprise Custom Field CostCenter will be hidden, if internal field Cost = 0. To use different fields change FieldToCheck and FieldToHide accordingly. Using the appropriate line for "var RESTAppendix", you can decide if you want to retrieve the value of the saved or the published version of the project.

<!-- Change path for jquery-2.1.1.min.js --> 
<script type = "text/javascript" src = "/sites/pwa/Scripts/jquery-2.1.1.min.js"></script>
<script type = "text/javascript">
    // This script will hide a Enterprise Custom Field on a Project Detail Page if an internal filed not displayed on the page is empty or 0

    // Change FieldToCheck to internal field name to be checked. Replace "Cost" by field to be used. Using an object for future purposes
    var FieldToCheck = {
        Cost: undefined
    };

// Change To Enterprise Custom Field name to be hidden
var FieldToHide = "CostCenter";

// Use appropriate variable RESTAppendix
var RESTAppendix = "/Draft/ProjectSummaryTask" //Draft data as available after save only
    //var RESTAppendix = "/ProjectSummaryTask" //Without "Draft", last published information will be evaluated

//A global variable is necessary
var Delegate; // Online necessary in on premise environments
//var FieldToCheckValue={};

//Call main function
$(document).ready(ExecuteOrDelayUntilScriptLoaded(MainFunction, "sp.js"));

//MainFunction 
function MainFunction() {

    //Use this part only with On Premise - begin  
    if (WPSC.WebPartPage.WebURL.indexOf("sharepoint.com") == 0) {
        CheckDelegate();
        if (Delegate == true) {
            console.log("Delegate session active - REST not working on premise");
            return;
        }
    }
    //Use this part only with On Premise - end

    //function to retrieve Project information
    GetProjectProperties(PDP_projUid, FieldToCheck, RESTAppendix);
    //GetProjectProperties is written to return more than one information. To call function FieldToCheck we need only one field with ist value
    var FieldToCheckValue = {};
    FieldToCheckValue.name = Object.keys(FieldToCheck)[0];
    FieldToCheckValue.value = FieldToCheck[Object.keys(FieldToCheck)[0]];
    CheckFieldValue(FieldToCheckValue);
}


function CheckDelegate() {
    var data = $.ajax({
        // we need the result, therefore "async: false"
        async: false,
        url: _spPageContextInfo.siteAbsoluteUrl + "/_api/Projectserver()?$SELECT=IsDelegate",
        type: "GET",
        dataType: "json",
        headers: {
            Accept: "application/json;odata=verbose"
        }
    });

    data.done(function(data) {
        if (data.d.results == undefined) {
            Delegate = data.d.IsDelegate;
        }
    });
}


//Get ProjectProperties: FieldsToLock,
function GetProjectProperties(ProjectUID, InternalFields, REST) {

    var data = $.ajax({
        async: false,
        url: _spPageContextInfo.siteAbsoluteUrl + "/_api/ProjectServer/Projects(guid'" + ProjectUID + "')" + REST,
        type: "GET",
        dataType: "json",
        headers: {
            Accept: "application/json;odata=verbose"
        }
    });
    data.done(function(data) {
        if (data.d.results == undefined) {
            //This script is written to be re-used for future purposes. To get a specific value directly, the following lines can be replaced by e.g.
            //  InternalFields["Cost"] = data.d.Cost  //remove "//" at begin of this line to enable simple approach
            //  /*                                    //remove "//" at begin of this line to enable simple approach
            ResultData = data.d;
            for (var pfProperty in InternalFields) {
                for (var key in ResultData) {
                    if (key == pfProperty) {
                        console.log('property: ' + key + 'value: ' + ResultData[key]);
                        InternalFields[pfProperty] = ResultData[key];
                    }
                }
            }
            //  */                                    //remove "//" at begin of this line to enable simple approach
        }
    });
}


//This function will evaluate the field value to define visibility requirement
function CheckFieldValue(field) {
    if (field != null && field.value != "" && field.value != 0) {
        setFieldVisibility(FieldToHide, true);
    } else {
        setFieldVisibility(FieldToHide, false);
    }
}

//Show/Hide a field
function setFieldVisibility(field, bool) {
    $(".ms-accentText").each(function(index) {
        if ($(this).text() == field) {
            $(this).closest('tr').toggle(bool);
        }
    });
} 
</script>

Copy above code into a text editor, modify at least the marked sections, save with file extension "js" or "html", and upload to your script library.

Pingbacks and trackbacks (1)+

Loading