如何用JavaScript将人员选择器DisplayText插入‘人员或组’列?
首先得说,你当前的getUserInfo函数返回的是拼接成字符串的用户信息,这对插入SharePoint人员列没啥用——因为SP的「人员或组」列需要的是结构化的用户实体数据(比如用户ID、登录名或者邮箱对应的用户对象),不是纯文本。所以先调整这个函数,让它返回包含关键信息的用户对象数组:
function getUserInfo(PeoplepickerId) { var peoplePicker = this.SPClientPeoplePicker.SPClientPeoplePickerDict[PeoplepickerId + "_TopSpan"]; if (peoplePicker.HasInputError) return []; // 有错误返回空数组 else if (!peoplePicker.HasResolvedUsers()) return []; // 未解析出有效用户返回空数组 else if (peoplePicker.TotalUserCount > 0) { // 映射出包含关键信息的用户对象数组 return peoplePicker.GetAllUserInfo().map(user => ({ displayText: user.DisplayText, email: user.EntityData.Email, loginName: user.EntityData.LoginName // 这个是SP识别用户的关键,格式一般是i:0#.f|membership|xxx@domain.com })); } return []; }
接下来分两种最常用的前端实现方式给你讲解:
方式一:使用SharePoint JSOM(JavaScript对象模型)
JSOM是SP原生的前端操作API,兼容性好,适合在SP页面内使用。核心思路是:先通过用户的登录名获取SP用户实体,再转换成SP.FieldUserValue对象,最后赋值给列表项的人员列。
function addListItemWithPeopleField(listTitle, peopleFieldInternalName, selectedUsers) { // 获取当前站点上下文 var context = new SP.ClientContext.get_current(); var web = context.get_web(); var targetList = web.get_lists().getByTitle(listTitle); // 先批量获取每个选中用户的SP用户对象,转换成FieldUserValue var userValuePromises = selectedUsers.map(user => { // 通过登录名确保用户存在于当前站点 return web.ensureUser(user.loginName).then(spUser => { return new SP.FieldUserValue.fromUser(spUser.get_id()); }); }); // 等待所有用户处理完成后,创建列表项 Promise.all(userValuePromises).then(userValues => { var itemCreateInfo = new SP.ListItemCreationInformation(); var newListItem = targetList.addItem(itemCreateInfo); // 给人员列赋值:如果是多值人员列,直接传数组;单值列传数组第一个元素 newListItem.set_item(peopleFieldInternalName, userValues.length > 1 ? userValues : userValues[0]); newListItem.update(); // 执行请求 context.executeQueryAsync( () => console.log("列表项添加成功!"), (sender, args) => console.error("添加失败: " + args.get_message()) ); }).catch(err => console.error("处理用户信息失败: " + err)); } // 使用示例:替换成你的人员选择器ID、列表名称、人员列内部名称 var selectedUsers = getUserInfo("YourPeoplePickerId"); if (selectedUsers.length > 0) { addListItemWithPeopleField("你的目标列表名称", "PeopleFieldInternalName", selectedUsers); }
方式二:使用SharePoint REST API
REST API更灵活,适合现代前端项目(比如SPFx),核心是构造符合SP要求的JSON payload,通过POST请求提交到列表API端点。
function addListItemWithPeopleFieldREST(listTitle, peopleFieldInternalName, selectedUsers) { var siteUrl = _spPageContextInfo.webAbsoluteUrl; var apiEndpoint = `${siteUrl}/_api/web/lists/getbytitle('${listTitle}')/items`; // 构造人员列需要的格式:每个用户对应SP.FieldUserValue对象 var peopleFieldValues = selectedUsers.map(user => ({ "__metadata": { "type": "SP.FieldUserValue" }, "Email": user.email // 也可以用LoginName或者Id,优先用Email或LoginName })); // 构造请求的payload:注意列表项的类型是SP.Data.xxxListItem,xxx是列表名称去掉空格 var payload = { "__metadata": { "type": `SP.Data.${listTitle.replace(/\s/g, "")}ListItem` }, }; // 给人员列赋值:多值列传数组,单值列传单个对象 payload[peopleFieldInternalName] = peopleFieldValues.length > 1 ? peopleFieldValues : peopleFieldValues[0]; // 发送POST请求 fetch(apiEndpoint, { method: "POST", headers: { "Accept": "application/json;odata=verbose", "Content-Type": "application/json;odata=verbose", "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value // 页面自带的请求验证值 }, body: JSON.stringify(payload) }) .then(response => { if (!response.ok) throw new Error(`请求失败:${response.statusText}`); return response.json(); }) .then(data => console.log("列表项添加成功!", data)) .catch(err => console.error("添加失败: ", err)); } // 使用示例 var selectedUsers = getUserInfo("YourPeoplePickerId"); if (selectedUsers.length > 0) { addListItemWithPeopleFieldREST("你的目标列表名称", "PeopleFieldInternalName", selectedUsers); }
关键注意事项
- 人员列的内部名称:一定要用列的内部名称,不是显示名称!可以在列表设置→列设置里查看,或者通过REST API
/_api/web/lists/getbytitle('列表名')/fields获取列的InternalName属性。 - JSOM依赖:如果用JSOM,确保页面已经加载了SP的核心脚本:
<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script> <script type="text/javascript" src="/_layouts/15/sp.js"></script> - 权限:当前用户需要有目标列表的添加权限,否则会报错。
内容的提问来源于stack exchange,提问作者Kuldeep
相关产品推荐
相关产品推荐

