From 2d5334a45e06bbd1610b32817d2bfe1224cf6a23 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Fri, 11 Jan 2019 13:06:23 -0500 Subject: [PATCH] LP1811288 Combobox support entrylist+async / id labels Allow the caller to pass a seed entrylist value for async comboboxes. This is useful when a value should be applied to the box on load instead of wiating for user input for typeahead loading. Allow combobox entries to default to using the 'id' field for the label if no label is provided. Signed-off-by: Bill Erickson --- .../src/app/share/combobox/combobox.component.html | 2 +- .../src/app/share/combobox/combobox.component.ts | 41 +++++++++++++++------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/Open-ILS/src/eg2/src/app/share/combobox/combobox.component.html b/Open-ILS/src/eg2/src/app/share/combobox/combobox.component.html index 47237e9f9b..0a5deeeb8c 100644 --- a/Open-ILS/src/eg2/src/app/share/combobox/combobox.component.html +++ b/Open-ILS/src/eg2/src/app/share/combobox/combobox.component.html @@ -1,7 +1,7 @@ -{{r.label}} +{{r.label || r.id}}
diff --git a/Open-ILS/src/eg2/src/app/share/combobox/combobox.component.ts b/Open-ILS/src/eg2/src/app/share/combobox/combobox.component.ts index 323623c3a0..272a27189d 100644 --- a/Open-ILS/src/eg2/src/app/share/combobox/combobox.component.ts +++ b/Open-ILS/src/eg2/src/app/share/combobox/combobox.component.ts @@ -11,7 +11,8 @@ import {StoreService} from '@eg/core/store.service'; export interface ComboboxEntry { id: any; - label: string; + // If no label is provided, the 'id' value is used. + label?: string; freetext?: boolean; } @@ -69,8 +70,17 @@ export class ComboboxComponent implements OnInit { defaultSelectionApplied: boolean; @Input() set entries(el: ComboboxEntry[]) { - this.entrylist = el; - this.applySelection(); + if (el) { + this.entrylist = el; + this.applySelection(); + + // It's possible to provide an entrylist at load time, but + // fetch all future data via async data source. Track the + // values we already have so async lookup won't add them again. + // A new entry list wipes out any existing async values. + this.asyncIds = {}; + el.forEach(entry => this.asyncIds['' + entry.id] = true); + } } // Emitted when the value is changed via UI. @@ -138,6 +148,14 @@ export class ComboboxComponent implements OnInit { this.selected = this.entrylist.filter(e => e.id === entryId)[0]; } + addAsyncEntry(entry: ComboboxEntry) { + // Avoid duplicate async entries + if (!this.asyncIds['' + entry.id]) { + this.asyncIds['' + entry.id] = true; + this.addEntry(entry); + } + } + onBlur() { // When the selected value is a string it means we have either // no value (user cleared the input) or a free-text value. @@ -180,12 +198,7 @@ export class ComboboxComponent implements OnInit { return new Observable(observer => { this.asyncDataSource(term).subscribe( - (entry: ComboboxEntry) => { - if (!this.asyncIds['' + entry.id]) { - this.asyncIds['' + entry.id] = true; - this.addEntry(entry); - } - }, + (entry: ComboboxEntry) => this.addAsyncEntry(entry), err => {}, () => { observer.next(term); @@ -215,6 +228,9 @@ export class ComboboxComponent implements OnInit { map((term: string) => { if (term === '' || term === '_CLICK_') { + // Avoid displaying the existing entries on-click + // for async sources, becuase that implies we have + // the full data set. (setting?) if (this.asyncDataSource) { return []; } else { @@ -226,9 +242,10 @@ export class ComboboxComponent implements OnInit { // Filter entrylist whose labels substring-match the // text entered. - return this.entrylist.filter(entry => - entry.label.toLowerCase().indexOf(term.toLowerCase()) > -1 - ); + return this.entrylist.filter(entry => { + const label = entry.label || entry.id; + return label.toLowerCase().indexOf(term.toLowerCase()) > -1; + }); }) ); } -- 2.11.0