/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
flowableModule
.directive('restrictInput', ["$parse", function ($parse) {
return {
restrict: 'A',
require: 'ngModel',
priority: 1002,
link: function postLink(scope, elm, attrs, ctrl) {
var acceptedFormat = attrs["restrictInput"];
if (acceptedFormat == undefined || acceptedFormat == null || acceptedFormat == "") {
acceptedFormat = attrs["dateFormat"];
}
scope.field.acceptedFormat=acceptedFormat;
function calculateAcceptedFormats(format) {
var format1 = format.toUpperCase(); //d-m-yyyy
var format2 = format1.replace(/-D-/,"-DD-").replace(/^D-/,"DD-").replace(/-D$/,"-DD"); //dd-m-yyyy
var format3 = format1.replace(/-M-/,"-MM-").replace(/^M-/,"MM-").replace(/-M$/,"-MM"); //d-mm-yyyy
var format4 = format2.replace(/-M-/,"-MM-").replace(/^M-/,"MM-").replace(/-M$/,"-MM"); //dd-mm-yyyy
return [format1,format2,format3,format4];
}
var acceptedFormats = calculateAcceptedFormats(acceptedFormat);
var skipValidation = false;
if (acceptedFormat == undefined || acceptedFormat == null || acceptedFormat == "") {
skipValidation = true;
}
var oldRenderer = ctrl.$render;
ctrl.$render = function () {
elm.val(ctrl.$viewValue);
if (ctrl.$dateValue && !isNaN(ctrl.$dateValue.getTime())) {
if (oldRenderer) {
oldRenderer();
}
}
};
function isValidText(viewValue, format) {
if (viewValue === undefined || viewValue == null || viewValue ==='') return true;
if (viewValue.length > format.length) return false;
for (var i = 0; i < Math.min(format.length, viewValue.length); i++) {
var charType = format[i];
if (charType.toUpperCase().match(/D|M|Y/)) {
if (viewValue[i].match(/\d/) == null) return false;
}else {
if (viewValue[i] != charType) return false;
}
}
return true;
}
ctrl.$parsers.unshift(function (viewValue) {
if (skipValidation) return viewValue; //just skip this parser
var isValid = false;
for(var i =0 ; i < acceptedFormats.length && !isValid; i++){
isValid |= isValidText(viewValue,acceptedFormats[i]);
}
if (!isValid) {
//should restore to the latest known well formated date.
ctrl.$dateValue = null;
} else {
ctrl.$lastValidText = viewValue;
//by default the date picker in angular strap does not reset the dateValue if the viewValue is null or empty.
if (viewValue === undefined || viewValue == null || viewValue === '') {
ctrl.$dateValue = null;
}
return viewValue;
}
ctrl.$setViewValue(ctrl.$lastValidText);
ctrl.$render();
return ctrl.$lastValidText;
});
}
}
}
]);
flowableModule
.directive('autoHeight', ['$rootScope', '$timeout', function($rootScope, $timeout) {
return {
restrict: 'AC',
scope: {
'toWatch': '=autoHeight'
},
compile: function (element, attr) {
return function ($scope, $element, $attrs) {
var offset = 0;
if($attrs['offset']) {
offset = parseInt($attrs['offset']);
if(isNaN(offset) || offset == undefined) {
offset = 0;
}
}
var update = function($element) {
// Get hold of parent and iterate all the children to get available height
$timeout(function() {
var total = $element.parent().outerHeight() - offset;
var found = false;
$element.parent().children().each(function() {
if(!found) {
if($element[0] == this) {
found = true;
} else {
// Substract preceding child's height
total -= angular.element(this).outerHeight();
}
}
});
if(found) {
$element.height(total);
}
}, 0);
};
if($scope.unregisterWatcher) {
$scope.unregisterWatcher();
}
$scope.unregisterWatcher = $rootScope.$watch('window.height', function(windowHeight) {
update($element);
});
if($scope.unregisterForceWatcher) {
$scope.unregisterForceWatcher();
}
$scope.unregisterForceWatcher = $rootScope.$watch('window.forceRefresh', function(forceValue) {
update($element);
});
$scope.$on('$destroy', function() {
// Cleanup watcher for window-height
if($scope.unregisterWatcher) {
$scope.unregisterWatcher();
}
if($scope.unregisterForceWatcher) {
$scope.unregisterForceWatcher();
}
});
}
}
};
}]);
/**
* Directive that ensures the child-element with class .active is visible and scrolls if needed. Watches the value
* of the directive and will re-apply if this value is changes.
*/
flowableModule
.directive('scrollToActive', ['$timeout', function($timeout) {
return {
restrict: 'AC',
scope: {
toWatch: "=scrollToActiveModel"
},
compile: function (element, attr) {
return function ($scope, $element, $attrs) {
$scope.$watch('toWatch', function() {
$timeout(function() {
var useParent = $attrs['useParent'];
var offsetTop = $attrs['offsetTop'];
if(offsetTop) {
offsetTop = parseInt(offsetTop);
if(isNaN(offsetTop)) {
offsetTop = 0;
}
}
if (!offsetTop) {
offsetTop = 0;
}
var selectedArr = $element.children('.active');
if(selectedArr && selectedArr.length > 0) {
var selected = angular.element(selectedArr[0]);
if(useParent) {
$element = angular.element($element.parent());
}
var selectedTop = selected.position().top - $element.position().top + $element.scrollTop();
var selectedBottom = selectedTop + selected.outerHeight();
var elementBottom = $element.scrollTop() + $element.innerHeight();
var elementTop = elementBottom - $element.innerHeight();
if(selectedTop <= elementTop) {
// scroll up
$element.scrollTop(selectedTop - selected.outerHeight() - offsetTop);
} else if(selectedBottom > elementBottom) {
// scroll down
$element.scrollTop(elementTop + selected.outerHeight() - offsetTop);
}
}
}, 0);
});
}
}
};
}]);
/**
* Directive that ensures the popup is scrolled into view, using the first parent as scroll-pane that has
* a class 'scroll-container' set on it. Is applied when the popup is shown.
*/
flowableModule
.directive('autoScroll', ['$timeout', function($timeout) {
return {
restrict: 'AC',
compile: function (element, attr) {
return function ($scope, $element, $attrs) {
$scope.$on('tooltip.show', function() {
$timeout(function() {
// Find appropriate parent
var parent = $element[0];
while(parent) {
if(parent.className && parent.className.indexOf('scroll-container') >= 0) {
break;
}
parent = parent.parentNode;
}
if(parent) {
parent = angular.element(parent);
var selectedTop = $element.offset().top - parent.offset().top + $element.scrollTop();
var selectedBottom = selectedTop + $element.outerHeight();
if(selectedBottom + 30 >= parent.outerHeight()) {
parent.scrollTop(selectedTop);
}
}
}, 50);
});
}
}
};
}]);
flowableModule
.directive('userName', function() {
var directive = {};
directive.template = '{{user | username}}';
directive.scope = {
user: "=userName"
};
return directive;
});
/**
* Executes the method that is set on the directive attribute value when ANY OTHER element is clicked, which is not the element the
* directive is on, or any of it's children.
*
*/
flowableModule
.directive('clickAnywhere', ["$document", "$parse", function ($document, $parse) {
var linkFunction = function ($scope, $element, $attributes) {
var scopeExpression = $attributes.clickAnywhere;
var invoker = $parse(scopeExpression);
var ignoreId = $attributes.ignore;
var ignoreClass = $attributes.ignoreClass;
var ignorePopupEvents = $attributes.ignorePopupEvents == 'true';
var handler = function (event) {
// Check source of event
var parent = event.target;
while(parent) {
if(parent == $element[0] ||
(ignoreId && parent.id == ignoreId) ||
(ignoreClass && parent.className && parent.className.indexOf(ignoreClass) >= 0)) {
event.stopPropagation();
event.preventDefault();
return;
}
parent = parent.parentNode;
}
$scope.$apply(
function () {
invoker($scope, {$event: event});
}
);
};
$document.on("click", handler);
$scope.$on('$destroy', function () {
$document.off("click", handler);
});
// Special handling for tooltips which don't destroy the scope
var hideReg = $scope.$on('tooltip.hide', function () {
if(!ignorePopupEvents) {
$document.off("click", handler);
hideReg();
}
});
};
// Return the linking function.
return( linkFunction );
}
]);
flowableModule
.directive('autoFocus', ['$timeout', '$parse', function($timeout, $parse) {
return {
restrict: 'AC',
compile: function($element, attr) {
var selectText;
if(attr["selectText"]) {
selectText = $parse(attr["selectText"]);
}
return function(_scope, _element, _attrs) {
var firstChild = (_attrs.focusFirstChild !== undefined);
$timeout(function () {
if (firstChild) {
// look for first input-element in child-tree and focus that
var inputs = _element.find('input');
if (inputs && inputs.length > 0) {
inputs[0].focus();
if(selectText && selectText(_scope.$parent)) {
input[0].setSelectionRange(0,input[0].value.length);
}
}
} else {
// Focus element where the directive is put on
_element[0].focus();
if(selectText && selectText(_scope.$parent)) {
_element[0].setSelectionRange(0,_element[0].value.length);
}
}
}, 100);
}
}
};
}]);
flowableModule
.directive('focusWhen', ['$timeout', function ($timeout) {
return {
link: function (scope, element, attrs) {
scope.$watch(attrs.ngFocus, function (val) {
if (angular.isDefined(val) && val) {
$timeout(function () {
element[0].focus();
});
}
}, true);
element.bind('blur', function () {
if (angular.isDefined(attrs.ngFocusLost)) {
scope.safeApply(attrs.ngFocusLost);
}
});
}
};
}]);
flowableModule
.directive('loading', [function() {
var directive = {};
directive.restrict = 'A';
directive.template = '
';
directive.scope = {
loading : "=loading",
loadingText: "=loadingText"
};
return directive;
}]);
// Workaround for https://github.com/twbs/bootstrap/issues/8379 :
// prototype.js interferes with regular dropdown behavior
flowableModule
.directive('activitiFixDropdownBug', function() {
return {
restrict: 'AEC',
link: function(scope, element, attrs) {
element.on('hidden.bs.dropdown ', function () {
element.show(); // evil prototype.js has added display:none to it ...
})
}
};
});
/**
* Directive for rendering user link.
*/
flowableModule
.directive('userLink', function() {
var directive = {};
directive.template = '{{user.firstName && user.firstName || ""}} {{user.lastName && user.lastName || ""}} {{ (user.email && !user.firstName && !user.lastName) && user.email || ""}}';
directive.scope = {
user: "=userLink"
};
directive.compile = function(element, attributes) {
element.addClass('people-link');
};
return directive;
});
/**
* Directive for rendering a form field.
*/
flowableModule
.directive('formField', function () {
var directive = {};
directive.template = ' {{field.name || ""}} - {{field.id}}';
directive.scope = {
field: "=formField"
};
directive.compile = function (element, attributes) {
element.addClass('form-field');
};
return directive;
});
/**
* Directive to capture mouse up, down, enter and escape on input fields (eg. list navigation)
*/
flowableModule
.directive('customKeys', ["$parse", function ($parse) {
var directive = {};
directive.compile = function($element, attr) {
var up, down, enter, escape;
if(attr["upPressed"]) {
up = $parse(attr["upPressed"]);
}
if(attr["downPressed"]) {
down = $parse(attr["downPressed"]);
}
if(attr["enterPressed"]) {
enter = $parse(attr["enterPressed"]);
}
if(attr["escapePressed"]) {
escape = $parse(attr["escapePressed"]);
}
return function(scope, element, attr) {
element.on('keyup', function(e) {
if(e.keyCode === 38) {
scope.$apply(function() {
if(up) {
up(scope, {$event:e});
}
});
} else if(e.keyCode === 40) {
scope.$apply(function() {
if(down) {
down(scope, {$event:e});
}
});
} else if(e.keyCode === 13) {
scope.$apply(function() {
if(enter) {
enter(scope, {$event:e});
}
});
} else if(e.keyCode === 27) {
scope.$apply(function() {
if(escape) {
escape(scope, {$event:e});
}
});
}
});
element.on('keydown', element, function (e) {
if (e.keyCode === 38 || e.keyCode === 40 || e.keyCode === 13 || e.keyCode === 27)
e.preventDefault();
});
};
};
return directive;
}]);
// Delayed setting of model value in scope, based on input value unchanged after a number of millis
// See below: ngDebounce is preferred (as it hooks into ngModel, meaning that ng-change will keep working - but not with delayedModel)
flowableModule
.directive('delayedModel', ['$timeout', function($timeout) {
return {
scope: {
targetModel: '=delayedModel'
},
link: function(scope, element, attrs) {
element.val(scope.targetModel);
// Also watch model for any changes not triggered by timer
scope.$watch('targetModel', function(newVal, oldVal) {
if(scheduled) {
$timeout.cancel(scheduled);
}
if (newVal !== oldVal) {
element.val(scope.targetModel);
}
});
var scheduled;
element.on('keyup paste search', function() {
if(element.val() !== scope.targetModel) {
if(scheduled) {
$timeout.cancel(scheduled);
}
scheduled = $timeout(function() {
scope.targetModel = element[0].value;
element.val(scope.targetModel);
scope.$apply();
}, attrs.delay || 200);
}
});
}
};
}]);
// From https://gist.github.com/benbrandt22/bb44184a2eddcd4b0b8a
flowableModule.directive('ngDebounce', ['$timeout', function($timeout) {
return {
restrict: 'A',
require: 'ngModel',
priority: 99,
link: function(scope, elm, attr, ngModelCtrl) {
if (attr.type === 'radio' || attr.type === 'checkbox') return;
elm.unbind('input');
var debounce;
elm.bind('input', function() {
$timeout.cancel(debounce);
debounce = $timeout( function() {
scope.$apply(function() {
ngModelCtrl.$setViewValue(elm.val());
});
}, attr.ngDebounce || 1000);
});
elm.bind('blur', function() {
scope.$apply(function() {
ngModelCtrl.$setViewValue(elm.val());
});
});
}
}
}]);
flowableModule.directive('externalContent', ['$parse', '$timeout', 'appResourceRoot', function ($parse, $timeout, appResourceRoot) {
var directive = {};
directive.restrict = 'A';
directive.templateUrl = appResourceRoot + '../views/common/templates/external-content-template.html';
directive.scope = {
taskId : '=taskId',
processInstanceId: '=formDefinition',
caseInstanceId: '=caseId',
folderSelect: '=folderSelect',
linkOnly: '=linkOnly',
preSelectedAlfrescoAccount: '=account',
uploadInProgress: '=uploadInProgress'
};
directive.link = function ($scope, $element, $attributes) {
if($attributes["onContentUpload"]) {
$scope.uploadedCallback = $parse($attributes['onContentUpload']);
}
if($attributes["onFolderSelect"]) {
$scope.folderSelectCallback = $parse($attributes['onFolderSelect']);
}
if($attributes["onUploadInProgress"]) {
$scope.uploadInProgressCallback = $parse($attributes['onUploadInProgress']);
}
// Schedule hooking in of click-listener. we cannot use angular ng-click since this
// will force a new $apply/$digest to happen when the click() is called on the button
$timeout(function() {
$element.find('div.select-file').click(function() {
$element.find('input[type="file"]').click();
});
}, 200);
};
directive.controller = ['$scope', '$element', 'RelatedContentService', '$modal', '$window', '$translate', '$rootScope', function($scope, $element, RelatedContentService, $modal, $window, $translate, $rootScope) {
$scope.uploadModel = {uploading: false};
$scope.clearPopupError = function() {
};
$scope.openFileSelect = function(element) {
$scope.errorMessage = undefined;
var parent = angular.element(element).parent();
parent.children('input').click();
};
$scope.onFileSelect = function ($files, isIE) {
$scope.errorMessage = undefined;
if(!$scope.linkOnly) {
$scope.errorMessage = undefined;
if(!$scope.folderSelect && !$scope.uploadModel.uploading && $files.length > 0) {
if ($scope.uploadInProgressCallback) {
$scope.uploadInProgressCallback($scope.$parent, {status: true});
}
$scope.uploadModel.uploading = true;
var file = $files[0];
$scope.clearPopupError();
RelatedContentService.addRelatedContent($scope.taskId, $scope.processInstanceId, $scope.caseInstanceId, file, isIE).progress(function (evt) {
$scope.uploadModel.uploadProgress = parseInt(100.0 * evt.loaded / evt.total);
}).then(function (data) {
if ($scope.uploadInProgressCallback) {
$scope.uploadInProgressCallback($scope.$parent, {status: false});
}
$scope.uploadModel.uploading = false;
if($scope.uploadedCallback) {
$scope.uploadedCallback($scope.$parent, {'content': data});
}
}, function (error) {
// Error callback
if ($scope.uploadInProgressCallback) {
$scope.uploadInProgressCallback($scope.$parent, {status: false});
}
if(error && error.messageKey) {
var formattedData = {};
if(error.customData) {
formattedData.quota = $scope.formatFileSize(error.customData.quota)
};
$translate(error.messageKey, formattedData).then(function(message) {
$scope.errorMessage = message;
});
}
$scope.uploadModel.uploading = false;
});
}
}
};
}];
return directive;
}]);
flowableModule.
directive('selectPeoplePopover', ['$rootScope', '$http', '$popover', 'appResourceRoot', 'UserService', '$parse', function($rootScope, $http, $popover, appResourceRoot, UserService, $parse) {
var directive = {};
directive.restrict = 'A';
directive.scope = {
excludeTaskId: '=excludeTaskId',
excludeProcessId: '=excludeProcessId',
excludeUserId: '=excludeUserId',
excludeUserIds: '=excludeUserIds',
tenantId: '=tenantId',
type: '=type',
restrictWithGroup: '=restrictWithGroup',
selectPeopleFormFields: '=selectPeopleFormFields',
ignoreContainer: '=ignoreContainer'
};
directive.link = function($scope, $element, attrs) {
// Set defaults
var placement = "bottom";
$element.addClass("toggle-people-select");
if(attrs.placement) {
placement = attrs.placement;
}
var closeOnSelect = true;
if(attrs.closeOnSelect !== undefined) {
closeOnSelect = attrs.closeOnSelect;
}
if ($scope.ignoreContainer) {
$scope.popover = $popover($element, {template: appResourceRoot + '../views/common/popover/select-people-popover.html?' +
Date.now(), placement: placement});
} else {
$scope.popover = $popover($element, {template: appResourceRoot + '../views/common/popover/select-people-popover.html?' +
Date.now(), placement: placement, container: 'body'});
}
// Parse callbacks
var selectedCallback, cancelledCallback;
if (attrs['onPeopleSelected']) {
selectedCallback = $parse(attrs['onPeopleSelected']);
}
if (attrs['onCancel']) {
cancelledCallback = $parse(attrs['onCancel']);
}
// Parse type
// Can be 'workflow' or 'idm'. In 'workflow', the users are retrieved for filling task assignments etc. This is the default if this param is omitted. 'idm' is more strict.
var backendType = 'workflow';
if ($scope.type !== null && $scope.type !== undefined) {
backendType = $scope.type;
}
var popoverScope = $scope.popover.$scope;
popoverScope.title = attrs['popoverTitle'];
popoverScope.popupModel = {
userResults: [],
userField: {},
userFieldFilter: ['people']
};
if ($scope.selectPeopleFormFields) {
popoverScope.popupModel.formFields = $scope.selectPeopleFormFields;
}
popoverScope.setSearchType = function() {
popoverScope.popupModel.userSourceType = 'search';
};
popoverScope.setFormFieldType = function() {
popoverScope.popupModel.userSourceType = 'field';
};
popoverScope.$watch('popupModel.userField', function() {
if (popoverScope.popupModel.userField && popoverScope.popupModel.userField.id) {
if (selectedCallback) {
// Run callback in parent scope of directive
var simpleUserField = {
id: popoverScope.popupModel.userField.id,
name: popoverScope.popupModel.userField.name,
type: popoverScope.popupModel.userField.type
}
selectedCallback($scope.$parent, {'userField': simpleUserField});
popoverScope.popupModel.userField = {};
}
if (closeOnSelect || closeOnSelect === 'true') {
popoverScope.$hide();
}
}
});
popoverScope.$watch('popupModel.filter', function() {
if (popoverScope.popupModel.filter && popoverScope.popupModel.filter.length > 0) {
var userGetPromise;
if (backendType === 'idm') {
userGetPromise = UserService.getFilteredUsersStrict(popoverScope.popupModel.filter, $scope.tenantId, $scope.restrictWithGroup);
} else {
// Default: go to workflow users backend
userGetPromise = UserService.getFilteredUsers(popoverScope.popupModel.filter, $scope.excludeTaskId,
$scope.excludeProcessId, $scope.tenantId, $scope.restrictWithGroup);
}
userGetPromise.then(function(result) {
popoverScope.popupModel.showRecentResults = false;
var users = [];
var excludeUserIdSet = $scope.excludeUserId !== null && $scope.excludeUserId !== undefined;
var excludeUserIdsSet = $scope.excludeUserIds !== null && $scope.excludeUserIds !== undefined;
if (excludeUserIdSet === true || excludeUserIdsSet === true) {
for (var userIndex=0; userIndex < result.data.length; userIndex++) {
var userExcluded = false;
if (excludeUserIdSet === true && result.data[userIndex].id === $scope.excludeUserId) {
userExcluded = true;
}
if (excludeUserIdsSet === true && $scope.excludeUserIds.indexOf(result.data[userIndex].id) >= 0) {
userExcluded = true;
}
if (!userExcluded) {
users.push(result.data[userIndex]);
}
}
} else {
users = result.data;
}
popoverScope.popupModel.userResults = users;
popoverScope.resetSelection();
});
} else {
popoverScope.resetSelection();
popoverScope.popupModel.userResults = [];
}
});
popoverScope.resetSelection = function() {
popoverScope.popupModel.selectedUser = undefined;
popoverScope.popupModel.selectedIndex = -1;
};
popoverScope.nextUser = function() {
var users = popoverScope.popupModel.userResults;
if(users && users.length > 0 && popoverScope.popupModel.selectedIndex < users.length -1) {
popoverScope.popupModel.selectedIndex+=1;
popoverScope.popupModel.selectedUser = users[popoverScope.popupModel.selectedIndex];
}
};
popoverScope.previousUser = function() {
var users = popoverScope.popupModel.userResults;
if(users && users.length > 0 && popoverScope.popupModel.selectedIndex > 0) {
popoverScope.popupModel.selectedIndex-=1;
popoverScope.popupModel.selectedUser = users[popoverScope.popupModel.selectedIndex];
}
};
popoverScope.confirmUser = function(user) {
if (!user) {
// Selection is done with keyboard, use selection index
var users = popoverScope.popupModel.userResults;
if (popoverScope.popupModel.selectedIndex >= 0 && popoverScope.popupModel.selectedIndex 0) {
var tenantId;
if ($rootScope.common !== null && $rootScope.common !== undefined && $rootScope.common.selectedTenantId !== null && $rootScope.common.selectedTenantId !== undefined) {
tenantId = $rootScope.common.selectedTenantId > 0 ? $rootScope.common.selectedTenantId : undefined;
}
FunctionalGroupService.getFilteredGroups(popoverScope.popupModel.filter, $scope.restrictWithGroup, tenantId).then(function(result) {
var groups = [];
if ($scope.excludeGroupId != null && $scope.excludeGroupId) {
for (var groupIndex=0; groupIndex < result.data.length; groupIndex++) {
if (result.data[groupIndex].id !== $scope.excludeGroupId) {
groups.push(result.data[groupIndex]);
}
}
} else if ($scope.excludeGroupIds != null && $scope.excludeGroupIds !== undefined) {
for (var groupIndex=0; groupIndex < result.data.length; groupIndex++) {
if ($scope.excludeGroupIds.indexOf(result.data[groupIndex].id) < 0) {
groups.push(result.data[groupIndex]);
}
}
} else {
groups = result.data;
}
popoverScope.popupModel.groupResults = groups;
popoverScope.resetSelection();
});
} else {
popoverScope.resetSelection();
popoverScope.popupModel.groupResults = [];
}
});
popoverScope.resetSelection = function() {
popoverScope.popupModel.selectedGroup = undefined;
popoverScope.popupModel.selectedIndex = -1;
};
popoverScope.nextGroup = function() {
var groups = popoverScope.popupModel.groupResults;
if (groups && groups.length > 0 && popoverScope.popupModel.selectedIndex < groups.length -1) {
popoverScope.popupModel.selectedIndex+=1;
popoverScope.popupModel.groupUser = groups[popoverScope.popupModel.selectedIndex];
}
};
popoverScope.previousGroup = function() {
var groups = popoverScope.popupModel.groupResults;
if (groups && groups.length > 0 && popoverScope.popupModel.selectedIndex > 0) {
popoverScope.popupModel.selectedIndex-=1;
popoverScope.popupModel.selectedGroup = groups[popoverScope.popupModel.selectedIndex];
}
};
popoverScope.confirmGroup = function(group) {
if (!group) {
// Selection is done with keyboard, use selection index
var groups = popoverScope.popupModel.groupResults;
if (popoverScope.popupModel.selectedIndex >= 0 && popoverScope.popupModel.selectedIndex < groups.length) {
group = groups[popoverScope.popupModel.selectedIndex];
}
}
if (group) {
if(selectedCallback) {
// Run callback in parent scope of directive
selectedCallback($scope.$parent, {'group': group});
}
if (closeOnSelect === 'true') {
popoverScope.$hide();
} else {
var groups = popoverScope.popupModel.groupResults;
groups.splice(jQuery.inArray(group, groups), 1);
popoverScope.popupModel.selectedIndex = 0;
popoverScope.popupModel.selectedGroup = groups[popoverScope.popupModel.selectedIndex];
}
}
};
popoverScope.$on('tooltip.hide', function() {
popoverScope.popupModel.groupResults = [];
popoverScope.popupModel.filter = '';
if (popoverScope.popupModel.added) {
popoverScope.popupModel.added = false;
} else {
if (cancelledCallback) {
// Run callback in parent scope of directive
cancelledCallback($scope.$parent);
}
}
});
};
return directive;
}]);
flowableModule.directive('tabControl', ['$compile', '$http', '$templateCache', function($compile, $http, $templateCache) {
var updateTemplate = function($scope, element, attributes) {
if(!$scope.activeTemplate || $scope.activeTemplate != $scope.activeTab.id) {
// Check if current loaded template is still the right one
var contentDiv = $(element.children()[1]);
var childScope = angular.element(element.children()[1]).scope();
if($scope.activeTemplate && childScope != $scope) {
// Child-scope created by the included element, should be destroyed
childScope.$destroy();
}
if($scope.activeTab && $scope.activeTab.templateUrl) {
// Load the HTML-fragment or get from cache
var loader = $http.get($scope.activeTab.templateUrl, {cache: $templateCache});
var promise = loader.success(function(html) {
contentDiv.html(html);
}).then(function (response) {
$scope.activeTemplate = $scope.activeTab.id;
contentDiv.replaceWith($compile(contentDiv.html())($scope));
});
} else {
// No templates are being used, no need to use the contentDiv for this tab, clear it
contentDiv.empty();
}
}
};
var directive = {};
directive.restrict = 'A';
directive.replace = true;
directive.transclude = true;
directive.template = '