').append(clone);\n\n var transcludedMatch = transcluded.querySelectorAll('.ui-select-match');\n transcludedMatch.removeAttr('ui-select-match'); //To avoid loop in case directive as attr\n transcludedMatch.removeAttr('data-ui-select-match'); // Properly handle HTML5 data-attributes\n if (transcludedMatch.length !== 1) {\n throw uiSelectMinErr('transcluded', \"Expected 1 .ui-select-match but got '{0}'.\", transcludedMatch.length);\n }\n element.querySelectorAll('.ui-select-match').replaceWith(transcludedMatch);\n\n var transcludedChoices = transcluded.querySelectorAll('.ui-select-choices');\n transcludedChoices.removeAttr('ui-select-choices'); //To avoid loop in case directive as attr\n transcludedChoices.removeAttr('data-ui-select-choices'); // Properly handle HTML5 data-attributes\n if (transcludedChoices.length !== 1) {\n throw uiSelectMinErr('transcluded', \"Expected 1 .ui-select-choices but got '{0}'.\", transcludedChoices.length);\n }\n element.querySelectorAll('.ui-select-choices').replaceWith(transcludedChoices);\n\n var transcludedNoChoice = transcluded.querySelectorAll('.ui-select-no-choice');\n transcludedNoChoice.removeAttr('ui-select-no-choice'); //To avoid loop in case directive as attr\n transcludedNoChoice.removeAttr('data-ui-select-no-choice'); // Properly handle HTML5 data-attributes\n if (transcludedNoChoice.length == 1) {\n element.querySelectorAll('.ui-select-no-choice').replaceWith(transcludedNoChoice);\n }\n\n var transcludedHeader = transcluded.querySelectorAll('.ui-select-header');\n transcludedHeader.removeAttr('ui-select-header'); // To avoid loop in case directive as attr\n transcludedHeader.removeAttr('data-ui-select-header'); // Properly handle HTML5 data-attributes\n if (transcludedHeader.length == 1) {\n element.querySelectorAll('.ui-select-header').replaceWith(transcludedHeader);\n } else {\n element.querySelectorAll('.ui-select-header').remove();\n }\n\n var transcludedFooter = transcluded.querySelectorAll('.ui-select-footer');\n transcludedFooter.removeAttr('ui-select-footer'); // To avoid loop in case directive as attr\n transcludedFooter.removeAttr('data-ui-select-footer'); // Properly handle HTML5 data-attributes\n if (transcludedFooter.length == 1) {\n element.querySelectorAll('.ui-select-footer').replaceWith(transcludedFooter);\n } else {\n element.querySelectorAll('.ui-select-footer').remove();\n }\n });\n\n scope.$watch('$select.open', function(isOpen) {\n if (isOpen) {\n // Attach global handlers that cause the dropdowns to close\n $window.addEventListener('mousedown', closeOnClick, true);\n $window.addEventListener('scroll', closeOnScroll, true);\n $window.addEventListener('resize', closeOnResize, true);\n\n if (appendToBody) {\n // Wait for ui-select-match child directive, it hasn't started rendering yet.\n scope.$evalAsync(positionDropdown);\n }\n\n scope.calculateDropdownPos();\n } else {\n resetDropdown();\n }\n });\n\n // Move the dropdown back to its original location when the scope is destroyed. Otherwise\n // it might stick around when the user routes away or the select field is otherwise removed\n scope.$on('$destroy', resetDropdown);\n\n scope.calculateDropdownPos = function() {\n if (!$select.open) { return; }\n\n dropdown = dropdown.length ? dropdown : angular.element(element).querySelectorAll('.ui-select-dropdown');\n if (!dropdown.length) { return; }\n\n // Clear existing state and hide dropdown\n dropdown[0].style.position = '';\n dropdown[0].style.top = '';\n dropdown[0].style.visibility = 'hidden';\n element.removeClass('direction-up dropdown-menu-right');\n\n // Determine X positioning\n var offset = uisOffset(element);\n var offsetDropdown = uisOffset(dropdown);\n var scrollTarget = documentElement || $document[0].body;\n var xState = $select.dropdownXPosition;\n dropdown.toggleClass('dropdown-menu-right', xState === 'right' ||\n (xState === 'auto' && offset.left + offsetDropdown.width - scrollTarget.scrollLeft > documentElement.clientWidth)\n );\n\n // Determine Y positioning\n var yState = $select.dropdownYPosition;\n var top = yState === 'up' || (yState === 'auto' && offset.top + offset.height + offsetDropdown.height - scrollTarget.scrollTop > documentElement.clientHeight) ?\n (offsetDropdown.height * -1) + 'px' :\n '';\n\n // Apply and make visible.\n dropdown[0].style.position = top ? 'absolute' : '';\n dropdown[0].style.top = top;\n dropdown[0].style.visibility = '';\n if (top) {\n element.addClass('direction-up');\n }\n };\n\n function calculateSelectLeftPosition(offset) {\n var scrollLeft = documentElement.scrollLeft || $document[0].body.scrollLeft;\n var edgeOffscreenAmount = (offset.left + offset.width) - (scrollLeft + documentElement.clientWidth);\n var paddingFromEdge = 30;\n\n var leftPosition = offset.left;\n if (edgeOffscreenAmount > 0) {\n leftPosition -= (edgeOffscreenAmount + paddingFromEdge);\n }\n\n return leftPosition;\n }\n\n function closeOnClick(e) {\n if (!$select.open) return; //Skip it if dropdown is close\n\n var contains = false;\n var target = e.target || e.srcElement;\n\n if (window.jQuery) {\n // Firefox 3.6 does not support element.contains()\n // See Node.contains https://developer.mozilla.org/en-US/docs/Web/API/Node.contains\n contains = window.jQuery.contains(element[0], target);\n } else {\n contains = element[0].contains(target);\n }\n if (!contains && !$select.clickTriggeredSelect) {\n var skipFocusser;\n if (!$select.skipFocusser) {\n //Will lose focus only with certain targets\n var focusableControls = ['input','button','textarea','select'];\n var targetController = angular.element(target).controller('uiSelect'); //To check if target is other ui-select\n skipFocusser = targetController && targetController !== $select; //To check if target is other ui-select\n if (!skipFocusser) skipFocusser = ~focusableControls.indexOf(target.tagName.toLowerCase()); //Check if target is input, button or textarea\n } else {\n skipFocusser = true;\n }\n\n $select.close(skipFocusser);\n scope.$digest();\n }\n $select.clickTriggeredSelect = false;\n }\n\n function closeOnResize() {\n $select.close(false);\n }\n\n function closeOnScroll(e) {\n if (!element[0].contains(e.target || e.srcElement)) {\n $select.close(false);\n }\n }\n\n function positionDropdown() {\n // Remember the absolute position of the element\n var offset = uisOffset(element);\n\n // Clone the element into a placeholder element to take its original place in the DOM\n placeholder = angular.element('
');\n placeholder[0].style.width = offset.width + 'px';\n placeholder[0].style.height = offset.height + 'px';\n element.after(placeholder);\n\n // Remember the original value of the element width inline style, so it can be restored\n // when the dropdown is closed\n originalWidth = element[0].style.width;\n element[0].style.position = 'absolute';\n element[0].style.left = calculateSelectLeftPosition(offset) + 'px';\n element[0].style.top = offset.top + 'px';\n element[0].style.width = offset.width + 'px';\n $document[0].body.appendChild(element[0]);\n }\n\n function resetDropdown() {\n $window.removeEventListener('mousedown', closeOnClick, true);\n $window.removeEventListener('scroll', closeOnResize, true);\n $window.removeEventListener('resize', resetDropdown, true);\n\n // Move the dropdown element back to its original location in the DOM if we moved it.\n if (placeholder) {\n element[0].style.position = '';\n element[0].style.left = '';\n element[0].style.top = '';\n element[0].style.width = originalWidth;\n placeholder.replaceWith(element);\n placeholder = null;\n resetFocus();\n }\n }\n\n function resetFocus() {\n $timeout($select.setFocus);\n }\n };\n }\n };\n}]);\n\nuis.directive('uiSelectFooter', ['uiSelectConfig', function (uiSelectConfig) {\n return {\n templateUrl: function (tElement) {\n // Needed so the uiSelect can detect the transcluded content\n tElement.addClass('ui-select-footer');\n\n // Gets theme attribute from parent (ui-select)\n var theme = tElement.parent().attr('theme') || uiSelectConfig.theme;\n return theme + '/footer.tpl.html';\n },\n restrict: 'EA',\n transclude: true,\n replace: true\n };\n}]);\n\nuis.directive('uiSelectHeader', ['uiSelectConfig', function (uiSelectConfig) {\n return {\n templateUrl: function (tElement) {\n // Needed so the uiSelect can detect the transcluded content\n tElement.addClass('ui-select-header');\n\n // Gets theme attribute from parent (ui-select)\n var theme = tElement.parent().attr('theme') || uiSelectConfig.theme;\n return theme + '/header.tpl.html';\n },\n restrict: 'EA',\n transclude: true,\n replace: true\n };\n}]);\n\nuis.directive('uiSelectHeaderGroupSelectable', ['$timeout', function($timeout) {\n return {\n restrict: 'EA',\n require: ['^uiSelect'],\n scope: {\n isEnabled: \" model\n ngModel.$parsers.unshift(function () {\n var locals = {},\n result,\n resultMultiple = [];\n for (var j = $select.selected.length - 1; j >= 0; j--) {\n locals = {};\n locals[$select.parserResult.itemName] = $select.selected[j];\n result = $select.parserResult.modelMapper(scope, locals);\n resultMultiple.unshift(result);\n }\n return resultMultiple;\n });\n\n // From model --> view\n ngModel.$formatters.unshift(function (inputValue) {\n var data = $select.parserResult && $select.parserResult.source (scope, { $select : {search:''}}), //Overwrite $search\n locals = {},\n result;\n if (!data) return inputValue;\n var resultMultiple = [];\n var checkFnMultiple = function(list, value){\n if (!list || !list.length) return;\n for (var p = list.length - 1; p >= 0; p--) {\n locals[$select.parserResult.itemName] = list[p];\n result = $select.parserResult.modelMapper(scope, locals);\n if($select.parserResult.trackByExp){\n var propsItemNameMatches = /(\\w*)\\./.exec($select.parserResult.trackByExp);\n var matches = /\\.([^\\s]+)/.exec($select.parserResult.trackByExp);\n if(propsItemNameMatches && propsItemNameMatches.length > 0 && propsItemNameMatches[1] == $select.parserResult.itemName){\n if(matches && matches.length>0 && result[matches[1]] == value[matches[1]]){\n resultMultiple.unshift(list[p]);\n return true;\n }\n }\n }\n if (angular.equals(result,value)){\n resultMultiple.unshift(list[p]);\n return true;\n }\n }\n return false;\n };\n if (!inputValue) return resultMultiple; //If ngModel was undefined\n for (var k = inputValue.length - 1; k >= 0; k--) {\n //Check model array of currently selected items\n if (!checkFnMultiple($select.selected, inputValue[k])){\n //Check model array of all items available\n if (!checkFnMultiple(data, inputValue[k])){\n //If not found on previous lists, just add it directly to resultMultiple\n resultMultiple.unshift(inputValue[k]);\n }\n }\n }\n return resultMultiple;\n });\n\n //Watch for external model changes\n scope.$watchCollection(function(){ return ngModel.$modelValue; }, function(newValue, oldValue) {\n if (oldValue != newValue){\n //update the view value with fresh data from items, if there is a valid model value\n if(angular.isDefined(ngModel.$modelValue)) {\n ngModel.$modelValue = null; //Force scope model value and ngModel value to be out of sync to re-run formatters\n }\n $selectMultiple.refreshComponent();\n }\n });\n\n ngModel.$render = function() {\n // Make sure that model value is array\n if(!angular.isArray(ngModel.$viewValue)){\n // Have tolerance for null or undefined values\n if (isNil(ngModel.$viewValue)){\n ngModel.$viewValue = [];\n } else {\n throw uiSelectMinErr('multiarr', \"Expected model value to be array but got '{0}'\", ngModel.$viewValue);\n }\n }\n $select.selected = ngModel.$viewValue;\n $selectMultiple.refreshComponent();\n scope.$evalAsync(); //To force $digest\n };\n\n scope.$on('uis:select', function (event, item) {\n if($select.selected.length >= $select.limit) {\n return;\n }\n $select.selected.push(item);\n var locals = {};\n locals[$select.parserResult.itemName] = item;\n\n $timeout(function(){\n $select.onSelectCallback(scope, {\n $item: item,\n $model: $select.parserResult.modelMapper(scope, locals)\n });\n });\n $selectMultiple.updateModel();\n });\n\n scope.$on('uis:activate', function () {\n $selectMultiple.activeMatchIndex = -1;\n });\n\n scope.$watch('$select.disabled', function(newValue, oldValue) {\n // As the search input field may now become visible, it may be necessary to recompute its size\n if (oldValue && !newValue) $select.sizeSearchInput();\n });\n\n $select.searchInput.on('keydown', function(e) {\n var key = e.which;\n scope.$apply(function() {\n var processed = false;\n // var tagged = false; //Checkme\n if(KEY.isHorizontalMovement(key)){\n processed = _handleMatchSelection(key);\n }\n if (processed && key != KEY.TAB) {\n //TODO Check si el tab selecciona aun correctamente\n //Crear test\n $select.cancelEvent(e);\n }\n });\n });\n function _getCaretPosition(el) {\n if(angular.isNumber(el.selectionStart)) return el.selectionStart;\n // selectionStart is not supported in IE8 and we don't want hacky workarounds so we compromise\n else return el.value.length;\n }\n // Handles selected options in \"multiple\" mode\n function _handleMatchSelection(key){\n var caretPosition = _getCaretPosition($select.searchInput[0]),\n length = $select.selected.length,\n // none = -1,\n first = 0,\n last = length-1,\n curr = $selectMultiple.activeMatchIndex,\n next = $selectMultiple.activeMatchIndex+1,\n prev = $selectMultiple.activeMatchIndex-1,\n newIndex = curr;\n\n if(caretPosition > 0 || ($select.search.length && key == KEY.RIGHT)) return false;\n\n $select.close();\n\n function getNewActiveMatchIndex(){\n switch(key){\n case KEY.LEFT:\n // Select previous/first item\n if(~$selectMultiple.activeMatchIndex) return prev;\n // Select last item\n else return last;\n break;\n case KEY.RIGHT:\n // Open drop-down\n if(!~$selectMultiple.activeMatchIndex || curr === last){\n $select.activate();\n return false;\n }\n // Select next/last item\n else return next;\n break;\n case KEY.BACKSPACE:\n // Remove selected item and select previous/first\n if(~$selectMultiple.activeMatchIndex){\n if($selectMultiple.removeChoice(curr)) {\n return prev;\n } else {\n return curr;\n }\n\n } else {\n // If nothing yet selected, select last item\n return last;\n }\n break;\n case KEY.DELETE:\n // Remove selected item and select next item\n if(~$selectMultiple.activeMatchIndex){\n $selectMultiple.removeChoice($selectMultiple.activeMatchIndex);\n return curr;\n }\n else return false;\n }\n }\n\n newIndex = getNewActiveMatchIndex();\n\n if(!$select.selected.length || newIndex === false) $selectMultiple.activeMatchIndex = -1;\n else $selectMultiple.activeMatchIndex = Math.min(last,Math.max(first,newIndex));\n\n return true;\n }\n\n $select.searchInput.on('keyup', function(e) {\n\n if ( ! KEY.isVerticalMovement(e.which) ) {\n scope.$evalAsync( function () {\n $select.activeIndex = $select.taggingLabel === false ? -1 : 0;\n });\n }\n // Push a \"create new\" item into array if there is a search string\n if ( $select.tagging.isActivated && $select.search.length > 0 ) {\n\n // return early with these keys\n if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC || KEY.isVerticalMovement(e.which) ) {\n return;\n }\n // always reset the activeIndex to the first item when tagging\n $select.activeIndex = $select.taggingLabel === false ? -1 : 0;\n // taggingLabel === false bypasses all of this\n if ($select.taggingLabel === false) return;\n\n var items = angular.copy( $select.items );\n var stashArr = angular.copy( $select.items );\n var newItem;\n var item;\n var hasTag = false;\n var dupeIndex = -1;\n var tagItems;\n var tagItem;\n\n // case for object tagging via transform `$select.tagging.fct` function\n if ( $select.tagging.fct !== undefined) {\n tagItems = $select.$filter('filter')(items,{'isTag': true});\n if ( tagItems.length > 0 ) {\n tagItem = tagItems[0];\n }\n // remove the first element, if it has the `isTag` prop we generate a new one with each keyup, shaving the previous\n if ( items.length > 0 && tagItem ) {\n hasTag = true;\n items = items.slice(1,items.length);\n stashArr = stashArr.slice(1,stashArr.length);\n }\n newItem = $select.tagging.fct($select.search);\n // verify the new tag doesn't match the value of a possible selection choice or an already selected item.\n if (\n stashArr.some(function (origItem) {\n return angular.equals(origItem, newItem);\n }) ||\n $select.selected.some(function (origItem) {\n return angular.equals(origItem, newItem);\n })\n ) {\n scope.$evalAsync(function () {\n $select.activeIndex = 0;\n $select.items = items;\n });\n return;\n }\n if (newItem) newItem.isTag = true;\n // handle newItem string and stripping dupes in tagging string context\n } else {\n // find any tagging items already in the $select.items array and store them\n tagItems = $select.$filter('filter')(items,function (item) {\n return item.match($select.taggingLabel);\n });\n if ( tagItems.length > 0 ) {\n tagItem = tagItems[0];\n }\n item = items[0];\n // remove existing tag item if found (should only ever be one tag item)\n if ( item !== undefined && items.length > 0 && tagItem ) {\n hasTag = true;\n items = items.slice(1,items.length);\n stashArr = stashArr.slice(1,stashArr.length);\n }\n newItem = $select.search+' '+$select.taggingLabel;\n if ( _findApproxDupe($select.selected, $select.search) > -1 ) {\n return;\n }\n // verify the the tag doesn't match the value of an existing item from\n // the searched data set or the items already selected\n if ( _findCaseInsensitiveDupe(stashArr.concat($select.selected)) ) {\n // if there is a tag from prev iteration, strip it / queue the change\n // and return early\n if ( hasTag ) {\n items = stashArr;\n scope.$evalAsync( function () {\n $select.activeIndex = 0;\n $select.items = items;\n });\n }\n return;\n }\n if ( _findCaseInsensitiveDupe(stashArr) ) {\n // if there is a tag from prev iteration, strip it\n if ( hasTag ) {\n $select.items = stashArr.slice(1,stashArr.length);\n }\n return;\n }\n }\n if ( hasTag ) dupeIndex = _findApproxDupe($select.selected, newItem);\n // dupe found, shave the first item\n if ( dupeIndex > -1 ) {\n items = items.slice(dupeIndex+1,items.length-1);\n } else {\n items = [];\n if (newItem) items.push(newItem);\n items = items.concat(stashArr);\n }\n scope.$evalAsync( function () {\n $select.activeIndex = 0;\n $select.items = items;\n\n if ($select.isGrouped) {\n // update item references in groups, so that indexOf will work after angular.copy\n var itemsWithoutTag = newItem ? items.slice(1) : items;\n $select.setItemsFn(itemsWithoutTag);\n if (newItem) {\n // add tag item as a new group\n $select.items.unshift(newItem);\n $select.groups.unshift({name: '', items: [newItem], tagging: true});\n }\n }\n });\n }\n });\n function _findCaseInsensitiveDupe(arr) {\n if ( arr === undefined || $select.search === undefined ) {\n return false;\n }\n var hasDupe = arr.filter( function (origItem) {\n if ( $select.search.toUpperCase() === undefined || origItem === undefined ) {\n return false;\n }\n return origItem.toUpperCase() === $select.search.toUpperCase();\n }).length > 0;\n\n return hasDupe;\n }\n function _findApproxDupe(haystack, needle) {\n var dupeIndex = -1;\n if(angular.isArray(haystack)) {\n var tempArr = angular.copy(haystack);\n for (var i = 0; i
model\n ngModel.$parsers.unshift(function (inputValue) {\n // Keep original value for undefined and null\n if (isNil(inputValue)) {\n return inputValue;\n }\n\n // Allow the null value to be considered a valid model value\n if (inputValue.$$null) {\n return inputValue[$select.itemProperty];\n }\n\n var locals = {};\n locals[$select.parserResult.itemName] = inputValue;\n return $select.parserResult.modelMapper(scope, locals);\n });\n\n //From model --> view\n ngModel.$formatters.unshift(function (inputValue) {\n // Keep original value for undefined and null\n if (isNil(inputValue)) {\n return inputValue;\n }\n\n var data = $select.parserResult && $select.parserResult.source (scope, { $select : {search:''}}), //Overwrite $search\n locals = {},\n result;\n if (data){\n var checkFnSingle = function(d){\n locals[$select.parserResult.itemName] = d;\n result = $select.parserResult.modelMapper(scope, locals);\n return result === inputValue;\n };\n //If possible pass same object stored in $select.selected\n if ($select.selected && checkFnSingle($select.selected)) {\n return $select.selected;\n }\n for (var i = data.length - 1; i >= 0; i--) {\n if (checkFnSingle(data[i])) return data[i];\n }\n }\n return inputValue;\n });\n\n //Update viewValue if model change\n scope.$watch('$select.selected', function(newValue) {\n if (ngModel.$viewValue !== newValue) {\n ngModel.$setViewValue(newValue);\n }\n });\n\n ngModel.$render = function() {\n $select.selected = ngModel.$viewValue;\n };\n\n scope.$on('uis:select', function (event, item) {\n $select.selected = item;\n var locals = {};\n locals[$select.parserResult.itemName] = item;\n\n $timeout(function() {\n $select.onSelectCallback(scope, {\n $item: item,\n $model: isNil(item) ? item : $select.parserResult.modelMapper(scope, locals)\n });\n });\n });\n\n scope.$on('uis:close', function (event, skipFocusser) {\n $timeout(function(){\n if (!skipFocusser) $select.focusser[0].focus();\n },0,false);\n });\n\n //Idea from: https://github.com/ivaynberg/select2/blob/79b5bf6db918d7560bdd959109b7bcfb47edaf43/select2.js#L1954\n var focusser = angular.element(\" \");\n $compile(focusser)(scope);\n $select.focusser = focusser;\n\n // Move focuser out of because append-to-body=\"true\" will move the focusser out of :tabbable order.\n element.parent().parent().prepend(focusser);\n\n scope.$on('$destroy', function() {\n if ($select.focusser) {\n $select.focusser.remove();\n }\n });\n\n focusser.on(\"focus\", function(){\n scope.$evalAsync(function(){\n $select.focus = true;\n });\n });\n\n focusser.on(\"blur\", function(){\n scope.$evalAsync(function(){\n $select.focus = false;\n });\n });\n\n focusser.on(\"keydown\", function(e){\n if (e.which === KEY.BACKSPACE && $select.backspaceReset !== false) {\n $select.select($select.nullValue);\n $select.cancelEvent(e);\n scope.$apply();\n return;\n }\n\n if (e.which === KEY.TAB) {\n $select.tabNavigate(e.shiftKey);\n $select.cancelEvent(e);\n return;\n }\n\n if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {\n return;\n }\n\n if (e.which == KEY.DOWN || e.which == KEY.UP || e.which == KEY.ENTER || e.which == KEY.SPACE){\n $select.cancelEvent(e);\n $select.activate();\n }\n\n scope.$digest();\n });\n\n focusser.on(\"keyup input\", function(e){\n if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC || e.which == KEY.ENTER || e.which === KEY.BACKSPACE) {\n return;\n }\n\n $select.activate(focusser.val()); //User pressed some regular key, so we pass it to the search input\n focusser.val('');\n scope.$digest();\n });\n }\n };\n}]);\n\n// Make multiple matches sortable\nuis.directive('uiSelectSort', ['$timeout', 'uiSelectConfig', 'uiSelectMinErr', function($timeout, uiSelectConfig, uiSelectMinErr) {\n return {\n require: ['^^uiSelect', '^ngModel'],\n link: function(scope, element, attrs, ctrls) {\n if (scope[attrs.uiSelectSort] === null) {\n throw uiSelectMinErr('sort', 'Expected a list to sort');\n }\n\n var $select = ctrls[0];\n var $ngModel = ctrls[1];\n\n var options = angular.extend({\n axis: 'horizontal'\n },\n scope.$eval(attrs.uiSelectSortOptions));\n\n var axis = options.axis;\n var draggingClassName = 'dragging';\n var droppingClassName = 'dropping';\n var droppingBeforeClassName = 'dropping-before';\n var droppingAfterClassName = 'dropping-after';\n\n scope.$watch(function(){\n return $select.sortable;\n }, function(newValue){\n if (newValue) {\n element.attr('draggable', true);\n } else {\n element.removeAttr('draggable');\n }\n });\n\n if (element.data('disallowDrop')) {\n return;\n }\n\n element.on('dragstart', function(event) {\n element.addClass(draggingClassName);\n\n (event.dataTransfer || event.originalEvent.dataTransfer).setData('text', scope.$index.toString());\n });\n\n element.on('dragend', function() {\n removeClass(draggingClassName);\n });\n\n var move = function(from, to) {\n /*jshint validthis: true */\n this.splice(to, 0, this.splice(from, 1)[0]);\n };\n\n var removeClass = function(className) {\n angular.forEach($select.$element.querySelectorAll('.' + className), function(el){\n angular.element(el).removeClass(className);\n });\n };\n\n var dragOverHandler = function(event) {\n event.preventDefault();\n\n var offset = axis === 'vertical' ? event.offsetY || event.layerY || (event.originalEvent ? event.originalEvent.offsetY : 0) : event.offsetX || event.layerX || (event.originalEvent ? event.originalEvent.offsetX : 0);\n\n if (offset < (this[axis === 'vertical' ? 'offsetHeight' : 'offsetWidth'] / 2)) {\n removeClass(droppingAfterClassName);\n element.addClass(droppingBeforeClassName);\n\n } else {\n removeClass(droppingBeforeClassName);\n element.addClass(droppingAfterClassName);\n }\n };\n\n var dropTimeout;\n\n var dropHandler = function(event) {\n event.preventDefault();\n\n var droppedItemIndex = parseInt((event.dataTransfer || event.originalEvent.dataTransfer).getData('text'), 10);\n\n // prevent event firing multiple times in firefox\n $timeout.cancel(dropTimeout);\n dropTimeout = $timeout(function() {\n _dropHandler(droppedItemIndex);\n }, 20);\n };\n\n var _dropHandler = function(droppedItemIndex) {\n var theList = scope.$eval(attrs.uiSelectSort);\n var itemToMove = theList[droppedItemIndex];\n var newIndex = null;\n\n if (element.hasClass(droppingBeforeClassName)) {\n if (droppedItemIndex < scope.$index) {\n newIndex = scope.$index - 1;\n } else {\n newIndex = scope.$index;\n }\n } else {\n if (droppedItemIndex < scope.$index) {\n newIndex = scope.$index;\n } else {\n newIndex = scope.$index + 1;\n }\n }\n\n move.apply(theList, [droppedItemIndex, newIndex]);\n\n $ngModel.$setViewValue(Date.now());\n\n scope.$apply(function() {\n scope.$emit('uiSelectSort:change', {\n array: theList,\n item: itemToMove,\n from: droppedItemIndex,\n to: newIndex\n });\n });\n\n removeClass(droppingClassName);\n removeClass(droppingBeforeClassName);\n removeClass(droppingAfterClassName);\n\n element.off('drop', dropHandler);\n };\n\n element.on('dragenter', function() {\n if (element.hasClass(draggingClassName)) {\n return;\n }\n\n element.addClass(droppingClassName);\n\n element.on('dragover', dragOverHandler);\n element.on('drop', dropHandler);\n });\n\n element.on('dragleave', function(event) {\n if (event.target != element) {\n return;\n }\n\n removeClass(droppingClassName);\n removeClass(droppingBeforeClassName);\n removeClass(droppingAfterClassName);\n\n element.off('dragover', dragOverHandler);\n element.off('drop', dropHandler);\n });\n }\n };\n}]);\n\nuis.directive('uisOpenClose', ['$parse', '$timeout', function ($parse, $timeout) {\n return {\n restrict: 'A',\n require: 'uiSelect',\n link: function (scope, element, attrs, $select) {\n $select.onOpenCloseCallback = $parse(attrs.uisOpenClose);\n\n scope.$watch('$select.open', function (isOpen, previousState) {\n if (isOpen !== previousState) {\n $timeout(function () {\n $select.onOpenCloseCallback(scope, {\n isOpen: isOpen\n });\n });\n }\n });\n }\n };\n}]);\n\n/**\n * Parses \"repeat\" attribute.\n *\n * Taken from AngularJS ngRepeat source code\n * See https://github.com/angular/angular.js/blob/v1.2.15/src/ng/directive/ngRepeat.js#L211\n *\n * Original discussion about parsing \"repeat\" attribute instead of fully relying on ng-repeat:\n * https://github.com/angular-ui/ui-select/commit/5dd63ad#commitcomment-5504697\n */\n\nuis.service('uisRepeatParser', ['uiSelectMinErr', '$parse', function(uiSelectMinErr, $parse) {\n var self = this;\n\n /**\n * Example:\n * expression = \"address in addresses | filter: {street: $select.search} track by $index\"\n * itemName = \"address\",\n * source = \"addresses | filter: {street: $select.search}\",\n * trackByExp = \"$index\",\n */\n self.parse = function(expression) {\n\n\n var match;\n //var isObjectCollection = /\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)/.test(expression);\n // If an array is used as collection\n\n // if (isObjectCollection){\n // 000000000000000000000000000000111111111000000000000000222222222222220033333333333333333333330000444444444444444444000000000000000055555555555000000000000000000000066666666600000000\n match = expression.match(/^\\s*(?:([\\s\\S]+?)\\s+as\\s+)?(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+(\\s*[\\s\\S]+?)?(?:\\s+track\\s+by\\s+([\\s\\S]+?))?\\s*$/);\n\n // 1 Alias\n // 2 Item\n // 3 Key on (key,value)\n // 4 Value on (key,value)\n // 5 Source expression (including filters)\n // 6 Track by\n\n if (!match) {\n throw uiSelectMinErr('iexp', \"Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.\",\n expression);\n }\n\n var source = match[5],\n filters = '';\n\n // When using (key,value) ui-select requires filters to be extracted, since the object\n // is converted to an array for $select.items\n // (in which case the filters need to be reapplied)\n if (match[3]) {\n // Remove any enclosing parenthesis\n source = match[5].replace(/(^\\()|(\\)$)/g, '');\n // match all after | but not after ||\n var filterMatch = match[5].match(/^\\s*(?:[\\s\\S]+?)(?:[^\\|]|\\|\\|)+([\\s\\S]*)\\s*$/);\n if(filterMatch && filterMatch[1].trim()) {\n filters = filterMatch[1];\n source = source.replace(filters, '');\n }\n }\n\n return {\n itemName: match[4] || match[2], // (lhs) Left-hand side,\n keyName: match[3], //for (key, value) syntax\n source: $parse(source),\n filters: filters,\n trackByExp: match[6],\n getTrackedValue: function(scope, item) {\n if (!this.trackByExp) {\n return item;\n } else {\n var locals = {};\n locals[this.itemName] = item;\n return scope.$eval(this.trackByExp, locals);\n }\n },\n modelMapper: $parse(match[1] || match[4] || match[2]),\n repeatExpression: function (grouped) {\n var expression = this.itemName + ' in ' + (grouped ? '$group.items' : '$select.items');\n if (this.trackByExp) {\n expression += ' track by ' + this.trackByExp;\n }\n return expression;\n }\n };\n\n };\n\n self.getGroupNgRepeatExpression = function() {\n return '$group in $select.groups track by $group.name';\n };\n\n}]);\n\n}());\nangular.module(\"ui.select\").run([\"$templateCache\", function($templateCache) {$templateCache.put(\"bootstrap/choices.tpl.html\",\"\");\n$templateCache.put(\"bootstrap/footer.tpl.html\",\"\");\n$templateCache.put(\"bootstrap/header.tpl.html\",\"\");\n$templateCache.put(\"bootstrap/match-multiple.tpl.html\",\" × \");\n$templateCache.put(\"bootstrap/match.tpl.html\",\"
\");\n$templateCache.put(\"bootstrap/no-choice.tpl.html\",\"\");\n$templateCache.put(\"bootstrap/select-multiple.tpl.html\",\" 0\\\" class=\\\"ui-select-dropdown dropdown-menu\\\">
\");\n$templateCache.put(\"bootstrap/select.tpl.html\",\"
0\\\" class=\\\"ui-select-dropdown dropdown-menu\\\">
\");\n$templateCache.put(\"select2/choices.tpl.html\",\"\");\n$templateCache.put(\"select2/footer.tpl.html\",\"\");\n$templateCache.put(\"select2/header.tpl.html\",\"\");\n$templateCache.put(\"select2/match-multiple.tpl.html\",\" \");\n$templateCache.put(\"select2/match.tpl.html\",\" \");\n$templateCache.put(\"select2/no-choice.tpl.html\",\"\");\n$templateCache.put(\"select2/select-multiple.tpl.html\",\"\");\n$templateCache.put(\"select2/select.tpl.html\",\"\");\n$templateCache.put(\"selectize/choices.tpl.html\",\"\");\n$templateCache.put(\"selectize/footer.tpl.html\",\"\");\n$templateCache.put(\"selectize/header.tpl.html\",\"\");\n$templateCache.put(\"selectize/match-multiple.tpl.html\",\" ×
\");\n$templateCache.put(\"selectize/match.tpl.html\",\"
\");\n$templateCache.put(\"selectize/no-choice.tpl.html\",\"\");\n$templateCache.put(\"selectize/select-multiple.tpl.html\",\"\");\n$templateCache.put(\"selectize/select.tpl.html\",\"\");}]);",null,null]}
\ No newline at end of file
+{"version":3,"sources":["select.js","select_without_templates.js","templates.js"],"names":["isNil","value","undefined","uiSelectCtrl","$scope","$element","$timeout","$filter","$$uisDebounce","RepeatParser","uiSelectMinErr","uiSelectConfig","$parse","$window","isEmpty","selected","ctrl","$$null","multiple","length","getSelectedText","find","text","getPlaceholder","placeholder","_findIndex","collection","predicate","thisArg","findIndex","list","Object","i","call","_resetSearchInput","resetSearchInput","search","EMPTY_SEARCH","setActiveIndexToSelected","active","parserResult","angular","equals","nullValue","items","isNullValue","trackedValue","getTrackedValue","item","_isItemDisabled","activeIndex","_groupsFilter","groups","groupNames","j","result","name","push","itemProperty","activate","initSearchValue","avoidReset","disabled","open","searchEnabled","close","$broadcast","taggingLabel","focusSearchInput","tagging","isActivated","_ensureHighlightVisible","searchInput","focus","findGroupByName","noStrict","filter","group","parseRepeatAttr","repeatAttr","groupByExp","groupFilterExp","createArrayFromObject","origSrc","originalSource","$uisSource","keys","map","v","keyName","createNullItem","nullItem","needsNullItem","required","nullLabel","toLowerCase","indexOf","some","onOriginalSourceChange","newVal","oldVal","onSourceChange","isArray","refreshItems","isDefined","ngModel","$modelValue","data","excludeSelected","isNotSelected","selectedItem","selectedItems","every","source","removeSelected","setItemsFn","calculateDropdownPos","updateFlatItems","unshift","updateGroups","groupFn","$eval","forEach","groupName","isFunction","groupFilterFn","reduce","concat","parse","isGrouped","itemName","filters","$watch","$watchCollection","refresh","refreshAttr","refreshDelayPromise","cancel","$select","minimumInputLength","refreshPromise","then","refreshing","refreshDelay","isActive","itemScope","itemIndex","isUndefined","onHighlightCallback","_isItemSelected","selection","_updateItemDisabled","isDisabled","disabledItemIndex","disabledItems","splice","disableChoiceExpression","isTag","select","skipFocusser","$event","clickTriggeredSelect","type","fct","replace","trim","closeOnSelect","$setTouched","setFocus","clear","stopPropagation","focusser","toggle","e","cancelEvent","_initaliseLockedChoices","doInitalise","_updateItemLocked","isLocked","lockedItemIndex","lockedItems","_isItemlocked","isLockedFn","lockChoiceExpression","sizeSearchInput","calculateContainerWidth","container","clientWidth","input","offsetParent","updateIfVisible","containerWidth","inputWidth","offsetLeft","css","sizeWatch","updaterScheduled","$$postDigest","noop","_handleDropDownSelection","key","shiftKey","processed","KEY","DOWN","UP","len","Math","max","min","TAB","tabNavigate","ENTER","ESC","preventDefault","focusEl","focusable","element","index","el","onSearchInputKeyDown","which","$apply","tagged","taggingTokens","tokens","MAP","keyCode","triggerHandler","newItem","isVerticalMovement","onSearchInputPaste","window","clipboardData","getData","originalEvent","separator","toSeparator","split","oldsearch","paste","onSearchInputTagged","querySelectorAll","choices","highlighted","posY","offsetTop","clientHeight","scrollTop","height","offsetHeight","isLockChoiceExpressionDefined","onActiveIndexChange","attr","generatedId","onDestroy","off","onResize","onOpenChange","removeAttr","this","dropdownXPosition","dropdownYPosition","sortable","spinnerClass","spinnerEnabled","on","$on","SPACE","LEFT","RIGHT","SHIFT","CTRL","ALT","PAGE_UP","PAGE_DOWN","HOME","END","BACKSPACE","DELETE","COMMAND","91","8","9","13","16","17","18","19","20","27","32","33","34","35","36","37","38","39","40","43","44","45","46","48","49","50","51","52","53","54","55","56","57","59","61","65","66","67","68","69","70","71","72","73","74","75","76","77","78","79","80","81","82","83","84","85","86","87","88","89","90","96","97","98","99","100","101","102","103","104","105","106","107","109","110","111","112","113","114","115","116","117","118","119","120","121","122","123","144","145","186","187","188","189","190","191","192","219","220","221","222","isControl","k","metaKey","ctrlKey","isFunctionKey","isHorizontalMovement","sep","prototype","selector","closest","elem","matchesSelector","matches","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","bind","parentElement","latestId","uis","module","constant","theme","generateId","appendToBody","backspaceReset","service","minErr","$$minErr","error","apply","arguments","message","RegExp","Error","directive","link","scope","attrs","transclude","clone","append","escapeRegexp","queryToEscape","matchItem","query","factory","$document","boundingClientRect","getBoundingClientRect","width","prop","top","pageYOffset","documentElement","left","pageXOffset","scrollLeft","callback","debounceTime","timeoutPromise","self","args","Array","slice","$compile","restrict","require","templateUrl","tElement","addClass","parent","compile","tAttrs","repeat","groupBy","groupFilter","getGroupNgRepeatExpression","repeatExpression","rowsInner","clickTarget","document","addEventListener","uiDisableChoice","onHighlight","parseInt","position","String","newValue","$observe","prerender","controller","uisOffset","controllerAs","match","exec","ngClass","combined","inputId","id","ctrls","transcludeFn","calculateSelectLeftPosition","offset","body","edgeOffscreenAmount","paddingFromEdge","leftPosition","closeOnClick","contains","target","srcElement","jQuery","focusableControls","targetController","tagName","$digest","closeOnResize","closeOnScroll","positionDropdown","style","after","originalWidth","appendChild","resetDropdown","removeEventListener","replaceWith","resetFocus","$fieldset","dropdown","baseTitle","title","focusserTitle","focusserId","onSelectCallback","onSelect","onRemoveCallback","onRemove","choiceGrouped","tabindex","limit","taggingEval","ngRequired","oldRequired","autofocus","focusOn","transcluded","transcludedMatch","transcludedChoices","transcludedNoChoice","transcludedHeader","remove","transcludedFooter","isOpen","$evalAsync","visibility","removeClass","offsetDropdown","scrollTarget","xState","toggleClass","yState","isEnabled","getElements","console","enableClick","hasClass","disableClick","getAttribute","attribute","hasAttribute","multi","uiLockChoice","activeMatchIndex","updateModel","$setViewValue","Date","now","refreshComponent","removeChoice","removedChoice","locals","$item","$model","modelMapper","_getCaretPosition","isNumber","selectionStart","_handleMatchSelection","getNewActiveMatchIndex","$selectMultiple","prev","last","curr","next","caretPosition","first","newIndex","_findCaseInsensitiveDupe","arr","hasDupe","origItem","toUpperCase","_findApproxDupe","haystack","needle","dupeIndex","tempArr","copy","mockObj","isObject","$isEmpty","$parsers","resultMultiple","$formatters","inputValue","checkFnMultiple","p","trackByExp","propsItemNameMatches","oldValue","$render","$viewValue","event","tagItems","tagItem","stashArr","hasTag","itemsWithoutTag","checkFnSingle","d","prepend","val","uiSelectSort","$ngModel","options","extend","axis","uiSelectSortOptions","draggingClassName","droppingClassName","droppingBeforeClassName","droppingAfterClassName","dataTransfer","setData","$index","toString","dropTimeout","move","from","to","className","dragOverHandler","offsetY","layerY","offsetX","layerX","dropHandler","droppedItemIndex","_dropHandler","theList","itemToMove","$emit","array","onOpenCloseCallback","uisOpenClose","previousState","expression","filterMatch","grouped","run","$templateCache","put"],"mappings":"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","file":"select.min.js","sourcesContent":["/*! ui-select@0.20.1 https://github.com/bdb-opensource/ui-select (MIT License) */\n(function () { \n\"use strict\";\nvar KEY = {\n TAB: 9,\n ENTER: 13,\n ESC: 27,\n SPACE: 32,\n LEFT: 37,\n UP: 38,\n RIGHT: 39,\n DOWN: 40,\n SHIFT: 16,\n CTRL: 17,\n ALT: 18,\n PAGE_UP: 33,\n PAGE_DOWN: 34,\n HOME: 36,\n END: 35,\n BACKSPACE: 8,\n DELETE: 46,\n COMMAND: 91,\n\n MAP: { 91 : \"COMMAND\", 8 : \"BACKSPACE\" , 9 : \"TAB\" , 13 : \"ENTER\" , 16 : \"SHIFT\" , 17 : \"CTRL\" , 18 : \"ALT\" , 19 : \"PAUSEBREAK\" , 20 : \"CAPSLOCK\" , 27 : \"ESC\" , 32 : \"SPACE\" , 33 : \"PAGE_UP\", 34 : \"PAGE_DOWN\" , 35 : \"END\" , 36 : \"HOME\" , 37 : \"LEFT\" , 38 : \"UP\" , 39 : \"RIGHT\" , 40 : \"DOWN\" , 43 : \"+\" , 44 : \"PRINTSCREEN\" , 45 : \"INSERT\" , 46 : \"DELETE\", 48 : \"0\" , 49 : \"1\" , 50 : \"2\" , 51 : \"3\" , 52 : \"4\" , 53 : \"5\" , 54 : \"6\" , 55 : \"7\" , 56 : \"8\" , 57 : \"9\" , 59 : \";\", 61 : \"=\" , 65 : \"A\" , 66 : \"B\" , 67 : \"C\" , 68 : \"D\" , 69 : \"E\" , 70 : \"F\" , 71 : \"G\" , 72 : \"H\" , 73 : \"I\" , 74 : \"J\" , 75 : \"K\" , 76 : \"L\", 77 : \"M\" , 78 : \"N\" , 79 : \"O\" , 80 : \"P\" , 81 : \"Q\" , 82 : \"R\" , 83 : \"S\" , 84 : \"T\" , 85 : \"U\" , 86 : \"V\" , 87 : \"W\" , 88 : \"X\" , 89 : \"Y\" , 90 : \"Z\", 96 : \"0\" , 97 : \"1\" , 98 : \"2\" , 99 : \"3\" , 100 : \"4\" , 101 : \"5\" , 102 : \"6\" , 103 : \"7\" , 104 : \"8\" , 105 : \"9\", 106 : \"*\" , 107 : \"+\" , 109 : \"-\" , 110 : \".\" , 111 : \"/\", 112 : \"F1\" , 113 : \"F2\" , 114 : \"F3\" , 115 : \"F4\" , 116 : \"F5\" , 117 : \"F6\" , 118 : \"F7\" , 119 : \"F8\" , 120 : \"F9\" , 121 : \"F10\" , 122 : \"F11\" , 123 : \"F12\", 144 : \"NUMLOCK\" , 145 : \"SCROLLLOCK\" , 186 : \";\" , 187 : \"=\" , 188 : \",\" , 189 : \"-\" , 190 : \".\" , 191 : \"/\" , 192 : \"`\" , 219 : \"[\" , 220 : \"\\\\\" , 221 : \"]\" , 222 : \"'\"\n },\n\n isControl: function (e) {\n var k = e.which;\n switch (k) {\n case KEY.COMMAND:\n case KEY.SHIFT:\n case KEY.CTRL:\n return true;\n }\n\n if (e.metaKey || e.ctrlKey) return true;\n\n return false;\n },\n isFunctionKey: function (k) {\n k = k.which ? k.which : k;\n return k >= 112 && k <= 123;\n },\n isVerticalMovement: function (k){\n return ~[KEY.UP, KEY.DOWN].indexOf(k);\n },\n isHorizontalMovement: function (k){\n return ~[KEY.LEFT,KEY.RIGHT,KEY.BACKSPACE,KEY.DELETE].indexOf(k);\n },\n toSeparator: function (k) {\n var sep = {ENTER:\"\\n\",TAB:\"\\t\",SPACE:\" \"}[k];\n if (sep) return sep;\n // return undefined for special keys other than enter, tab or space.\n // no way to use them to cut strings.\n return KEY[k] ? undefined : k;\n }\n };\n\nfunction isNil(value) {\n return value === undefined || value === null;\n}\n\n/**\n * Add querySelectorAll() to jqLite.\n *\n * jqLite find() is limited to lookups by tag name.\n * TODO This will change with future versions of AngularJS, to be removed when this happens\n *\n * See jqLite.find - why not use querySelectorAll? https://github.com/angular/angular.js/issues/3586\n * See feat(jqLite): use querySelectorAll instead of getElementsByTagName in jqLite.find https://github.com/angular/angular.js/pull/3598\n */\nif (angular.element.prototype.querySelectorAll === undefined) {\n angular.element.prototype.querySelectorAll = function(selector) {\n return angular.element(this[0].querySelectorAll(selector));\n };\n}\n\n/**\n * Add closest() to jqLite.\n */\nif (angular.element.prototype.closest === undefined) {\n angular.element.prototype.closest = function( selector) {\n var elem = this[0];\n var matchesSelector = elem.matches || elem.webkitMatchesSelector || elem.mozMatchesSelector || elem.msMatchesSelector;\n\n while (elem) {\n if (matchesSelector.bind(elem)(selector)) {\n return elem;\n } else {\n elem = elem.parentElement;\n }\n }\n return false;\n };\n}\n\nvar latestId = 0;\n\nvar uis = angular.module('ui.select', [])\n\n.constant('uiSelectConfig', {\n theme: 'bootstrap',\n searchEnabled: true,\n sortable: false,\n placeholder: '', // Empty by default, like HTML tag \n refreshDelay: 1000, // In milliseconds\n closeOnSelect: true,\n skipFocusser: false,\n dropdownXPosition: 'auto',\n dropdownYPosition: 'auto',\n removeSelected: true,\n resetSearchInput: true,\n generateId: function() {\n return latestId++;\n },\n appendToBody: false,\n spinnerEnabled: false,\n spinnerClass: 'glyphicon glyphicon-refresh ui-select-spin',\n backspaceReset: true,\n nullLabel: '(none)',\n nullValue: null,\n})\n\n// See Rename minErr and make it accessible from outside https://github.com/angular/angular.js/issues/6913\n.service('uiSelectMinErr', function() {\n var minErr = angular.$$minErr('ui.select');\n return function() {\n var error = minErr.apply(this, arguments);\n var message = error.message.replace(new RegExp('\\nhttp://errors.angularjs.org/.*'), '');\n return new Error(message);\n };\n})\n\n// Recreates old behavior of ng-transclude. Used internally.\n.directive('uisTranscludeAppend', function () {\n return {\n link: function (scope, element, attrs, ctrl, transclude) {\n transclude(scope, function (clone) {\n element.append(clone);\n });\n }\n };\n})\n\n/**\n * Highlights text that matches $select.search.\n *\n * Taken from AngularUI Bootstrap Typeahead\n * See https://github.com/angular-ui/bootstrap/blob/0.10.0/src/typeahead/typeahead.js#L340\n */\n.filter('highlight', function() {\n function escapeRegexp(queryToEscape) {\n return ('' + queryToEscape).replace(/([.?*+^$[\\]\\\\(){}|-])/g, '\\\\$1');\n }\n\n return function(matchItem, query) {\n return query && matchItem ? ('' + matchItem).replace(new RegExp(escapeRegexp(query), 'gi'), '$& ') : matchItem;\n };\n})\n\n/**\n * A read-only equivalent of jQuery's offset function: http://api.jquery.com/offset/\n *\n * Taken from AngularUI Bootstrap Position:\n * See https://github.com/angular-ui/bootstrap/blob/master/src/position/position.js#L70\n */\n.factory('uisOffset',\n ['$document', '$window',\n function ($document, $window) {\n\n return function(element) {\n var boundingClientRect = element[0].getBoundingClientRect();\n return {\n width: boundingClientRect.width || element.prop('offsetWidth'),\n height: boundingClientRect.height || element.prop('offsetHeight'),\n top: boundingClientRect.top + ($window.pageYOffset || $document[0].documentElement.scrollTop),\n left: boundingClientRect.left + ($window.pageXOffset || $document[0].documentElement.scrollLeft)\n };\n };\n}]);\n\n/**\n * Debounces functions\n *\n * Taken from UI Bootstrap $$debounce source code\n * See https://github.com/angular-ui/bootstrap/blob/master/src/debounce/debounce.js\n *\n */\nuis.factory('$$uisDebounce', ['$timeout', function($timeout) {\n return function(callback, debounceTime) {\n var timeoutPromise;\n\n return function() {\n var self = this;\n var args = Array.prototype.slice.call(arguments);\n if (timeoutPromise) {\n $timeout.cancel(timeoutPromise);\n }\n\n timeoutPromise = $timeout(function() {\n callback.apply(self, args);\n }, debounceTime);\n };\n };\n}]);\n\nuis.directive('uiSelectChoices',\n ['uiSelectConfig', 'uisRepeatParser', 'uiSelectMinErr', '$compile', '$window',\n function(uiSelectConfig, RepeatParser, uiSelectMinErr, $compile, $window) {\n\n return {\n restrict: 'EA',\n require: '^uiSelect',\n replace: true,\n transclude: true,\n templateUrl: function(tElement) {\n // Needed so the uiSelect can detect the transcluded content\n tElement.addClass('ui-select-choices');\n\n // Gets theme attribute from parent (ui-select)\n var theme = tElement.parent().attr('theme') || uiSelectConfig.theme;\n return theme + '/choices.tpl.html';\n },\n\n compile: function(tElement, tAttrs) {\n\n if (!tAttrs.repeat) throw uiSelectMinErr('repeat', \"Expected 'repeat' expression.\");\n\n // var repeat = RepeatParser.parse(attrs.repeat);\n var groupByExp = tAttrs.groupBy;\n var groupFilterExp = tAttrs.groupFilter;\n var groups = tElement.querySelectorAll('.ui-select-choices-group');\n\n // Prevent unnecessary watches when dropdown is closed\n // On original ui-select implementation, pre-rendering was off by default (i.e. `ng-if` was always set)\n groups.attr('ng-if', '$select.open || $select.prerender');\n\n if (groupByExp) {\n if (groups.length !== 1) throw uiSelectMinErr('rows', \"Expected 1 .ui-select-choices-group but got '{0}'.\", groups.length);\n groups.attr('ng-repeat', RepeatParser.getGroupNgRepeatExpression());\n }\n\n var parserResult = RepeatParser.parse(tAttrs.repeat);\n\n var choices = tElement.querySelectorAll('.ui-select-choices-row');\n if (choices.length !== 1) {\n throw uiSelectMinErr('rows', \"Expected 1 .ui-select-choices-row but got '{0}'.\", choices.length);\n }\n\n choices.attr('ng-repeat', parserResult.repeatExpression(groupByExp));\n\n var rowsInner = tElement.querySelectorAll('.ui-select-choices-row-inner');\n if (rowsInner.length !== 1) {\n throw uiSelectMinErr('rows', \"Expected 1 .ui-select-choices-row-inner but got '{0}'.\", rowsInner.length);\n }\n rowsInner.attr('uis-transclude-append', ''); //Adding uisTranscludeAppend directive to row element after choices element has ngRepeat\n\n // If IE8 then need to target rowsInner to apply the ng-click attr as choices will not capture the event.\n var clickTarget = $window.document.addEventListener ? choices : rowsInner;\n clickTarget.attr('ng-click', '$select.select(' + parserResult.itemName + ',$select.skipFocusser,$event)');\n\n return function link(scope, element, attrs, $select) {\n $select.parseRepeatAttr(attrs.repeat, groupByExp, groupFilterExp); //Result ready at $select.parserResult\n $select.disableChoiceExpression = attrs.uiDisableChoice;\n $select.onHighlightCallback = attrs.onHighlight;\n $select.minimumInputLength = parseInt(attrs.minimumInputLength) || 0;\n\n // Position may be: [auto|up|down] [auto|left|right].\n var position = String(attrs.position || '').toLowerCase().split(/\\s+/g);\n $select.dropdownYPosition = position[0] || uiSelectConfig.dropdownYPosition;\n $select.dropdownXPosition = position[1] || uiSelectConfig.dropdownXPosition;\n\n scope.$watch('$select.search', function(newValue) {\n if(newValue && !$select.open && $select.multiple) $select.activate(false, true);\n $select.activeIndex = $select.tagging.isActivated ? -1 : 0;\n if (!attrs.minimumInputLength || $select.search.length >= attrs.minimumInputLength) {\n $select.refresh(attrs.refresh);\n } else {\n $select.items = [];\n }\n });\n\n attrs.$observe('prerender', function(prerender) {\n prerender = scope.$eval(prerender);\n $select.prerender = prerender !== false;\n });\n\n attrs.$observe('refreshDelay', function(refreshDelay) {\n refreshDelay = scope.$eval(refreshDelay);\n $select.refreshDelay = refreshDelay !== undefined ? refreshDelay : uiSelectConfig.refreshDelay;\n });\n\n attrs.$observe('nullValue', function(value) {\n value = scope.$eval(value);\n $select.nullValue = value !== undefined ? value : null;\n $select.refreshItems();\n });\n\n attrs.$observe('nullLabel', function(value) {\n $select.nullLabel = value !== undefined && value !== '' ? value : uiSelectConfig.nullLabel;\n });\n\n scope.$watch('$select.open', function(open) {\n if (open) {\n element.attr('role', 'listbox');\n $select.refresh(attrs.refresh);\n } else {\n element.removeAttr('role');\n }\n });\n };\n }\n };\n}]);\n\n/**\n * Contains ui-select \"intelligence\".\n *\n * The goal is to limit dependency on the DOM whenever possible and\n * put as much logic in the controller (instead of the link functions) as possible so it can be easily tested.\n */\nuis.controller('uiSelectCtrl', [\n '$scope', '$element', '$timeout', '$filter', '$$uisDebounce', 'uisRepeatParser', 'uiSelectMinErr', 'uiSelectConfig',\n '$parse', '$window', uiSelectCtrl\n]);\n\nfunction uiSelectCtrl($scope, $element, $timeout, $filter, $$uisDebounce, RepeatParser, uiSelectMinErr, uiSelectConfig, $parse, $window) {\n //#region Declarations\n var ctrl = this; // jshint ignore:line\n var disabledItems = [];\n var EMPTY_SEARCH = '';\n var onResize = $$uisDebounce(sizeSearchInput, 50);\n var refreshDelayPromise;\n var sizeWatch = null;\n var updaterScheduled = false;\n ctrl.$element = $element;\n ctrl.$filter = $filter;\n ctrl.activeIndex = 0; //Dropdown of choices\n ctrl.clickTriggeredSelect = false;\n ctrl.closeOnSelect = true; //Initialized inside uiSelect directive link function\n ctrl.disableChoiceExpression = undefined; // Initialized inside uiSelectChoices directive link function\n ctrl.disabled = false;\n ctrl.dropdownXPosition = 'auto';\n ctrl.dropdownYPosition = 'auto';\n ctrl.focus = false;\n ctrl.focusser = undefined; //Reference to input element used to handle focus events\n ctrl.items = []; //All available choices\n ctrl.lockChoiceExpression = undefined; // Initialized inside uiSelectMatch directive link function\n ctrl.multiple = undefined; // Initialized inside uiSelect directive link function\n ctrl.nullLabel = uiSelectConfig.nullLabel;\n ctrl.nullValue = uiSelectConfig.nullValue;\n ctrl.open = false;\n ctrl.paste = uiSelectConfig.paste;\n ctrl.placeholder = uiSelectConfig.placeholder;\n ctrl.refreshDelay = uiSelectConfig.refreshDelay;\n ctrl.refreshing = false;\n ctrl.removeSelected = uiSelectConfig.removeSelected; //If selected item(s) should be removed from dropdown list\n ctrl.resetSearchInput = uiSelectConfig.resetSearchInput;\n ctrl.search = EMPTY_SEARCH;\n ctrl.searchEnabled = uiSelectConfig.searchEnabled;\n ctrl.searchInput = $element.querySelectorAll('input.ui-select-search');\n ctrl.selected = undefined;\n ctrl.skipFocusser = false; //Set to true to avoid returning focus to ctrl when item is selected\n ctrl.sortable = uiSelectConfig.sortable;\n ctrl.spinnerClass = uiSelectConfig.spinnerClass;\n ctrl.spinnerEnabled = uiSelectConfig.spinnerEnabled;\n ctrl.tagging = {isActivated: false, fct: undefined};\n ctrl.taggingTokens = {isActivated: false, tokens: undefined};\n //#endregion\n\n //#region Controller Interface\n ctrl.activate = activate;\n ctrl.cancelEvent = cancelEvent;\n ctrl.clear = clear;\n ctrl.close = close;\n ctrl.findGroupByName = findGroupByName;\n ctrl.focusSearchInput = focusSearchInput;\n ctrl.getPlaceholder = getPlaceholder;\n ctrl.getSelectedText = getSelectedText;\n ctrl.isActive = isActive;\n ctrl.isDisabled = isDisabled;\n ctrl.isEmpty = isEmpty;\n ctrl.isLocked = function() { return false; }; // Overwritten: assume unlocked until _initaliseLockedChoices\n ctrl.parseRepeatAttr = parseRepeatAttr;\n ctrl.refresh = refresh;\n ctrl.refreshItems = angular.noop; // Overwritten: do nothing until parseRepeatAttr is called\n ctrl.select = select;\n ctrl.setFocus = setFocus;\n ctrl.sizeSearchInput = sizeSearchInput;\n ctrl.tabNavigate = tabNavigate;\n ctrl.toggle = toggle;\n //#endregion\n\n //#region Initialization\n if (ctrl.searchInput.length !== 1) {\n throw uiSelectMinErr('searchInput', \"Expected 1 input.ui-select-search but got '{0}'.\", ctrl.searchInput.length);\n }\n\n angular.element($window).on('resize', onResize);\n ctrl.searchInput.on('keydown', onSearchInputKeyDown);\n ctrl.searchInput.on('paste', onSearchInputPaste);\n ctrl.searchInput.on('tagged', onSearchInputTagged);\n $scope.$on('$destroy', onDestroy);\n $scope.$watch(isLockChoiceExpressionDefined, _initaliseLockedChoices);\n $scope.$watch('$select.activeIndex', onActiveIndexChange);\n $scope.$watch('$select.open', onOpenChange);\n //#endregion\n\n //#region Controller Functions\n function isEmpty() {\n var selected = ctrl.selected;\n return isNil(selected) || selected === '' || selected.$$null || (ctrl.multiple && !selected.length);\n }\n\n function getSelectedText() {\n return ctrl.$element.find('.ui-select-match-text').text();\n }\n\n function getPlaceholder() {\n var selected = ctrl.selected;\n if (selected && selected.length) { return; }\n\n return ctrl.placeholder;\n }\n\n function _findIndex(collection, predicate, thisArg) {\n if (collection.findIndex) {\n return collection.findIndex(predicate, thisArg);\n } else {\n var list = Object(collection);\n var length = list.length >>> 0;\n var value;\n\n for (var i = 0; i < length; i++) {\n value = list[i];\n if (predicate.call(thisArg, value, i, list)) {\n return i;\n }\n }\n return -1;\n }\n }\n\n // Most of the time the user does not want to empty the search input when in typeahead mode\n function _resetSearchInput() {\n if (ctrl.resetSearchInput) {\n ctrl.search = EMPTY_SEARCH;\n setActiveIndexToSelected();\n }\n }\n\n function setActiveIndexToSelected() {\n // Don't change activeIndex to selected if we can select multiple items\n if (ctrl.multiple) { return; }\n\n // If we have a track by expression, use that to find the selected item since it might be a copy/different\n // prototype. Otherwise, do equality checks.\n var active = -1;\n var selected = ctrl.selected;\n var parserResult = ctrl.parserResult;\n if (angular.equals(selected, ctrl.nullValue)) {\n active = _findIndex(ctrl.items, isNullValue);\n } else if (parserResult && ctrl.items.length) {\n // If tracked by option.field.id, ng-model={field: {id}}, and items [{field: {id}, oopsNotSelected: true}],\n // angular.equals will not find the ng-model, thus leaving unselected, due to oopsNotSelected.\n var trackedValue = parserResult.getTrackedValue($scope, selected);\n active = _findIndex(ctrl.items, function(item) {\n return angular.equals(parserResult.getTrackedValue($scope, item), trackedValue);\n });\n }\n\n // If we don't have an active index, select first enabled non-generated null item.\n if (active < 0) {\n active = _findIndex(ctrl.items, function(item) {\n return !item.$$null && !_isItemDisabled(item);\n });\n }\n\n ctrl.activeIndex = active;\n }\n\n function _groupsFilter(groups, groupNames) {\n for (var i = 0, j, result = []; i < groupNames.length; i++) {\n for (j = 0; j < groups.length; j++) {\n if (groups[j].name == [groupNames[i]]) {\n result.push(groups[j]);\n }\n }\n }\n\n return result;\n }\n\n function isNullValue(item) {\n return item.$$null || angular.equals(item[ctrl.itemProperty], ctrl.nullValue);\n }\n\n // When the user clicks on ui-select, displays the dropdown list\n function activate(initSearchValue, avoidReset) {\n if (!ctrl.disabled && !ctrl.open) {\n if (!avoidReset) {\n _resetSearchInput();\n }\n\n $scope.$broadcast('uis:activate');\n ctrl.open = true;\n\n // Tagging label variant should select the first item\n if (ctrl.taggingLabel) {\n ctrl.activeIndex = 0;\n } else {\n setActiveIndexToSelected();\n }\n\n $timeout(function() {\n focusSearchInput(initSearchValue);\n if (!ctrl.tagging.isActivated && ctrl.items.length > 1 && ctrl.open) {\n _ensureHighlightVisible();\n }\n });\n } else if (ctrl.open && !ctrl.searchEnabled) {\n // Close the selection if we don't have search enabled, and we click on the select again\n close();\n }\n }\n\n function focusSearchInput(initSearchValue) {\n ctrl.search = initSearchValue || ctrl.search;\n ctrl.searchInput[0].focus();\n }\n\n function findGroupByName(name, noStrict) {\n return ctrl.groups && ctrl.groups.filter(function(group) {\n if (noStrict) {\n return group.name == name;\n } else {\n return group.name === name;\n }\n })[0];\n }\n\n function parseRepeatAttr(repeatAttr, groupByExp, groupFilterExp) {\n var parserResult = RepeatParser.parse(repeatAttr);\n var originalSource = parserResult.source;\n ctrl.isGrouped = !!groupByExp;\n ctrl.itemProperty = parserResult.itemName;\n ctrl.parserResult = parserResult;\n ctrl.refreshItems = refreshItems;\n ctrl.setItemsFn = groupByExp ? updateGroups : updateFlatItems;\n\n if (parserResult.keyName) { // Check for (key,value) syntax\n createArrayFromObject();\n parserResult.source = $parse('$uisSource' + parserResult.filters);\n $scope.$watch(originalSource, onOriginalSourceChange, true);\n }\n\n // See https://github.com/angular/angular.js/blob/v1.2.15/src/ng/directive/ngRepeat.js#L259\n $scope.$watchCollection(parserResult.source, onSourceChange);\n\n //When an object is used as source, we better create an array and use it as 'source'\n function createArrayFromObject() {\n var origSrc = originalSource($scope);\n $scope.$uisSource = Object.keys(origSrc).map(function(v) {\n var result = {};\n result[ctrl.parserResult.keyName] = v;\n result.value = origSrc[v];\n return result;\n });\n }\n\n function createNullItem() {\n var nullItem = {$$null: true};\n nullItem[ctrl.itemProperty] = ctrl.nullValue;\n return nullItem;\n }\n\n function needsNullItem(items) {\n return !ctrl.taggingLabel && !ctrl.required && (!ctrl.search || ctrl.nullLabel.toLowerCase().indexOf(ctrl.search) > -1) && !items.some(isNullValue);\n }\n\n function onOriginalSourceChange(newVal, oldVal) {\n if (newVal !== oldVal) {\n createArrayFromObject();\n }\n }\n\n function onSourceChange(items) {\n if (isNil(items)) {\n // If the user specifies undefined or null => reset the collection\n // Special case: items can be undefined if the user did not initialized the collection on the scope\n // i.e $scope.addresses = [] is missing\n ctrl.items = [];\n } else if (!angular.isArray(items)) {\n throw uiSelectMinErr('items', \"Expected an array but got '{0}'.\", items);\n } else {\n //Remove already selected items (ex: while searching)\n ctrl.refreshItems(items);\n\n //update the view value with fresh data from items, if there is a valid model value\n if (angular.isDefined(ctrl.ngModel.$modelValue)) {\n ctrl.ngModel.$modelValue = null; //Force scope model value and ngModel value to be out of sync to re-run formatters\n }\n }\n }\n\n function refreshItems(data) {\n //TODO should implement for single mode removeSelected\n var selectedItems = ctrl.selected;\n data = data || ctrl.parserResult.source($scope) || ctrl.items || [];\n if (!ctrl.multiple || !ctrl.removeSelected || isEmpty() || (angular.isArray(selectedItems) && !selectedItems.length)) {\n ctrl.setItemsFn(data);\n } else if (!isNil(data)) {\n ctrl.setItemsFn(data.filter(excludeSelected));\n }\n\n $timeout($scope.calculateDropdownPos);\n $scope.$broadcast('uis:refresh');\n\n function excludeSelected(item) {\n return angular.isArray(selectedItems) ? selectedItems.every(isNotSelected) : isNotSelected(selectedItems);\n\n function isNotSelected(selectedItem) {\n return !angular.equals(item, selectedItem);\n }\n }\n }\n\n function updateFlatItems(items) {\n ctrl.items = items;\n\n // Insert our null item at the head of the items\n if (needsNullItem(items)) {\n items.unshift(createNullItem());\n }\n }\n\n function updateGroups(items) {\n items = items || ctrl.items;\n\n // Group items together by the group by expression\n var groupFn = $scope.$eval(groupByExp);\n ctrl.items = [];\n ctrl.groups = [];\n items.forEach(function(item) {\n var groupName = angular.isFunction(groupFn) ? groupFn(item) : item[groupFn];\n var group = findGroupByName(groupName);\n if (group) {\n group.items.push(item);\n } else {\n ctrl.groups.push({name: groupName, items: [item]});\n }\n });\n\n // Filter the groups by the given filter expression\n var groupFilterFn = groupFilterExp && $scope.$eval(groupFilterExp);\n if (angular.isFunction(groupFilterFn)) {\n ctrl.groups = groupFilterFn(ctrl.groups);\n } else if (angular.isArray(groupFilterFn)) {\n ctrl.groups = _groupsFilter(ctrl.groups, groupFilterFn);\n }\n\n // Collect the remaining items in the same order of the filtered groups.\n items = ctrl.items = ctrl.groups.reduce(function(items, group) {\n return items.concat(group.items);\n }, []);\n\n // Insert our null item at the head of the list if we dont have an item that represents null.\n if (needsNullItem(items)) {\n var group = ctrl.groups[0] || (ctrl.groups[0] = {name: '', items: []});\n var nullItem = createNullItem();\n group.items.unshift(nullItem);\n items.unshift(nullItem);\n }\n }\n }\n\n /**\n * Typeahead mode: lets the user refresh the collection using his own function.\n *\n * See Expose $select.search for external / remote filtering https://github.com/angular-ui/ui-select/pull/31\n */\n function refresh(refreshAttr) {\n if (!isNil(refreshAttr)) {\n // Debounce\n // See https://github.com/angular-ui/bootstrap/blob/0.10.0/src/typeahead/typeahead.js#L155\n // FYI AngularStrap typeahead does not have debouncing: https://github.com/mgcrea/angular-strap/blob/v2.0.0-rc.4/src/typeahead/typeahead.js#L177\n if (refreshDelayPromise) {\n $timeout.cancel(refreshDelayPromise);\n }\n\n refreshDelayPromise = $timeout(function() {\n if ($scope.$select.search.length >= $scope.$select.minimumInputLength) {\n var refreshPromise = $scope.$eval(refreshAttr);\n if (refreshPromise && angular.isFunction(refreshPromise.then) && !ctrl.refreshing) {\n ctrl.refreshing = true;\n refreshPromise.finally(function() {\n ctrl.refreshing = false;\n });\n }\n }\n }, ctrl.refreshDelay);\n }\n }\n\n function isActive(itemScope) {\n if (!ctrl.open) { return false; }\n\n var itemIndex = ctrl.items.indexOf(itemScope[ctrl.itemProperty]);\n var isActive = itemIndex == ctrl.activeIndex;\n if (!isActive || itemIndex < 0) { return false; }\n\n if (isActive && !angular.isUndefined(ctrl.onHighlightCallback)) {\n itemScope.$eval(ctrl.onHighlightCallback);\n }\n\n return isActive;\n }\n\n function _isItemSelected(item) {\n var selected = ctrl.selected;\n return (angular.isArray(selected) && selected.filter(function(selection) {\n return angular.equals(selection, item);\n }).length > 0);\n }\n\n function _updateItemDisabled(item, isDisabled) {\n var disabledItemIndex = disabledItems.indexOf(item);\n if (isDisabled && disabledItemIndex === -1) {\n disabledItems.push(item);\n }\n\n if (!isDisabled && disabledItemIndex > -1) {\n disabledItems.splice(disabledItemIndex, 1);\n }\n }\n\n function _isItemDisabled(item) {\n return disabledItems.indexOf(item) > -1;\n }\n\n function isDisabled(itemScope) {\n if (!ctrl.open) { return; }\n\n var item = itemScope[ctrl.itemProperty];\n var itemIndex = ctrl.items.indexOf(item);\n var isDisabled = false;\n if (itemIndex >= 0 && (angular.isDefined(ctrl.disableChoiceExpression) || ctrl.multiple)) {\n if (item.isTag) { return false; }\n\n if (ctrl.multiple) {\n isDisabled = _isItemSelected(item);\n }\n\n if (!isDisabled && angular.isDefined(ctrl.disableChoiceExpression)) {\n isDisabled = !!(itemScope.$eval(ctrl.disableChoiceExpression));\n }\n\n _updateItemDisabled(item, isDisabled);\n }\n\n return isDisabled;\n }\n\n // When the user selects an item with ENTER or clicks the dropdown\n function select(item, skipFocusser, $event) {\n if (isNil(item) || !_isItemDisabled(item)) {\n if (!ctrl.items && !ctrl.search && !ctrl.tagging.isActivated) { return; }\n\n if (!item || !_isItemDisabled(item)) {\n // if click is made on existing item, prevent from tagging, ctrl.search does not matter\n ctrl.clickTriggeredSelect = false;\n if ($event && ($event.type === 'click' || $event.type === 'touchend') && item) {\n ctrl.clickTriggeredSelect = true;\n }\n\n if (ctrl.tagging.isActivated && ctrl.clickTriggeredSelect === false) {\n // if taggingLabel is disabled and item is undefined we pull from ctrl.search\n if (ctrl.taggingLabel === false) {\n if (ctrl.activeIndex < 0) {\n if (item === undefined) {\n item = ctrl.tagging.fct !== undefined ? ctrl.tagging.fct(ctrl.search) : ctrl.search;\n }\n\n if (!item || angular.equals(ctrl.items[0], item)) { return; }\n } else {\n // keyboard nav happened first, user selected from dropdown\n item = ctrl.items[ctrl.activeIndex];\n }\n } else {\n // tagging always operates at index zero, taggingLabel === false pushes\n // the ctrl.search value without having it injected\n if (ctrl.activeIndex === 0) {\n // ctrl.tagging pushes items to ctrl.items, so we only have empty val\n // for `item` if it is a detected duplicate\n if (item === undefined) { return; }\n\n // create new item on the fly if we don't already have one;\n // use tagging function if we have one\n if (ctrl.tagging.fct !== undefined && typeof item === 'string') {\n item = ctrl.tagging.fct(item);\n if (!item) { return; }\n // if item type is 'string', apply the tagging label\n } else if (typeof item === 'string') {\n // trim the trailing space\n item = item.replace(ctrl.taggingLabel, '').trim();\n }\n }\n }\n // search ctrl.selected for dupes potentially caused by tagging and return early if found\n if (_isItemSelected(item)) {\n close(skipFocusser);\n return;\n }\n }\n\n _resetSearchInput();\n $scope.$broadcast('uis:select', item);\n\n if (ctrl.closeOnSelect) {\n close(skipFocusser);\n }\n }\n }\n }\n\n // Closes the dropdown\n function close(skipFocusser) {\n if (!ctrl.open) { return; }\n\n if (ctrl.ngModel && ctrl.ngModel.$setTouched) {\n ctrl.ngModel.$setTouched();\n }\n\n ctrl.open = false;\n _resetSearchInput();\n $scope.$broadcast('uis:close', skipFocusser);\n }\n\n\n function setFocus() {\n if (!ctrl.focus) {\n ctrl.searchInput[0].focus();\n }\n }\n\n function clear($event) {\n select(ctrl.nullValue);\n $event.stopPropagation();\n $timeout(function() {\n ctrl.focusser[0].focus();\n }, 0, false);\n }\n\n // Toggle dropdown\n function toggle(e) {\n if (ctrl.open) {\n close();\n } else {\n activate();\n }\n\n cancelEvent(e);\n }\n\n function _initaliseLockedChoices(doInitalise) {\n if (!doInitalise) { return; }\n\n var lockedItems = [];\n ctrl.isLocked = isLockedFn;\n\n function _updateItemLocked(item, isLocked) {\n var lockedItemIndex = lockedItems.indexOf(item);\n if (isLocked && lockedItemIndex === -1) {\n lockedItems.push(item);\n }\n\n if (!isLocked && lockedItemIndex > -1) {\n lockedItems.splice(lockedItemIndex, 1);\n }\n }\n\n function _isItemlocked(item) {\n return lockedItems.indexOf(item) > -1;\n }\n\n function isLockedFn(itemScope, itemIndex) {\n var isLocked = false;\n var item = ctrl.selected[itemIndex];\n\n if (item) {\n if (itemScope) {\n isLocked = !!itemScope.$eval(ctrl.lockChoiceExpression);\n _updateItemLocked(item, isLocked);\n } else {\n isLocked = _isItemlocked(item);\n }\n }\n\n return isLocked;\n }\n }\n\n function sizeSearchInput() {\n var input = ctrl.searchInput[0];\n var container = ctrl.$element[0];\n ctrl.searchInput.css('width', '10px');\n $timeout(function() { //Give tags time to render correctly\n if (sizeWatch === null && !updateIfVisible(calculateContainerWidth())) {\n sizeWatch = $scope.$watch(function() {\n if (!updaterScheduled) {\n updaterScheduled = true;\n $scope.$$postDigest(function() {\n updaterScheduled = false;\n if (updateIfVisible(calculateContainerWidth())) {\n sizeWatch();\n sizeWatch = null;\n }\n });\n }\n }, angular.noop);\n }\n });\n\n function calculateContainerWidth() {\n // Return the container width only if the search input is visible\n return container.clientWidth * !!input.offsetParent;\n }\n\n function updateIfVisible(containerWidth) {\n if (containerWidth === 0) { return false; }\n\n var inputWidth = containerWidth - input.offsetLeft;\n if (inputWidth < 50) {\n inputWidth = containerWidth;\n }\n\n ctrl.searchInput.css('width', inputWidth + 'px');\n return true;\n }\n }\n\n function _handleDropDownSelection(key, shiftKey) {\n var processed = true;\n switch (key) {\n case KEY.DOWN:\n case KEY.UP:\n if (!ctrl.open && ctrl.multiple) {\n // In case its the search input in 'multiple' mode\n activate(false, true);\n } else {\n var len = ctrl.items.length;\n do {\n ctrl.activeIndex += key === KEY.UP ? -1 : 1;\n } while (ctrl.activeIndex > 0 && ctrl.activeIndex < len && _isItemDisabled(ctrl.items[ctrl.activeIndex]));\n\n ctrl.activeIndex = Math.max(0, Math.min(len - 1, ctrl.activeIndex));\n }\n\n break;\n case KEY.TAB:\n if (!ctrl.multiple || ctrl.open) {\n select(ctrl.items[ctrl.activeIndex], true);\n tabNavigate(shiftKey);\n }\n\n break;\n case KEY.ENTER:\n if (ctrl.open && (ctrl.tagging.isActivated || ctrl.activeIndex >= 0)) {\n // Make sure at least one dropdown item is highlighted before adding if not in tagging mode\n select(ctrl.items[ctrl.activeIndex], ctrl.skipFocusser);\n } else {\n // In case its the search input in 'multiple' mode\n activate(false, true);\n }\n\n break;\n case KEY.ESC:\n close();\n break;\n default:\n processed = false;\n }\n return processed;\n }\n\n function cancelEvent(e) {\n e.preventDefault();\n e.stopPropagation();\n }\n\n function tabNavigate(shiftKey) {\n close(true);\n\n $timeout(function() {\n var focusEl = ctrl.focusser && ctrl.focusser[0];\n if (!focusEl) { return; }\n\n var focusable = angular.element(':tabbable');\n var index = focusable.index(focusEl);\n if (index > -1) {\n index += shiftKey ? -1 : 1;\n var el = focusable[index + (index < 0 ? focusable.length : 0)];\n if (el) {\n el.focus();\n }\n }\n }, 50);\n }\n\n function onSearchInputKeyDown(e) {\n var key = e.which;\n if (~[KEY.ENTER, KEY.ESC, KEY.TAB].indexOf(key)) {\n cancelEvent(e);\n }\n\n $scope.$apply(function() {\n var tagged = false;\n if (ctrl.items.length > 0 || ctrl.tagging.isActivated) {\n if (!_handleDropDownSelection(key, e.shiftKey) && !ctrl.searchEnabled) {\n cancelEvent(e);\n }\n\n if (ctrl.taggingTokens.isActivated) {\n for (var i = 0; i < ctrl.taggingTokens.tokens.length; i++) {\n if (ctrl.taggingTokens.tokens[i] === KEY.MAP[e.keyCode]) {\n // make sure there is a new value to push via tagging\n if (ctrl.search.length > 0) {\n tagged = true;\n }\n }\n }\n\n if (tagged) {\n $timeout(function() {\n ctrl.searchInput.triggerHandler('tagged');\n var newItem = ctrl.search.replace(KEY.MAP[e.keyCode], '').trim();\n if (ctrl.tagging.fct) {\n newItem = ctrl.tagging.fct(newItem);\n }\n\n if (newItem) {\n select(newItem, true);\n }\n });\n }\n }\n } else if (key === KEY.TAB) {\n // Don't trap users in lists with no items\n tabNavigate(e.shiftKey);\n }\n });\n\n if (KEY.isVerticalMovement(key) && ctrl.items.length > 0) {\n _ensureHighlightVisible();\n }\n }\n\n function onSearchInputPaste(e) {\n var data;\n if (window.clipboardData && window.clipboardData.getData) { // IE\n data = window.clipboardData.getData('Text');\n } else {\n data = (e.originalEvent || e).clipboardData.getData('text/plain');\n }\n\n // Prepend the current input field text to the paste buffer.\n data = ctrl.search + data;\n if (data && data.length > 0) {\n // If tagging try to split by tokens and add items\n if (ctrl.taggingTokens.isActivated) {\n var items = [];\n for (var i = 0; i < ctrl.taggingTokens.tokens.length; i++) { // split by first token that is contained in data\n var separator = KEY.toSeparator(ctrl.taggingTokens.tokens[i]) || ctrl.taggingTokens.tokens[i];\n if (data.indexOf(separator) > -1) {\n items = data.split(separator);\n break; // only split by one token\n }\n }\n\n if (items.length === 0) {\n items = [data];\n }\n\n var oldsearch = ctrl.search;\n items.forEach(function(item) {\n var newItem = ctrl.tagging.fct ? ctrl.tagging.fct(item) : item;\n if (newItem) {\n select(newItem, true);\n }\n });\n ctrl.search = oldsearch || EMPTY_SEARCH;\n cancelEvent(e);\n } else if (ctrl.paste) {\n ctrl.paste(data);\n ctrl.search = EMPTY_SEARCH;\n cancelEvent(e);\n }\n }\n }\n\n function onSearchInputTagged() {\n $timeout(_resetSearchInput);\n }\n\n // See https://github.com/ivaynberg/select2/blob/3.4.6/select2.js#L1431\n function _ensureHighlightVisible() {\n var container = $element.querySelectorAll('.ui-select-choices-content');\n var choices = container.querySelectorAll('.ui-select-choices-row');\n if (choices.length < 1) {\n throw uiSelectMinErr('choices', \"Expected multiple .ui-select-choices-row but got '{0}'.\", choices.length);\n }\n\n // Bail out if we can't find the highlighted row.\n var highlighted = choices[ctrl.activeIndex];\n if (!highlighted) { return; }\n\n var posY = highlighted.offsetTop + highlighted.clientHeight - container[0].scrollTop;\n var height = container[0].offsetHeight;\n if (posY > height) {\n container[0].scrollTop += posY - height;\n } else if (posY < highlighted.clientHeight) {\n if (ctrl.isGrouped && ctrl.activeIndex === 0) {\n container[0].scrollTop = 0; //To make group header visible when going all the way up\n } else {\n container[0].scrollTop -= highlighted.clientHeight - posY;\n }\n }\n }\n\n function isLockChoiceExpressionDefined() {\n return angular.isDefined(ctrl.lockChoiceExpression) && ctrl.lockChoiceExpression !== \"\";\n }\n\n function onActiveIndexChange(activeIndex) {\n if (activeIndex) {\n $element.find('input').attr(\n 'aria-activedescendant',\n 'ui-select-choices-row-' + ctrl.generatedId + '-' + activeIndex);\n }\n }\n\n function onDestroy() {\n ctrl.searchInput.off('keyup keydown tagged blur paste');\n angular.element($window).off('resize', onResize);\n }\n\n function onOpenChange(open) {\n if (!open) {\n $element.find('input').removeAttr('aria-activedescendant');\n }\n }\n //#endregion\n}\n\nuis.directive('uiSelect',\n ['$document', 'uiSelectConfig', 'uiSelectMinErr', 'uisOffset', '$parse', '$timeout', '$window',\n function($document, uiSelectConfig, uiSelectMinErr, uisOffset, $parse, $timeout, $window) {\n\n return {\n restrict: 'EA',\n templateUrl: function(tElement, tAttrs) {\n var theme = tAttrs.theme || uiSelectConfig.theme;\n return theme + (angular.isDefined(tAttrs.multiple) ? '/select-multiple.tpl.html' : '/select.tpl.html');\n },\n replace: true,\n transclude: true,\n require: ['uiSelect', '^ngModel', '?^^fieldset'],\n scope: true,\n\n controller: 'uiSelectCtrl',\n controllerAs: '$select',\n compile: function(tElement, tAttrs) {\n\n // Allow setting ngClass on uiSelect\n var match = /{(.*)}\\s*{(.*)}/.exec(tAttrs.ngClass);\n if(match) {\n var combined = '{'+ match[1] +', '+ match[2] +'}';\n tAttrs.ngClass = combined;\n tElement.attr('ng-class', combined);\n }\n\n //Multiple or Single depending if multiple attribute presence\n if (angular.isDefined(tAttrs.multiple))\n tElement.append(' ').removeAttr('multiple');\n else\n tElement.append(' ');\n\n if (tAttrs.inputId)\n tElement.querySelectorAll('input.ui-select-search')[0].id = tAttrs.inputId;\n\n return function(scope, element, attrs, ctrls, transcludeFn) {\n var $select = ctrls[0];\n var ngModel = ctrls[1];\n var $fieldset = ctrls[2];\n\n var documentElement = $document[0].documentElement;\n var dropdown = angular.element(); // Hold on to a reference to the .ui-select-dropdown element for direction support.\n var originalWidth = '';\n var placeholder = null; // Hold on to a reference to the .ui-select-container element for appendToBody support\n\n // Support for appending the select field to the body when its open\n var appendToBody = scope.$eval(attrs.appendToBody);\n if (appendToBody === undefined) {\n appendToBody = uiSelectConfig.appendToBody;\n }\n\n $select.generatedId = uiSelectConfig.generateId();\n $select.baseTitle = attrs.title || 'Select box';\n $select.focusserTitle = $select.baseTitle + ' focus';\n $select.focusserId = 'focusser-' + $select.generatedId;\n\n $select.closeOnSelect = function() {\n if (angular.isDefined(attrs.closeOnSelect)) {\n return $parse(attrs.closeOnSelect)();\n } else {\n return uiSelectConfig.closeOnSelect;\n }\n }();\n\n scope.$watch('skipFocusser', function() {\n var skipFocusser = scope.$eval(attrs.skipFocusser);\n $select.skipFocusser = skipFocusser !== undefined ? skipFocusser : uiSelectConfig.skipFocusser;\n });\n\n $select.onSelectCallback = $parse(attrs.onSelect);\n $select.onRemoveCallback = $parse(attrs.onRemove);\n\n //Set reference to ngModel from uiSelectCtrl\n $select.ngModel = ngModel;\n\n $select.choiceGrouped = function(group){\n return $select.isGrouped && group && group.name;\n };\n\n if(attrs.tabindex){\n attrs.$observe('tabindex', function(value) {\n $select.searchInput.attr('tabindex', value);\n element.removeAttr('tabindex');\n });\n }\n\n scope.$watch(function () { return scope.$eval(attrs.searchEnabled); }, function(newVal) {\n $select.searchEnabled = newVal !== undefined ? newVal : uiSelectConfig.searchEnabled;\n });\n\n scope.$watch('sortable', function() {\n var sortable = scope.$eval(attrs.sortable);\n $select.sortable = sortable !== undefined ? sortable : uiSelectConfig.sortable;\n });\n\n attrs.$observe('backspaceReset', function() {\n // $eval() is needed otherwise we get a string instead of a boolean\n var backspaceReset = scope.$eval(attrs.backspaceReset);\n $select.backspaceReset = backspaceReset !== undefined ? backspaceReset : true;\n });\n\n attrs.$observe('limit', function() {\n //Limit the number of selections allowed\n $select.limit = (angular.isDefined(attrs.limit)) ? parseInt(attrs.limit, 10) : undefined;\n });\n\n scope.$watch('removeSelected', function() {\n var removeSelected = scope.$eval(attrs.removeSelected);\n $select.removeSelected = removeSelected !== undefined ? removeSelected : uiSelectConfig.removeSelected;\n });\n\n // If the disable attribute is applied, or a parent fieldset becomes disabled, disable the select.\n scope.$watch(function() { return element.attr('disabled') || $fieldset && $fieldset.isDisabled(); }, function(disabled) {\n $select.disabled = disabled;\n });\n\n attrs.$observe('resetSearchInput', function() {\n // $eval() is needed otherwise we get a string instead of a boolean\n var resetSearchInput = scope.$eval(attrs.resetSearchInput);\n $select.resetSearchInput = resetSearchInput !== undefined ? resetSearchInput : true;\n });\n\n attrs.$observe('paste', function() {\n $select.paste = scope.$eval(attrs.paste);\n });\n\n attrs.$observe('tagging', function() {\n if(attrs.tagging !== undefined)\n {\n // $eval() is needed otherwise we get a string instead of a boolean\n var taggingEval = scope.$eval(attrs.tagging);\n $select.tagging = {isActivated: true, fct: taggingEval !== true ? taggingEval : undefined};\n }\n else\n {\n $select.tagging = {isActivated: false, fct: undefined};\n }\n });\n\n attrs.$observe('taggingLabel', function() {\n if(attrs.tagging !== undefined )\n {\n // check eval for FALSE, in this case, we disable the labels\n // associated with tagging\n if ( attrs.taggingLabel === 'false' ) {\n $select.taggingLabel = false;\n }\n else\n {\n $select.taggingLabel = attrs.taggingLabel !== undefined ? attrs.taggingLabel : '(new)';\n }\n }\n });\n\n attrs.$observe('taggingTokens', function() {\n if (attrs.tagging !== undefined) {\n var tokens = attrs.taggingTokens !== undefined ? attrs.taggingTokens.split('|') : [',','ENTER'];\n $select.taggingTokens = {isActivated: true, tokens: tokens };\n }\n });\n\n attrs.$observe('spinnerEnabled', function() {\n // $eval() is needed otherwise we get a string instead of a boolean\n var spinnerEnabled = scope.$eval(attrs.spinnerEnabled);\n $select.spinnerEnabled = spinnerEnabled !== undefined ? spinnerEnabled : uiSelectConfig.spinnerEnabled;\n });\n\n attrs.$observe('spinnerClass', function() {\n var spinnerClass = attrs.spinnerClass;\n $select.spinnerClass = spinnerClass !== undefined ? attrs.spinnerClass : uiSelectConfig.spinnerClass;\n });\n\n // Keep track of whether or not this field is required, if it is, do not allow it to be cleared.\n scope.$watch(\n function() { return !!scope.$eval(attrs.ngRequired); },\n function(required, oldRequired) {\n $select.required = required;\n $select.refreshItems();\n }\n );\n\n //Automatically gets focus when loaded\n if (angular.isDefined(attrs.autofocus)) {\n resetFocus();\n }\n\n //Gets focus based on scope event name (e.g. focus-on='SomeEventName')\n if (angular.isDefined(attrs.focusOn)) {\n scope.$on(attrs.focusOn, resetFocus);\n }\n\n // Move transcluded elements to their correct position in main template\n transcludeFn(scope, function(clone) {\n // See Transclude in AngularJS http://blog.omkarpatil.com/2012/11/transclude-in-angularjs.html\n\n // One day jqLite will be replaced by jQuery and we will be able to write:\n // var transcludedElement = clone.filter('.my-class')\n // instead of creating a hackish DOM element:\n var transcluded = angular.element('').append(clone);\n\n var transcludedMatch = transcluded.querySelectorAll('.ui-select-match');\n transcludedMatch.removeAttr('ui-select-match'); //To avoid loop in case directive as attr\n transcludedMatch.removeAttr('data-ui-select-match'); // Properly handle HTML5 data-attributes\n if (transcludedMatch.length !== 1) {\n throw uiSelectMinErr('transcluded', \"Expected 1 .ui-select-match but got '{0}'.\", transcludedMatch.length);\n }\n element.querySelectorAll('.ui-select-match').replaceWith(transcludedMatch);\n\n var transcludedChoices = transcluded.querySelectorAll('.ui-select-choices');\n transcludedChoices.removeAttr('ui-select-choices'); //To avoid loop in case directive as attr\n transcludedChoices.removeAttr('data-ui-select-choices'); // Properly handle HTML5 data-attributes\n if (transcludedChoices.length !== 1) {\n throw uiSelectMinErr('transcluded', \"Expected 1 .ui-select-choices but got '{0}'.\", transcludedChoices.length);\n }\n element.querySelectorAll('.ui-select-choices').replaceWith(transcludedChoices);\n\n var transcludedNoChoice = transcluded.querySelectorAll('.ui-select-no-choice');\n transcludedNoChoice.removeAttr('ui-select-no-choice'); //To avoid loop in case directive as attr\n transcludedNoChoice.removeAttr('data-ui-select-no-choice'); // Properly handle HTML5 data-attributes\n if (transcludedNoChoice.length == 1) {\n element.querySelectorAll('.ui-select-no-choice').replaceWith(transcludedNoChoice);\n }\n\n var transcludedHeader = transcluded.querySelectorAll('.ui-select-header');\n transcludedHeader.removeAttr('ui-select-header'); // To avoid loop in case directive as attr\n transcludedHeader.removeAttr('data-ui-select-header'); // Properly handle HTML5 data-attributes\n if (transcludedHeader.length == 1) {\n element.querySelectorAll('.ui-select-header').replaceWith(transcludedHeader);\n } else {\n element.querySelectorAll('.ui-select-header').remove();\n }\n\n var transcludedFooter = transcluded.querySelectorAll('.ui-select-footer');\n transcludedFooter.removeAttr('ui-select-footer'); // To avoid loop in case directive as attr\n transcludedFooter.removeAttr('data-ui-select-footer'); // Properly handle HTML5 data-attributes\n if (transcludedFooter.length == 1) {\n element.querySelectorAll('.ui-select-footer').replaceWith(transcludedFooter);\n } else {\n element.querySelectorAll('.ui-select-footer').remove();\n }\n });\n\n scope.$watch('$select.open', function(isOpen) {\n if (isOpen) {\n // Attach global handlers that cause the dropdowns to close\n $window.addEventListener('mousedown', closeOnClick, true);\n $window.addEventListener('scroll', closeOnScroll, true);\n $window.addEventListener('resize', closeOnResize, true);\n\n if (appendToBody) {\n // Wait for ui-select-match child directive, it hasn't started rendering yet.\n scope.$evalAsync(positionDropdown);\n }\n\n scope.calculateDropdownPos();\n } else {\n resetDropdown();\n }\n });\n\n // Move the dropdown back to its original location when the scope is destroyed. Otherwise\n // it might stick around when the user routes away or the select field is otherwise removed\n scope.$on('$destroy', resetDropdown);\n\n scope.calculateDropdownPos = function() {\n if (!$select.open) { return; }\n\n dropdown = dropdown.length ? dropdown : angular.element(element).querySelectorAll('.ui-select-dropdown');\n if (!dropdown.length) { return; }\n\n // Clear existing state and hide dropdown\n dropdown[0].style.position = '';\n dropdown[0].style.top = '';\n dropdown[0].style.visibility = 'hidden';\n element.removeClass('direction-up dropdown-menu-right');\n\n // Determine X positioning\n var offset = uisOffset(element);\n var offsetDropdown = uisOffset(dropdown);\n var scrollTarget = documentElement || $document[0].body;\n var xState = $select.dropdownXPosition;\n dropdown.toggleClass('dropdown-menu-right', xState === 'right' ||\n (xState === 'auto' && offset.left + offsetDropdown.width - scrollTarget.scrollLeft > documentElement.clientWidth)\n );\n\n // Determine Y positioning\n var yState = $select.dropdownYPosition;\n var top = yState === 'up' || (yState === 'auto' && offset.top + offset.height + offsetDropdown.height - scrollTarget.scrollTop > documentElement.clientHeight) ?\n (offsetDropdown.height * -1) + 'px' :\n '';\n\n // Apply and make visible.\n dropdown[0].style.position = top ? 'absolute' : '';\n dropdown[0].style.top = top;\n dropdown[0].style.visibility = '';\n if (top) {\n element.addClass('direction-up');\n }\n };\n\n function calculateSelectLeftPosition(offset) {\n var scrollLeft = documentElement.scrollLeft || $document[0].body.scrollLeft;\n var edgeOffscreenAmount = (offset.left + offset.width) - (scrollLeft + documentElement.clientWidth);\n var paddingFromEdge = 30;\n\n var leftPosition = offset.left;\n if (edgeOffscreenAmount > 0) {\n leftPosition -= (edgeOffscreenAmount + paddingFromEdge);\n }\n\n return leftPosition;\n }\n\n function closeOnClick(e) {\n if (!$select.open) return; //Skip it if dropdown is close\n\n var contains = false;\n var target = e.target || e.srcElement;\n\n if (window.jQuery) {\n // Firefox 3.6 does not support element.contains()\n // See Node.contains https://developer.mozilla.org/en-US/docs/Web/API/Node.contains\n contains = window.jQuery.contains(element[0], target);\n } else {\n contains = element[0].contains(target);\n }\n if (!contains && !$select.clickTriggeredSelect) {\n var skipFocusser;\n if (!$select.skipFocusser) {\n //Will lose focus only with certain targets\n var focusableControls = ['input','button','textarea','select'];\n var targetController = angular.element(target).controller('uiSelect'); //To check if target is other ui-select\n skipFocusser = targetController && targetController !== $select; //To check if target is other ui-select\n if (!skipFocusser) skipFocusser = ~focusableControls.indexOf(target.tagName.toLowerCase()); //Check if target is input, button or textarea\n } else {\n skipFocusser = true;\n }\n\n $select.close(skipFocusser);\n scope.$digest();\n }\n $select.clickTriggeredSelect = false;\n }\n\n function closeOnResize() {\n $select.close(false);\n }\n\n function closeOnScroll(e) {\n if (!element[0].contains(e.target || e.srcElement)) {\n $select.close(false);\n }\n }\n\n function positionDropdown() {\n // Remember the absolute position of the element\n var offset = uisOffset(element);\n\n // Clone the element into a placeholder element to take its original place in the DOM\n placeholder = angular.element('
');\n placeholder[0].style.width = offset.width + 'px';\n placeholder[0].style.height = offset.height + 'px';\n element.after(placeholder);\n\n // Remember the original value of the element width inline style, so it can be restored\n // when the dropdown is closed\n originalWidth = element[0].style.width;\n element[0].style.position = 'absolute';\n element[0].style.left = calculateSelectLeftPosition(offset) + 'px';\n element[0].style.top = offset.top + 'px';\n element[0].style.width = offset.width + 'px';\n $document[0].body.appendChild(element[0]);\n }\n\n function resetDropdown() {\n $window.removeEventListener('mousedown', closeOnClick, true);\n $window.removeEventListener('scroll', closeOnResize, true);\n $window.removeEventListener('resize', resetDropdown, true);\n\n // Move the dropdown element back to its original location in the DOM if we moved it.\n if (placeholder) {\n element[0].style.position = '';\n element[0].style.left = '';\n element[0].style.top = '';\n element[0].style.width = originalWidth;\n placeholder.replaceWith(element);\n placeholder = null;\n resetFocus();\n }\n }\n\n function resetFocus() {\n $timeout($select.setFocus);\n }\n };\n }\n };\n}]);\n\nuis.directive('uiSelectFooter', ['uiSelectConfig', function (uiSelectConfig) {\n return {\n templateUrl: function (tElement) {\n // Needed so the uiSelect can detect the transcluded content\n tElement.addClass('ui-select-footer');\n\n // Gets theme attribute from parent (ui-select)\n var theme = tElement.parent().attr('theme') || uiSelectConfig.theme;\n return theme + '/footer.tpl.html';\n },\n restrict: 'EA',\n transclude: true,\n replace: true\n };\n}]);\n\nuis.directive('uiSelectHeader', ['uiSelectConfig', function (uiSelectConfig) {\n return {\n templateUrl: function (tElement) {\n // Needed so the uiSelect can detect the transcluded content\n tElement.addClass('ui-select-header');\n\n // Gets theme attribute from parent (ui-select)\n var theme = tElement.parent().attr('theme') || uiSelectConfig.theme;\n return theme + '/header.tpl.html';\n },\n restrict: 'EA',\n transclude: true,\n replace: true\n };\n}]);\n\nuis.directive('uiSelectHeaderGroupSelectable', ['$timeout', function($timeout) {\n return {\n restrict: 'EA',\n require: ['^uiSelect'],\n scope: {\n isEnabled: \" model\n ngModel.$parsers.unshift(function () {\n var locals = {},\n result,\n resultMultiple = [];\n for (var j = $select.selected.length - 1; j >= 0; j--) {\n locals = {};\n locals[$select.parserResult.itemName] = $select.selected[j];\n result = $select.parserResult.modelMapper(scope, locals);\n resultMultiple.unshift(result);\n }\n return resultMultiple;\n });\n\n // From model --> view\n ngModel.$formatters.unshift(function (inputValue) {\n var data = $select.parserResult && $select.parserResult.source (scope, { $select : {search:''}}), //Overwrite $search\n locals = {},\n result;\n if (!data) return inputValue;\n var resultMultiple = [];\n var checkFnMultiple = function(list, value){\n if (!list || !list.length) return;\n for (var p = list.length - 1; p >= 0; p--) {\n locals[$select.parserResult.itemName] = list[p];\n result = $select.parserResult.modelMapper(scope, locals);\n if($select.parserResult.trackByExp){\n var propsItemNameMatches = /(\\w*)\\./.exec($select.parserResult.trackByExp);\n var matches = /\\.([^\\s]+)/.exec($select.parserResult.trackByExp);\n if(propsItemNameMatches && propsItemNameMatches.length > 0 && propsItemNameMatches[1] == $select.parserResult.itemName){\n if(matches && matches.length>0 && result[matches[1]] == value[matches[1]]){\n resultMultiple.unshift(list[p]);\n return true;\n }\n }\n }\n if (angular.equals(result,value)){\n resultMultiple.unshift(list[p]);\n return true;\n }\n }\n return false;\n };\n if (!inputValue) return resultMultiple; //If ngModel was undefined\n for (var k = inputValue.length - 1; k >= 0; k--) {\n //Check model array of currently selected items\n if (!checkFnMultiple($select.selected, inputValue[k])){\n //Check model array of all items available\n if (!checkFnMultiple(data, inputValue[k])){\n //If not found on previous lists, just add it directly to resultMultiple\n resultMultiple.unshift(inputValue[k]);\n }\n }\n }\n return resultMultiple;\n });\n\n //Watch for external model changes\n scope.$watchCollection(function(){ return ngModel.$modelValue; }, function(newValue, oldValue) {\n if (oldValue != newValue){\n //update the view value with fresh data from items, if there is a valid model value\n if(angular.isDefined(ngModel.$modelValue)) {\n ngModel.$modelValue = null; //Force scope model value and ngModel value to be out of sync to re-run formatters\n }\n $selectMultiple.refreshComponent();\n }\n });\n\n ngModel.$render = function() {\n // Make sure that model value is array\n if(!angular.isArray(ngModel.$viewValue)){\n // Have tolerance for null or undefined values\n if (isNil(ngModel.$viewValue)){\n ngModel.$viewValue = [];\n } else {\n throw uiSelectMinErr('multiarr', \"Expected model value to be array but got '{0}'\", ngModel.$viewValue);\n }\n }\n $select.selected = ngModel.$viewValue;\n $selectMultiple.refreshComponent();\n scope.$evalAsync(); //To force $digest\n };\n\n scope.$on('uis:select', function (event, item) {\n if($select.selected.length >= $select.limit) {\n return;\n }\n $select.selected.push(item);\n var locals = {};\n locals[$select.parserResult.itemName] = item;\n\n $timeout(function(){\n $select.onSelectCallback(scope, {\n $item: item,\n $model: $select.parserResult.modelMapper(scope, locals)\n });\n });\n $selectMultiple.updateModel();\n });\n\n scope.$on('uis:activate', function () {\n $selectMultiple.activeMatchIndex = -1;\n });\n\n scope.$watch('$select.disabled', function(newValue, oldValue) {\n // As the search input field may now become visible, it may be necessary to recompute its size\n if (oldValue && !newValue) $select.sizeSearchInput();\n });\n\n $select.searchInput.on('keydown', function(e) {\n var key = e.which;\n scope.$apply(function() {\n var processed = false;\n // var tagged = false; //Checkme\n if(KEY.isHorizontalMovement(key)){\n processed = _handleMatchSelection(key);\n }\n if (processed && key != KEY.TAB) {\n //TODO Check si el tab selecciona aun correctamente\n //Crear test\n $select.cancelEvent(e);\n }\n });\n });\n function _getCaretPosition(el) {\n if(angular.isNumber(el.selectionStart)) return el.selectionStart;\n // selectionStart is not supported in IE8 and we don't want hacky workarounds so we compromise\n else return el.value.length;\n }\n // Handles selected options in \"multiple\" mode\n function _handleMatchSelection(key){\n var caretPosition = _getCaretPosition($select.searchInput[0]),\n length = $select.selected.length,\n // none = -1,\n first = 0,\n last = length-1,\n curr = $selectMultiple.activeMatchIndex,\n next = $selectMultiple.activeMatchIndex+1,\n prev = $selectMultiple.activeMatchIndex-1,\n newIndex = curr;\n\n if(caretPosition > 0 || ($select.search.length && key == KEY.RIGHT)) return false;\n\n $select.close();\n\n function getNewActiveMatchIndex(){\n switch(key){\n case KEY.LEFT:\n // Select previous/first item\n if(~$selectMultiple.activeMatchIndex) return prev;\n // Select last item\n else return last;\n break;\n case KEY.RIGHT:\n // Open drop-down\n if(!~$selectMultiple.activeMatchIndex || curr === last){\n $select.activate();\n return false;\n }\n // Select next/last item\n else return next;\n break;\n case KEY.BACKSPACE:\n // Remove selected item and select previous/first\n if(~$selectMultiple.activeMatchIndex){\n if($selectMultiple.removeChoice(curr)) {\n return prev;\n } else {\n return curr;\n }\n\n } else {\n // If nothing yet selected, select last item\n return last;\n }\n break;\n case KEY.DELETE:\n // Remove selected item and select next item\n if(~$selectMultiple.activeMatchIndex){\n $selectMultiple.removeChoice($selectMultiple.activeMatchIndex);\n return curr;\n }\n else return false;\n }\n }\n\n newIndex = getNewActiveMatchIndex();\n\n if(!$select.selected.length || newIndex === false) $selectMultiple.activeMatchIndex = -1;\n else $selectMultiple.activeMatchIndex = Math.min(last,Math.max(first,newIndex));\n\n return true;\n }\n\n $select.searchInput.on('keyup', function(e) {\n\n if ( ! KEY.isVerticalMovement(e.which) ) {\n scope.$evalAsync( function () {\n $select.activeIndex = $select.taggingLabel === false ? -1 : 0;\n });\n }\n // Push a \"create new\" item into array if there is a search string\n if ( $select.tagging.isActivated && $select.search.length > 0 ) {\n\n // return early with these keys\n if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC || KEY.isVerticalMovement(e.which) ) {\n return;\n }\n // always reset the activeIndex to the first item when tagging\n $select.activeIndex = $select.taggingLabel === false ? -1 : 0;\n // taggingLabel === false bypasses all of this\n if ($select.taggingLabel === false) return;\n\n var items = angular.copy( $select.items );\n var stashArr = angular.copy( $select.items );\n var newItem;\n var item;\n var hasTag = false;\n var dupeIndex = -1;\n var tagItems;\n var tagItem;\n\n // case for object tagging via transform `$select.tagging.fct` function\n if ( $select.tagging.fct !== undefined) {\n tagItems = $select.$filter('filter')(items,{'isTag': true});\n if ( tagItems.length > 0 ) {\n tagItem = tagItems[0];\n }\n // remove the first element, if it has the `isTag` prop we generate a new one with each keyup, shaving the previous\n if ( items.length > 0 && tagItem ) {\n hasTag = true;\n items = items.slice(1,items.length);\n stashArr = stashArr.slice(1,stashArr.length);\n }\n newItem = $select.tagging.fct($select.search);\n // verify the new tag doesn't match the value of a possible selection choice or an already selected item.\n if (\n stashArr.some(function (origItem) {\n return angular.equals(origItem, newItem);\n }) ||\n $select.selected.some(function (origItem) {\n return angular.equals(origItem, newItem);\n })\n ) {\n scope.$evalAsync(function () {\n $select.activeIndex = 0;\n $select.items = items;\n });\n return;\n }\n if (newItem) newItem.isTag = true;\n // handle newItem string and stripping dupes in tagging string context\n } else {\n // find any tagging items already in the $select.items array and store them\n tagItems = $select.$filter('filter')(items,function (item) {\n return item.match($select.taggingLabel);\n });\n if ( tagItems.length > 0 ) {\n tagItem = tagItems[0];\n }\n item = items[0];\n // remove existing tag item if found (should only ever be one tag item)\n if ( item !== undefined && items.length > 0 && tagItem ) {\n hasTag = true;\n items = items.slice(1,items.length);\n stashArr = stashArr.slice(1,stashArr.length);\n }\n newItem = $select.search+' '+$select.taggingLabel;\n if ( _findApproxDupe($select.selected, $select.search) > -1 ) {\n return;\n }\n // verify the the tag doesn't match the value of an existing item from\n // the searched data set or the items already selected\n if ( _findCaseInsensitiveDupe(stashArr.concat($select.selected)) ) {\n // if there is a tag from prev iteration, strip it / queue the change\n // and return early\n if ( hasTag ) {\n items = stashArr;\n scope.$evalAsync( function () {\n $select.activeIndex = 0;\n $select.items = items;\n });\n }\n return;\n }\n if ( _findCaseInsensitiveDupe(stashArr) ) {\n // if there is a tag from prev iteration, strip it\n if ( hasTag ) {\n $select.items = stashArr.slice(1,stashArr.length);\n }\n return;\n }\n }\n if ( hasTag ) dupeIndex = _findApproxDupe($select.selected, newItem);\n // dupe found, shave the first item\n if ( dupeIndex > -1 ) {\n items = items.slice(dupeIndex+1,items.length-1);\n } else {\n items = [];\n if (newItem) items.push(newItem);\n items = items.concat(stashArr);\n }\n scope.$evalAsync( function () {\n $select.activeIndex = 0;\n $select.items = items;\n\n if ($select.isGrouped) {\n // update item references in groups, so that indexOf will work after angular.copy\n var itemsWithoutTag = newItem ? items.slice(1) : items;\n $select.setItemsFn(itemsWithoutTag);\n if (newItem) {\n // add tag item as a new group\n $select.items.unshift(newItem);\n $select.groups.unshift({name: '', items: [newItem], tagging: true});\n }\n }\n });\n }\n });\n function _findCaseInsensitiveDupe(arr) {\n if ( arr === undefined || $select.search === undefined ) {\n return false;\n }\n var hasDupe = arr.filter( function (origItem) {\n if ( $select.search.toUpperCase() === undefined || origItem === undefined ) {\n return false;\n }\n return origItem.toUpperCase() === $select.search.toUpperCase();\n }).length > 0;\n\n return hasDupe;\n }\n function _findApproxDupe(haystack, needle) {\n var dupeIndex = -1;\n if(angular.isArray(haystack)) {\n var tempArr = angular.copy(haystack);\n for (var i = 0; i
model\n ngModel.$parsers.unshift(function (inputValue) {\n // Keep original value for undefined and null\n if (isNil(inputValue)) {\n return inputValue;\n }\n\n // Allow the null value to be considered a valid model value\n if (inputValue.$$null) {\n return inputValue[$select.itemProperty];\n }\n\n var locals = {};\n locals[$select.parserResult.itemName] = inputValue;\n return $select.parserResult.modelMapper(scope, locals);\n });\n\n //From model --> view\n ngModel.$formatters.unshift(function (inputValue) {\n // Keep original value for undefined and null\n if (isNil(inputValue)) {\n return inputValue;\n }\n\n var data = $select.parserResult && $select.parserResult.source (scope, { $select : {search:''}}), //Overwrite $search\n locals = {},\n result;\n if (data){\n var checkFnSingle = function(d){\n locals[$select.parserResult.itemName] = d;\n result = $select.parserResult.modelMapper(scope, locals);\n return result === inputValue;\n };\n //If possible pass same object stored in $select.selected\n if ($select.selected && checkFnSingle($select.selected)) {\n return $select.selected;\n }\n for (var i = data.length - 1; i >= 0; i--) {\n if (checkFnSingle(data[i])) return data[i];\n }\n }\n return inputValue;\n });\n\n //Update viewValue if model change\n scope.$watch('$select.selected', function(newValue) {\n if (ngModel.$viewValue !== newValue) {\n ngModel.$setViewValue(newValue);\n }\n });\n\n ngModel.$render = function() {\n $select.selected = ngModel.$viewValue;\n };\n\n scope.$on('uis:select', function (event, item) {\n $select.selected = item;\n var locals = {};\n locals[$select.parserResult.itemName] = item;\n\n $timeout(function() {\n $select.onSelectCallback(scope, {\n $item: item,\n $model: isNil(item) ? item : $select.parserResult.modelMapper(scope, locals)\n });\n });\n });\n\n scope.$on('uis:close', function (event, skipFocusser) {\n $timeout(function(){\n if (!skipFocusser) $select.focusser[0].focus();\n },0,false);\n });\n\n //Idea from: https://github.com/ivaynberg/select2/blob/79b5bf6db918d7560bdd959109b7bcfb47edaf43/select2.js#L1954\n var focusser = angular.element(\" \");\n $compile(focusser)(scope);\n $select.focusser = focusser;\n\n // Move focuser out of because append-to-body=\"true\" will move the focusser out of :tabbable order.\n element.parent().parent().prepend(focusser);\n\n scope.$on('$destroy', function() {\n if ($select.focusser) {\n $select.focusser.remove();\n }\n });\n\n focusser.on(\"focus\", function(){\n scope.$evalAsync(function(){\n $select.focus = true;\n });\n });\n\n focusser.on(\"blur\", function(){\n scope.$evalAsync(function(){\n $select.focus = false;\n });\n });\n\n focusser.on(\"keydown\", function(e){\n if (e.which === KEY.BACKSPACE && $select.backspaceReset !== false) {\n $select.select($select.nullValue);\n $select.cancelEvent(e);\n scope.$apply();\n return;\n }\n\n if (e.which === KEY.TAB) {\n $select.tabNavigate(e.shiftKey);\n $select.cancelEvent(e);\n return;\n }\n\n if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {\n return;\n }\n\n if (e.which == KEY.DOWN || e.which == KEY.UP || e.which == KEY.ENTER || e.which == KEY.SPACE){\n $select.cancelEvent(e);\n $select.activate();\n }\n\n scope.$digest();\n });\n\n focusser.on(\"keyup input\", function(e){\n if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC || e.which == KEY.ENTER || e.which === KEY.BACKSPACE) {\n return;\n }\n\n $select.activate(focusser.val()); //User pressed some regular key, so we pass it to the search input\n focusser.val('');\n scope.$digest();\n });\n }\n };\n}]);\n\n// Make multiple matches sortable\nuis.directive('uiSelectSort', ['$timeout', 'uiSelectConfig', 'uiSelectMinErr', function($timeout, uiSelectConfig, uiSelectMinErr) {\n return {\n require: ['^^uiSelect', '^ngModel'],\n link: function(scope, element, attrs, ctrls) {\n if (scope[attrs.uiSelectSort] === null) {\n throw uiSelectMinErr('sort', 'Expected a list to sort');\n }\n\n var $select = ctrls[0];\n var $ngModel = ctrls[1];\n\n var options = angular.extend({\n axis: 'horizontal'\n },\n scope.$eval(attrs.uiSelectSortOptions));\n\n var axis = options.axis;\n var draggingClassName = 'dragging';\n var droppingClassName = 'dropping';\n var droppingBeforeClassName = 'dropping-before';\n var droppingAfterClassName = 'dropping-after';\n\n scope.$watch(function(){\n return $select.sortable;\n }, function(newValue){\n if (newValue) {\n element.attr('draggable', true);\n } else {\n element.removeAttr('draggable');\n }\n });\n\n if (element.data('disallowDrop')) {\n return;\n }\n\n element.on('dragstart', function(event) {\n element.addClass(draggingClassName);\n\n (event.dataTransfer || event.originalEvent.dataTransfer).setData('text', scope.$index.toString());\n });\n\n element.on('dragend', function() {\n removeClass(draggingClassName);\n });\n\n var move = function(from, to) {\n /*jshint validthis: true */\n this.splice(to, 0, this.splice(from, 1)[0]);\n };\n\n var removeClass = function(className) {\n angular.forEach($select.$element.querySelectorAll('.' + className), function(el){\n angular.element(el).removeClass(className);\n });\n };\n\n var dragOverHandler = function(event) {\n event.preventDefault();\n\n var offset = axis === 'vertical' ? event.offsetY || event.layerY || (event.originalEvent ? event.originalEvent.offsetY : 0) : event.offsetX || event.layerX || (event.originalEvent ? event.originalEvent.offsetX : 0);\n\n if (offset < (this[axis === 'vertical' ? 'offsetHeight' : 'offsetWidth'] / 2)) {\n removeClass(droppingAfterClassName);\n element.addClass(droppingBeforeClassName);\n\n } else {\n removeClass(droppingBeforeClassName);\n element.addClass(droppingAfterClassName);\n }\n };\n\n var dropTimeout;\n\n var dropHandler = function(event) {\n event.preventDefault();\n\n var droppedItemIndex = parseInt((event.dataTransfer || event.originalEvent.dataTransfer).getData('text'), 10);\n\n // prevent event firing multiple times in firefox\n $timeout.cancel(dropTimeout);\n dropTimeout = $timeout(function() {\n _dropHandler(droppedItemIndex);\n }, 20);\n };\n\n var _dropHandler = function(droppedItemIndex) {\n var theList = scope.$eval(attrs.uiSelectSort);\n var itemToMove = theList[droppedItemIndex];\n var newIndex = null;\n\n if (element.hasClass(droppingBeforeClassName)) {\n if (droppedItemIndex < scope.$index) {\n newIndex = scope.$index - 1;\n } else {\n newIndex = scope.$index;\n }\n } else {\n if (droppedItemIndex < scope.$index) {\n newIndex = scope.$index;\n } else {\n newIndex = scope.$index + 1;\n }\n }\n\n move.apply(theList, [droppedItemIndex, newIndex]);\n\n $ngModel.$setViewValue(Date.now());\n\n scope.$apply(function() {\n scope.$emit('uiSelectSort:change', {\n array: theList,\n item: itemToMove,\n from: droppedItemIndex,\n to: newIndex\n });\n });\n\n removeClass(droppingClassName);\n removeClass(droppingBeforeClassName);\n removeClass(droppingAfterClassName);\n\n element.off('drop', dropHandler);\n };\n\n element.on('dragenter', function() {\n if (element.hasClass(draggingClassName)) {\n return;\n }\n\n element.addClass(droppingClassName);\n\n element.on('dragover', dragOverHandler);\n element.on('drop', dropHandler);\n });\n\n element.on('dragleave', function(event) {\n if (event.target != element) {\n return;\n }\n\n removeClass(droppingClassName);\n removeClass(droppingBeforeClassName);\n removeClass(droppingAfterClassName);\n\n element.off('dragover', dragOverHandler);\n element.off('drop', dropHandler);\n });\n }\n };\n}]);\n\nuis.directive('uisOpenClose', ['$parse', '$timeout', function ($parse, $timeout) {\n return {\n restrict: 'A',\n require: 'uiSelect',\n link: function (scope, element, attrs, $select) {\n $select.onOpenCloseCallback = $parse(attrs.uisOpenClose);\n\n scope.$watch('$select.open', function (isOpen, previousState) {\n if (isOpen !== previousState) {\n $timeout(function () {\n $select.onOpenCloseCallback(scope, {\n isOpen: isOpen\n });\n });\n }\n });\n }\n };\n}]);\n\n/**\n * Parses \"repeat\" attribute.\n *\n * Taken from AngularJS ngRepeat source code\n * See https://github.com/angular/angular.js/blob/v1.2.15/src/ng/directive/ngRepeat.js#L211\n *\n * Original discussion about parsing \"repeat\" attribute instead of fully relying on ng-repeat:\n * https://github.com/angular-ui/ui-select/commit/5dd63ad#commitcomment-5504697\n */\n\nuis.service('uisRepeatParser', ['uiSelectMinErr', '$parse', function(uiSelectMinErr, $parse) {\n var self = this;\n\n /**\n * Example:\n * expression = \"address in addresses | filter: {street: $select.search} track by $index\"\n * itemName = \"address\",\n * source = \"addresses | filter: {street: $select.search}\",\n * trackByExp = \"$index\",\n */\n self.parse = function(expression) {\n\n\n var match;\n //var isObjectCollection = /\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)/.test(expression);\n // If an array is used as collection\n\n // if (isObjectCollection){\n // 000000000000000000000000000000111111111000000000000000222222222222220033333333333333333333330000444444444444444444000000000000000055555555555000000000000000000000066666666600000000\n match = expression.match(/^\\s*(?:([\\s\\S]+?)\\s+as\\s+)?(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+(\\s*[\\s\\S]+?)?(?:\\s+track\\s+by\\s+([\\s\\S]+?))?\\s*$/);\n\n // 1 Alias\n // 2 Item\n // 3 Key on (key,value)\n // 4 Value on (key,value)\n // 5 Source expression (including filters)\n // 6 Track by\n\n if (!match) {\n throw uiSelectMinErr('iexp', \"Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.\",\n expression);\n }\n\n var source = match[5],\n filters = '';\n\n // When using (key,value) ui-select requires filters to be extracted, since the object\n // is converted to an array for $select.items\n // (in which case the filters need to be reapplied)\n if (match[3]) {\n // Remove any enclosing parenthesis\n source = match[5].replace(/(^\\()|(\\)$)/g, '');\n // match all after | but not after ||\n var filterMatch = match[5].match(/^\\s*(?:[\\s\\S]+?)(?:[^\\|]|\\|\\|)+([\\s\\S]*)\\s*$/);\n if(filterMatch && filterMatch[1].trim()) {\n filters = filterMatch[1];\n source = source.replace(filters, '');\n }\n }\n\n return {\n itemName: match[4] || match[2], // (lhs) Left-hand side,\n keyName: match[3], //for (key, value) syntax\n source: $parse(source),\n filters: filters,\n trackByExp: match[6],\n getTrackedValue: function(scope, item) {\n if (!this.trackByExp) {\n return item;\n } else {\n var locals = {};\n locals[this.itemName] = item;\n return scope.$eval(this.trackByExp, locals);\n }\n },\n modelMapper: $parse(match[1] || match[4] || match[2]),\n repeatExpression: function (grouped) {\n var expression = this.itemName + ' in ' + (grouped ? '$group.items' : '$select.items');\n if (this.trackByExp) {\n expression += ' track by ' + this.trackByExp;\n }\n return expression;\n }\n };\n\n };\n\n self.getGroupNgRepeatExpression = function() {\n return '$group in $select.groups track by $group.name';\n };\n\n}]);\n\n}());\nangular.module(\"ui.select\").run([\"$templateCache\", function($templateCache) {$templateCache.put(\"bootstrap/choices.tpl.html\",\"\");\n$templateCache.put(\"bootstrap/footer.tpl.html\",\"\");\n$templateCache.put(\"bootstrap/header.tpl.html\",\"\");\n$templateCache.put(\"bootstrap/match-multiple.tpl.html\",\" × \");\n$templateCache.put(\"bootstrap/match.tpl.html\",\"
\");\n$templateCache.put(\"bootstrap/no-choice.tpl.html\",\"\");\n$templateCache.put(\"bootstrap/select-multiple.tpl.html\",\" 0\\\" class=\\\"ui-select-dropdown dropdown-menu\\\">
\");\n$templateCache.put(\"bootstrap/select.tpl.html\",\"
0\\\" class=\\\"ui-select-dropdown dropdown-menu\\\">
\");\n$templateCache.put(\"selectize/choices.tpl.html\",\"\");\n$templateCache.put(\"selectize/footer.tpl.html\",\"\");\n$templateCache.put(\"selectize/header.tpl.html\",\"\");\n$templateCache.put(\"selectize/match-multiple.tpl.html\",\" ×
\");\n$templateCache.put(\"selectize/match.tpl.html\",\"
\");\n$templateCache.put(\"selectize/no-choice.tpl.html\",\"\");\n$templateCache.put(\"selectize/select-multiple.tpl.html\",\"\");\n$templateCache.put(\"selectize/select.tpl.html\",\"\");\n$templateCache.put(\"select2/choices.tpl.html\",\"\");\n$templateCache.put(\"select2/footer.tpl.html\",\"\");\n$templateCache.put(\"select2/header.tpl.html\",\"\");\n$templateCache.put(\"select2/match-multiple.tpl.html\",\" \");\n$templateCache.put(\"select2/match.tpl.html\",\" \");\n$templateCache.put(\"select2/no-choice.tpl.html\",\"\");\n$templateCache.put(\"select2/select-multiple.tpl.html\",\"\");\n$templateCache.put(\"select2/select.tpl.html\",\"\");}]);",null,null]}
\ No newline at end of file
diff --git a/src/uiSelectChoicesDirective.js b/src/uiSelectChoicesDirective.js
index f05242119..34fde921a 100644
--- a/src/uiSelectChoicesDirective.js
+++ b/src/uiSelectChoicesDirective.js
@@ -23,9 +23,13 @@ uis.directive('uiSelectChoices',
// var repeat = RepeatParser.parse(attrs.repeat);
var groupByExp = tAttrs.groupBy;
var groupFilterExp = tAttrs.groupFilter;
+ var groups = tElement.querySelectorAll('.ui-select-choices-group');
+
+ // Prevent unnecessary watches when dropdown is closed
+ // On original ui-select implementation, pre-rendering was off by default (i.e. `ng-if` was always set)
+ groups.attr('ng-if', '$select.open || $select.prerender');
if (groupByExp) {
- var groups = tElement.querySelectorAll('.ui-select-choices-group');
if (groups.length !== 1) throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-group but got '{0}'.", groups.length);
groups.attr('ng-repeat', RepeatParser.getGroupNgRepeatExpression());
}
@@ -39,10 +43,6 @@ uis.directive('uiSelectChoices',
choices.attr('ng-repeat', parserResult.repeatExpression(groupByExp));
- // Prevent unnecessary watches when dropdown is closed
- // On original ui-select implementation, pre-rendering was off by default (i.e. `ng-if` was always set)
- choices.attr('ng-if', '$select.open || $select.prerender');
-
var rowsInner = tElement.querySelectorAll('.ui-select-choices-row-inner');
if (rowsInner.length !== 1) {
throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-row-inner but got '{0}'.", rowsInner.length);