Skip to content

Commit ed21f9e

Browse files
authored
Merge pull request #196 from cal-smith/dropdown
fix(dropdown): add value input for ngModel
2 parents a08ee32 + 7e5cda3 commit ed21f9e

File tree

4 files changed

+57
-12
lines changed

4 files changed

+57
-12
lines changed

src/dropdown/dropdown.component.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ export class Dropdown implements OnInit, AfterContentInit, OnDestroy {
115115
* @memberof Dropdown
116116
*/
117117
@Input() scrollableContainer: string;
118+
/**
119+
* Specifies the property to be used as the return value to `ngModel`
120+
*/
121+
@Input() value: string;
118122
/**
119123
* Accessible label for the button that opens the dropdown list.
120124
* Defaults to the `DROPDOWN.OPEN` value from the i18n service.
@@ -221,15 +225,17 @@ export class Dropdown implements OnInit, AfterContentInit, OnDestroy {
221225
this.view.size = this.size;
222226
this.elementRef.nativeElement.classList.add(this.buildClass());
223227
this.view.select.subscribe(event => {
224-
if (this.type === "single") {
225-
this.closeMenu();
226-
this.dropdownButton.nativeElement.focus();
227-
}
228228
if (this.type === "multi") {
229229
this.propagateChange(this.view.getSelected());
230230
} else {
231-
if (event.item.selected) {
232-
this.propagateChange(event.item);
231+
this.closeMenu();
232+
this.dropdownButton.nativeElement.focus();
233+
if (event.item && event.item.selected) {
234+
if (this.value) {
235+
this.propagateChange(event.item[this.value]);
236+
} else {
237+
this.propagateChange(event.item);
238+
}
233239
} else {
234240
this.propagateChange(null);
235241
}
@@ -266,12 +272,16 @@ export class Dropdown implements OnInit, AfterContentInit, OnDestroy {
266272
* @memberof Dropdown
267273
*/
268274
writeValue(value: any) {
269-
if (value) {
270-
if (this.type === "single") {
271-
this.view.propagateSelected([value]);
275+
if (this.type === "single") {
276+
if (this.value) {
277+
const newValue = Object.assign({}, this.view.items.find(item => item[this.value] === value));
278+
newValue.selected = true;
279+
this.view.propagateSelected([newValue]);
272280
} else {
273-
this.view.propagateSelected(value);
281+
this.view.propagateSelected([value]);
274282
}
283+
} else {
284+
this.view.propagateSelected(value);
275285
}
276286
}
277287

src/dropdown/dropdown.stories.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { storiesOf, moduleMetadata } from "@storybook/angular";
22
import { withNotes } from "@storybook/addon-notes";
33
import { action } from "@storybook/addon-actions";
4-
import { withKnobs, boolean, object } from "@storybook/addon-knobs/angular";
4+
import { withKnobs, boolean, object, text } from "@storybook/addon-knobs/angular";
55

66
import { DropdownModule } from "../";
77

88
// needed to init ngx translate and load the translations
99
import { BootstrapModule } from "../../.storybook/bootstrap.module";
10+
import { stringify } from "querystring";
1011

1112
storiesOf("Dropdown", module)
1213
.addDecorator(
@@ -62,4 +63,26 @@ storiesOf("Dropdown", module)
6263
selected: action("Selected fired for multi-select dropdown"),
6364
onClose: action("Multi-select dropdown closed")
6465
}
65-
})));
66+
})))
67+
.add("With ngModel", () => ({
68+
template: `
69+
<ibm-dropdown
70+
placeholder="Select"
71+
[disabled]="disabled"
72+
[(ngModel)]="model"
73+
value="content">
74+
<ibm-dropdown-list [items]="items"></ibm-dropdown-list>
75+
</ibm-dropdown>
76+
<span>{{model | json}}</span>
77+
`,
78+
props: {
79+
disabled: boolean("disabled", false),
80+
items: [
81+
{ content: "one" },
82+
{ content: "two" },
83+
{ content: "three" },
84+
{ content: "four" }
85+
],
86+
model: null
87+
}
88+
}));

src/dropdown/list-item.interface.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,9 @@ export interface ListItem {
4444
* @memberof ListItem
4545
*/
4646
items?: ListItem[];
47+
48+
/**
49+
* Allows for any other custom properties to be included in the ListItem
50+
*/
51+
[x: string]: any;
4752
}

src/dropdown/list/dropdown-list.component.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,13 @@ export class DropdownList implements AbstractDropdownView, AfterViewInit, OnChan
218218
}, 0);
219219
this.index = this.items.findIndex(item => item.selected);
220220
this.setupFocusObservable();
221+
setTimeout(() => {
222+
if (this.type === "single") {
223+
this.select.emit({ item: this.items.find(item => item.selected) });
224+
} else {
225+
this.select.emit(this.getSelected() || []);
226+
}
227+
});
221228
}
222229

223230
/**

0 commit comments

Comments
 (0)