Often in SharePoint projects we hear the requirement that the form of a list or library should be modified, depending on the values of the current item. This could be achieved with some JavaScript, but what, when this should also happen in subwebs. Well, this could also be done with JavaScript and when this customization is added in a proper way, it could be very easy. First, the following only works with the classic UI of SharePoint.

For this example, we use a very simple SharePoint list that was created using PowerShell, because only in this case we have full control over the internal name of a field and its Id.

The requirement will be that the field “Status Comment” should only be shown, when the value of the “Status Field” is finished. In all other cases, this field should be hidden for the user. We keep this example simple, but in real world scenarios it could be very complex. Our solution must modify all three forms of the list, the one for new item, the one for editing items and the one to display an item. An example for some JavaScript to modify the edit form could look like this:


function pbPageModificationFunc() {
    var statusValue = $("#StatusField_8bd36554-9b41-49be-9c96-c2e25743c53a_\\$DropDownChoice option:selected").text();

    if (statusValue != "finished") {
        $("#StatusComment").parent().parent().hide();
    }

    setOnChangeForStatusField();
}

function setOnChangeForStatusField() {
    $("#StatusField_8bd36554-9b41-49be-9c96-c2e25743c53a_\\$DropDownChoice").on("change", function () { showStatusCommentField(); });
}

function showStatusCommentField() {
    var statusValue = $("#StatusField_8bd36554-9b41-49be-9c96-c2e25743c53a_\\$DropDownChoice option:selected").text();

    if (statusValue != "finished") {
        $("#StatusComment").parent().parent().hide();
    } else {
        $("#StatusComment").parent().parent().show();
    }
}

The main problem in the solution is, how to add this script to the form. This could be done using a Content Editor Webpart, but in this case we must manually add the webpart, when a similar list is added in any subweb. To automate this task, we use another JavaScript that is used as a loader.


// create a mapping for the form and the modifier file
var mapping =
{
    values:
    [
    	{ "/lists/statuslist/newform.aspx": "/scripts/StatusListNewForm.js" },
    	{ "/lists/statuslist/dispform.aspx": "/scripts/StatusListDispForm.js" },
        { "/lists/statuslist/editform.aspx": "/scripts/StatusListEditForm.js" }
    ]
};

$(document).ready(function () {
    var scriptFile = "";

    for (var i = 0; i < mapping.values.length; i++) {
        var obj = mapping.values[i];

        for (var key in obj) {
            var value = obj[key].toString();

            if (window.location.href.toLowerCase().indexOf(key) != -1) {
                scriptFile = _spPageContextInfo.siteAbsoluteUrl + value;

                break;
            }
        }
    }

    SP.SOD.registerSod("formModifier.js", scriptFile);

    SP.SOD.executeFunc('formModifier.js', null, function () {
        pbPageModificationFunc();
    });
});

This script has a mapping table that contains a fragment of the url for the page and the JavaScript file that should be added, when the user opens the page in the browser. This loader script is added by a JavaScript link to the whole site collection, so it runs for each page that a user opens. When the additional script for the current page was loaded, a function (pbPageModificationFunc) is called to modify the current page.


# the script is assuming that a connection to a SharePoint Online site is already established

Write-Host -ForegroundColor Magenta "Upload scripts"

Write-Host "Create scripts library"

$l = New-PnPList -Title "Scripts" -Template DocumentLibrary -Url "scripts" -OnQuickLaunch:$false

Write-Host "Disable modern ui for scripts library"

$list = Get-PnPList -Identity "Scripts" -Includes "ListExperienceOptions"
(Get-PnPContext).Load($list)
Invoke-PnPQuery

$list.ListExperienceOptions = "ClassicExperience"
$list.Update()
Invoke-PnPQuery

Write-Host "Upload the script files"

Write-Host "- FormModifierLoader.js"

$f = Add-PnPFile -Path .\Scripts\FormModifierLoader.js -Folder "scripts"

Write-Host "- StatusListNewForm.js"

$f = Add-PnPFile -Path .\Scripts\StatusListNewForm.js -Folder "scripts"

Write-Host "- StatusListDispForm.js"

$f = Add-PnPFile -Path .\Scripts\StatusListDispForm.js -Folder "scripts"

Write-Host "- StatusListEditForm.js"

$f = Add-PnPFile -Path .\Scripts\StatusListEditForm.js -Folder "scripts"

Write-Host "Register script files"

Write-Host "- jQuery"

$jsLink = Get-PnPJavaScriptLink -Name "jQuery" -Scope Site

if ($jsLink -ne $null)
{
	Remove-PnPJavaScriptLink -Identity "jQuery" -Scope Site -Force
}

Add-PnPJavaScriptLink -Name "jQuery" -Url "https://code.jquery.com/jquery.min.js" -Sequence 10 -Scope Site

Write-Host "- FormModifierLoader.js"

$site = Get-PnPSite
$fileUrl = $site.Url + "/Scripts/FormModifierLoader.js"

$jsLink = Get-PnPJavaScriptLink -Name "FormModifierLoader" -Scope Site

if ($jsLink -ne $null)
{
	Remove-PnPJavaScriptLink -Identity "FormModifierLoader" -Scope Site -Force
}

Write-Host $fileUrl

Add-PnPJavaScriptLink -Name "FormModifierLoader" -Url $fileUrl -Sequence 15 -Scope Site

Write-Host "Done."

To organize the files, we store the JavaScript files in a separate library called “Scripts”. And that’s all. After all scripts are available in the site collection and the loader script is registered, the desired functionality is available for the user.

The whole demo project is available in a GitHub project. To deploy the solution, a SharePoint team site with the classic UI must be created and the PowerShell PnP extensions must be available.

 

 

Advertisements