/* * @ngdoc fbFormMultiSelect * @name fasit.directives.#fbFormMultiSelect * @fbFormMultiSelect * * @description * Directive som skapar en div med class-namnet "form-group" och en label med tillhörande select under den. */ fbDeprecatedFile('fbMultiSelect'); angular.module('fasit') //.directive('fbFormMultiSelect',['fbFormService', function (fbFormService:fb.IFbFormService) { .directive('fbFormMultiSelect', [function () { 'use strict'; var controller = ['$scope', '$attrs', '$element', '$timeout', '$filter', 'commonService', function ( $scope: fb.IFbFormMultiSelectScope, $attrs: any, $element: ng.IAugmentedJQuery, $timeout: ng.ITimeoutService, $filter: ng.IFilterService, commonService: fb.ICommonService) { var inputEl: JQuery = $element.find('.input'); $scope.externalOptionFn = false; if (angular.isDefined($attrs.optionsFn)) { $scope.externalOptionFn = true; } if (angular.isDefined($attrs.noLabel)) { $attrs.noLabel = false; } if (angular.isDefined($attrs.compareKeyWithTypeConversion)) { $attrs.compareKeyWithTypeConversion = true; } function resizeInput() { setTimeout(function () { inputEl.css('width', (inputEl.val().length) * 9 + 3); }); } function onKeydown(e: JQueryKeyEventObject) { if (e.keyCode === 13 && $scope.showDroppis) { e.stopPropagation(); } else if (e.keyCode === 13 && !$scope.showDroppis) { return; } else if (e.keyCode === 8) { if ($scope.newItem === '') { $scope.model.pop(); createPureOptions(); showDroppis(); $scope.$apply(); } } else { showDroppis(); } resizeInput(); } function getPropValue(propString: string, option: Object): any { var properties = propString.split('.'); var value = option; for (var i = 0; i < properties.length; ++i) { if (_.isUndefined(value)) { return; } value = value[properties[i]]; } return value; } function getKeyValue(option: Object): any { if ($scope.keyAttrArray === undefined) { return option; } return getPropValue($scope.keyAttrArray, option); } function getDisplayValue(option: any): string { if (_.isUndefined(option)) { return ''; } if ($scope.showAttrFilter) { return $filter($scope.showAttrFilter)(option); } if ($scope.showAttrArray === undefined) { return option.toString ? option.toString() : option; } if (!_.isObject(option)) { return ''; } return getPropValue($scope.showAttrArray, option) || ''; } inputEl.on('keydown', onKeydown); $scope.$on('$destroy', function () { inputEl.off('keydown', onKeydown); }); $scope.getDisplayTextForOption = function (option: Object): string { return getDisplayValue(option); }; $scope.getDisplayTextForModel = function (item: any): string { var compare = commonService.changeTrack.isChangeTrackObject(item) ? item.value : item; var selectedOption = _.filter($scope.options, function (option: any) { var comparer = getKeyValue(option); comparer = commonService.changeTrack.isChangeTrackObject(comparer) ? comparer.value : comparer; if ($attrs.compareKeyWithTypeConversion === true) { /* tslint:disable */ /*jslint eqeq: true*/ return comparer == compare; /* tslint:enable */ } return comparer === compare; })[0]; // Om vald modell saknas i options (selectedOption är undefined) kan modellen i vissa fall fortfarande veta sin displayvalue, ex om en valjer hela databärare och inte bara id. return getDisplayValue(_.isUndefined(selectedOption) ? item : selectedOption); }; $scope.newItem = ''; $scope.remove = function (item: any) { $timeout(function () { $scope.model.splice($scope.model.indexOf(item), 1); createPureOptions(); }, 1); }; $scope.focusInput = function () { $element.find('input').focus(); showDroppis(); }; $scope.hasFocusInput = function () { return $element.find('input').is(":focus"); }; $scope.checkFocus = function (e) { if (!shouldShowDroppis()) { e.preventDefault(); } } $scope.selected = function (option) { $timeout(function () { $scope.newItem = ''; $scope.model.push(getKeyValue(option)); if ($scope.externalOptionFn) { $scope.options = []; } createPureOptions(); }, 1); }; $scope.addNewItem = function () { var data = { value: $scope.newItem }; $scope.onAdd({ input: data }); $scope.model.push(data.value); $scope.options.push(data.value); createPureOptions(); //Denna behövs inte köras nu, men om nån ändrar något någon gång kanske den behövs showDroppis(); $scope.newItem = ''; }; $scope.hideDroppis = function () { $scope.newItem = ''; $scope.showDroppis = false; }; var shouldShowDroppis = function () { if ($scope.disable) { return false; } //return $scope.pureOptions.length !== 0; return $scope.pureOptions.length !== 0 || $scope.externalOptionFn; } var showDroppis = function () { if (shouldShowDroppis()) { $scope.showDroppis = true; } else { $scope.showDroppis = false; //$element.find('input').blur(); } } var createPureOptions = function () { var pureOptions = _($scope.options).filter(function (option: Object) { var optionKeyValue = getKeyValue(option); optionKeyValue = commonService.changeTrack.isChangeTrackObject(optionKeyValue) ? optionKeyValue.value : optionKeyValue; var isNoShow = angular.isDefined(_.find($scope.model, function (item: any) { return commonService.changeTrack.isChangeTrackObject(item) ? item.value === optionKeyValue : item === optionKeyValue; })); // Om nyckelvärde är nummer och vi tillåter type-conversion, kolla om sträng-representationen finns vald if (_.isNumber(optionKeyValue) && $attrs.compareKeyWithTypeConversion === true && !isNoShow) { isNoShow = _($scope.model).contains(optionKeyValue.toString()); } var displayValue = getDisplayValue(option) if (typeof displayValue === 'string' && displayValue.toLowerCase().indexOf($scope.newItem.toLowerCase()) === -1) { //Se till att telefonnummer som börjar på en 0a matchar deras motsvarande normaliserade värde if ($scope.newItem.length > 1 && $scope.newItem.charAt(0) === '0' && displayValue.toLowerCase().indexOf($scope.newItem.toLowerCase().substr(1, $scope.newItem.length - 1))) { isNoShow = false; } else { isNoShow = true; } } return !isNoShow; }); $scope.pureOptions = _.sortBy(pureOptions, function (item) { return getDisplayValue(item); }); }; $scope.$watch('options.length', function (newVal, oldVal) { //createPureOptions(); if ((newVal || newVal === 0) && newVal !== oldVal) { createPureOptions(); } }); $scope.$watch('model.length', function () { resizeInput(); createPureOptions(); }); /*$scope.$watch('newItem.length', function (newVal, oldVal) { createPureOptions(); });*/ var timeout: ng.IPromise; $scope.loading = { $resolved: true }; // borde köra på $scope.searching, men funkar inte av nån anledning $scope.searching = null; $scope.$watch('newItem', function (newVal: string, oldVal: string) { if (newVal && newVal !== oldVal && $scope.externalOptionFn) { $scope.options = []; if (newVal.length > 2 && (!$scope.optionsFnConditionToRun || $scope.optionsFnConditionToRun({ input: newVal })) ) { $scope.loading.$resolved = false; if (timeout) { $timeout.cancel(timeout); } timeout = $timeout(function () { $scope.searching = $scope.optionsFn({ input: newVal }); $scope.searching.then(function (res) { _.each(res, function (option) { $scope.options.push(option); }); createPureOptions(); $scope.loading.$resolved = true; }); }, 300); } showDroppis(); } else { createPureOptions(); } }); $scope.originalOptions = []; var setOriginalOptions = $scope.$watch('options.length', function (newVal, oldVal) { if (newVal) { if ($scope.options && $scope.options.length > 0) { _.each($scope.options, function (option) { $scope.originalOptions.push($scope.options); }); setOriginalOptions(); // clearar watchern //createPureOptions(); } } }); $scope.modelInvalid = function (option): boolean { if (!angular.isDefined($scope.invalidCondition)) { return false; } else { return $scope.invalidCondition({ option: option }); } } $scope.orderByWarningInvalid = function (option) { if ($scope.modelInvalid(option)) { return 0; } else if ($scope.modelWarning(option)) { return 1; } else { return 2; } } $scope.modelWarning = function (option): boolean { if (!angular.isDefined($scope.warningCondition)) { return false } else { return $scope.warningCondition({ option: option }); } } /*var link = function (scope: any, element: ng.IAugmentedJQuery, attrs: any) { fbFormService.functions.preLink(scope, element, attrs); fbFormService.functions.postLink(scope, element, attrs); } var compile = function (element: fb.IRootElementService, attrs: any) { fbFormService.functions.preCompile(element, attrs); fbFormService.functions.postCompile(element, attrs); return link; }*/ //if ($scope.options && $scope.options.$promise) { // $scope.options.$promise.then(function () { // createPureOptions(); // }) //} else { // createPureOptions(); //} resizeInput(); }]; return { restrict: 'E', scope: {/*fbFormService.getScopeObject({ options: '=', onAdd: '&', showAttrArray: '@', keyAttrArray: '@', allowAdd: '@', placeholder: '@', adaptiveLabel: '@', label: '@', noLabel: '@', minlength: '@', maxlength: '@', invalidCondition: '&', warningCondition: '&'*/ model: '=', options: '=', optionsFn: '&?', optionsFnConditionToRun: '&?', onAdd: '&', showAttrArray: '@', showAttrFilter: '@?', keyAttrArray: '@', allowAdd: '@', placeholder: '@', adaptiveLabel: '@', label: '@', noLabel: '@', minlength: '@', maxlength: '@', invalidCondition: '&', warningCondition: '&', disable: '=?' }, templateUrl: 'app/Directives/fbFormMultiSelect/fbFormMultiSelect.html', controller: controller }; }]);