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>