PeoplePicker web part on SharePoint Framework using Angular JS

Привет всем.

Сегодня хотел поделиться информацией как можно создать аналог PeoplePicker для SharePoint в собственной веб части используя SharePoint Framework с Angular JS.

Screen Shot 2016-10-12 at 8.57.23 AM

Для начала необходимо настроить вам все необходимые для этого инструменты, я описавал это в статье.

После этого необходимо воспользоваться SharePoint REST API для получения всех пользователей сайта. (https://site/_api/web/siteusers)

Очень хороший инструмент для работы с JSON - плагин JaSON для Chrome браузера.

Screen Shot 2016-10-12 at 9.05.00 AM

Далее, что нам необходимо сделать это создать метод для вызова и получения пользователей.

private _getSPListDataUsers(): Promise<ISPLists> {

return this.context.httpClient.get(this.context.pageContext.web.absoluteUrl + "/_api/web/siteusers")
.then((response: Response) => {
return response.json();
});
}

После этого нам необходимо преобразовать это правильный формат для дальнейшего вывода.

angular
.module('SedIncomeModule', ['ngMaterial'])
.controller('IncomeCtrl', ['$scope', function ($scope, $timeout, $q) {
$scope = this;

$scope.readonly = false;
$scope.selectedItemUsers = null;
$scope.searchTextUsers = null;
$scope.querySearchUsers = querySearchUsers;
$scope.users = loadUsers();
$scope.selectedUsers = [];
$scope.autocompleteRequireMatch = true;
$scope.transformChip = transformChip;

unction transformChip(chip) {
// If it is an object, it's already a known chip
if (angular.isObject(chip)) {
return chip;
}
}

function querySearchUsers (query) {
var results = query ? $scope.users.filter(createFilterFor(query)) : [];
return results;
}

function loadUsers() {
var allusers = usersItems;

return allusers.map( function (result) {
result.Title = result.Title.toLowerCase();
result.Id = result.Id;
return result;
});
}

function createFilterFor(query) {
var lowercaseQuery = angular.lowercase(query);

return function filterFn(result) {
return (result.Title.indexOf(lowercaseQuery) === 0);
};

}
}]);
// HTML разметка
this.domElement.innerHTML = require('./Layouts/IncomeTemplate.html');
angular.bootstrap(this.domElement, ['SedIncomeModule']);
}

Осталось за малым, нам необходимо вывести это в веб часть, используя компонент от Angular JS Material Chips https://material.angularjs.org/latest/api/directive/mdChips.

<html>
<head>
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
<link rel="stylesheet" href="/node_modules/angular-material/angular-material.css">
</head>
<body ng-app="SedIncomeModule">
<div ng-controller="IncomeCtrl as ctrl" layout="column" ng-cloak>
<md-content class="md-padding">
<form ng-submit="$event.preventDefault()">

<md-input-container class="md-block">
<label>Безпосередні виконавці</label></br>
</md-input-container>
<md-chips ng-model="ctrl.selectedUsers" md-autocomplete-snap
md-transform-chip="ctrl.transformChip($chip)"
md-require-match="ctrl.autocompleteRequireMatch">
<md-autocomplete
md-selected-item="ctrl.selectedItemUsers"
md-search-text="ctrl.searchTextUsers"
md-items="item in ctrl.querySearchUsers(ctrl.searchTextUsers)"
md-item-text="item.Title"
placeholder="Знайти">
<span md-highlight-text="ctrl.searchTextUsers">{{item.Title}} :: {{item.Id}}</span>
</md-autocomplete>
<md-chip-template>
<span>
<strong>{{$chip.Title}}</strong>
<em>({{$chip.Id}})</em>
</span>
</md-chip-template>
</md-chips>
</form>
</md-content>
</div>
</body>
</html>

Вот и все.