Skip to content

Instantly share code, notes, and snippets.

@Aymkdn
Last active June 1, 2020 23:22
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save Aymkdn/5925efc9f4fecccc40612c6a5db7efc9 to your computer and use it in GitHub Desktop.
Save Aymkdn/5925efc9f4fecccc40612c6a5db7efc9 to your computer and use it in GitHub Desktop.
Create a Sharepoint 2013 native People Picker in JavaScript (using jQuery, or using SharepointPlus)
<!-- load jQuery -->
<!-- the HTML element use to load the people picker -->
<div id="peoplePickerDiv">Loading people picker...</div>
<button type="button" onclick="getInfo()">Get Info</button>
<script>
var mp = new MyPeoplePicker();
mp.init('peoplePickerDiv', {AllowMultipleValues:false});
$('#peoplePickerDiv').on('user:changed', function() {
// triggered when the users changed
var users=mp.getUsers().map(function(u) { return u.DisplayText });
alert("Names entered: "+users.join("; "));
})
function getInfo() {
console.log(mp.getUsers()); // -> return an array of the users
mp.getUsersID(function() {
console.log(arguments); // -> return the User ID
})
}
</script>
// using jQuery
var MyPeoplePicker = function() {
this.ready = false;
this.pickerID = "";
this.users = [];
/**
* Render and initialize the client-side People Picker.
* @param {String} peoplePickerElementId The `id` from the <div>
* @param {Object} [options]
* @param {String} [options.PrincipalAccountType='User,DL,SecGroup,SPGroup']
* @param {Number} [options.SearchPrincipalSource=15]
* @param {Number} [options.ResolvePrincipalSource=15]
* @param {Boolean} [options.AllowMultipleValues=true]
* @param {Number} [options.MaximumEntitySuggestions=50]
* @param {String} [options.Width='280px']
* @param {Function} [callback] To do an action after the loading
*/
this.init=function(peoplePickerElementId, options, callback) {
// Create a schema to store picker properties, and set the properties.
var schema = {}, _this=this;
_this.pickerID = peoplePickerElementId;
if (typeof options === "function") {
callback=options;
options={};
}
callback = callback || function(){};
// the options
schema['PrincipalAccountType'] = 'User,DL,SecGroup,SPGroup';
schema['SearchPrincipalSource'] = 15;
schema['ResolvePrincipalSource'] = 15;
schema['AllowMultipleValues'] = true;
schema['MaximumEntitySuggestions'] = 50;
schema['Width'] = '280px';
schema = jQuery.extend({}, schema, options);
// Render and initialize the picker.
// Pass the ID of the DOM element that contains the picker, an array of initial
// PickerEntity objects to set the picker value, and a schema that defines
// picker properties.
// and do it only when all is ready
$.each(['sp.core.js', 'sp.runtime.js', 'sp.js', 'autofill.js', 'clientpeoplepicker.js', 'clientforms.js', 'clienttemplates.js'], function(idx, val) {
if (!_v_dictSod[val]) RegisterSod(val, "\u002f_layouts\u002f15\u002f"+val);
}
);
SP.SOD.loadMultiple(['sp.core.js', 'sp.runtime.js', 'sp.js', 'autofill.js', 'clientpeoplepicker.js', 'clientforms.js', 'clienttemplates.js'], function() {
SPClientPeoplePicker_InitStandaloneControlWrapper(peoplePickerElementId, null, schema);
_this.ready=true;
// monitor this field to do something when the value change
_this._monitor();
callback.call(_this)
});
};
// Query the picker for user information.
/**
* Return an array of users' info
* @return {[type]} [description]
*/
this.getUsers=function() {
var _this=this;
if (_this.ready === false) {
alert("[ERROR] Please init the object first")
return
}
// Get the people picker object from the page.
var peoplePicker = SPClientPeoplePicker.SPClientPeoplePickerDict[_this.pickerID+"_TopSpan"];
// Get information about all users.
_this.users = peoplePicker.GetAllUserInfo();
return _this.users;
// Get user keys.
//var keys = peoplePicker.GetAllUserKeys();
};
/**
* Get the user ID for the selected users
* @param {Function} callback With a parameter that is an array of IDs
*/
this.getUsersID=function(callback) {
var context = new SP.ClientContext.get_current();
var _this=this;
if (_this.ready === false) {
alert("[ERROR] Please init the object first")
return
}
callback = callback || function(){};
var users=_this.getUsers();
// for each users we create a deferred object
if (jQuery.type(users) !== "array") users = [ users ];
var fctDeferred = jQuery.map(users, function(u) {
var deferred=jQuery.Deferred();
var user = context.get_web().ensureUser(u.Key);
context.load(user);
context.executeQueryAsync(
(function() { deferred.resolve(user.get_id()) }),
(function(sender, args) { deferred.reject('Query failed. Error: ' + args.get_message()) })
);
return deferred;
});
$.when.apply(_this,fctDeferred).done(function() {
callback.apply(_this,arguments)
}).fail(function(error) {
alert(error)
})
};
/**
* This function will monitor the field and if something changed then it will send the event "user:changed"
*/
this._monitor=function() {
var _this=this;
_this.monitorID = _this.pickerID+"_TopSpan_HiddenInput";
_this.monitorValue=document.getElementById(_this.monitorID).value;
_this.monitorInterval = setInterval(function() {
var el = document.getElementById(_this.monitorID);
if (!el) clearInterval(_this.monitorInterval);
else {
if (_this.monitorValue !== el.value) {
$('#'+_this.pickerID).trigger("user:changed");
}
_this.monitorValue = el.value;
}
}, 200);
},
/**
* It will set some users into the PeoplePicker
* @param {String|Array} users Must be a key value (e.g. "i:0#.w|europe\aymeric_de_martin")
*/
this.setUsers=function(users) {
if (jQuery.type(users) === "array") users=users.join(";");
var peoplePicker = SPClientPeoplePicker.SPClientPeoplePickerDict[this.pickerID+"_TopSpan"];
var e = document.getElementById(peoplePicker.ResolvedListElementId);
if (e) {
e = e.querySelectorAll('span');
var id = e.length;
// remove existing values from the peoplePicker
while(id--) { peoplePicker.DeleteProcessedUser(); }
}
peoplePicker.AddUserKeys(users, false)
}
};
// using SharepointPlus (http://aymkdn.github.io/SharepointPlus/) and Promise
// and we need a polyfill for new CustomEvent
!function(){function t(t,e){e=e||{bubbles:!1,cancelable:!1,detail:void 0};var n=document.createEvent("CustomEvent");return n.initCustomEvent(t,e.bubbles,e.cancelable,e.detail),n}return"function"==typeof window.CustomEvent?!1:(t.prototype=window.Event.prototype,void(window.CustomEvent=t))}();
var MyPeoplePicker = function() {
this.ready = false;
this.pickerID = "";
this.users = [];
/**
* Render and initialize the client-side People Picker.
* @param {String} peoplePickerElementId The `id` from the <div>
* @param {Object} [options]
* @param {String} [options.PrincipalAccountType='User,DL,SecGroup,SPGroup']
* @param {Number} [options.SearchPrincipalSource=15]
* @param {Number} [options.ResolvePrincipalSource=15]
* @param {Boolean} [options.AllowMultipleValues=true]
* @param {Number} [options.MaximumEntitySuggestions=50]
* @param {String} [options.Width='280px']
* @param {Function} [callback] To do an action after the loading
*/
this.init=function(peoplePickerElementId, options, callback) {
// Create a schema to store picker properties, and set the properties.
var schema = {}, _this=this;
_this.pickerID = peoplePickerElementId;
if (typeof options === "function") {
callback=options;
options={};
}
callback = callback || function(){};
// the options
schema['PrincipalAccountType'] = 'User,DL,SecGroup,SPGroup';
schema['SearchPrincipalSource'] = 15;
schema['ResolvePrincipalSource'] = 15;
schema['AllowMultipleValues'] = true;
schema['MaximumEntitySuggestions'] = 50;
schema['Width'] = '280px';
SPExtend(options, schema);
// Render and initialize the picker.
// Pass the ID of the DOM element that contains the picker, an array of initial
// PickerEntity objects to set the picker value, and a schema that defines
// picker properties.
// and do it only when all is ready
['sp.core.js', 'sp.runtime.js', 'sp.js', 'autofill.js', 'clientpeoplepicker.js', 'clientforms.js', 'clienttemplates.js'].forEach(function(val,idx) {
if (!_v_dictSod[val]) RegisterSod(val, "\u002f_layouts\u002f15\u002f"+val);
});
SP.SOD.loadMultiple(['sp.core.js', 'sp.runtime.js', 'sp.js', 'autofill.js', 'clientpeoplepicker.js', 'clientforms.js', 'clienttemplates.js'], function() {
SPClientPeoplePicker_InitStandaloneControlWrapper(peoplePickerElementId, null, options);
_this.ready=true;
// monitor this field to do something when the value change
_this._monitor();
callback.call(_this)
});
};
// Query the picker for user information.
/**
* Return an array of users' info
* @return {[type]} [description]
*/
this.getUsers=function() {
var _this=this;
if (_this.ready === false) {
alert("[ERROR] Please init the object first")
return
}
// Get the people picker object from the page.
var peoplePicker = SPClientPeoplePicker.SPClientPeoplePickerDict[_this.pickerID+"_TopSpan"];
// Get information about all users.
_this.users = peoplePicker.GetAllUserInfo();
return _this.users;
// Get user keys.
//var keys = peoplePicker.GetAllUserKeys();
};
/**
* Get the user ID for the selected users
* @param {Promise} resolve(array of IDs)
*/
this.getUsersID=function(callback) {
var _this=this;
return new Promise(function(prom_res, prom_rej) {
var context = new SP.ClientContext.get_current();
if (_this.ready === false) {
throw "[ERROR] Please init the object first";
}
var users=_this.getUsers();
// for each users we create a Promise object
if (!SPIsArray(users)) users = [ users ];
var aProm = users.map(function(u) {
return new Promise(function(p_res, p_rej) {
var user = context.get_web().ensureUser(u.Key);
context.load(user);
context.executeQueryAsync(
(function() { p_res(user.get_id()) }),
(function(sender, args) { p_rej('Query failed. Error: ' + args.get_message()) })
);
});
});
Promise.all(aProm).then(function(aUserID) {
prom_res(aUserID)
}).catch(function(error) {
prom_rej(error)
})
})
};
/**
* This function will monitor the field and if something changed then it will send the event "user:changed"
*/
this._monitor=function() {
var _this=this;
_this.monitorID = _this.pickerID+"_TopSpan_HiddenInput";
_this.monitorValue=document.getElementById(_this.monitorID).value;
_this.monitorInterval = setInterval(function() {
var el = document.getElementById(_this.monitorID);
if (!el) clearInterval(_this.monitorInterval);
else {
if (_this.monitorValue !== el.value) {
document.querySelector('#'+_this.pickerID).dispatchEvent(new CustomEvent("user:changed"));
}
_this.monitorValue = el.value;
}
}, 200);
},
/**
* It will set some users into the PeoplePicker
* @param {String|Array} users Must be a key value (e.g. "i:0#.w|domain\john_doe" or "domain\john_doe" or "john_doe@corp.com")
*/
this.setUsers=function(users) {
if (SPIsArray(users)) users=users.join(";");
var peoplePicker = SPClientPeoplePicker.SPClientPeoplePickerDict[this.pickerID+"_TopSpan"];
var e = document.getElementById(peoplePicker.ResolvedListElementId);
if (e) {
e = e.querySelectorAll('span');
var id = e.length;
// remove existing values from the peoplePicker
while(id--) { peoplePicker.DeleteProcessedUser(); }
}
peoplePicker.AddUserKeys(users, false)
}
};

Details about some of the options.

SearchPrincipalSource

The principal sources to search.

  • All (15) – Search all principal sources.
  • MembershipProvider (4) – Search the current membership provider.
  • None (0) – Search no principal sources.
  • RoleProvider (8) – Search the current role provider.
  • UserInfoList (1) – Search the user information list.
  • Windows (2) – Search active directory.

ResolvePrincipalType

The principal types to return.

  • All (15) – Return all entity types.
  • DistributionList (2) – Return distribution list entity types.
  • None (0) – Return no principal types.
  • SecurityGroup (4) – Return security group entity types.
  • SharePointGroup (8) – Return sharepoint group entity types.
  • User (1) – Return user entity types.
@gauravIT99
Copy link

How to use these files in our code.
Regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment