This repository has been archived by the owner on Jun 14, 2018. It is now read-only.
Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
ng-officeuifabric/src/components/peoplepicker/peoplePickerDirective.ts /
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1265 lines (1117 sloc)
44.4 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import * as angular from 'angular'; | |
| import { PersonaStyleEnum } from '../../core/personaStyleEnum'; | |
| import { PersonaSize } from '../persona/sizeEnum'; | |
| import { IPerson } from '../../core/person'; | |
| import { IconEnum } from '../icon/iconEnum'; | |
| let peopleSearchEventName: string = 'uif-people-search'; | |
| /** | |
| * @ngdoc interface | |
| * @name IPersonPicker | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @description | |
| * Helper interface used by the people picker directive. | |
| * | |
| * @property {interface} group - Reference to person's group | |
| * @property {Array of IPersonPicker} additionalData - Additional persons to populate under current person | |
| */ | |
| export interface IPersonPicker extends IPerson { | |
| group: IGroup; | |
| additionalData: IPersonPicker[]; | |
| } | |
| /** | |
| * @ngdoc interface | |
| * @name IGroup | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @description | |
| * Helper interface used by the people picker directive. | |
| * | |
| * @property {string} name - Reference to person's group | |
| * @property {number} order - Group order, used when displaying search result with groups | |
| */ | |
| export interface IGroup { | |
| name: string; | |
| order: number; | |
| } | |
| /** | |
| * @ngdoc class | |
| * @name GroupedPeopleData | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @description | |
| * Helper class used by the people picker directive. | |
| * | |
| * @property {interface} group - Group reference | |
| * @property {Array of IPersonPicker} people - Persons who belongs to this particular group | |
| */ | |
| export class GroupedPeopleData { | |
| public group: IGroup; | |
| public people: IPersonPicker[] = []; | |
| } | |
| /** | |
| * @ngdoc controller | |
| * @name PeoplePickerController | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @description | |
| * Controller used for the `<uif-people-picker>` directive. | |
| */ | |
| export class PeoplePickerController { | |
| public static $inject: string[] = ['$scope', '$filter', '$element']; | |
| constructor( | |
| private $scope: IPeoplePickerScope, | |
| private $filter: angular.IFilterService, | |
| private $element: angular.IAugmentedJQuery) { | |
| } | |
| public getSelectedPersons(): IPersonPicker[] { | |
| return this.$scope.selectedPersons; | |
| } | |
| public pickerType(): string { | |
| let type: string = this.$scope.type; | |
| if (angular.isUndefined(type)) { | |
| return PeoplePickerTypes[PeoplePickerTypes.grouped]; | |
| } | |
| return this.$scope.type; | |
| } | |
| public searchQuery(): string { | |
| return this.$scope.searchQuery; | |
| } | |
| public search(): void { | |
| this.bindPeople(this.$scope.searchQuery); | |
| this.$scope.$broadcast(peopleSearchEventName, this.searchQuery()); | |
| } | |
| public bindPeople(query?: string): void { | |
| let peopleData: IPersonPicker[] | angular.IPromise<IPersonPicker[]> = this.$scope.peopleCallback()(query); | |
| peopleData = peopleData || []; | |
| if (peopleData instanceof Array) { // array | |
| this.$scope.groups = this.createPeopleDataStructure(peopleData); | |
| } else if (typeof peopleData.then === 'function') { // promise, async scenario | |
| let searchMoreCtrl: PeopleSearchMoreController = angular.element(this.$element[0].querySelector('.ms-PeoplePicker-searchMore')) | |
| .controller(`${PeopleSearchMoreDirective.directiveName}`); | |
| if (searchMoreCtrl) { | |
| searchMoreCtrl.isSearching(true); | |
| } | |
| let that: PeoplePickerController = this; | |
| peopleData | |
| .then(data => { | |
| that.$scope.groups = this.createPeopleDataStructure(data); | |
| }) | |
| .finally(() => { | |
| if (searchMoreCtrl) { | |
| searchMoreCtrl.isSearching(false); | |
| } | |
| }); | |
| } | |
| } | |
| private createPeopleDataStructure(people: IPersonPicker[]): GroupedPeopleData[] { | |
| let peopleData: GroupedPeopleData[] = []; | |
| angular.forEach(people, (person: IPersonPicker) => { | |
| let existingGroups: GroupedPeopleData[] = this.$filter('filter')(peopleData, { group: person.group }); | |
| let hasGroup: boolean = existingGroups.length === 1; | |
| if (!hasGroup) { | |
| let newPeopleData: GroupedPeopleData = new GroupedPeopleData(); | |
| newPeopleData.group = person.group; | |
| newPeopleData.people.push(person); | |
| peopleData.push(newPeopleData); | |
| } else { | |
| let existingData: GroupedPeopleData = existingGroups[0]; | |
| existingData.people.push(person); | |
| } | |
| }); | |
| return peopleData; | |
| } | |
| } | |
| /** | |
| * @ngdoc enum | |
| * @name PeoplePickerTypes | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @description | |
| * Determines people picker type | |
| */ | |
| enum PeoplePickerTypes { | |
| grouped = 0, | |
| compact = 1, | |
| memberList = 2, | |
| facePile = 3 | |
| } | |
| /** | |
| * @ngdoc interface | |
| * @name IPeoplePickerAttributes | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @description | |
| * Interface describing attributes for people picker directive | |
| * | |
| * @property {string} uifType - People picker type | |
| * @property {string} ngDisabled - Disabled state varible name | |
| * @property {string} uifSingle - Allow only one person to be selected | |
| */ | |
| interface IPeoplePickerAttributes extends angular.IAttributes { | |
| uifType: string; | |
| ngDisabled: string; | |
| uifSingle: string; | |
| } | |
| /** | |
| * @ngdoc interface | |
| * @name IPeoplePickerScope | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @description | |
| * Interface describing scope for people picker directive | |
| * | |
| * @property {object} ngModel - Reference to NgModelController | |
| * @property {function} peopleCallback - Function called every time when search event occur | |
| * @property {string} searchQuery - Search query typed into the search input | |
| * @property {string} placeholder - Placeholder for the search input | |
| * @property {string} type - People picker type, based on PeoplePickerTypes enum | |
| * @property {number} delay - Used by type-ahead scenario, dealy after which search query will be run | |
| * @property {object} groups - Groups used by the people picker | |
| * @property {function} onPeoplePickerActive - Reference to NgModelController | |
| * @property {function} addPersonToSelectedPeople - Function called when user click on person in search results | |
| * @property {function} removePersonFromSelectedPeople - Function called when user click on close icon under selected persons | |
| * @property {array} selectedPersons - People picker's selected persons | |
| * @property {function} removePersonFromSearchResults - Function called when user click on close icon under search results | |
| * @property {function} onSearchKeyUp - Callback for the keyup event | |
| * @property {string} facePileHeader - FacePile header, used only in face pile mode | |
| * @property {boolean} ngDisabled - Support for ng-disabled directive | |
| * @property {string} ngChange - Expression to evaluate when selectedPersons changes | |
| */ | |
| export interface IPeoplePickerScope extends angular.IScope { | |
| ngModel: angular.INgModelController; | |
| peopleCallback: () => (query: string) => IPersonPicker[] | angular.IPromise<IPersonPicker[]>; | |
| searchQuery: string; | |
| placeholder: string; | |
| type: string; | |
| delay: number; | |
| groups: GroupedPeopleData[]; | |
| onPeoplePickerActive: ($event: KeyboardEvent | MouseEvent) => void; | |
| addPersonToSelectedPeople: (person: IPersonPicker) => void; | |
| removePersonFromSelectedPeople: (person: IPersonPicker, $event: MouseEvent) => void; | |
| selectedPersons: IPersonPicker[]; | |
| removePersonFromSearchResults: (people: IPersonPicker[], person: IPersonPicker, $event: MouseEvent) => void; | |
| onSearchKeyUp: ($event: KeyboardEvent) => void; | |
| facePileHeader: string; | |
| ngDisabled: boolean; | |
| ngChange: () => () => void; | |
| } | |
| /** | |
| * @ngdoc directive | |
| * @name uifPeoplePicker | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @restrict E | |
| * | |
| * @description | |
| * `<uif-people-picker>` directive. | |
| * | |
| * @see {link http://dev.office.com/fabric/components/peoplepicker} | |
| * | |
| * @usage | |
| * | |
| * <uif-people-picker | |
| * uif-people="onSearch(query)" | |
| * ng-model="selectedPeople" | |
| * placeholder="Search for people" | |
| * uif-selected-person-click="personClicked"> | |
| * <uif-people-search-more> | |
| * <uif-secondary-text>Showing {{sourcePeople.length}} results</uif-secondary-text> | |
| * <uif-primary-text uif-search-for-text="You are searching for: ">Search organization people</uif-primary-text> | |
| * </uif-people-search-more> | |
| * </uif-people-picker> | |
| */ | |
| export class PeoplePickerDirective implements angular.IDirective { | |
| public static directiveName: string = 'uifPeoplePicker'; | |
| public replace: boolean = true; | |
| public require: string[] = ['ngModel', `${PeoplePickerDirective.directiveName}`]; | |
| public restrict: string = 'E'; | |
| public transclude: boolean = true; | |
| public controller: any = PeoplePickerController; | |
| public scope: {} = { | |
| delay: '@uifSearchDelay', | |
| facePileHeader: '@?uifFacepileHeader', | |
| ngChange: '&?', | |
| ngDisabled: '=?', | |
| ngModel: '=', | |
| onSelectedPersonClick: '&?uifSelectedPersonClick', | |
| peopleCallback: '&uifPeople', | |
| placeholder: '@?', | |
| type: '@?uifType' | |
| }; | |
| private templateTypes: { [peoplePickerType: number]: string } = {}; | |
| public static factory(): angular.IDirectiveFactory { | |
| const directive: angular.IDirectiveFactory = ( | |
| $document: angular.IDocumentService, $timeout: angular.ITimeoutService, $log: angular.ILogService, $window: angular.IWindowService) => | |
| new PeoplePickerDirective($document, $timeout, $log, $window); | |
| directive.$inject = ['$document', '$timeout', '$log', '$window']; | |
| return directive; | |
| } | |
| constructor( | |
| private $document: angular.IDocumentService, | |
| private $timeout: angular.ITimeoutService, | |
| private $log: angular.ILogService, | |
| private $window: angular.IWindowService) { | |
| this.templateTypes[PeoplePickerTypes.grouped] = | |
| `<div class="ms-PeoplePicker"> | |
| <div class="ms-PeoplePicker-searchBox"> | |
| <div class="ms-PeoplePicker-persona" ng-repeat="person in selectedPersons track by $index"> | |
| <uif-persona ng-click="onSelectedPersonClick()(person)" | |
| uif-style="${PersonaStyleEnum[PersonaStyleEnum.square]}" | |
| uif-size="${PersonaSize[PersonaSize.xsmall]}" | |
| uif-presence="{{person.presence}}" | |
| uif-image-url="{{person.icon}}"> | |
| <uif-persona-initials uif-color="{{person.color}}">{{person.initials}}</uif-persona-initials> | |
| <uif-persona-primary-text>{{person.primaryText}}</uif-persona-primary-text> | |
| </uif-persona> | |
| <button | |
| ng-if="!ngDisabled" | |
| type="button" | |
| ng-click="removePersonFromSelectedPeople(person, $event)" | |
| class="ms-PeoplePicker-personaRemove"> | |
| <uif-icon uif-type="${IconEnum[IconEnum.x]}"></uif-icon> | |
| </button> | |
| </div> | |
| <input ng-click="onPeoplePickerActive($event)" | |
| placeholder="{{placeholder}}" | |
| ng-model="searchQuery" | |
| class="ms-PeoplePicker-searchField" | |
| ng-focus="onPeoplePickerActive($event)" | |
| ng-keyup="onSearchKeyUp($event)" | |
| type="text"> | |
| </div> | |
| <div class="ms-PeoplePicker-results"> | |
| <div class="ms-PeoplePicker-resultGroups"> | |
| <div class="ms-PeoplePicker-resultGroup" ng-repeat="groupData in groups | orderBy:'-order'"> | |
| <div class="ms-PeoplePicker-resultGroupTitle">{{groupData.group.name}}</div> | |
| <uif-people-picker-result-list | |
| ng-model="groupData.people" | |
| uif-person-click="addPersonToSelectedPeople" | |
| uif-person-close-click="removePersonFromSearchResults" | |
| uif-style="${PersonaStyleEnum[PersonaStyleEnum.square]}" | |
| uif-size="${PersonaSize[PersonaSize.medium]}"></uif-people-picker-result-list> | |
| </div> | |
| </div> | |
| <ng-transclude /> | |
| </div> | |
| </div>`; | |
| this.templateTypes[PeoplePickerTypes.compact] = | |
| `<div class="ms-PeoplePicker ms-PeoplePicker--compact"> | |
| <div class="ms-PeoplePicker-searchBox"> | |
| <div class="ms-PeoplePicker-persona" ng-repeat="person in selectedPersons track by $index"> | |
| <uif-persona ng-click="onSelectedPersonClick()(person)" | |
| uif-style="${PersonaStyleEnum[PersonaStyleEnum.square]}" | |
| uif-size="${PersonaSize[PersonaSize.xsmall]}" | |
| uif-presence="{{person.presence}}" | |
| uif-image-url="{{person.icon}}"> | |
| <uif-persona-initials uif-color="{{person.color}}">{{person.initials}}</uif-persona-initials> | |
| <uif-persona-primary-text>{{person.primaryText}}</uif-persona-primary-text> | |
| </uif-persona> | |
| <button | |
| ng-if="!ngDisabled" | |
| type="button" | |
| ng-click="removePersonFromSelectedPeople(person, $event)" | |
| class="ms-PeoplePicker-personaRemove"> | |
| <uif-icon uif-type="${IconEnum[IconEnum.x]}"></uif-icon> | |
| </button> | |
| </div> | |
| <input ng-click="onPeoplePickerActive($event)" | |
| ng-model="searchQuery" | |
| placeholder="{{placeholder}}" | |
| class="ms-PeoplePicker-searchField" | |
| ng-focus="onPeoplePickerActive($event)" | |
| ng-keyup="onSearchKeyUp($event)" | |
| type="text"> | |
| </div> | |
| <div class="ms-PeoplePicker-results"> | |
| <div class="ms-PeoplePicker-resultGroups"> | |
| <div class="ms-PeoplePicker-resultGroup" ng-repeat="groupData in groups | orderBy:'-order'"> | |
| <div class="ms-PeoplePicker-resultGroupTitle">{{groupData.group.name}}</div> | |
| <uif-people-picker-result-list | |
| ng-model="groupData.people" | |
| uif-picker-type="${PeoplePickerTypes[PeoplePickerTypes.compact]}" | |
| uif-person-click="addPersonToSelectedPeople" | |
| uif-person-close-click="removePersonFromSearchResults" | |
| uif-style="${PersonaStyleEnum[PersonaStyleEnum.square]}" | |
| uif-size="${PersonaSize[PersonaSize.xsmall]}"></uif-people-picker-result-list> | |
| </div> | |
| </div> | |
| <ng-transclude /> | |
| </div> | |
| </div>`; | |
| this.templateTypes[PeoplePickerTypes.memberList] = ` | |
| <div class="ms-PeoplePicker ms-PeoplePicker--membersList"> | |
| <div class="ms-PeoplePicker-searchBox"> | |
| <input ng-click="onPeoplePickerActive($event)" | |
| placeholder="{{placeholder}}" | |
| ng-model="searchQuery" | |
| class="ms-PeoplePicker-searchField" | |
| ng-focus="onPeoplePickerActive($event)" | |
| ng-keyup="onSearchKeyUp($event)" | |
| type="text"> | |
| </div> | |
| <div class="ms-PeoplePicker-results"> | |
| <div class="ms-PeoplePicker-resultGroups"> | |
| <div class="ms-PeoplePicker-resultGroup" ng-repeat="groupData in groups | orderBy:'-order'"> | |
| <uif-people-picker-result-list | |
| ng-model="groupData.people" | |
| uif-person-click="addPersonToSelectedPeople" | |
| uif-style="${PersonaStyleEnum[PersonaStyleEnum.round]}" | |
| uif-size="${PersonaSize[PersonaSize.medium]}"></uif-people-picker-result-list> | |
| </div> | |
| </div> | |
| </div> | |
| <uif-people-picker-selected ng-model="selectedPersons" | |
| uif-selected-person-click="onSelectedPersonClick()" | |
| uif-person-close="removePersonFromSelectedPeople"> | |
| <ng-transclude></ng-transclude> | |
| </uif-people-picker-selected> | |
| </div>`; | |
| this.templateTypes[PeoplePickerTypes.facePile] = ` | |
| <div class="ms-PeoplePicker ms-PeoplePicker--Facepile"> | |
| <div class="ms-PeoplePicker-searchBox"> | |
| <input ng-click="onPeoplePickerActive($event)" | |
| placeholder="{{placeholder}}" | |
| ng-model="searchQuery" | |
| class="ms-PeoplePicker-searchField" | |
| ng-focus="onPeoplePickerActive($event)" | |
| ng-keyup="onSearchKeyUp($event)" | |
| type="text"> | |
| </div> | |
| <div class="ms-PeoplePicker-results"> | |
| <div class="ms-PeoplePicker-peopleListHeader"> | |
| <span>{{facePileHeader}}</span> | |
| </div> | |
| <div ng-repeat="groupData in groups | orderBy:'-order'"> | |
| <uif-people-picker-result-list | |
| ng-model="groupData.people" | |
| uif-person-click="addPersonToSelectedPeople" | |
| uif-style="${PersonaStyleEnum[PersonaStyleEnum.round]}" | |
| uif-size="${PersonaSize[PersonaSize.small]}"></uif-people-picker-result-list> | |
| </div> | |
| <div class="uif-search-more"></div> | |
| </div> | |
| <uif-people-picker-selected ng-model="selectedPersons" | |
| uif-selected-person-click="onSelectedPersonClick()" | |
| uif-person-close="removePersonFromSelectedPeople"> | |
| <div class="uif-people-header"></div> | |
| </uif-people-picker-selected> | |
| </div>`; | |
| } | |
| public template: any = ($element: angular.IAugmentedJQuery, $attrs: IPeoplePickerAttributes) => { | |
| let type: string = $attrs.uifType; | |
| if (angular.isUndefined(type)) { | |
| return this.templateTypes[PeoplePickerTypes.grouped]; | |
| } | |
| if (PeoplePickerTypes[type] === undefined) { | |
| this.$log.error('Error [ngOfficeUiFabric] officeuifabric.components.peoplepicker - unsupported people picker type:\n' + | |
| 'the type \'' + type + '\' is not supported by ng-Office UI Fabric as valid type for people picker.' + | |
| 'Supported types can be found under PeoplePickerTypes enum here:\n' + | |
| 'https://github.com/ngOfficeUIFabric/ng-officeuifabric/blob/master/src/components/peoplepicker/peoplePickerDirective.ts'); | |
| throw '[ngOfficeUiFabric] - Error'; | |
| } | |
| return this.templateTypes[PeoplePickerTypes[type]]; | |
| } | |
| public link: angular.IDirectiveLinkFn = ( | |
| $scope: IPeoplePickerScope, | |
| $element: angular.IAugmentedJQuery, | |
| $attrs: IPeoplePickerAttributes, | |
| ctrls: [angular.INgModelController, PeoplePickerController], | |
| $transclude: angular.ITranscludeFunction): void => { | |
| let ngModelCtrl: angular.INgModelController = ctrls[0]; | |
| let peoplePickerCtrl: PeoplePickerController = ctrls[1]; | |
| this.initDisabledState($element, $scope, $attrs); | |
| $scope.facePileHeader = $scope.facePileHeader || 'Suggested contacts'; | |
| $scope.$watchCollection('selectedPersons', (data: any, data2: any, data3: any) => { | |
| this.resizeSearchField($element); | |
| if ($scope.ngChange) { | |
| $scope.ngChange(); | |
| } | |
| }); | |
| ngModelCtrl.$render = () => { | |
| if (ngModelCtrl.$viewValue) { | |
| $scope.selectedPersons = ngModelCtrl.$viewValue; | |
| } else { | |
| $scope.selectedPersons = []; | |
| } | |
| this.resizeSearchField($element); | |
| }; | |
| peoplePickerCtrl.search(); | |
| let searchTimeout: angular.IPromise<void> = null; | |
| $scope.onSearchKeyUp = ($event: KeyboardEvent) => { | |
| let $searchMore: JQuery = angular.element($element[0].querySelector('.ms-PeoplePicker-searchMore')); | |
| if ($searchMore.length !== 0) { | |
| $scope.searchQuery ? $element.addClass('is-searching') : $element.removeClass('is-searching'); | |
| $scope.searchQuery ? $searchMore.addClass('is-active') : $searchMore.removeClass('is-active'); | |
| this.animateSelectedPeople($element); | |
| } | |
| if (!$scope.delay) { | |
| return; | |
| } | |
| if (searchTimeout != null) { | |
| this.$timeout.cancel(searchTimeout); | |
| } | |
| searchTimeout = this.$timeout( | |
| () => { | |
| peoplePickerCtrl.search(); | |
| }, | |
| $scope.delay); | |
| }; | |
| $scope.onPeoplePickerActive = ($event: KeyboardEvent | MouseEvent) => { | |
| this.smoothScrollTo($element[0]); | |
| if ($scope.type !== PeoplePickerTypes[PeoplePickerTypes.facePile]) { | |
| let $results: JQuery = angular.element($element[0].querySelector('.ms-PeoplePicker-results')); | |
| $results[0].style.width = $element[0].clientWidth - 2 + 'px'; | |
| } else if ($scope.type === PeoplePickerTypes[PeoplePickerTypes.facePile]) { | |
| this.animateSelectedPeople($element); | |
| } | |
| $event.stopPropagation(); | |
| $element.addClass('is-active'); | |
| }; | |
| $scope.addPersonToSelectedPeople = (person) => { | |
| if ($scope.selectedPersons.indexOf(person) !== -1) { | |
| return; | |
| } | |
| if (angular.isDefined($attrs.uifSingle) && $scope.selectedPersons.length > 0) { | |
| $scope.selectedPersons.length = 0; | |
| } | |
| $scope.selectedPersons.push(person); | |
| ngModelCtrl.$setViewValue($scope.selectedPersons); | |
| }; | |
| $scope.removePersonFromSelectedPeople = (person: IPersonPicker, $event: MouseEvent) => { | |
| let indx: number = $scope.selectedPersons.indexOf(person); | |
| $scope.selectedPersons.splice(indx, 1); | |
| ngModelCtrl.$setViewValue($scope.selectedPersons); | |
| $event.stopPropagation(); | |
| }; | |
| $scope.removePersonFromSearchResults = (people: IPersonPicker[], person: IPersonPicker, $event: MouseEvent) => { | |
| $event.stopPropagation(); | |
| let indx: number = people.indexOf(person); | |
| people.splice(indx, 1); | |
| }; | |
| this.$document.on('click', () => { | |
| $element.removeClass('is-active'); | |
| }); | |
| if ($scope.type === PeoplePickerTypes[PeoplePickerTypes.facePile]) { | |
| $transclude((clone: angular.IAugmentedJQuery) => { | |
| this.insertFacePileHeader(clone, $scope, $element); | |
| this.insertFacePileSearchMore(clone, $scope, $element); | |
| }); | |
| } | |
| } | |
| private initDisabledState($element: JQuery, $scope: IPeoplePickerScope, $attrs: IPeoplePickerAttributes): void { | |
| let $searchField: JQuery = angular.element($element[0].querySelector('.ms-PeoplePicker-searchField')); | |
| $attrs.$observe('disabled', (disabled) => { | |
| if (disabled) { | |
| $searchField.attr('disabled', 'disabled'); | |
| } else { | |
| $searchField.removeAttr('disabled'); | |
| } | |
| }); | |
| } | |
| private animateSelectedPeople($element: JQuery): void { | |
| let $selectedPeople: JQuery = angular.element($element[0].querySelector('.ms-PeoplePicker-selectedPeople')); | |
| $selectedPeople.addClass('ms-u-slideDownIn20'); | |
| setTimeout(() => { $selectedPeople.removeClass('ms-u-slideDownIn20'); }, 1000); | |
| } | |
| private currentYPosition(): number { | |
| if (this.$window.pageYOffset) { | |
| return this.$window.pageYOffset; | |
| } | |
| let body: HTMLElement = angular.element(this.$document[0]).find('body')[0]; | |
| if (body.scrollTop) { | |
| return body.scrollTop; | |
| } | |
| return 0; | |
| } | |
| private elmYPosition(element: HTMLElement): number { | |
| let y: number = element.offsetTop; | |
| let node: any = element; | |
| while (node.offsetParent && node.offsetParent !== document.body) { | |
| node = <Element>(node.offsetParent); | |
| y += node.offsetTop; | |
| } | |
| return y; | |
| } | |
| private smoothScrollTo(element: HTMLElement): void { | |
| let startY: number = this.currentYPosition(); | |
| let stopY: number = this.elmYPosition(element); | |
| let distance: number = stopY > startY ? stopY - startY : startY - stopY; | |
| if (distance < 100) { | |
| window.scrollTo(0, stopY); | |
| return; | |
| } | |
| let speed: number = Math.round(distance / 30); | |
| if (speed >= 20) { | |
| speed = 20; | |
| } | |
| let step: number = Math.round(distance / 25); | |
| let leapY: number = stopY > startY ? startY + step : startY - step; | |
| let timer: number = 0; | |
| if (stopY > startY) { | |
| for (let i: number = startY; i < stopY; i += step) { | |
| ((lY: number, t: number) => { | |
| setTimeout( | |
| () => { | |
| window.scrollTo(0, lY); | |
| }, | |
| t * speed); | |
| })(leapY, timer); | |
| leapY += step; | |
| if (leapY > stopY) { | |
| leapY = stopY; | |
| } | |
| timer++; | |
| } | |
| return; | |
| } | |
| for (let i: number = startY; i > stopY; i -= step) { | |
| ((lY: number, t: number) => { | |
| setTimeout( | |
| () => { | |
| window.scrollTo(0, lY); | |
| }, | |
| t * speed); | |
| })(leapY, timer); | |
| leapY -= step; | |
| if (leapY < stopY) { | |
| leapY = stopY; | |
| } | |
| timer++; | |
| } | |
| } | |
| private insertFacePileHeader(clone: angular.IAugmentedJQuery, $scope: IPeoplePickerScope, $element: angular.IAugmentedJQuery): void { | |
| let elementToReplace: JQuery = angular.element($element[0].querySelector('.uif-people-header')); | |
| for (let i: number = 0; i < clone.length; i++) { | |
| let element: angular.IAugmentedJQuery = angular.element(clone[i]); | |
| if (element.hasClass('ms-PeoplePicker-selectedCount')) { | |
| elementToReplace.replaceWith(element); | |
| break; | |
| } | |
| } | |
| } | |
| private insertFacePileSearchMore(clone: angular.IAugmentedJQuery, $scope: IPeoplePickerScope, $element: angular.IAugmentedJQuery): void { | |
| let elementToReplace: JQuery = angular.element($element[0].querySelector('.uif-search-more')); | |
| for (let i: number = 0; i < clone.length; i++) { | |
| let element: angular.IAugmentedJQuery = angular.element(clone[i]); | |
| if (element.hasClass('ms-PeoplePicker-searchMore')) { | |
| elementToReplace.replaceWith(element); | |
| break; | |
| } | |
| } | |
| } | |
| private resizeSearchField($peoplePicker: JQuery): void { | |
| let $searchBox: JQuery = angular.element($peoplePicker[0].querySelector('.ms-PeoplePicker-searchBox')); | |
| let $searchField: JQuery = angular.element($peoplePicker[0].querySelector('.ms-PeoplePicker-searchField')); | |
| let searchBoxLeftEdge: number = $searchBox.prop('offsetLeft'); | |
| let searchBoxWidth: number = $searchBox[0].clientWidth; | |
| let searchBoxRightEdge: number = searchBoxLeftEdge + searchBoxWidth; | |
| let $personaNodes: NodeListOf<Element> = $searchBox[0].querySelectorAll('.ms-PeoplePicker-persona'); | |
| if ($personaNodes.length === 0) { | |
| $searchField[0].style.width = '100%'; | |
| return; | |
| } | |
| let $lastPersona: JQuery = angular.element($personaNodes[$personaNodes.length - 1]); | |
| let lastPersonaLeftEdge: number = $lastPersona.prop('offsetLeft'); | |
| let lastPersonaWidth: number = $lastPersona[0].clientWidth; | |
| let lastPersonaRightEdge: number = lastPersonaLeftEdge + lastPersonaWidth; | |
| let newFieldWidth: number | string = searchBoxRightEdge - lastPersonaRightEdge - 5; | |
| if (newFieldWidth < 100) { | |
| newFieldWidth = '100%'; | |
| $searchField[0].style.width = '100%'; | |
| } else { | |
| $searchField[0].style.width = newFieldWidth + 'px'; | |
| } | |
| } | |
| } | |
| /** | |
| * @ngdoc interface | |
| * @name IPeoplePickerResultListScope | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @description | |
| * Interface used by the people picker result list directive. | |
| * | |
| * @property {array} people - Persons in search results | |
| * @property {function} expandAdditionalData - Callback when clicking on "expand" button under search results | |
| */ | |
| export interface IPeoplePickerResultListScope extends angular.IScope { | |
| people: IPersonPicker[]; | |
| expandAdditionalData: ($event: MouseEvent) => void; | |
| } | |
| /** | |
| * @ngdoc directive | |
| * @name uifPeoplePickerResultList | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @restrict E | |
| * | |
| * @description | |
| * `<uif-people-picker-result-list>` is a helper directive used by people picker. | |
| * | |
| * @see {link http://dev.office.com/fabric/components/peoplepicker} | |
| * | |
| * @usage | |
| * | |
| * <uif-people-picker-result-list | |
| * ng-model="groupData.people" | |
| * uif-person-click="addPersonToSelectedPeople" | |
| * uif-person-close-click="removePersonFromSearchResults" | |
| * uif-style="${PersonaStyleEnum[PersonaStyleEnum.square]}" | |
| * uif-size="${PersonaSize[PersonaSize.medium]}"> | |
| * </uif-people-picker-result-list> | |
| */ | |
| export class PeoplePickerResultListDirective implements angular.IDirective { | |
| public static directiveName: string = 'uifPeoplePickerResultList'; | |
| public replace: boolean = true; | |
| public restrict: string = 'E'; | |
| public transclude: boolean = true; | |
| public template: string = ` | |
| <ul class="ms-PeoplePicker-resultList"> | |
| <li class="ms-PeoplePicker-result" ng-repeat="person in people track by $index"> | |
| <div role="button" class="ms-PeoplePicker-resultBtn" | |
| ng-class="{'ms-PeoplePicker-resultBtn--compact': pickerType === 'compact'}" ng-click="onPersonClick()(person)"> | |
| <uif-persona | |
| uif-style="{{personStyle}}" | |
| uif-size="{{personSize}}" | |
| uif-presence="{{person.presence}}" | |
| uif-image-url="{{person.icon}}"> | |
| <uif-persona-initials uif-color="{{person.color}}">{{person.initials}}</uif-persona-initials> | |
| <uif-persona-primary-text>{{person.primaryText}}</uif-persona-primary-text> | |
| <uif-persona-secondary-text>{{person.secondaryText}}</uif-persona-secondary-text> | |
| </uif-persona> | |
| <button type="button" | |
| ng-if="!person.additionalData && onPersonCloseClick()" | |
| ng-click="onPersonCloseClick()(people, person, $event)" | |
| class="ms-PeoplePicker-resultAction js-resultRemove"> | |
| <uif-icon uif-type="${IconEnum[IconEnum.x]}"></uif-icon> | |
| </button> | |
| <button type="button" | |
| ng-if="person.additionalData" | |
| ng-click="expandAdditionalData($event)" | |
| class="ms-PeoplePicker-resultAction js-resultRemove"> | |
| <uif-icon uif-type="${IconEnum[IconEnum.chevronsDown]}"></uif-icon> | |
| </button> | |
| </div> | |
| <div ng-if="person.additionalData" class="ms-PeoplePicker-resultAdditionalContent"> | |
| <uif-people-picker-result-list | |
| ng-model="person.additionalData" | |
| uif-person-click="onPersonClick()" | |
| uif-person-close-click="onPersonCloseClick()" | |
| uif-picker-type="{{pickerType}}" | |
| uif-style="{{personStyle}}" | |
| uif-size="{{personSize}}"></uif-people-picker-result-list> | |
| </div> | |
| </li> | |
| </ul>`; | |
| public scope: {} = { | |
| onPersonClick: '&uifPersonClick', | |
| onPersonCloseClick: '&uifPersonCloseClick', | |
| people: '=ngModel', | |
| personSize: '@uifSize', | |
| personStyle: '@uifStyle', | |
| pickerType: '@uifPickerType' | |
| }; | |
| public static factory(): angular.IDirectiveFactory { | |
| const directive: angular.IDirectiveFactory = () => new PeoplePickerResultListDirective(); | |
| return directive; | |
| } | |
| constructor() { | |
| // | |
| } | |
| public link: angular.IDirectiveLinkFn = ( | |
| $scope: IPeoplePickerResultListScope, | |
| $element: angular.IAugmentedJQuery, | |
| $attrs: angular.IAttributes, | |
| peoplePickerCtrl: PeoplePickerController, | |
| $transclude: angular.ITranscludeFunction): void => { | |
| $scope.expandAdditionalData = ($event: MouseEvent) => { | |
| $event.stopPropagation(); | |
| let $button: JQuery = angular.element($event.target); | |
| for (let i: number = 0; i < 10; i++) { | |
| let $parent: JQuery = $button.parent(); | |
| if ($parent.hasClass('ms-PeoplePicker-result')) { | |
| $parent.toggleClass('is-expanded'); | |
| break; | |
| } | |
| $button = $parent; | |
| } | |
| }; | |
| } | |
| } | |
| /** | |
| * @ngdoc interface | |
| * @name IPeopleSearchMoreScope | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @description | |
| * Interface used by the scope for people search more directive. | |
| * | |
| * @property {function} onSearch - Function called when user click by "search more" component | |
| * @property {boolean} processing - Boolean indicating that search in progress (in async scenarious) | |
| * @property {string} pickerType - Determines people picker type (from parent directive people picker) | |
| * @property {boolean} disconnected - Boolean indicating disconnected scenario | |
| */ | |
| export interface IPeopleSearchMoreScope extends angular.IScope { | |
| onSearch: ($event: MouseEvent) => void; | |
| processing: boolean; | |
| pickerType: string; | |
| disconnected: boolean; | |
| } | |
| /** | |
| * @ngdoc controller | |
| * @name PeopleSearchMoreController | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @description | |
| * Controller used for the `<uif-people-search-more>` directive. | |
| */ | |
| export class PeopleSearchMoreController { | |
| public static $inject: string[] = ['$scope', '$element']; | |
| public searchCallbacks: { (): void; }[] = []; | |
| constructor( | |
| private $scope: IPeopleSearchMoreScope, | |
| private $element: angular.IAugmentedJQuery) { | |
| } | |
| public isSearching(searching: boolean): void { | |
| this.$scope.processing = searching; | |
| searching ? this.$element.addClass('is-searching') : this.$element.removeClass('is-searching'); | |
| } | |
| } | |
| export class PeopleSearchMoreDirective implements angular.IDirective { | |
| public static directiveName: string = 'uifPeopleSearchMore'; | |
| public replace: boolean = true; | |
| public restrict: string = 'E'; | |
| public transclude: boolean = true; | |
| public require: string = `^^${PeoplePickerDirective.directiveName}`; | |
| public controller: any = PeopleSearchMoreController; | |
| public template: string = ` | |
| <div class="ms-PeoplePicker-searchMore js-searchMore" | |
| ng-class="{'ms-PeoplePicker-searchMore--disconnected': disconnected}"> | |
| <button type="button" ng-if="pickerType === '${PeoplePickerTypes[PeoplePickerTypes.grouped]}' && !disconnected" | |
| ng-click="onSearch($event)" class="ms-PeoplePicker-searchMoreBtn"> | |
| <div class="ms-PeoplePicker-searchMoreIcon"> | |
| <uif-icon ng-if="!disconnected" uif-type="${IconEnum[IconEnum.search]}"></uif-icon> | |
| <uif-icon ng-if="disconnected" uif-type="${IconEnum[IconEnum.alert]}"></uif-icon> | |
| </div> | |
| <ng-transclude /> | |
| </button> | |
| <div role="button" ng-if="pickerType === '${PeoplePickerTypes[PeoplePickerTypes.compact]}' && !disconnected" | |
| ng-click="onSearch($event)" class="ms-PeoplePicker-searchMoreBtn ms-PeoplePicker-searchMoreBtn--compact"> | |
| <div class="ms-PeoplePicker-searchMoreIcon"> | |
| <uif-icon ng-if="!disconnected" uif-type="${IconEnum[IconEnum.search]}"></uif-icon> | |
| <uif-icon ng-if="disconnected" uif-type="${IconEnum[IconEnum.alert]}"></uif-icon> | |
| </div> | |
| <ng-transclude /> | |
| </div> | |
| <div role="button" ng-if="pickerType === '${PeoplePickerTypes[PeoplePickerTypes.facePile]}' && !disconnected" | |
| ng-click="onSearch($event)" class="ms-PeoplePicker-searchMoreBtn ms-PeoplePicker-searchMoreBtn--compact"> | |
| <div class="ms-PeoplePicker-searchMoreIcon"> | |
| <uif-icon ng-if="!disconnected" uif-type="${IconEnum[IconEnum.search]}"></uif-icon> | |
| <uif-icon ng-if="disconnected" uif-type="${IconEnum[IconEnum.alert]}"></uif-icon> | |
| </div> | |
| <ng-transclude /> | |
| </div> | |
| <div role="button" ng-if="disconnected" class="ms-PeoplePicker-searchMoreBtn"> | |
| <div class="ms-PeoplePicker-searchMoreIcon"> | |
| <uif-icon uif-type="${IconEnum[IconEnum.alert]}"></uif-icon> | |
| </div> | |
| <ng-transclude /> | |
| </div> | |
| <uif-spinner ng-show="processing"></uif-spinner> | |
| </div>`; | |
| public scope: {} = { | |
| disconnected: '=uifDisconnected' | |
| }; | |
| public static factory(): angular.IDirectiveFactory { | |
| const directive: angular.IDirectiveFactory = () => new PeopleSearchMoreDirective(); | |
| return directive; | |
| } | |
| constructor() { | |
| // | |
| } | |
| public link: angular.IDirectiveLinkFn = ( | |
| $scope: IPeopleSearchMoreScope, | |
| $element: angular.IAugmentedJQuery, | |
| $attrs: angular.IAttributes, | |
| peoplePickerCtrl: PeoplePickerController, | |
| $transclude: angular.ITranscludeFunction): void => { | |
| $scope.pickerType = peoplePickerCtrl.pickerType(); | |
| $scope.onSearch = ($event: MouseEvent) => { | |
| $event.stopPropagation(); | |
| peoplePickerCtrl.search(); | |
| $scope.$broadcast(peopleSearchEventName, peoplePickerCtrl.searchQuery()); | |
| }; | |
| } | |
| } | |
| /** | |
| * @ngdoc interface | |
| * @name IPrimaryTextScope | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @description | |
| * Interface used by the primary text directive. | |
| * | |
| * @property {string} searchingForText - Template for label "Search for" | |
| * @property {string} searchQuery - Search query from parent directive, i.e. people picker | |
| */ | |
| export interface IPrimaryTextScope extends angular.IScope { | |
| searchingForText: string; | |
| searchQuery: string; | |
| } | |
| /** | |
| * @ngdoc controller | |
| * @name PrimaryTextController | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @description | |
| * Controller used for the `<uif-primary-text>` directive. | |
| */ | |
| export class PrimaryTextController { | |
| public static $inject: string[] = ['$scope']; | |
| constructor( | |
| private $scope: IPrimaryTextScope) { | |
| this.$scope.$on(peopleSearchEventName, ($event: angular.IAngularEvent, query: string) => { | |
| this.$scope.searchQuery = query; | |
| }); | |
| } | |
| } | |
| /** | |
| * @ngdoc directive | |
| * @name uifPrimaryText | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @restrict E | |
| * | |
| * @description | |
| * `<uif-primary-text>` is a helper directive for search more component | |
| * | |
| * @see {link http://dev.office.com/fabric/components/peoplepicker} | |
| * | |
| * @usage | |
| * | |
| * <uif-primary-text uif-search-for-text="You are searching for: ">Search organization people</uif-primary-text> | |
| */ | |
| export class PrimaryTextDirective implements angular.IDirective { | |
| public static directiveName: string = 'uifPrimaryText'; | |
| public replace: boolean = true; | |
| public restrict: string = 'E'; | |
| public require: string[] = [`^^${PeopleSearchMoreDirective.directiveName}`, `^^${PeoplePickerDirective.directiveName}`]; | |
| public transclude: boolean = true; | |
| public controller: any = PrimaryTextController; | |
| public template: string = ` | |
| <div ng-show="!$parent.$parent.disconnected" class="ms-PeoplePicker-searchMorePrimary"> | |
| <div ng-show="$parent.$parent.processing">{{searchingForText}} {{searchQuery}}</div> | |
| <ng-transclude ng-show="!$parent.$parent.processing"></ng-transclude> | |
| </div>`; | |
| public scope: {} = { | |
| searchingForText: '@?uifSearchForText' | |
| }; | |
| public static factory(): angular.IDirectiveFactory { | |
| const directive: angular.IDirectiveFactory = () => new PrimaryTextDirective(); | |
| return directive; | |
| } | |
| constructor() { | |
| // | |
| } | |
| public link: angular.IDirectiveLinkFn = ( | |
| $scope: IPrimaryTextScope, | |
| $element: angular.IAugmentedJQuery, | |
| $attrs: angular.IAttributes, | |
| ctrls: [PeopleSearchMoreController, PeoplePickerController], | |
| $transclude: angular.ITranscludeFunction): void => { | |
| $scope.searchingForText = $scope.searchingForText || 'Searching for'; | |
| } | |
| } | |
| /** | |
| * @ngdoc directive | |
| * @name uifSecondaryText | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @restrict E | |
| * | |
| * @description | |
| * `<uif-secondary-text>` is a helper directive for search more component | |
| * | |
| * @see {link http://dev.office.com/fabric/components/peoplepicker} | |
| * | |
| * @usage | |
| * | |
| * <uif-secondary-text>Showing {{sourcePeople.length}} results</uif-secondary-text> | |
| */ | |
| export class SecondaryTextDirective implements angular.IDirective { | |
| public static directiveName: string = 'uifSecondaryText'; | |
| public replace: boolean = true; | |
| public restrict: string = 'E'; | |
| public transclude: boolean = true; | |
| public template: string = ` | |
| <div ng-show="!$parent.$parent.disconnected" class="ms-PeoplePicker-searchMoreSecondary"> | |
| <ng-transclude></ng-transclude> | |
| </div>`; | |
| public scope: boolean = true; | |
| public static factory(): angular.IDirectiveFactory { | |
| const directive: angular.IDirectiveFactory = () => new SecondaryTextDirective(); | |
| return directive; | |
| } | |
| constructor() { | |
| // | |
| } | |
| } | |
| /** | |
| * @ngdoc directive | |
| * @name uifDisconnectedText | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @restrict E | |
| * | |
| * @description | |
| * `<uif-disconnected-text>` is a helper directive for search more component | |
| * | |
| * @see {link http://dev.office.com/fabric/components/peoplepicker} | |
| * | |
| * @usage | |
| * | |
| * <uif-disconnected-text> We are having trouble connecting to the server. | |
| * <br> Please try again in a few minutes. | |
| * </uif-disconnected-text> | |
| */ | |
| export class DisconnectedTextDirective implements angular.IDirective { | |
| public static directiveName: string = 'uifDisconnectedText'; | |
| public replace: boolean = true; | |
| public restrict: string = 'E'; | |
| public transclude: boolean = true; | |
| public template: string = ` | |
| <div ng-show="$parent.$parent.disconnected" class="ms-PeoplePicker-searchMorePrimary"> | |
| <ng-transclude></ng-transclude> | |
| </div>`; | |
| public scope: boolean = true; | |
| public static factory(): angular.IDirectiveFactory { | |
| const directive: angular.IDirectiveFactory = () => new DisconnectedTextDirective(); | |
| return directive; | |
| } | |
| constructor() { | |
| // | |
| } | |
| } | |
| /** | |
| * @ngdoc directive | |
| * @name uifPeoplePickerSelected | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @restrict E | |
| * | |
| * @description | |
| * `<uif-people-picker-selected>` is a helper directive used in memeberList and facePile modes | |
| * | |
| * @see {link http://dev.office.com/fabric/components/peoplepicker} | |
| * | |
| * @usage | |
| * | |
| * <uif-people-picker-selected ng-model="selectedPersons" | |
| * uif-selected-person-click="onSelectedPersonClick()" | |
| * uif-person-close="removePersonFromSelectedPeople"> | |
| * <ng-transclude></ng-transclude> | |
| * </uif-people-picker-selected> | |
| */ | |
| export class PeoplePickerSelectedDirective implements angular.IDirective { | |
| public static directiveName: string = 'uifPeoplePickerSelected'; | |
| public replace: boolean = true; | |
| public restrict: string = 'E'; | |
| public transclude: boolean = true; | |
| public template: string = ` | |
| <div class="ms-PeoplePicker-selected" ng-class="{'is-active': selectedPeople && selectedPeople.length > 0}"> | |
| <div class="ms-PeoplePicker-selectedHeader"> | |
| <ng-transclude></ng-transclude> | |
| </div> | |
| <ul class="ms-PeoplePicker-selectedPeople"> | |
| <li class="ms-PeoplePicker-selectedPerson" ng-repeat="person in selectedPeople track by $index"> | |
| <uif-persona ng-click="onSelectedPersonClick()(person)" | |
| uif-style="${PersonaStyleEnum[PersonaStyleEnum.round]}" | |
| uif-size="${PersonaSize[PersonaSize.small]}" | |
| uif-presence="{{person.presence}}" | |
| uif-image-url="{{person.icon}}"> | |
| <uif-persona-initials uif-color="{{person.color}}">{{person.initials}}</uif-persona-initials> | |
| <uif-persona-primary-text>{{person.primaryText}}</uif-persona-primary-text> | |
| <uif-persona-secondary-text>{{person.secondaryText}}</uif-persona-secondary-text> | |
| </uif-persona> | |
| <button type="button" | |
| ng-click="removePersonFromSelectedPeople()(person, $event)" | |
| class="ms-PeoplePicker-resultAction js-resultRemove"> | |
| <uif-icon uif-type="${IconEnum[IconEnum.x]}"></uif-icon> | |
| </button> | |
| </li> | |
| </ul> | |
| </div>`; | |
| public scope: {} = { | |
| onSelectedPersonClick: '&?uifSelectedPersonClick', | |
| removePersonFromSelectedPeople: '&uifPersonClose', | |
| selectedPeople: '=ngModel' | |
| }; | |
| public static factory(): angular.IDirectiveFactory { | |
| const directive: angular.IDirectiveFactory = () => new PeoplePickerSelectedDirective(); | |
| return directive; | |
| } | |
| constructor() { | |
| // | |
| } | |
| } | |
| /** | |
| * @ngdoc interface | |
| * @name IGroup | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @description | |
| * Helper interface used by the people picker directive. | |
| * | |
| * @property {Array} selectedPersons - Persons selected in people picker | |
| */ | |
| export interface ISelectedPeopleHeaderScope extends angular.IScope { | |
| selectedPersons: IPersonPicker[]; | |
| } | |
| /** | |
| * @ngdoc directive | |
| * @name uifSelectedPeopleHeader | |
| * @module officeuifabric.components.peoplepicker | |
| * | |
| * @restrict E | |
| * | |
| * @description | |
| * `<uif-selected-people-header>` is a helper directive used in memeberList and facePile modes | |
| * | |
| * @see {link http://dev.office.com/fabric/components/peoplepicker} | |
| * | |
| * @usage | |
| * | |
| * <uif-selected-people-header>{{selectedPeople.length}} selected person(s)</uif-selected-people-header> | |
| */ | |
| export class SelectedPeopleHeaderDirective implements angular.IDirective { | |
| public static directiveName: string = 'uifSelectedPeopleHeader'; | |
| public require: string = `^^${PeoplePickerDirective.directiveName}`; | |
| public replace: boolean = true; | |
| public restrict: string = 'E'; | |
| public transclude: boolean = true; | |
| public scope: boolean = true; | |
| public template: string = `<span class="ms-PeoplePicker-selectedCount" ng-transclude></span>`; | |
| public static factory(): angular.IDirectiveFactory { | |
| const directive: angular.IDirectiveFactory = () => new SelectedPeopleHeaderDirective(); | |
| return directive; | |
| } | |
| public link: angular.IDirectiveLinkFn = ( | |
| $scope: ISelectedPeopleHeaderScope, | |
| $element: angular.IAugmentedJQuery, | |
| $attrs: angular.IAttributes, | |
| peoplePickerCtrl: PeoplePickerController, | |
| $transclude: angular.ITranscludeFunction): void => { | |
| $scope.selectedPersons = peoplePickerCtrl.getSelectedPersons(); | |
| } | |
| } | |
| export let module: angular.IModule = angular.module('officeuifabric.components.peoplepicker', [ | |
| 'officeuifabric.components']) | |
| .directive(PeoplePickerDirective.directiveName, PeoplePickerDirective.factory()) | |
| .directive(PrimaryTextDirective.directiveName, PrimaryTextDirective.factory()) | |
| .directive(SecondaryTextDirective.directiveName, SecondaryTextDirective.factory()) | |
| .directive(PeoplePickerResultListDirective.directiveName, PeoplePickerResultListDirective.factory()) | |
| .directive(DisconnectedTextDirective.directiveName, DisconnectedTextDirective.factory()) | |
| .directive(PeoplePickerSelectedDirective.directiveName, PeoplePickerSelectedDirective.factory()) | |
| .directive(SelectedPeopleHeaderDirective.directiveName, SelectedPeopleHeaderDirective.factory()) | |
| .directive(PeopleSearchMoreDirective.directiveName, PeopleSearchMoreDirective.factory()); |