"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(); }; } }; }]); }());