From b95bf9ffc7e5bab23fadfd871e451421764906cb Mon Sep 17 00:00:00 2001 From: user378230 Date: Fri, 8 Jul 2016 18:27:55 +0100 Subject: [PATCH] fix(isDisabled): do not modify item Previously the item from the list was modified with the _uiSelectChoiceDisabled property. This allowed a leakage of information from ui-select to outside the directive. It also caused issues when the was used outside of the directive. This commit adds a reference array to store disabled items and so prevents the need to modify the item in place. Closes #1200 and #1661 Partially supersedes #1641 --- src/uiSelectController.js | 40 +++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/uiSelectController.js b/src/uiSelectController.js index 1a5afec85..6cea09d81 100644 --- a/src/uiSelectController.js +++ b/src/uiSelectController.js @@ -324,18 +324,42 @@ uis.controller('uiSelectCtrl', ctrl.selected.filter(function (selection) { return angular.equals(selection, item); }).length > 0); }; + var disabledItems = []; + + function _updateItemDisabled(item, isDisabled) { + var disabledItemIndex = disabledItems.indexOf(item); + if (isDisabled && disabledItemIndex === -1) { + disabledItems.push(item); + } + + if (!isDisabled && disabledItemIndex > -1) { + disabledItems.splice(disabledItemIndex, 0); + } + } + + function _isItemDisabled(item) { + return disabledItems.indexOf(item) > -1; + } + ctrl.isDisabled = function(itemScope) { if (!ctrl.open) return; - var itemIndex = ctrl.items.indexOf(itemScope[ctrl.itemProperty]); + var item = itemScope[ctrl.itemProperty]; + var itemIndex = ctrl.items.indexOf(item); var isDisabled = false; - var item; + + if (itemIndex >= 0 && (angular.isDefined(ctrl.disableChoiceExpression) || ctrl.multiple)) { - if (itemIndex >= 0 && (!angular.isUndefined(ctrl.disableChoiceExpression) || ctrl.multiple)) { - item = ctrl.items[itemIndex]; - isDisabled = !!(itemScope.$eval(ctrl.disableChoiceExpression)) || _isItemSelected(item); // force the boolean value - item._uiSelectChoiceDisabled = isDisabled; // store this for later reference + if (ctrl.multiple) { + isDisabled = _isItemSelected(item); + } + + if (!isDisabled && angular.isDefined(ctrl.disableChoiceExpression)) { + isDisabled = !!(itemScope.$eval(ctrl.disableChoiceExpression)); + } + + _updateItemDisabled(item, isDisabled); } return isDisabled; @@ -344,11 +368,11 @@ uis.controller('uiSelectCtrl', // When the user selects an item with ENTER or clicks the dropdown ctrl.select = function(item, skipFocusser, $event) { - if (item === undefined || !item._uiSelectChoiceDisabled) { + if (item === undefined || !_isItemDisabled(item)) { if ( ! ctrl.items && ! ctrl.search && ! ctrl.tagging.isActivated) return; - if (!item || !item._uiSelectChoiceDisabled) { + if (!item || !_isItemDisabled(item)) { if(ctrl.tagging.isActivated) { // if taggingLabel is disabled and item is undefined we pull from ctrl.search if ( ctrl.taggingLabel === false ) {