Retrieve Email Address from sharepoint people picker using javascript

nen picture nen · Nov 11, 2010 · Viewed 7.6k times · Source

I am using SharePoint 2007. I have a custom aspx page in the layouts folder containing a people picker (PeopleEditor) control.

Users can enter n nunmber of users in the control. I want to retrevie the users' emails from the people picker control using javascript, can someone please help.

Answer

Kit Menke picture Kit Menke · Nov 11, 2010

General

People fields are pretty complicated, but I'll do my best to explain what I've found out from doing some work with them while updating my library (SPUtility.js). You can take a look at the SPUserField class in the library to see. I mostly used Firebug + Firefox to reverse engineer the field. Unfortunately, the field is generated differently depending on what browser is used.

  • In Firefox, a regular old textarea is displayed.
  • In IE, seems to use a content editable div.

First, a list of the controls that make up the field:

  • upLevelDiv - A content editable div by downlevelTextBox
  • downlevelTextBox - Textarea
  • hiddenSpanData - Textbox storing some data
  • checkNames - ImageButton the user clicks to validate entered names via AJAX

There actually are a couple more controls, but I haven't found them to be useful (HiddenEntityKey, HiddenEntityDisplayText).

Getting the controls

I'm not sure how the HTML works in an ASPX page but in a regular SharePoint form, there is a <span class="ms-usereditor">. All the other controls seem to be contained in this span. This makes it relatively easy to get the other controls:

var controls = this.Controls.select('span.ms-usereditor');
if (null !== controls && 1 === controls.length) {
    this.spanUserField = controls[0];
    this.upLevelDiv = $(this.spanUserField.id + '_upLevelDiv');
    this.textareaDownLevelTextBox = $(this.spanUserField.id + '_downlevelTextBox');
    this.linkCheckNames = $(this.spanUserField.id + '_checkNames');
    this.txtHiddenSpanData = $(this.spanUserField.id + '_hiddenSpanData');
}

Setting the field

To understand, I'm including the details for setting the field as well.

if (Prototype.Browser.IE) {
    this.upLevelDiv.innerHTML = value;
    this.txtHiddenSpanData.setValue(value);
    this.linkCheckNames.click();
}
else { // FireFox (maybe others?)
    this.textareaDownLevelTextBox.setValue(value);
    this.linkCheckNames.onclick();
}

Getting the field value

After the Check Names button is clicked and the AJAX executes, your controls should then be populated with new information. The upLevelDiv seems to contain most of it but hiddenSpanData also contains some.

After an execution, upLevelDiv (or hiddenSpanData) will probably contain something like this:

<SPAN class=ms-entity-resolved id=spanDOMAIN\account12345 title=DOMAIN\account12345 contentEditable=false tabIndex=-1>
<DIV id=divEntityData style="DISPLAY: none" description="DOMAIN\account12345" isresolved="True" displaytext="LastName, FirstName" key="DOMAIN\account12345">
<DIV data='<ArrayOfDictionaryEntry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><DictionaryEntry><Key xsi:type="xsd:string">SPUserID</Key><Value xsi:type="xsd:string">2</Value></DictionaryEntry><DictionaryEntry><Key xsi:type="xsd:string">Email</Key><Value xsi:type="xsd:string">[email protected]</Value></DictionaryEntry><DictionaryEntry><Key xsi:type="xsd:string">DisplayName</Key><Value xsi:type="xsd:string">LastName, FirstName</Value></DictionaryEntry><DictionaryEntry><Key xsi:type="xsd:string">Department</Key><Value xsi:type="xsd:string">My Department Name</Value></DictionaryEntry><DictionaryEntry><Key xsi:type="xsd:string">SIPAddress</Key><Value xsi:type="xsd:string">[email protected]</Value></DictionaryEntry><DictionaryEntry><Key xsi:type="xsd:string">PrincipalType</Key><Value xsi:type="xsd:string">User</Value></DictionaryEntry><DictionaryEntry><Key xsi:type="xsd:string">Title</Key><Value xsi:type="xsd:string">My Job Title</Value></DictionaryEntry></ArrayOfDictionaryEntry>'></DIV></DIV><SPAN oncontextmenu=onContextMenuSpnRw(); onmousedown=onMouseDownRw(); id=content contentEditable=true tabIndex=-1>LastName, FirstName</SPAN></SPAN>

Then, all you need to do is parse out the ArrayOfDictionaryEntry XML object to read their email.