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

feat(oui-select): allow items to be disabled #291

Merged
merged 1 commit into from
Oct 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions packages/oui-select/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,24 @@
</oui-select>
```

### Disabled Items

```html:preview
<oui-select name="country"
model="$ctrl.country"
data-title="Select a country"
placeholder="Select a country..."
items="$ctrl.countries"
disable-items="$ctrl.disableItems($item)"
required
match="name"
data-align="start">
<span ng-bind="$item.name"></span>
</oui-select>
```

**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.
Expand Down Expand Up @@ -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 | <? | no | `true`, `false` | `false` | define if the field is required
| `disabled` | boolean | <? | no | `true`, `false` | `false` | define if the field is disabled
| `group-by` | function | <? | no | n/a | n/a | function taking an item as parameter and returning the group name as as string
Expand Down
54 changes: 54 additions & 0 deletions packages/oui-select/src/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,5 +289,59 @@ describe("ouiSelect", () => {
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(`
<oui-select name="country"
model="$ctrl.country"
title="Select a country"
placeholder="Select a country..."
items="$ctrl.countries"
disable-items="$ctrl.disableCountry($item)"
match="name">
<span ng-bind="$item.name"></span>
</oui-select>`, {
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(`
<oui-select name="country"
model="$ctrl.country"
title="Select a country"
placeholder="Select a country..."
items="$ctrl.countries"
disable-items="$ctrl.disableCountry($item)"
match="name">
<span ng-bind="$item.name"></span>
</oui-select>`, {
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();
});
});
});
});
1 change: 1 addition & 0 deletions packages/oui-select/src/select.directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default () => ({
title: "@?",
placeholder: "@?",
items: "<",
disableItems: "&",
match: "@?",
groupBy: "<?",
align: "@?",
Expand Down
2 changes: 1 addition & 1 deletion packages/oui-select/src/select.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
on-focus="$ctrl.onUiSelectFocus()"
on-select="$ctrl.onChange({ modelValue: $model })">
<oui-ui-select-match placeholder="{{::$ctrl.placeholder}}"></oui-ui-select-match>
<oui-ui-select-choices repeat="$item in $ctrl.items track by $index"></oui-ui-select-choices>
<oui-ui-select-choices repeat="$item in $ctrl.items track by $index" ui-disable-choice="$ctrl.disableItems({ $item: $item })"></oui-ui-select-choices>
</oui-ui-select>
3 changes: 2 additions & 1 deletion packages/oui-select/src/templates/choices.html
Original file line number Diff line number Diff line change
Expand Up @@ -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">
<span class="ui-select-choices-row-inner" ng-class="{ 'ui-select-choices-row-inner_grouped': $select.isGrouped }">
Expand Down