LP#1775466 Combobox additions
authorBill Erickson <berickxx@gmail.com>
Fri, 6 Jul 2018 22:06:53 +0000 (18:06 -0400)
committerBill Erickson <berickxx@gmail.com>
Wed, 5 Sep 2018 14:05:23 +0000 (10:05 -0400)
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 5c31968..47237e9 100644 (file)
@@ -9,6 +9,9 @@
     class="form-control"
     [ngClass]="{'text-success font-italic font-weight-bold': selected && selected.freetext}"
     [placeholder]="placeholder"
+    [name]="name"
+    [disabled]="isDisabled"
+    [required]="isRequired"
     [(ngModel)]="selected" 
     [ngbTypeahead]="filter"
     [resultTemplate]="displayTemplate"
index 47fedf9..875ce33 100644 (file)
@@ -38,10 +38,13 @@ export class ComboboxComponent implements OnInit {
     selected: ComboboxEntry;
     click$: Subject<string>;
     entrylist: ComboboxEntry[];
-    freeTextId: number;
 
     @ViewChild('instance') instance: NgbTypeahead;
 
+    // Applies a name attribute to the input.
+    // Useful in forms.
+    @Input() name: string;
+
     // Placeholder text for selector input
     @Input() placeholder = '';
 
@@ -49,6 +52,18 @@ export class ComboboxComponent implements OnInit {
 
     @Input() allowFreeText = false;
 
+    // Add a 'required' attribute to the input
+    isRequired: boolean
+    @Input() set required(r: boolean) {
+        this.isRequired = r;
+    }
+
+    // Disable the input
+    isDisabled: boolean;
+    @Input() set disabled(d: boolean) {
+        this.isDisabled = d;
+    }
+
     // Entry ID of the default entry to select (optional)
     // onChange() is NOT fired when applying the default value
     @Input() startId: any;
@@ -67,6 +82,7 @@ export class ComboboxComponent implements OnInit {
     }
 
     // Emitted when the value is changed via UI.
+    // When the UI value is cleared, null is emitted.
     @Output() onChange: EventEmitter<ComboboxEntry>;
 
     // Useful for massaging the match string prior to comparison 
@@ -81,7 +97,6 @@ export class ComboboxComponent implements OnInit {
         this.asyncIds = {};
         this.click$ = new Subject<string>();
         this.onChange = new EventEmitter<ComboboxEntry>();
-        this.freeTextId = -1;
         this.defaultSelectionApplied = false;
 
         this.formatDisplayString = (result: ComboboxEntry) => {
@@ -121,31 +136,33 @@ export class ComboboxComponent implements OnInit {
     }
 
     onBlur() {
+        // When the selected value is a string it means we have either
+        // no value (user cleared the input) or a free-text value.
 
-        if (typeof this.selected === 'string' && this.selected !== '') {
-            // Free text entered which does not match a known entry
+        if (typeof this.selected === 'string') {
 
-            if (this.allowFreeText) {
+            if (this.allowFreeText && this.selected !== '') {
+                // Free text entered which does not match a known entry
                 // translate it into a dummy ComboboxEntry
-                // and manually fire the onchange handler.
                 this.selected = {
-                    id: this.freeTextId--,
+                    id: null,
                     label: this.selected,
                     freetext: true
                 }
-                this.selectorChanged(
-                    {item: this.selected, preventDefault: () => true});
+
             } else {
-                // If free text is not allowed, clear the value when
-                // the user navigates away to avoid confusion.
+
                 this.selected = null;
             }
+
+            // Manually fire the onchange since NgbTypeahead fails
+            // to fire the onchange when the value is cleared.
+            this.selectorChanged(
+                {item: this.selected, preventDefault: () => true});
         }
     }
 
     // Fired by the typeahead to inform us of a change.
-    // This only fires when an item in the list is selected, not when
-    // the value is cleared or free-text is used.
     selectorChanged(selEvent: NgbTypeaheadSelectItemEvent) {
         this.onChange.emit(selEvent.item);
     }