SmartIT_Extensions/BMC/smart-it-full/scripts/app/common/selection-directive.js

187 lines
10 KiB
JavaScript

"use strict";
(function () {
'use strict';
angular.module('myitsmApp')
.directive('selection', ['i18nService', '$timeout',
function (i18nService, $timeout) {
return {
restrict: 'E',
templateUrl: 'views/common/selection-directive.html',
replace: true,
require: '?^form',
scope: {
// mandatory attributes
selectionItems: '=',
selectedItem: '=',
name: '@selectedItem',
// optional attributes
selectionCallback: '&',
titleText: '@',
label: '@',
value: '@',
selectionFilter: '@',
selectionFilterPlaceholderText: '@',
tier: '@',
i18nPrefix: '@',
updateSelectedItem: '@',
loadingFlag: '=',
disabledSelection: '=',
ariaRequired: '@',
firstItemEmpty: '=',
itemHeader: '@',
placeholderText: '@',
inputId: '@',
typeaheadMode: '=',
typeaheadDetails: '@',
typeaheadGetList: '&',
showChunkingTooltip: '=',
required: '=',
fieldName: '@',
entity: '=',
duplicateKey: '@',
showClear: '@',
clearCallback: '&'
},
compile: function (element, attrs) {
var modelElement = element.find("[name='selectedItem']");
if (modelElement) {
modelElement.attr('name', attrs.selectedItem);
}
return function (scope, element, attr, formCtrl) {
var dropdownToggle = element.find('.dropdown-toggle'), checkSelectionItem = false;
scope.state = {
isOpen: false
};
scope.search = {
searchFilterText: '',
typeaheadText: ''
};
scope.searchFilterText = '';
scope.tooltip = {
showTooltip: false
};
scope.handleKeyup = function ($event) {
// Need to intercept the keyup event before ui.bootstrap.dropdown
// otherwise, the input filter will lost all the input events
scope.searchFilterText = $event.target.value;
if (scope.searchFilterText === "" && scope.oldSelectionItems) {
scope.selectionItems = _.cloneDeep(scope.oldSelectionItems);
}
$event.stopPropagation();
};
scope.handleKeydown = function ($event) {
// Need to intercept the escape key before $modal action blade
// otherwise, hitting escape key in dropdown expand mode will close the $modal action blade instead
if ($event.keyCode === 27) { // escape key
$timeout(function () {
dropdownToggle.trigger('click');
dropdownToggle.focus();
}, 0);
$event.stopPropagation();
}
};
scope.itemSelected = function (item) {
if (scope.updateSelectedItem && scope.updateSelectedItem === 'true') {
scope.selectedItem = item;
if (formCtrl && formCtrl[scope.name] && formCtrl[scope.name].$viewValue != item) {
formCtrl[scope.name].$setViewValue(item);
}
}
$timeout(function () {
if (scope.tier && scope.selectionCallback) {
scope.selectionCallback({ tier: parseInt(scope.tier), item: item });
}
else if (scope.selectionCallback) {
scope.selectionCallback({ item: item });
}
//manual close of dropdown for IE9-IE10
if (scope.state.isOpen) {
scope.state.isOpen = false;
}
if (scope.selectionItems.length === 0 && scope.oldSelectionItems) {
scope.searchFilterText = "";
scope.selectionItems = _.cloneDeep(scope.oldSelectionItems);
}
dropdownToggle.focus();
}, 0);
};
scope.getList = function (name) {
scope.tooltip.showTooltip = false;
if (!checkSelectionItem) {
scope.oldSelectionItems = _.cloneDeep(scope.selectionItems);
checkSelectionItem = true;
}
scope.selectionItems = [];
if (!scope.showChunkingTooltip) {
return scope.typeaheadGetList({ name: name });
}
else {
return scope.typeaheadGetList({ name: name }).then(function (response) {
scope.tooltip.showTooltip = response.exceedsChunkSize;
return response.list;
});
}
};
scope.onBlur = function () {
$timeout(function () {
scope.search.typeaheadText = '';
if (scope.oldSelectionItems) {
scope.selectionItems = _.cloneDeep(scope.oldSelectionItems);
}
}, 1000); //typeahead-on-select function doesn't get fired due to this ng-blur function
//timeout will allow the select function to execute first.
};
scope.getLabel = function (item) {
var itemLabel = item ? (scope.label ? item[scope.label] : item) : '';
if (scope.i18nPrefix && itemLabel) {
itemLabel = i18nService.getLocalizedString(scope.i18nPrefix + itemLabel);
}
if (itemLabel && scope.duplicateKey && item.duplicate) {
itemLabel = itemLabel + ' (' + item[scope.duplicateKey] + ')';
}
return itemLabel;
};
scope.getValue = function (item) {
return item ? (scope.value ? item[scope.value] : item) : '';
};
scope.filterDropDown = function (filterText) {
return function (item) {
return _.includes(String(scope.getLabel(item)).toLowerCase(), filterText.toLowerCase());
};
};
scope.clear = function () {
if (scope.oldSelectionItems) {
scope.selectionItems = _.cloneDeep(scope.oldSelectionItems);
}
scope.selectedItem = null;
scope.clearCallback({ item: scope.selectedItem });
};
function init() {
// set default value for optional attributes
if (scope.selectionFilter) {
scope.selectionFilterPlaceholderText = scope.selectionFilterPlaceholderText || '';
}
scope.placeholderText = scope.placeholderText || '';
scope.selectedItemLabel = scope.selectedItem ? scope.getLabel(scope.selectedItem) : scope.placeholderText;
scope.selectedItemValue = scope.getValue(scope.selectedItem);
scope.$watch('selectedItem', function (newValue) {
scope.selectedItemLabel = scope.getLabel(newValue) ? scope.getLabel(newValue) : scope.placeholderText;
scope.selectedItemValue = scope.getValue(newValue);
if (scope.tempFieldName && formCtrl && formCtrl[scope.tempFieldName]) {
formCtrl[scope.tempFieldName].$setViewValue(scope.getLabel(newValue) ? scope.getLabel(newValue) : '');
}
}, true);
if (angular.isDefined(attr.autofocus)) {
$timeout(function () {
dropdownToggle.focus();
}, 300);
}
scope.tempFieldName = 'dummyField_' + Math.floor(Math.random() * 1000);
}
init();
};
}
};
}]);
}());