1

I am trying to implement a solution in SharePoint Online by customizing the NewForm.aspx page of a out of the box Calendar List using JavaScript with the following requirements:

  1. When page loads, a people picker field gets automatically populated with the current logged in user (and automatically resolved)
  2. If a the user changes the value of the people picker, I want to be able to detect the value change event so that I can apply some custom logic

For the first requirement, I was able to populate the people picker field but not automatically resolve it. For the second requirement, I was not able to detect the change on the poeple picker's value.

In the end you can find the code I am using and it contains several approaches on second requirement that I was still not able to put any of them to work.

The problem seems to be accessing the people picker object itself using the following code:

var peoplePickerDiv = jQuery("div[title='People Picker']");
var peoplePickerDivId = peoplePickerDiv.attr('id');
var peoplePickerObject = SPClientPeoplePicker.SPClientPeoplePickerDict[peoplePickerDivId];

In runtime, the peoplePickerObject is always null.

In the research I made on the Internet, any solution to address both requirements used the above code, i.e., getting a SPClientPeoplePicker object by accessing SPClientPeoplePickerDict supplying the people picker's Id. I confirmed that the id I am supplying is correct.

NOTE: I was able to successfully use the same approach against on-prem SharePoint 2013 but not with SharePoint Online. Not sure if HTML of the people picker changed or there is a different behavior of the JavaScript API to get SPClientPeoplePicker objects in SharePoint Online in comparison with on-prem SharePoint 2013.

Did someone found the same problem and was able to solve it?

Code I am using:

<script type="text/javascript" src="/_layouts/15/clientforms.js"></script>
<script type="text/javascript" src="/_layouts/15/clientpeoplepicker.js"></script>
<script type="text/javascript" src="/_layouts/15/autofill.js"></script>
<script type="text/javascript">

var loginName;

jQuery(document).ready(function () {
//alert("page loaded");
SetPeoplePickerWithCurrentUser();
SetCurrentUserAvailableDays();

jQuery(".ms-inputuserfield").bind('input propertychange', function() { 
     alert("Onchange event" ); 
})

ExecuteOrDelayUntilScriptLoaded(function () {
        setTimeout(function () {
            attachPeoplePickerChange();
        }, 2000);
    }, 'clientpeoplepicker.js');

/*jQuery(".ms-inputuserfield textarea").change(function() {
 alert( "Handler for .change() called." );
});

jQuery(".ms-input").change(function() {
 alert( "Handler for input .change() called." );
});*/

//attachPeoplePickerChange();
}); /*End document ready*/

function SetPeoplePickerWithCurrentUser()
{
var userid = _spPageContextInfo.userId;

//alert("userid: " + userid);

var endpointUrl = _spPageContextInfo.webAbsoluteUrl
+ "/_api/web/getuserbyid(" + userid + ")";
var requestHeaders = { "accept" : "application/json;odata=verbose" };

jQuery.ajax({
   type: "GET",
   url: endpointUrl,
   contentType: "application/json; charset=utf-8",
   dataType: "json"
})
.done(function (data) {
   loginName = data.Title;
   //alert("loginName: " + loginName);
   //SetUserFieldValue("Colaborador",loginName);
   window.setTimeout(SetPeoplePicker, 500);
   //SetUserFieldValue("People Picker",loginName);
})
.fail(function (jqXHR, textStatus, errorThrown) {
   alert("Error: " + errorThrown);
   console.log(jqXHR.status + " : " + textStatus + " - " + errorThrown);
})
.always(function () {
}); 
}

function SetPeoplePicker()
{
SetUserFieldValue("People Picker", loginName);
}

