LP1888723 Support disabling select entries in combobox
authorBill Erickson <berickxx@gmail.com>
Wed, 3 Mar 2021 15:52:36 +0000 (10:52 -0500)
committerBill Erickson <berickxx@gmail.com>
Mon, 12 Jul 2021 15:25:15 +0000 (11:25 -0400)
Adds a new @Input() disableEntries: any[] for tracking identifier
values in the combobox that should be marked as disabled / unselectable.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/share/combobox/combobox.component.html
Open-ILS/src/eg2/src/app/share/combobox/combobox.component.ts

index a26b6fd..38b2507 100644 (file)
@@ -1,14 +1,15 @@
 
-<!-- todo disabled -->
 <ng-template #defaultDisplayTemplate let-r="result">
-{{r.label || r.id}}
+  <span id="{{domId}}-{{r.id}}">{{r.label}}</span>
 </ng-template>
 
 <ng-template #acqfTemplate egIdlClass="acqf" let-r="result">
-  {{r.fm.code()}} ({{r.fm.year()}})
+  <span id="{{domId}}-{{r.id}}">{{r.fm.code()}} ({{r.fm.year()}})</span>
 </ng-template>
 <ng-template #acplTemplate egIdlClass="acpl" let-r="result">
-  {{r.fm.name()}} ({{getOrgShortname(r.fm.owning_lib())}})
+  <span id="{{domId}}-{{r.id}}">
+    {{r.fm.name()}} ({{getOrgShortname(r.fm.owning_lib())}})
+  </span>
 </ng-template>
 
 <div class="d-flex">
index 2291168..747b27f 100644 (file)
@@ -23,6 +23,7 @@ export interface ComboboxEntry {
   freetext?: boolean;
   userdata?: any; // opaque external value; ignored by this component.
   fm?: IdlObject;
+  disabled?: boolean;
 }
 
 @Directive({
@@ -81,6 +82,9 @@ export class ComboboxComponent implements ControlValueAccessor, OnInit, AfterVie
         this.isRequired = r;
     }
 
+    // Array of entry identifiers to disable in the selector
+    @Input() disableEntries: any[] = [];
+
     // Disable the input
     isDisabled: boolean;
     @Input() set disabled(d: boolean) {
@@ -116,7 +120,8 @@ export class ComboboxComponent implements ControlValueAccessor, OnInit, AfterVie
                     this.entrylist = [{
                         id: id,
                         label: this.getFmRecordLabel(rec),
-                        fm: rec
+                        fm: rec,
+                        disabled : this.disableEntries.includes(id)
                     }];
                     this.selected = this.entrylist.filter(e => e.id === id)[0];
                 });
@@ -479,6 +484,18 @@ export class ComboboxComponent implements ControlValueAccessor, OnInit, AfterVie
         });
     }
 
+    // NgbTypeahead doesn't offer a way to style the dropdown
+    // button directly, so we have to reach up and style it ourselves.
+    applyDisableStyle() {
+        this.disableEntries.forEach(id => {
+            const node = document.getElementById(`${this.domId}-${id}`);
+            if (node) {
+                const button = node.parentNode as HTMLElement;
+                button.classList.add('disabled');
+            }
+        });
+    }
+
     filter = (text$: Observable<string>): Observable<ComboboxEntry[]> => {
         return text$.pipe(
             debounceTime(200),
@@ -502,6 +519,10 @@ export class ComboboxComponent implements ControlValueAccessor, OnInit, AfterVie
                 // click action occurred.
                 if (term === '') { return []; }
 
+                // Give the typeahead a chance to open before applying
+                // the disabled entry styling.
+                setTimeout(() => this.applyDisableStyle());
+
                 // In sync-data mode, a click displays the full list.
                 if (term === '_CLICK_' && !this.asyncDataSource) {
                     return this.entrylist;