From 1f6c9b60e2aad209c50b94dbac760eb2a2accae0 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 waiting 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 Signed-off-by: Jane Sandberg Signed-off-by: Dan Wells --- .../share/combobox/combobox.component.html | 2 +- .../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.43.2