Sunday, February 20, 2011

How to Set SharePoint People Picker Default Value to Current User through JavaScript

With the common SharePoint field types you can specify “[Me]” in the default value property to set the current logged in user. But for the Person or Group field type they haven’t enable this feature. This is a common requirement and I needed to find a good standard approach.

We can achieve this in two scenarios:
  1. After the list item save: We can trigger a workflow and programmatically set the logged in user to the field
  2. Before the list item save: We can modify the list item add new form page to set the current logged in user using JavaScript
In my case, the requirement was second scenario and this blog post is mainly focused on that.

If we are modifying the list item add new form page to achieve this, we need to consider two things:

How to get the current user information in SharePoint context via JavaScript

For this I had to refer SharePoint 2010 - Client Object Model and how to get the logged in user information using SharePoint JavaScript api.

How to set the value to the People Picker control

I found the post on how to manipulate a list form fields using JavaScript but it doesn’t mention how to do it for the People Picker control. Unlike other form fields we can’t uniquely identify the People Picker control in html markup (Other form fields can be identified by the title attribute. Title attribute has set to the field name of list item). Therefore in my approach I had to know the parent element of the People Picker control to identify the People Picker control.

I have bundled this functionality to a JavaScript class and we can reuse it whenever needed. One thing that I learned working with Puzzlepart team was you must simplify your implementation as much as possible and isolate it in a generic manner that we can reuse it other places.

PeoplePicker Class
<script type="text/javascript">

function PeoplePicker(){

    this.context = null;
    this.web = null;
    this.currentUser = null;
    this.parentTagId = null    
    
    this.SetParentTagId = function(id){
        this.parentTagId = id;
    }
    
    this.SetLoggedInUser = function(){
        if(this.parentTagId != null){
            this.getWebUserData();            
        }    
    }
    
    this.getWebUserData = function(){
        this.context = new SP.ClientContext.get_current();
        this.web = this.context.get_web();
        this.currentUser = this.web.get_currentUser();
        this.currentUser.retrieve();
        this.context.load(this.web);
        this.context.executeQueryAsync(Function.createDelegate(this, this.onSuccessMethod), 
                                       Function.createDelegate(this, this.onFailureMethod));
    }    
    
    this.onSuccessMethod = function(){ 
        this.setDefaultValue(this.currentUser.get_title());        
    }

    this.onFailureMethod = function(){
        alert('request failed ' + args.get_message() + '\n' + args.get_stackTrace());
    }    
        
    this.setDefaultValue = function(value){         
        var parentTag = document.getElementById(this.parentTagId);
        if (parentTag != null) {
            var peoplePickerTag = this.getTagFromIdentifierAndTitle(parentTag, 'div', 
                                                    'UserField_upLevelDiv', 'People Picker');
            if (peoplePickerTag) {
                peoplePickerTag.innerHTML = value;
            }            
        }
    }    
    
    this.getTagFromIdentifierAndTitle = function(parentElement, tagName, identifier, title){     
        var len = identifier.length;
        var tags = parentElement.getElementsByTagName(tagName);
        for (var i = 0; i < tags.length; i++) {
            var tempString = tags[i].id;
            if (tags[i].title == title && (identifier == "" || 
                                tempString.indexOf(identifier) == tempString.length - len)) {
                return tags[i];
            }
        }
        return null;
    }
}

</script>
Now you can reuse this in your aspx markup:
<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">

<sharepoint:scriptlink localizable="false" name="SP.js" ondemand="true" runat="server"/>  

<script type="text/javascript">

ExecuteOrDelayUntilScriptLoaded(SetWebUserData, "sp.js");

function SetWebUserData() {
    var pplPicker = new PeoplePicker();
    // Set the parent tag id of the people the picker.
    pplPicker.SetParentTagId('ctl00_UserField_containerCell');
    pplPicker.SetLoggedInUser();
}

</script>

</asp:Content>

19 comments:

Anonymous said...

