使用 AngularJS/jQuery 为 SharePoint 2013 开发自定义日期选择器、人员选择器和选择(菜单选择)





5.00/5 (7投票s)
使用 AngularJs/jQuery 为 SharePoint 2013 应用或内容编辑器 Web 部件创建自定义日期选择器、人员选择器和选择。
引言
当我们需要创建一个自定义表单来添加新项或编辑列表中的项时,我们可能会在一些字段上遇到困难,例如 日期
、人员
或组
以及选择
。其原因在于:用户很可能希望为这些类型的字段使用日期选择器、人员选择器和下拉列表、单选按钮或复选框。我们不能强制用户在文本输入框中输入这些字段的精确值,然后保存。如果我们这样做,那将非常糟糕,我猜想。因此,本文的目的是:如何创建这些控件以改善我们用户的用户体验。
初始设置
在我们深入本文之前,需要具备以下知识。
- AngularJs
- jQuery
- SharePoint 2013 REST API to List (SharePoint 2013 REST API 与列表)
- SharePoint 2013 和 AngularJs
出于演示目的,我假设我们有一个名为 Task
的列表,其中包含以下字段
标题 | 单行文本 |
DueDate (到期日期) | 日期和时间 |
AssignedTo (指派给) | People or Group (人员或组) |
状态 | 选择 |
为了测试,请在 Status
(状态) 字段中输入一些值,例如 Running
(运行中)、Closed
(已关闭) 等。现在,我们需要下载一些库,例如
- jQuery(从官方网站或 nuget 下载)
- AngularJs(从官方网站或 nuget 下载)
- jQuey UI(从官方网站或 nuget 下载)
- ui-date 指令(如果您想使用 AngularJs 开发日期选择器,它将很有帮助)
- ngTagsInput(如果您想使用 AngularJs 开发人员选择器,它将很有帮助)
- bootstrap-tagsinput(如果您想使用 jQuery 开发日期选择器,它将很有帮助)
为了对所有内容进行样式设置,bootstrap 是一个不错的选择。我在这里不展示创建应用或内容编辑器 Web 部件的步骤,但在附件中您会找到一个使用 AngularJs 的 SharePoint 托管应用。在本文中,我将只讨论方法。因此,在创建这些控件之前,请将上述库添加到您的项目中。
选择
要创建选择输入字段,首先,我们必须获取选择字段的值。
var choiceFieldEndPoint = "/_api/web/lists/GetByTitle('List Name')/
fields?$filter=EntityPropertyName eq 'Name of the Choice field'"
如果您向上述 URL 发送一个 get
请求,它将返回 Choice
字段的所有值。在 AngularJs 中,您可以这样编写 HTML
<select class="form-control"
data-ng-model="vm.newTask.status"
data-ng-options="status as status for status in vm.newTask.taskStatusOptions">
</select>
现在,在控制器中,从您的服务中获取 Choice
字段的值,并将其绑定到 vm.newTask.taskStatusOptions
。
demoAppSvc.getTaskStatusOptions()
.then(function (response) {
vm.newTask.taskStatusOptions = response.d.results[0].Choices.results;
});
如果您的 Choice
字段允许多选,则创建复选框组,如下所示
<label ng-repeat="status in vm.newTask.taskStatusOptions">
<input type="checkbox"
value="{{status}}"
ng-checked="vm.selectedOptions.indexOf(status) > -1"
ng-click="vm.toggleSelection(status)"> {{status}}
</label>
在控制器中,添加以下代码使其正常工作
vm.selectedOptions = [];
vm.toggleSelection = function toggleSelection(status) {
var index = vm.selectedOptions.indexOf(status);
if (index > -1) {
vm.selectedOptions.splice(index, 1);
} else {
vm.selectedOptions.push(status);
}
};
当您将值保存到 Choice
字段时,如果您的 Choice
字段不允许多选,请编写以下代码。
function saveTask(task) {
var data = {
__metadata: {
'type': 'SP.Data.TaskListItem'
},
Status: task.status //It's a string
};
var url = "/_api/web/lists/GetByTitle('Task')/Items";
return baseSvc.postRequest(data, url);
}
如果 Choice
字段允许多选,那么您必须传递一个 string
数组。
function saveTask(task) {
var data = {
__metadata: {
'type': 'SP.Data.TaskListItem'
},
Status: {
results: task.selectedOptions //It's an array
}
};
var url = "/_api/web/lists/GetByTitle('Task')/Items";
return baseSvc.postRequest(data, url);
}
我在这里不展示 baseSvc.postRequest
的创建方法。我之前写过另外两篇文章,分别使用 jQuery 和 AngularJs 进行了介绍。
我们如何使用 jQuery 来实现这一点,让我们在实践中看看。
<select id="task-status"></select>
现在,通过 Ajax 请求获取 Choice
值,并像下面这样填充下拉列表
function createStatusOptions() {
$.ajax({
url: _spPageContextInfo.siteAbsoluteUrl + choiceFieldEndPoint,
type: "GET",
headers: {
"accept": "application/json;odata=verbose",
},
success: function(response) {
var statusOptions = response.d.results[0].Choices.results
var status = $('#task-status');
$.each(statusOptions, function(index, value) {
status.append($("<option>").attr('value', index).text(value));
});
},
error: function(error) {
alert(JSON.stringify(error));
}
});
}
如果您的 choice
字段允许多选,那么使用 jQuery 创建一个 checkbox
组而不是 select
,这正是我在上面使用 AngularJs 所做的。
日期和时间选择器
在 SharePoint 中,我们可以使用 jQuery UI 日期选择器。它在 AngularJs 中也有相同的版本。让我们从 AngularJs 开始。基本上,我推荐 这个。在使用之前,请阅读文档。
<input class="form-control" data-ui-date="vm.dateOptions" data-ng-model="vm.newTask.dueDate" />
这里使用了 ui-date
指令。您必须像下面这样向它传递日期选项
vm.dateOptions = {
changeYear: true,
changeMonth: true,
yearRange: '1900:-0'
};
为了将此值保存到 Date
和 Time
字段,您必须将其转换为 ISOString
。
function saveTask(task) {
var data = {
__metadata: {
'type': 'SP.Data.TaskListItem'
},
Status: task.status,
DueDate: new Date(task.dueDate).toISOString()
};
var url = "/_api/web/lists/GetByTitle('Task')/Items";
return baseSvc.postRequest(data, url);
}
对于 jQuery,以下代码演示了 HTML 和 jQuery 代码
<input type="text" id="due-date">
$(function() {
$("#datepicker").datepicker({
changeYear: true,
changeMonth: true,
yearRange: '1900:-0'
});
});
您可以添加更多此处 可用 的选项。
人员或组选择器
对于这个控件,我搜索了很多,因为我们知道它是一个非常复杂的控件。我们需要在输入字段中键入时显示建议,然后从输入字段中删除用户等等。最后,我设法找到了 这个 和 这个。基本上,这个指令允许我们在输入字段中添加标签,它在键入时还会显示建议。我试图将其制作成一个人员或组选择器。让我们一步一步地从 AngularJs 开始。第一步应该是输入时获得建议。我们可以从以下三个端点获取建议。
var userSearchSuggestionEndpoint = "/_api/web/siteusers?$select=Id,
Title&$filter=substringof('some character', Title)";
您可以通过上述 URL 获取搜索建议,这非常好。但是有一个问题:搜索是区分大小写的。我的意思是,如果您搜索“Mo
”,它将返回 Title
中包含“Mo
”的结果,而不会返回那些包含“mo
”的结果。
var userSearchSuggestionEndpoint =
"/_api/SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser";
上述端点非常强大。它可以搜索所有目录中的用户。我们可以通过 POST
请求向其发送建议。
var data = {
queryParams: {
__metadata: {
type: 'SP.UI.ApplicationPages.ClientPeoplePickerQueryParameters'
},
AllowEmailAddresses: true,
AllowMultipleEntities: false,
AllUrlZones: false,
MaximumEntitySuggestions: 50,
PrincipalSource: 15,
PrincipalType: 15,
QueryString: "Your search string"
Required: false,
SharePointGroupID: null,
UrlZone: null,
UrlZoneSpecified: false,
Web: null,
WebApplicationID: null
}
}
在 MSDN 中了解更多关于 SP.UI.ApplicationPages.ClientPeoplePickerQueryParameters
的信息。
它还有一个问题,那就是它不会在响应中返回 People or Group Id
(人员或组 ID)。保存值到 People or Group
字段时需要 Id
。但它在响应中返回 LoginName
作为键,我们可以从 LoginName
中获取 Id
。请参见 此处。
现在我找到的最后一个端点似乎很有帮助。它没有区分大小写或 LoginName
的问题。它为我们提供了创建人员或组选择器所需的一切。
function getPeoplePickerSuggestion(searchKey) {
var userSearchSuggestionEndpoint = "/_vti_bin/ListData.svc/UserInformationList?
$select=Id,Name&$filter=substringof('" + searchKey + "',Name)";
return baseSvc.getRequest(userSearchSuggestionEndpoint);
}
现在看看我从 这里 使用的指令。请阅读文档以获得更多自定义选项。
<tags-input ng-model="vm.newTask.assignedUsers"
display-property="Name"
placeholder="Pick User"
add-from-autocomplete-only="true"
replace-spaces-with-dashes="false">
<auto-complete source="vm.getPeoplePickerSuggestion($query)"></auto-complete>
</tags-input>
基本上,您必须将一个数组作为 ng-model
传递,该数组将负责所有选中的用户,还有一个函数返回延迟的建议结果。请参阅我的控制器代码。
vm.newTask = {
assignedUsers: []
};
vm.getPeoplePickerSuggestion = function(searchString) {
return demoAppSvc.getPeoplePickerSuggestion(searchString)
.then(function(response) {
var results = response.d.results;
return results.filter(function(user) {
return user.Name.toLowerCase().indexOf(searchString.toLowerCase()) != -1;
});
});
};
如果您的 People or Group
字段不允许多选,那么您的代码应该如下所示
function saveTask(task) {
var data = {
__metadata: {
'type': 'SP.Data.TaskListItem'
},
Title: task.title,
DueDate: new Date(task.dueDate).toISOString(),
Status: task.status,
AssignedToId: 'Id of the selected user'
};
var url = "/_api/web/lists/GetByTitle('Task')/Items";
return baseSvc.postRequest(data, url);
}
以下是多选的。您需要传递一个整数数组而不是单个整数。
function saveTask(task) {
var data = {
__metadata: {
'type': 'SP.Data.TaskListItem'
},
Title: task.title,
DueDate: new Date(task.dueDate).toISOString(),
Status: task.status,
AssignedToId: {
results: [] // construct a array of user Id from selected users or groups
}
};
var url = "/_api/web/lists/GetByTitle('Task')/Items";
return baseSvc.postRequest(data, url);
}
对于 jQuery 版本,首先请查看 此 文档,并以您自己的方式实现。
<input type="text" id="people-picker" />
$('#people-picker').tagsinput({
itemValue: 'Id',
itemText: 'Name',
typeaheadjs: {
name: 'users',
displayKey: 'Name',
source: getPeoplePickerSuggestion() // this function returns user or group suggestions
}
});
结论
在整篇文章中,我给了您高层次的想法。因此,也请下载我的源代码并开始深入研究。别忘了将库引用添加到您的项目中。否则,它将无法工作。