diff --git a/packages/oui-select/README.md b/packages/oui-select/README.md index 23eb4613..d6b4e6a7 100644 --- a/packages/oui-select/README.md +++ b/packages/oui-select/README.md @@ -68,6 +68,24 @@ ``` +### Disabled Items + +```html:preview + + + +``` + +**Note**: For each `$item` in `items` array, `disable-item` will be called with current `$item` as an argument. If it returns true, `$item` will be disabled. + ### On Change **Note**: Model will not be refreshed until the `on-change` callback hasn't returned. If you want to access the new model inside the `on-change` callback you need to use the `modelValue` variable as below. @@ -110,6 +128,7 @@ | `placeholder` | string | @? | yes | n/a | n/a | placeholder displayed when model is undefined | `match` | string | @? | no | n/a | n/a | property of item to show as selected item | `items` | array | < | no | n/a | n/a | array used to populate the list +| `disable-items`| function | & | no | n/a | n/a | predicate to determine items to disable | `required` | boolean | { expect(onChange).toHaveBeenCalledWith(data[index2]); }); }); + + describe("Disable options", () => { + it("should disable corresponding items", () => { + const disableCountry = (item) => item.name === data[3].name; + const element = TestUtils.compileTemplate(` + + + `, { + countries: data, + disableCountry + }); + + $timeout.flush(); + + // Trigger click to update the options with corresponding dynamic attributes + getDropdownButton(element).click(); + expect(angular.element(getDropdownItem(element, 3)).prop("disabled")).toBeTruthy(); + }); + + it("should update item", () => { + const countries = data.concat({ name: "Imaginary country", code: "IC" }); + const disableCountry = (item) => item.code === ""; + const element = TestUtils.compileTemplate(` + + + `, { + countries, + disableCountry + }); + + $timeout.flush(); + + // Trigger click to update the options with corresponding dynamic attributes + getDropdownButton(element).click(); + expect(angular.element(getDropdownItem(element, data.length - 1)).prop("disabled")).toBeFalsy(); + + element.scope().$ctrl.countries[data.length - 1].code = ""; + $timeout.flush(); + + expect(angular.element(getDropdownItem(element, data.length - 1)).prop("disabled")).toBeTruthy(); + }); + }); }); }); diff --git a/packages/oui-select/src/select.directive.js b/packages/oui-select/src/select.directive.js index d2233f54..45a76cd9 100644 --- a/packages/oui-select/src/select.directive.js +++ b/packages/oui-select/src/select.directive.js @@ -17,6 +17,7 @@ export default () => ({ title: "@?", placeholder: "@?", items: "<", + disableItems: "&", match: "@?", groupBy: " - + diff --git a/packages/oui-select/src/templates/choices.html b/packages/oui-select/src/templates/choices.html index 39ca7a5f..80888d58 100644 --- a/packages/oui-select/src/templates/choices.html +++ b/packages/oui-select/src/templates/choices.html @@ -5,10 +5,11 @@ ng-attr-id="ui-select-choices-row-{{ $select.generatedId }}-{{$index}}" class="ui-select-choices-row oui-dropdown-option" ng-class="{ - active: $select.isActive(this), + active: $select.isActive(this) && !$select.isDisabled(this), selected: $select.isSelected(this), disabled: $select.isDisabled(this) }" + ng-disabled="$select.isDisabled(this)" role="option" type="button">