function SetUserFieldValue(fieldName, userName) {
var peoplePickerDiv = jQuery("div[title='" + fieldName + "']");
var peoplePickerDivId = peoplePickerDiv.attr('id');
//var peoplePickerEditorInput = jQuery("input[title='" + fieldName + "']");
//var peoplePickerEditorInput = jQuery("textarea[title='" + fieldName + "']");
var peoplePickerEditorInput = peoplePickerDiv.find("[title='" + fieldName + "']");
    //alert(userName);
//peoplePickerEditorInput.val(userName);

jQuery("div[title='People Picker']").text(userName);

    //Find the Specific People picker field "Colaborador" and set its value
    /*jQuery().SPServices.SPFindPeoplePicker({
  peoplePickerDisplayName: "Colaborador",
  valueToSet: user,
  checkNames: true
});*/

//var peoplePickerEditorObject = SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan;
//var peoplePickerEditorObject = SPClientPeoplePicker.SPClientPeoplePickerDict[peoplePickerDivId];
//var peoplePickerEditorObject = SPClientPeoplePicker.SPClientPeoplePickerDict["ctl00_ctl40_g_a543006a_dd2e_46e0_93c8_deeb4d72af44_ctl00_ctl05_ctl06_ctl00_ctl00_ctl04_ctl00_ctl00_UserField_downlevelTextBox"];
//peoplePickerEditorObject.AddUnresolvedUserFromEditor(true);
//_PeoplePickerEditor.attr("disabled", "disabled");
}

function SetCurrentUserAvailableDays()
{
var userid = _spPageContextInfo.userId;

//alert("userid: " + userid);

var endpointUrl = _spPageContextInfo.webAbsoluteUrl
+ "/_api/web/lists/getbytitle('Dias Férias 2016')/items?$filter=IniciaisId eq " + userid;
var requestHeaders = { "accept" : "application/json;odata=verbose" };

jQuery.ajax({
   type: "GET",
   url: endpointUrl,
   contentType: "application/json; charset=utf-8",
   dataType: "json"
})
.done(function (data) {
   var availableDays = data.value[0].Dias_x0020_dispon_x00ed_veis;
   jQuery("input[title='Dias úteis']").val(availableDays);
})
.fail(function (jqXHR, textStatus, errorThrown) {
   alert("Error: " + errorThrown);
   console.log(jqXHR.status + " : " + textStatus + " - " + errorThrown);
})
.always(function () {
}); 
}

function attachPeoplePickerChange() {
    //container needs to be an dom element containing the peoplepicker
    var peoplePickerDiv = jQuery("div[title='People Picker']");
    var peoplePickerDivId = peoplePickerDiv.attr('id');
    //helper function to ensure all elements are already created
    var addOnChanged = function (ctx) {
    //alert("addOnChanged");
        //is everything ready we need?
        if (SPClientPeoplePicker && SPClientPeoplePicker.SPClientPeoplePickerDict && SPClientPeoplePicker.SPClientPeoplePickerDict[peoplePickerDivId]) {
            //get picker instance (which has a lot of useful properties btw)
            alert("addOnChanged");
            var picker = SPClientPeoplePicker.SPClientPeoplePickerDict[peoplePickerDivId];
            //save old event (needs to stay in its context due to internal calls
            picker.oldChanged = picker.OnControlResolvedUserChanged;
            picker.OnControlResolvedUserChanged = function () {
                //do your code here
                console.log('OnControlResolvedUserChanged');
                //get current selected users
                console.log(picker.GetAllUserInfo());
                //let old event do its magic
                picker.oldChanged();
            };
        } else {
            //not everything was ready - wait a 10th of a sec
            setTimeout(function () { addOnChanged(ctx); }, 100);
        }
    };
    addOnChanged();
}

</script>

I compared html in SharePoint 2013 onprem with SharePoint Online and they in fact different:

