Skip to content

Commit 70ad8b8

Browse files
cyrusfurtadocal-smith
authored andcommitted
fix(dropdown): add reset for multi-select
Dropdown updates (#415) * replaced selected count with reset button count & added secondary content to list item * Removed scss files * removed style files * added demo for multi select with template * requested changes for dropdown.component.ts * Changes for resetting all selected list items as per request in PR * changes to getDisplayValue method * suggested change for button closing tag
1 parent 4d15fb3 commit 70ad8b8

File tree

7 files changed

+110
-21
lines changed

7 files changed

+110
-21
lines changed

package-lock.json

Lines changed: 21 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/dialog/overflow-menu/overflow-menu.stories.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ storiesOf("Overflow Menu", module)
6363
<ibm-overflow-menu-option href="https://www.ibm.com" (selected)="selected($event)">Option 3</ibm-overflow-menu-option>
6464
<ibm-overflow-menu-option href="https://www.ibm.com" (selected)="selected($event)">Option 4</ibm-overflow-menu-option>
6565
<ibm-overflow-menu-option href="https://www.ibm.com" disabled="true" (selected)="selected($event)">Disabled</ibm-overflow-menu-option>
66-
<ibm-overflow-menu-option href="https://www.ibm.com" type="danger" (selected)="selected($event)">Danger option</ibm-overflow-menu-option>
66+
<ibm-overflow-menu-option href="https://www.ibm.com" type="danger" (selected)="selected($event)">
67+
Danger option
68+
</ibm-overflow-menu-option>
6769
</ibm-overflow-menu>
6870
<ibm-placeholder></ibm-placeholder>
6971
`,

src/dropdown/abstract-dropdown-view.class.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,9 @@ export class AbstractDropdownView {
9595
* In most cases this just calls `getCurrentElement().focus()`
9696
*/
9797
initFocus(): void {}
98+
99+
/**
100+
* Resets all selected items
101+
*/
102+
resetSelected(): void {}
98103
}

src/dropdown/dropdown.component.ts

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,27 @@ import { DropdownService } from "./dropdown.service";
4343
[ngClass]="{'a': !menuIsClosed}"
4444
[attr.aria-expanded]="!menuIsClosed"
4545
[attr.aria-disabled]="disabled"
46-
(click)="toggleMenu()"
4746
(blur)="onBlur()"
4847
[disabled]="disabled">
49-
<span class="bx--list-box__label">{{getDisplayValue() | async}}</span>
50-
<div *ngIf="!skeleton" class="bx--list-box__menu-icon" [ngClass]="{'bx--list-box__menu-icon--open': !menuIsClosed }">
51-
<svg fill-rule="evenodd" height="5" role="img" viewBox="0 0 10 5" width="10" [attr.aria-label]="menuButtonLabel">
52-
<title>{{menuButtonLabel}}</title>
53-
<path d="M0 0l5 4.998L10 0z"></path>
48+
<span (click)="clearSelected()" *ngIf="type === 'multi' && view.getSelected() && view.getSelected().length"
49+
class="bx--list-box__selection bx--list-box__selection--multi">
50+
{{view.getSelected().length}}
51+
&nbsp;
52+
<svg class="close-tag" width="8" height="8" viewBox="0 0 10 10">
53+
<path d="M6.32 5L10 8.68 8.68 10 5 6.32 1.32 10 0 8.68 3.68 5 0 1.32 1.32 0 5 3.68 8.68 0 10 1.32 6.32 5z"></path>
5454
</svg>
55+
</span>
56+
<div class="click-container" (click)="toggleMenu()" style="width: 100%; text-align: left;">
57+
<span class="bx--list-box__label">
58+
{{getDisplayValue() | async}}
59+
</span>
60+
<div *ngIf="!skeleton" class="bx--list-box__menu-icon" [ngClass]="{'bx--list-box__menu-icon--open': !menuIsClosed }">
61+
<svg fill-rule="evenodd" height="5" role="img" viewBox="0 0 10 5" width="10"
62+
alt="Open menu" [attr.aria-label]="menuButtonLabel">
63+
<title>{{menuButtonLabel}}</title>
64+
<path d="M0 0l5 4.998L10 0z"></path>
65+
</svg>
66+
</div>
5567
</div>
5668
</button>
5769
<div
@@ -226,6 +238,7 @@ export class Dropdown implements OnInit, AfterContentInit, OnDestroy {
226238
this.propagateChange(this.view.getSelected());
227239
} else {
228240
this.closeMenu();
241+
this.dropdownButton.nativeElement.focus();
229242
if (event.item && event.item.selected) {
230243
if (this.value) {
231244
this.propagateChange(event.item[this.value]);
@@ -336,16 +349,18 @@ export class Dropdown implements OnInit, AfterContentInit, OnDestroy {
336349
}
337350

338351
/**
339-
* Returns the display value if there is no selection, otherwise the selection will be returned.
340-
*/
352+
* Returns the display value if there is a selection and displayValue is set,
353+
* if there is just a selection the ListItem content property will be returned,
354+
* otherwise the placeholder will be returned.
355+
*/
341356
getDisplayValue(): Observable<string> {
342357
if (!this.view) {
343358
return;
344359
}
345360
let selected = this.view.getSelected();
346361
if (selected && !this.displayValue) {
347362
if (this.type === "multi") {
348-
return of(`${selected.length} ${this.selectedLabel}`);
363+
return of(`${this.placeholder}`);
349364
} else {
350365
return of(selected[0].content);
351366
}
@@ -547,4 +562,10 @@ export class Dropdown implements OnInit, AfterContentInit, OnDestroy {
547562

548563
return false;
549564
}
565+
566+
clearSelected() {
567+
this.view.resetSelected();
568+
this.selected.emit([]);
569+
this.propagateChange([]);
570+
}
550571
}

src/dropdown/dropdown.stories.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,45 @@ storiesOf("Dropdown", module)
6969
onClose: action("Multi-select dropdown closed")
7070
}
7171
})))
72+
.add("Multi-select with custom template", withNotes({ text: "Notes on multi select" })(() => ({
73+
template: `
74+
<div style="width: 300px">
75+
<ng-template #customListItem let-item>
76+
<input
77+
class="bx--checkbox"
78+
type="checkbox"
79+
[checked]="item.selected"
80+
[disabled]="item.disabled"
81+
(click)="doClick($event, item)"
82+
tabindex="-1">
83+
<label class="bx--checkbox-label">
84+
<span>{{item.content}}</span>
85+
&nbsp;<span [hidden]="!item.other_content" class="sec-content">({{item.other_content}})</span>
86+
</label>
87+
</ng-template>
88+
<ibm-dropdown
89+
type="multi"
90+
placeholder="Multi-select"
91+
displayValue="Selections"
92+
[disabled]="disabled"
93+
(selected)="selected($event)"
94+
(onClose)="onClose($event)">
95+
<ibm-dropdown-list [items]="items" [listTpl]="customListItem"></ibm-dropdown-list>
96+
</ibm-dropdown>
97+
</div>
98+
`,
99+
props: {
100+
disabled: boolean("disabled", false),
101+
items: object("items", [
102+
{ content: "one" },
103+
{ content: "two", other_content: "Some secondary Content" },
104+
{ content: "three", other_content: "Some more content" },
105+
{ content: "four" }
106+
]),
107+
selected: action("Selected fired for multi-select dropdown"),
108+
onClose: action("Multi-select dropdown closed")
109+
}
110+
})))
72111
.add("With ngModel", () => ({
73112
template: `
74113
<div style="width: 300px">

src/dropdown/list-item.interface.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,13 @@ export interface ListItem {
2525
* @memberof ListItem
2626
*/
2727
content: string;
28+
2829
/**
2930
* Flag for the selected state of the item.
3031
* @type {boolean}
3132
* @memberof ListItem
3233
*/
33-
selected: boolean;
34+
selected?: boolean;
3435
/**
3536
* If the item is in a disabled state.
3637
* (Note: not all lists have to support disabled states, and not all lists behave the same with disabled items)

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,20 +69,22 @@ import { Observable, isObservable, Subscription } from "rxjs";
6969
}">
7070
<div
7171
*ngIf="!listTpl && type === 'multi'"
72-
class="bx--form-item bx--checkbox-wrapper">
72+
class="bx--form-item">
7373
<input
7474
class="bx--checkbox"
7575
type="checkbox"
7676
[checked]="item.selected"
7777
[disabled]="item.disabled"
7878
(click)="doClick($event, item)"
7979
tabindex="-1">
80-
<label class="bx--checkbox-label">{{item.content}}</label>
80+
<label class="bx--checkbox-label">
81+
<span>{{item.content}}</span>
82+
</label>
8183
</div>
8284
<ng-container *ngIf="!listTpl && type === 'single'">{{item.content}}</ng-container>
8385
<ng-template
8486
*ngIf="listTpl"
85-
[ngTemplateOutletContext]="{item: item}"
87+
[ngTemplateOutletContext]="{$implicit: item}"
8688
[ngTemplateOutlet]="listTpl">
8789
</ng-template>
8890
</li>
@@ -457,4 +459,9 @@ export class DropdownList implements AbstractDropdownView, AfterViewInit, OnDest
457459
element.classList.remove("bx--list-box__menu-item--highlighted");
458460
element.tabIndex = -1;
459461
}
462+
463+
resetSelected() {
464+
const clearedItems = this.getListItems().map(item => Object.assign({}, item, {selected: false}));
465+
this.updateList(clearedItems);
466+
}
460467
}

0 commit comments

Comments
 (0)