Table of contents
Very often there is a need to select the User Profile properties for another user apart of "my user" (the user that is currently logged in). Since this is not implemented in skybow Solution Studio and skybow Rich Forms/Modern Forms out of the box, due to the issue with permissions and security (the user who is querying the user profile information needs to have appropriate permissions to actually do it), here is a workaround how to implement this manually.
In the use case below, there are two fields on the form: a People Picker field bound to the field with internal name "PersonField", and a Text field, bound to the field with internal name "DepartmentField". The goal is, that when a person is selected in the people picker field ("PersonField"), that the "DepartnemtField" is automatically populated with the Department value from that user's profile.
How to do that in skybow modern forms
In the Expression configuration of the "DepartmentField", in the "Calculated" value, the following "Function code" script should be set.
Please note, that on line 2 proper field name should be set for the people picker, and on line 29 proper user profile property name.
Important: since this script will always be executed in the user context, if logged user does not have rights to read User Profile property values, the script will not work for that user.
var personProperties;
var targetUser = [[PersonField.LoginName]];
function LoadFiles() {
return new Promise(function (resolve, reject) {
if (typeof SP.UserProfiles == 'undefined') {
var scriptKey = 'SP.UserProfiles.js';
SP.SOD.registerSod(scriptKey, '/_layouts/15/SP.UserProfiles.js');
SP.SOD.loadMultiple(['SP.UserProfiles.js'], resolve);
} else {
resolve();
}
});
}
function getUserProperties(targetUser) {
return new Promise(function (resolve, reject) {
// Get the current client context and PeopleManager instance.
var clientContext = new SP.ClientContext.get_current();
var peopleManager = new SP.UserProfiles.PeopleManager(clientContext);
// Get user properties for the target user.
// To get the PersonProperties object for the current user, use the
// getMyProperties method.
personProperties = peopleManager.getPropertiesFor(targetUser);
// Load the PersonProperties object and send the request.
clientContext.load(personProperties);
clientContext.executeQueryAsync(
function () {
try {
// Get a property from the UserProfileProperties property.
var messageText = personProperties.get_userProfileProperties()["Department"];
resolve(messageText);
}
catch (e) {
reject("Error: " + e);
}
},
function (sender, args) {
reject("Error: " + args.get_message());
});
});
}
return new Promise(function (resolve, reject) {
LoadFiles().then(function () {
if (targetUser) {
getUserProperties(targetUser).then(function (messageText) { resolve(messageText); }).catch(function (err) { reject(err); });
}
else {
resolve("");
}
});
});
How to do that in skybow rich forms
In the "Behavior" ribbon group of the "DepartmentField", in the "Calculated" value, the following "Function code" script should be set.
Please note, that on lines 2 and 39 proper field names should be set for the people picker and text field, and on line 37 proper user profile property name.
Important: since this script will always be executed in the user context, if logged user does not have rights to read User Profile property values, the script will not work for that user.
var personProperties;
var targetUser = [[PersonField.LoginName]];
function LoadFiles() {
var defer = jQuery.Deferred();
if (typeof SP.UserProfiles == 'undefined') {
var scriptKey = 'SP.UserProfiles.js';
SP.SOD.registerSod(scriptKey, '/_layouts/15/SP.UserProfiles.js');
SP.SOD.loadMultiple(['SP.UserProfiles.js'], defer.resolve);
} else {
defer.resolve();
}
return defer.promise();
}
function getUserProperties(targetUser) {
// Get the current client context and PeopleManager instance.
var clientContext = new SP.ClientContext.get_current();
var peopleManager = new SP.UserProfiles.PeopleManager(clientContext);
// Get user properties for the target user.
// To get the PersonProperties object for the current user, use the
// getMyProperties method.
personProperties = peopleManager.getPropertiesFor(targetUser);
// Load the PersonProperties object and send the request.
clientContext.load(personProperties);
clientContext.executeQueryAsync(onRequestSuccess, onRequestFail);
}
// This function runs if the executeQueryAsync call succeeds.
function onRequestSuccess() {
try {
// Get a property from the UserProfileProperties property.
var messageText = personProperties.get_userProfileProperties()["Department"];
var inputController = jQuery('span.ms-formbody[fieldname="DepartmentField"]').closest('.ard-formfield').data('Controller');
inputController.InstanseData.SetValue(messageText);
}
catch(e) {
}
}
// This function runs if the executeQueryAsync call fails.
function onRequestFail(sender, args) {
alert("Error: " + args.get_message());
}
LoadFiles().then(function(){
if(targetUser) {
getUserProperties(targetUser);
}
});