I am trying to get the people picker value on EditForm.aspx using Jquery. I have 2 people picker controls on Edit form.
I am not able to get it using jquery.
Please help me to sort it out.
I am trying to get the people picker value on EditForm.aspx using Jquery. I have 2 people picker controls on Edit form.
I am not able to get it using jquery.
Please help me to sort it out.
You can access normal peoplepicker in SP2013 the same way you would access a clientside one.
The Problem is, that you need to know the ID to identify the peoplepicker.
If you check out the SPClientPeoplePicker.SPClientPeoplePickerDict object in your debugging console, there are all peoplepicker of this page stored in it.

You can access the entered user's information like this:
SPClientPeoplePicker.SPClientPeoplePickerDict[yourPickersID].GetAllUserInfo()
Now every object has stored the properties of an user that was entered in the picker.

Here's an example for a group

Here's some code to iterate over all picker and output all users to the console:
// get all user from all peoplepicker on the page - without jQuery
for (var propertyName in SPClientPeoplePicker.SPClientPeoplePickerDict) {
var allUserInfo = SPClientPeoplePicker.SPClientPeoplePickerDict[propertyName].GetAllUserInfo()
for (var user in allUserInfo) {
console.log(allUserInfo[user]);
}
}
SPClientPeoplePicker.SPClientPeoplePickerDict created by SharePoint. There is no "jQuery-way" to access a variable. But I'll create a ready-to-run example just for you. Just wait for it.
– Mx.
Aug 24 '15 at 16:00
// get all user from all peoplepicker on the page - without jQuery for (var propertyName in SPClientPeoplePicker.SPClientPeoplePickerDict) { var allUserInfo = SPClientPeoplePicker.SPClientPeoplePickerDict[propertyName].GetAllUserInfo() for (var user in allUserInfo) { console.log(allUserInfo[user]); } } :)
– Mx.
Aug 24 '15 at 16:18
SCRIPT5009: 'SPClientPeoplePicker' is undefined in the console window.
– vapcguy
Aug 24 '15 at 16:52
$(document).ready() code and had not finished loading into the box when the ready() code was trying to pull it out.
– vapcguy
Aug 24 '15 at 19:10
You are smart when you have jQuery with you.
$('div[id$="_upLevelDiv"]').eq(2).find('div').eq(0).attr('description')
I have used index because I have more than two peoplePicker in my form.
I have captured the third $('div[id$="_upLevelDiv"]').eq(2) people picker resolved value.
Since in SharePoint 2013 Client Side Rendering (CSR) is the default rendering mode, i would recommend you the following approach of getting People Picker value in Edit form.
Assume a Tasks list that contains AssignedTo field, then the following example demonstrates how to retrieve the value of AssignedTo field in Edit form:
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function() {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
OnPreRender: function(ctx) {
var assignedTo = ctx.ListData.Items[0].AssignedTo;
}
});
});
Result
AssignedTo value:
[
{
"Claim": null,
"Key": "Approvers",
"DisplayText": "Approvers",
"IsResolved": true,
"Description": "Approvers",
"EntityType": "",
"EntityGroupName": "",
"HierarchyIdentifier": null,
"EntityData": {
"SPUserID": "11",
"AccountName": "Approvers",
"PrincipalType": "User"
},
"EntityDataElements": [
{
"First": "SPUserID",
"Second": "11"
},
{
"First": "AccountName",
"Second": "Approvers"
},
{
"First": "PrincipalType",
"Second": "User"
}
],
"MultipleMatches": [],
"ProviderName": "",
"ProviderDisplayName": ""
}
]
How to apply the changes
There are at least two options how to apply the changes:
Script Editor/Content Editor
web partsHere is how to apply the changes using the second option:
Script Editor webpart right below the list view web part.script tag code into the Script Editor, for example: <script type="text/javascript">{Template JS code goes here}</script>call the below fun inside document.ready ()
var mPplPickerName= getEditorPeoplePickerValues("your
pplpicker fieldname");
outside the doc.ready function:
function getEditorPeoplePickerValues(fieldName) { // Field Title
//alert(' inside get pplpicker sub function');
editorNames = "";
var _PeoplePicker = $("div[title='" + fieldName + "']");
var _PeoplePickerTopId = _PeoplePicker.attr('id');
var ppobject =
SPClientPeoplePicker.SPClientPeoplePickerDict[_PeoplePickerTopId];
editorsInfo = ppobject.GetAllUserInfo();
var i;
for (i = 0; i < editorsInfo.length; ++i) {
editorNames += editorsInfo[i].DisplayText + ";#";
}
//alert(editorNames);
return editorNames;
}
i have tested, its working for me!
SPClientPeoplePicker is not defined. And that's after I added a var to editorNames and removed the unnecessary var i; before the loop.
– vapcguy
Oct 12 '21 at 22:20
So I had a case where I needed to get the value that was in the people picker field on page load, store it, then compare it if/when it was changed on the page prior to saving - and if so, set a checkbox field on the page so a workflow could grab the new person field value and send them a notification. I just used a REST call to get the value, initially, because if you try to get it from one of the spans, it won't be populated yet - even during the $(document).ready() event.
Set an array: var documentItems = [];
And a variable for a string of your original results: var originalPerson = "";
You'll only be setting an array of one item, but I found it was just easier for me since I use this construct whenever I'm grabbing items via AJAX.
In your $(document).ready(), do this:
$(document).ready(function() {
getPerson();
});
Then...
function getPerson() {
// Get the ID of the current item
var url = window.location.href;
var urlParams = url.split('ID=')[1]; // gets everything downstream of the equals
var id = urlParams.split('&')[0]; // gets everything upstream of the "&" separator: the ID
// or you can hardcode it for testing:
// var id = 1; // must be a valid item ID
var listName = "MyList";
var url = "https://somesite.com/sites/mysitecollection";
var complete, failure;
getMyListItem(url, id, listName, complete, failure);
}
function getMyListItem(url, id, listName, complete, failure) {
// Execute AJAX request
$.ajax({
url: url + "/_api/web/lists/getbytitle('" + listName + "')/items?$select=YourPersonField/Title,YourPersonField/Id&filter=ID%20eq%20" + id + "&$expand=YourPersonField",
method: "GET",
headers: { "Accept" : "application/json; odata=verbose" },
success: function (data) {
console.log("success, data: " + data + ", data length: " + data.d.results.length);
var items = data.d.results;
if (items.length > 0) {
console.log("item: " + data);
if (items[0].YourPersonField != undefined) {
console.log("found field");
if (items[0].YourPersonField.results != undefined) {
console.log("found results set");
if (items[0].YourPersonField.results > 0) {
console.log("found results > 0");
for (var i=0; i<items[0].YourPersonField.results.length; i++) {
var name = "";
console.log("Loop " + i + ", " + items[0].YourPersonField.results[i].Title);
name = items[0].YourPersonField.results[i].Title;
documentItems.push({
"name" : name
});
}
}
}
}
buildContent(items[0].YourPersonField.results.length);
}
},
error: function (data) {
console.log("failed");
}
});
}
function buildContent(itemCount) {
var htmlContent = ""; // sometimes I spit this out to a div I append after populating
if (itemCount > 0) {
for (var i = 0; i < documentItems.length; i++) {
htmlContent += documentItems[i].name + ";";
console.log("Added: " + documentItems[i].name);
}
htmlContent = htmlContent.trimEnd(';');
}
originalPerson = htmlContent; // populate our base variable
}
This is set up in case there are multiple values in the picker and you will need to change YourPersonField to the underlying name of your person field - not the display name. It could be Your_0x0020_Person_0x0020_Field, for example, if you created the field with spaces in it, originally (never a good idea because of that).
Once we know what the original value is, another way we can get the value directly from the screen is after a focusout. In the $(document).ready(), I added the focusout event onto the hidden input field associated with the people picker:
var personInput = $('input[title="YourPersonField"]');
personInput.focusout(function() {
doPersonDiff();
});
In doPersonDiff() is where I grab the value:
function doPersonDiff() {
console.log("Checking if person changed...");
var personSpan = $('span[id*="YourPersonField"]');
var newPerson = stripPickerValue(personSpan.text()); // parse it here
console.log("Original person: " + originalPerson + ", new person: " + newPerson);
// ... split newAgent on the "x"s, split originalPerson on the ";"
// do indexOf comparisons on "newPerson" to see if "newPerson" is missing "originalPerson" array values you iterate over
// and then an indexOf on the "originalPerson" string to see if "originalPerson" is missing "newPerson" array values you iterate over
// If any indexOf fails ( == -1 ), set listChanged = true;
// If listChanged == true, test if the field that represents a change was made is already set - if so, ignore
// If listChanged == true, and the field that represents a change was made is not set, set it
// If listChanged == false, unset the box.
}
I won't supply the full code on that since this question was not about how to compare strings and arrays. But I'll include my SPAN field text parser:
function stripPickerValue(person) {
var newPerson = person;
console.log("Span text: " + newPerson);
newPerson = newPerson.replace('Your Person Field','');
newPerson = newPerson.replace('Enter a name or email address...','');
newPerson = newPerson.replace('Enter names or email addresses...',''); // if your person field can contain multiple values
newPerson = newPerson.replace('xSuggestions are available. Use up and down arrows to select.',''); // for multiple values
newPerson = newPerson.replace('Suggestions are available. Use up and down arrows to select.','');
newPerson = newPerson.replace('\r','');
newPerson = newPerson.replace('\n','');
newPerson = newPerson.replace('\t','');
newPerson = newPerson.trim();
return newPerson;
}
That will clean up the span's HTML text. Even if your field doesn't allow multiple values, you can use this with all of the replace lines, since it will just skip it if it doesn't find it. Order is important, so that it finds longer text first and removes that, then checks for the shorter version, not the other way around.
So bottom line, either use the REST call if you need it onload, or get it on focusout and parse the content so you can get it when you click something else.
// in a routine that focusout calls...
var personSpan = $('span[id*="YourPersonField"]');
// Send personSpan through the parser
Be sure to override the Submit button in $(document).ready() so you can run that routine, though - focusout doesn't work if they immediately go for that Submit button after adding a value.
var submitBtn = $('input[name*="diidIOSaveItem"]');
submitBtn.parent().append('<input type="button" id="btnSubmit" value="Submit" onclick="doValidation()"></input>');
submitBtn.hide();
...and in doValidation():
function doValidation() {
doPersonDiff(); // or whatever routine you have that is grabbing the people picker value...
$('input[name*="diidIOSaveItem"]').click(); // submit as normal
}
You have to take site users by REST query. Store all users in some variable. Then in aspx page, use auto complete functionality of jquery UI. You can use following REST query to fetch all users from site users
_spPageContextInfo.webAbsoluteUrl + "/_api/web/SiteUsers