Excellent Post, but how do you determine the value ParentTagId on the NewForm.aspx page?

Janaka Jeewantha said...

If you are using NewForm.aspx, you can set the id of 'td' element (which is parent element of people picker). NewForm.aspx has a fixed 'table' structure. If you are using a customized new form, then you can set your own parent element id in aspx markup.

Vignesh said...

Fantastic. Thanks for the post.

Half said...

Excelent piece of code. If I save it to a js file, where should I put the file so that I can reference it from a Content Editor Web Part?

Thanks

Janaka Jeewantha said...

You can put the js file inside the 14\TEMPLATE\LAYOUTS folder.

Alderley plc said...

Im am struggling to get this working.

I have craeted a javascript file with the funtion in it and saved this into C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS

I named my file "DefaultPeoplePicker.js" because there was alreas a file called SP.js in the folder.


Next i added a reference to load the "DefaultPeoplePicker.js" file in the "PlaceHolderMain" tag in the NewForm.aspx file.

Directly underneath that i added the rest of the javscript with the SetWebUserData function

I changed the cell reference to the following:

pplPicker.SetParentTagId('ctl00_m_g_bbdf2997_5904_4d4c_873f_3ec18d07d7ec_ctl00_ctl05_ctl07_ctl00_ctl00_ctl04_ctl00_ctl00_UserField_containerCell');

Nothing happens when i load the form

akhilesh verma said...

it's a great article, saved lots of my time.
Regards,

Alderley plc said...

i got it working by adding the script file to my siteassets and refenceing it from there



Great script thanks!

Anonymous said...

This is very helpful. don't need to use codeplex spServices.works excellent.

Thank you
Geary

Anonymous said...

This article was a great aid! thanks a lot.

Anonymous said...

I cant make this work.
ive placed my JS and named it as people.js and place it in layouts

heres my code in newform.aspx

sharepoint:scriptlink localizable="false" name="people.js" ondemand="true" runat="server"
script type="text/javascript">
ExecuteOrDelayUntilScriptLoaded(SetWebUserData, "people.js");

function alertThis(value)
{
alert(value);
}
function SetWebUserData() {
alert('test');
var pplPicker = new PeoplePicker();
// Set the parent tag id of the people the picker.
pplPicker.SetParentTagId('ctl00_m_g_031a4528_7bdf_4b8d_ad7b_4598011265ad_ctl00_ctl05_ctl01_ctl00_ctl00_ctl04_ctl00_ctl00_UserField_containerCell');
pplPicker.SetLoggedInUser();
alert('END');
}

Unknown said...

Great Post, just an important note. If you need to run this code for a localized / non-english sharepoint site, e.g. German, the parameter 'People Picker' needs to be changed to its localized equivalent, e.g. 'Personenauswahl'.

Don't we love SharePoints multilingual capabilities? :-)

Anonymous said...

Is there any way to get this to work for a form designed in InfoPath? I'm having trouble determining the parentTagId of my people picker.

Vaqar Hyder said...

Great post!
but is there any way to save a value in People picker field inside a list using javascript/ECMAscript/JSOM (whatever you call it)
I would really appreciate a response on that.
Thanks

Unknown said...

I am using Visual Web Part and try to populate people picker filed on the web part from admin master list "AdminGroup" (People & Group Filed) using jquery .

Can you guide me what should i do to accomplish this.

Unknown said...

Thanks so much! Your instructions are very clear and helpful. I've been wondering how to do this for months and thrilled to find out how finally!
sharepoint developer training

Unknown said...

Hi,

where do i have to put the js file?
or where can i put the path to the file in the newform?

Thx
Stefan

Janaka Jeewantha said...

You can keep the js file inside the assets library and use the server relative url.

Unknown said...

hi again,

thx, i think i put it in a library, like other scripts that are working, but how do i know the correct pplPicker.SetParentTagID (Like yours 'ctl00_UserField_containerCell'?

Thx again and have i nice day

stefan