OnPrem:

    <div title="Utilizador" class="sp-peoplepicker-topLevel sp-peoplepicker-topLevelFocus" id="aps_user_13fce4eb-973e-44b9-8cba-ff3d6cddd687_$ClientPeoplePicker" SPClientPeoplePicker="true"><input name="aps_user_13fce4eb-973e-44b9-8cba-ff3d6cddd687_$ClientPeoplePicker_HiddenInput" id="aps_user_13fce4eb-973e-44b9-8cba-ff3d6cddd687_$ClientPeoplePicker_HiddenInput" type="hidden" value='[{"Key":"i:0#.w|dev\\sp_admin","Description":"DEV\\sp_admin","DisplayText":"SharePoint Admin","EntityType":"User","ProviderDisplayName":"Active Directory","ProviderName":"AD","IsResolved":true,"EntityData":{"Title":"","MobilePhone":"","SIPAddress":"","Department":"","Email":""},"MultipleMatches":[],"Resolved":true}]'><div class="sp-peoplepicker-autoFillContainer" id="aps_user_13fce4eb-973e-44b9-8cba-ff3d6cddd687_$ClientPeoplePicker_AutoFillDiv" style="left: -1px; top: 26px;" InputElementId="aps_user_13fce4eb-973e-44b9-8cba-ff3d6cddd687_$ClientPeoplePicker_EditorInput"></div><span class="sp-peoplepicker-initialHelpText ms-helperText" id="aps_user_13fce4eb-973e-44b9-8cba-ff3d6cddd687_$ClientPeoplePicker_InitialHelpText" style="display: none;">Introduza um nome ou endereço de correio eletrónico...</span><img class="sp-peoplepicker-waitImg" id="aps_user_13fce4eb-973e-44b9-8cba-ff3d6cddd687_$ClientPeoplePicker_WaitImage" style="left: 376px; top: 4px; display: none;" alt="Esta animação indica que a operação está em curso. Clique para remover esta imagem animada." src="/_layouts/15/images/gears_anv4.gif?rev=23"><span class="sp-peoplepicker-resolveList" id="aps_user_13fce4eb-973e-44b9-8cba-ff3d6cddd687_$ClientPeoplePicker_ResolvedList"><span class="sp-peoplepicker-userSpan" id="aps_user_13fce4eb-973e-44b9-8cba-ff3d6cddd687_$ClientPeoplePicker_i:0#.w|dev\sp_admin_ProcessedUser1" sid="i:0#.w|dev\sp_admin" resolveduser="true" data-sp-peoplepickerprocesseduser="true"><span class="sp-peoplepicker-userPresence" id="aps_user_13fce4eb-973e-44b9-8cba-ff3d6cddd687_$ClientPeoplePicker_i:0#.w|dev\sp_admin_ProcessedUser1_PresenceContainer"></span><span title="SharePoint Admin" class="ms-entity-resolved" id="aps_user_13fce4eb-973e-44b9-8cba-ff3d6cddd687_$ClientPeoplePicker_i:0#.w|dev\sp_admin_ProcessedUser1_UserDisplay" style="max-width: 331px;">SharePoint Admin</span><a title="Remover pessoa ou grupo SharePoint Admin" class="sp-peoplepicker-delImage" id="aps_user_13fce4eb-973e-44b9-8cba-ff3d6cddd687_$ClientPeoplePicker_i:0#.w|dev\sp_admin_ProcessedUser1_DeleteUserLink" onkeydown="SPClientPeoplePickerProcessedUser.HandleDeleteProcessedUserKey(event); return true;" onclick="SPClientPeoplePickerProcessedUser.DeleteProcessedUser(this.parentNode); return false;" href="#">x</a></span></span><input title="Utilizador" disabled="disabled" class="sp-peoplepicker-editorInput" id="aps_user_13fce4eb-973e-44b9-8cba-ff3d6cddd687_$ClientPeoplePicker_EditorInput" style="max-width: 366px;" type="text" size="1" value="" autocorrect="off" autocomplete="off" autocapitalize="off" data-sp-peoplePickerEditor="true" AutoFillContainerId="aps_user_13fce4eb-973e-44b9-8cba-ff3d6cddd687_$ClientPeoplePicker_AutoFillDiv"></div>

