Skip to content
This repository was archived by the owner on Aug 7, 2020. It is now read-only.

Commit 0daac4c

Browse files
committed
feat(oui-select): allow items to be disabled
1 parent a6a04b9 commit 0daac4c

File tree

5 files changed

+77
-2
lines changed

5 files changed

+77
-2
lines changed

packages/oui-select/README.md

+19
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,24 @@
6868
</oui-select>
6969
```
7070

71+
### Disabled Items
72+
73+
```html:preview
74+
<oui-select name="country"
75+
model="$ctrl.country"
76+
data-title="Select a country"
77+
placeholder="Select a country..."
78+
items="$ctrl.countries"
79+
disable-items="$ctrl.disableItems($item)"
80+
required
81+
match="name"
82+
data-align="start">
83+
<span ng-bind="$item.name"></span>
84+
</oui-select>
85+
```
86+
87+
**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.
88+
7189
### On Change
7290

7391
**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 @@
110128
| `placeholder` | string | @? | yes | n/a | n/a | placeholder displayed when model is undefined
111129
| `match` | string | @? | no | n/a | n/a | property of item to show as selected item
112130
| `items` | array | < | no | n/a | n/a | array used to populate the list
131+
| `disable-items`| function | & | no | n/a | n/a | predicate to determine items to disable
113132
| `required` | boolean | <? | no | `true`, `false` | `false` | define if the field is required
114133
| `disabled` | boolean | <? | no | `true`, `false` | `false` | define if the field is disabled
115134
| `group-by` | function | <? | no | n/a | n/a | function taking an item as parameter and returning the group name as as string

packages/oui-select/src/index.spec.js

+54
Original file line numberDiff line numberDiff line change
@@ -289,5 +289,59 @@ describe("ouiSelect", () => {
289289
expect(onChange).toHaveBeenCalledWith(data[index2]);
290290
});
291291
});
292+
293+
describe("Disable options", () => {
294+
it("should disable corresponding items", () => {
295+
const disableCountry = (item) => item.name === data[3].name;
296+
const element = TestUtils.compileTemplate(`
297+
<oui-select name="country"
298+
model="$ctrl.country"
299+
title="Select a country"
300+
placeholder="Select a country..."
301+
items="$ctrl.countries"
302+
disable-items="$ctrl.disableCountry($item)"
303+
match="name">
304+
<span ng-bind="$item.name"></span>
305+
</oui-select>`, {
306+
countries: data,
307+
disableCountry
308+
});
309+
310+
$timeout.flush();
311+
312+
// Trigger click to update the options with corresponding dynamic attributes
313+
getDropdownButton(element).click();
314+
expect(angular.element(getDropdownItem(element, 3)).prop("disabled")).toBeTruthy();
315+
});
316+
317+
it("should update item", () => {
318+
const countries = data.concat({ name: "Imaginary country", code: "IC" });
319+
const disableCountry = (item) => item.code === "";
320+
const element = TestUtils.compileTemplate(`
321+
<oui-select name="country"
322+
model="$ctrl.country"
323+
title="Select a country"
324+
placeholder="Select a country..."
325+
items="$ctrl.countries"
326+
disable-items="$ctrl.disableCountry($item)"
327+
match="name">
328+
<span ng-bind="$item.name"></span>
329+
</oui-select>`, {
330+
countries,
331+
disableCountry
332+
});
333+
334+
$timeout.flush();
335+
336+
// Trigger click to update the options with corresponding dynamic attributes
337+
getDropdownButton(element).click();
338+
expect(angular.element(getDropdownItem(element, data.length - 1)).prop("disabled")).toBeFalsy();
339+
340+
element.scope().$ctrl.countries[data.length - 1].code = "";
341+
$timeout.flush();
342+
343+
expect(angular.element(getDropdownItem(element, data.length - 1)).prop("disabled")).toBeTruthy();
344+
});
345+
});
292346
});
293347
});

packages/oui-select/src/select.directive.js

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export default () => ({
1717
title: "@?",
1818
placeholder: "@?",
1919
items: "<",
20+
disableItems: "&",
2021
match: "@?",
2122
groupBy: "<?",
2223
align: "@?",

packages/oui-select/src/select.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
on-focus="$ctrl.onUiSelectFocus()"
1010
on-select="$ctrl.onChange({ modelValue: $model })">
1111
<oui-ui-select-match placeholder="{{::$ctrl.placeholder}}"></oui-ui-select-match>
12-
<oui-ui-select-choices repeat="$item in $ctrl.items track by $index"></oui-ui-select-choices>
12+
<oui-ui-select-choices repeat="$item in $ctrl.items track by $index" ui-disable-choice="$ctrl.disableItems({ $item: $item })"></oui-ui-select-choices>
1313
</oui-ui-select>

packages/oui-select/src/templates/choices.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
ng-attr-id="ui-select-choices-row-{{ $select.generatedId }}-{{$index}}"
66
class="ui-select-choices-row oui-dropdown-option"
77
ng-class="{
8-
active: $select.isActive(this),
8+
active: $select.isActive(this) && !$select.isDisabled(this),
99
selected: $select.isSelected(this),
1010
disabled: $select.isDisabled(this)
1111
}"
12+
ng-disabled="$select.isDisabled(this)"
1213
role="option"
1314
type="button">
1415
<span class="ui-select-choices-row-inner" ng-class="{ 'ui-select-choices-row-inner_grouped': $select.isGrouped }">

0 commit comments

Comments
 (0)