SharePoint Online:

    <textarea name="ctl00$ctl40$g_a543006a_dd2e_46e0_93c8_deeb4d72af44$ctl00$ctl05$ctl06$ctl00$ctl00$ctl04$ctl00$ctl00$UserField$downlevelTextBox" title="People Picker" class="ms-inputuserfield ms-inputBox" id="ctl00_ctl40_g_a543006a_dd2e_46e0_93c8_deeb4d72af44_ctl00_ctl05_ctl06_ctl00_ctl00_ctl04_ctl00_ctl00_UserField_downlevelTextBox" style="width: 100%; display: none; ;" onkeydown="return onKeyDownRw('ctl00_ctl40_g_a543006a_dd2e_46e0_93c8_deeb4d72af44_ctl00_ctl05_ctl06_ctl00_ctl00_ctl04_ctl00_ctl00_UserField', 3, true, event);" onkeyup="return onKeyUpRw('ctl00_ctl40_g_a543006a_dd2e_46e0_93c8_deeb4d72af44_ctl00_ctl05_ctl06_ctl00_ctl00_ctl04_ctl00_ctl00_UserField');" onfocus="StoreOldValue('ctl00_ctl40_g_a543006a_dd2e_46e0_93c8_deeb4d72af44_ctl00_ctl05_ctl06_ctl00_ctl00_ctl04_ctl00_ctl00_UserField'); saveOldEntities('ctl00_ctl40_g_a543006a_dd2e_46e0_93c8_deeb4d72af44_ctl00_ctl05_ctl06_ctl00_ctl00_ctl04_ctl00_ctl00_UserField'); Sys.UI.DomElement.addCssClass(this, 'ms-inputBoxActive');" onblur="if(typeof(ExternalCustomControlCallback)=='function'){ if(ShouldCallCustomCallBack('ctl00_ctl40_g_a543006a_dd2e_46e0_93c8_deeb4d72af44_ctl00_ctl05_ctl06_ctl00_ctl00_ctl04_ctl00_ctl00_UserField',event)){if(!ValidatePickerControl('ctl00_ctl40_g_a543006a_dd2e_46e0_93c8_deeb4d72af44_ctl00_ctl05_ctl06_ctl00_ctl00_ctl04_ctl00_ctl00_UserField')){ShowValidationError();return false;}else {ExternalCustomControlCallback('ctl00_ctl40_g_a543006a_dd2e_46e0_93c8_deeb4d72af44_ctl00_ctl05_ctl06_ctl00_ctl00_ctl04_ctl00_ctl00_UserField');}}} Sys.UI.DomElement.removeCssClass(this, 'ms-inputBoxActive');" onchange="updateControlValue('ctl00_ctl40_g_a543006a_dd2e_46e0_93c8_deeb4d72af44_ctl00_ctl05_ctl06_ctl00_ctl00_ctl04_ctl00_ctl00_UserField');" rows="1" cols="20" autopostback="0" renderascontenteditablediv="true"></textarea>
0

These are the functions I use to interact with the people picker fields.

    function setUser(FieldName, Person){  //Sets this user exclusively
        var ppDiv = $("[id$='ClientPeoplePicker'][title='" + FieldName + "']"); //Find div with the name
        var ppEditor = ppDiv.find("[title='" + FieldName + "']"); //narrow down to input with name
        var spPP = SPClientPeoplePicker.SPClientPeoplePickerDict[ppDiv[0].id]; //get the instance of the peoplepicker from the dictionary
        var current = spPP.GetAllUserInfo(); //get current users
        current.forEach(function(index){ //delete current users
            spPP.DeleteProcessedUser(current[index]);
        });
        ppEditor.val(Person) // Set the value
        spPP.AddUnresolvedUserFromEditor(true); //resolve name
    }
    function clearUsers(FieldName){  //Clears all existing users from PP
        var ppDiv = $("[id$='ClientPeoplePicker'][title='" + FieldName + "']"); //Find div with the name
        var ppEditor = ppDiv.find("[title='" + FieldName + "']"); //narrow down to input with name
        var spPP = SPClientPeoplePicker.SPClientPeoplePickerDict[ppDiv[0].id]; //get the instance of the peoplepicker from the dictionary
        var current = spPP.GetAllUserInfo(); //get current users
        current.forEach(function(index){ //delete current users
            spPP.DeleteProcessedUser(current[index]);
        });
    }
    function addUser(FieldName, Person){  //Adds user without clearing existing users
        var ppDiv = $("[id$='ClientPeoplePicker'][title='" + FieldName + "']"); //Find div with the name
        var ppEditor = ppDiv.find("[title='" + FieldName + "']"); //narrow down to input with name
        var spPP = SPClientPeoplePicker.SPClientPeoplePickerDict[ppDiv[0].id]; //get the instance of the peoplepicker from the dictionary
        ppEditor.val(Person) // Set the value
        spPP.AddUnresolvedUserFromEditor(true); //resolve name
    }

These work great for me but I don't modify the NewForm.aspx directly. I inject code using the Content Editor web part on the NewForm.aspx page. Should work the same, but wanted to preface this anyway.

  • Thanks Scott, but I already tried this code in my initial attempt. The HTML has changed from onprem to SPO as you can see above. Do you have any other suggestions? Were you able to apply your suggestions in SharePoint Online? I also am using a Content Editor web part so that I don't have to change NewForm.aspx. Thanks Miguel – user20035 Apr 11 '16 at 8:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.