### File

`modules/list/src/ngui-autocomplete.component.ts`

### Extends

`NguiVirtualListComponent`

### Implements

`OnInit`

### Metadata

selector | `ngui-autocomplete`
styles | `:host {position: absolute; background-color: #fff; max-height: 300px; overflow: auto} .ngui-autocomplete { border: 1px solid #ccc; padding: 4px }`
template |
    <div *ngIf="isReady" class="ngui-autocomplete">
      <div #pages></div>
      <ngui-inview (inview)="addMorePages()"></ngui-inview>
    </div>

### Index

###### Properties
_acTimer _escapedFromList _focused _focusTimer _lastSelected _orgInputValue _prevInputValue _selectedFromList inputEl template _focused Public cdr Public dynamicComponentService Public element inviewPage inviewPages isListLoading pagesRef Public renderer template
###### Methods
addAutocompleteList addList addMorePages clearList ngOnInit onEscaped onInputElBlurred onInputElFocused onInputElKeyup onSelected positionThisUnderInputEl setFocused addAnInviewPageToPages addList ngAfterViewInit
###### Inputs
blankOption for minInputChars noMatchItem
###### Outputs
bottomInview escaped selected

### Inputs

`blankOption` | Default value: `'Select One'`
Defined in modules/list/src/ngui-autocomplete.component.ts:33

`for` | Type: `string`
Defined in modules/list/src/ngui-autocomplete.component.ts:31

`minInputChars` | Default value: `1`
Defined in modules/list/src/ngui-autocomplete.component.ts:32

`noMatchItem` | Default value: `'No Match Found'`
Defined in modules/list/src/ngui-autocomplete.component.ts:34

### Outputs

`bottomInview` | Event fired when bottom of the virtual list is in view The handler of this event must call `$event.addItems(items: Array<any>)` to fill contents If not, only the first page is loaded, and rest of the pages won't be loaded; ### example
    <ngui-virtual-list (bottomInview)="loadItems($event)">
       <ng-template let-items="items">
         <div *ngIf="items else noItems">
            <li *ngFor="let num of items; trackBy: num">row number: {{ num }}</li>
         </div>
         <ng-template #noItems>Loading</ng-template>
       </ng-template>
    </ngui-virtual-list>
`$event` type: `EventEmitter<any>`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:90

`escaped` | Fired when `ESC` key is pressed from `<ngui-list-item>` `$event` type: `EventEmitter<any>`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:71

`selected` | Fired when child `<ngui-list-item>` is selected `$event` type: `EventEmitter<any>`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:69

### Methods

addAutocompleteList
`addAutocompleteList()`
Defined in modules/list/src/ngui-autocomplete.component.ts:135
Complete the first page of autocomplete Returns : `void`

addList
`addList(items: Array)`
Defined in modules/list/src/ngui-autocomplete.component.ts:185
Parameters :
Name | Type | Optional
items | `Array<any>` | no
Returns : `void`

addMorePages
`addMorePages()`
Defined in modules/list/src/ngui-autocomplete.component.ts:150
Complete after the first page of autocomplete when it scrolls to the bottom Returns : `void`

clearList
`clearList()`
Defined in modules/list/src/ngui-autocomplete.component.ts:107
Returns : `void`

ngOnInit
`ngOnInit()`
Defined in modules/list/src/ngui-autocomplete.component.ts:64
Returns : `void`

onEscaped
`onEscaped()`
Defined in modules/list/src/ngui-autocomplete.component.ts:83
Returns : `void`

onInputElBlurred
`onInputElBlurred(event: )`
Defined in modules/list/src/ngui-autocomplete.component.ts:103
Parameters :
Name | Optional
event | no
Returns : `void`

onInputElFocused
`onInputElFocused(event: )`
Defined in modules/list/src/ngui-autocomplete.component.ts:93
Parameters :
Name | Optional
event | no
Returns : `void`

onInputElKeyup
`onInputElKeyup(event: KeyboardEvent)`
Defined in modules/list/src/ngui-autocomplete.component.ts:114
Parameters :
Name | Type | Optional
event | `KeyboardEvent` | no
Returns : `void`

onSelected
`onSelected(value: )`
Defined in modules/list/src/ngui-autocomplete.component.ts:75
Parameters :
Name | Optional
value | no
Returns : `void`

positionThisUnderInputEl
`positionThisUnderInputEl()`
Defined in modules/list/src/ngui-autocomplete.component.ts:172
Returns : `void`

setFocused
`setFocused(elType: "input" | "listItem", val: boolean)`
Defined in modules/list/src/ngui-autocomplete.component.ts:159
Parameters :
Name | Type | Optional
elType | `"input" | "listItem"` | no
val | `boolean` | no
Returns : `void`

addAnInviewPageToPages
`addAnInviewPageToPages()`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:118
When the bottom is inview port, this function is called It will insert a dynamicall created NguiInviewPageComponent with the given template. It will also fires (bottomInview) event, so that user can fill up items for the page. Returns : `void`

addList
`addList(items: Array)`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:136
Parameters :
Name | Type | Optional
items | `Array<any>` | no
Returns : `void`

ngAfterViewInit
`ngAfterViewInit()`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:107
Check if necessary input and output is provided Returns : `void`

### Properties

_acTimer
`_acTimer: ```
Defined in modules/list/src/ngui-autocomplete.component.ts:42

_escapedFromList
`_escapedFromList: `boolean``
Type : `boolean`
Defined in modules/list/src/ngui-autocomplete.component.ts:44

_focused
`_focused: `any``
Type : `any`
Default value : `{input: false, listItem: false}`
Defined in modules/list/src/ngui-autocomplete.component.ts:40

_focusTimer
`_focusTimer: ```
Defined in modules/list/src/ngui-autocomplete.component.ts:41

_lastSelected
`_lastSelected: `any``
Type : `any`
Defined in modules/list/src/ngui-autocomplete.component.ts:47

_orgInputValue
`_orgInputValue: `string``
Type : `string`
Defined in modules/list/src/ngui-autocomplete.component.ts:45

_prevInputValue
`_prevInputValue: `string``
Type : `string`
Defined in modules/list/src/ngui-autocomplete.component.ts:46

_selectedFromList
`_selectedFromList: `boolean``
Type : `boolean`
Defined in modules/list/src/ngui-autocomplete.component.ts:43

inputEl
`inputEl: `HTMLInputElement``
Type : `HTMLInputElement`
Defined in modules/list/src/ngui-autocomplete.component.ts:39

template
`template: `TemplateRef<any>``
Type : `TemplateRef<any>`
Decorators : `ContentChild`
Defined in modules/list/src/ngui-autocomplete.component.ts:37
Template of NguiInviewPage. Allow users to define their own template

_focused
`_focused: ```
Default value : `false`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:94

Public cdr
`cdr: `ChangeDetectorRef``
Type : `ChangeDetectorRef`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:103

Public dynamicComponentService
`dynamicComponentService: `DynamicComponentService``
Type : `DynamicComponentService`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:102

Public element
`element: `ElementRef``
Type : `ElementRef`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:101

inviewPage
`inviewPage: `ComponentRef<NguiInviewPageComponent>``
Type : `ComponentRef<NguiInviewPageComponent>`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:93
The last NguiInviewPageComponent being inserted

inviewPages
`inviewPages: `Array<ComponentRef<NguiInviewPageComponent>>``
Type : `Array<ComponentRef<NguiInviewPageComponent>>`
Default value : `[]`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:97

isListLoading
`isListLoading: `boolean``
Type : `boolean`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:96
Indicates if a page is still loading

pagesRef
`pagesRef: `ViewContainerRef``
Type : `ViewContainerRef`
Decorators : `ViewChild`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:65
the container NguiInviewPage will be inserted

Public renderer
`renderer: `Renderer2``
Type : `Renderer2`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:100

template
`template: `TemplateRef<any>``
Type : `TemplateRef<any>`
Decorators : `ContentChild`
Inherited from `NguiVirtualListComponent`
Defined in NguiVirtualListComponent:67
Template of NguiInviewPage. Allow users to define their own template

### Accessors

isReady
get `isReady()`
Defined in modules/list/src/ngui-autocomplete.component.ts:56
returns autocomplete display condition autocompolete list is only visible when input element is focused or list element is focused when input value has enought characters and user just did not selected or escaped Returns : `boolean`

    import {
      Component,
      ContentChild,
      Input,
      OnInit,
      TemplateRef
    } from '@angular/core';
    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/observable/fromEvent';
    import 'rxjs/add/operator/map';

    import { fireEvent } from '../../utils';
    import { NguiVirtualListComponent } from './ngui-virtual-list.component';
    import { NoMatchFound } from './no-match-found';
    import { NoneSelect } from './none-select';

    @Component({
      selector: 'ngui-autocomplete',
      template: `
        <div *ngIf="isReady" class="ngui-autocomplete">
          <div #pages></div>
          <ngui-inview (inview)="addMorePages()"></ngui-inview>
        </div>
      `,
      styles: [`
        :host {position: absolute; background-color: #fff; max-height: 300px; overflow: auto}
        .ngui-autocomplete { border: 1px solid #ccc; padding: 4px }
      `]
    })
    export class NguiAutocompleteComponent extends NguiVirtualListComponent implements OnInit {
      @Input() for: string; // input tag id
      @Input() minInputChars = 1;
      @Input() blankOption = 'Select One';
      @Input() noMatchItem = 'No Match Found';

      /** Template of NguiInviewPage. Allow users to define their own template  */
      @ContentChild(TemplateRef) template: TemplateRef<any>;

      inputEl: HTMLInputElement;
      _focused: any = {input: false, listItem: false};
      _focusTimer;
      _acTimer;
      _selectedFromList: boolean;
      _escapedFromList: boolean;
      _orgInputValue: string;
      _prevInputValue: string;
      _lastSelected: any;

      /**
       * returns autocomplete display condition
       * autocompolete list is only visible
       *   - when input element is focused or list element is focused
       *   - when input value has enought characters
       *   - and user just did not selected or escaped
       */
      get isReady(): boolean {
        const selectedOrEscaped = this._selectedFromList || this._escapedFromList;
        const focused = this._focused.input || this._focused.listItem;
        const minChars = this.inputEl.value.length >= this.minInputChars;

        return (!selectedOrEscaped && focused && minChars);
      }

      ngOnInit(): void {
        this.inputEl = <HTMLInputElement> document.querySelector('#' + this.for); // tslint:disable-line
        this.positionThisUnderInputEl();

        Observable.fromEvent(this.inputEl, 'keyup').subscribe(this.onInputElKeyup.bind(this));
        this.inputEl.addEventListener('focus', this.onInputElFocused.bind(this));
        this.inputEl.addEventListener('blur', this.onInputElBlurred.bind(this));
        this.selected.subscribe(this.onSelected.bind(this));
        this.escaped.subscribe(this.onEscaped.bind(this));
      }

      onSelected(value): void {
        this._selectedFromList = true;
        this.inputEl.focus();
        this._lastSelected = value;
        this.cdr.detectChanges();    // for ChangeDetectionStrategy.OnPush
        console.log('NguiAutoCompleteComponent.onSelected() is called', value);
      }

      onEscaped(): void {
        this._escapedFromList = true;
        this.inputEl.focus();
        if (!this._lastSelected) {
          this.inputEl.value = this._orgInputValue;
        }
        this.cdr.detectChanges(); // for ChangeDetectionStrategy.OnPush
        console.log('NguiAutoCompleteComponent.onEscaped() is called');
      }

      onInputElFocused(event): void {
        console.log('NguiAutoCompleteComponent.onInputElFocused() is called', event);
        this.isListLoading = false;
        if (typeof this._orgInputValue === 'undefined') {
          this._orgInputValue = this.inputEl.value;
        }
        this._prevInputValue = this.inputEl.value;
        this.setFocused('input', true);
      }

      onInputElBlurred(event): void {
        this.setFocused('input', false);
      }

      clearList(): void {
        this.inviewPages.forEach(compRef => {
          compRef.destroy();
        });
        this.inviewPages = [];
      }

      onInputElKeyup(event: KeyboardEvent): void {
        console.log('NguiAutoCompleteComponent.onInputKeyup() is called', event.key);
        const firstList = this.element.nativeElement.querySelector('ngui-list-item');
        if (event.key === 'Enter' || event.key === 'Escape') {
          if (firstList) {
            fireEvent(firstList, 'keyup', {key: event.key});
          } else {
            this.onEscaped();
          }
        } else if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {
          firstList && firstList.focus();
        } else if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {
          //
        } else if (this.inputEl.value.length >= this.minInputChars) {
          this._selectedFromList = false;
          this._escapedFromList = false;
          this.addAutocompleteList();
        }
      }

      /** Complete the first page of autocomplete */
      addAutocompleteList(): void {
        if (this.isReady) {
          clearTimeout(this._acTimer);
          this._acTimer = setTimeout(_ => {
            this.isListLoading = false; // ???????/
            this._prevInputValue = this.inputEl.value;
            this._escapedFromList = false;
            this._selectedFromList = false;
            this.clearList();
            this.addAnInviewPageToPages();
          }, 200);
        }
      }

      /** Complete after the first page of autocomplete when it scrolls to the bottom */
      addMorePages(): void {
        console.debug('NguiAutocompleteComponent.addMorePages() is called.');
        if (this.inviewPages.length) {
          this.addAnInviewPageToPages();
        } else {
          console.debug('skipping addMorePages');
        }
      }

      setFocused(elType: 'input' | 'listItem', val: boolean): void {
        if (val) {
          clearTimeout(this._focusTimer);
          this._focused = {input: false, listItem: false};
          this._focused[elType] = true;
        } else {
          this._focusTimer = setTimeout(_ => {
            this._focused[elType] = false;
            this.cdr.detectChanges(); // for ChangeDetectionStrategy.OnPush
          }, 100);
        }
      }

      positionThisUnderInputEl(): void {
        const thisEl = this.element.nativeElement;
        const thisElBCR = thisEl.getBoundingClientRect();
        const thisInputElBCR = this.inputEl.getBoundingClientRect();
        const closeToBottom = thisInputElBCR.bottom + 100 > window.innerHeight;
        const top = thisInputElBCR.top + thisInputElBCR.height + window.scrollY;

        this.renderer.setStyle(thisEl, 'left', `${thisInputElBCR.left}px`);
        this.renderer.setStyle(thisEl, 'top', `${top}px`);
        this.renderer.setStyle(thisEl, 'minWidth', `${thisInputElBCR.width}px`);
      }

      // set items of NguiInviewPageComponent
      addList(items: Array<any>): void {
        console.log('>>>>>> NguiAutocompleteComponent.addList() is called()');
        this.isListLoading = false;

        // TODO: ........ for 1st page only, show no match found or blank option
        let noMatchItem: any;
        let blankItem: any;
        if (this.inviewPages.length === 1) {
          if (this.noMatchItem && (!items || items.length === 0)) { // add no match item
            noMatchItem = new NoMatchFound();
            blankItem.html = this.noMatchItem;
          } else if (this.blankOption) {
            blankItem = new NoneSelect();
            blankItem.html = this.blankOption;
          }
        }

        const allItems = [].concat(noMatchItem, blankItem, items).filter(x => x);
        this.inviewPage.instance.setItems(allItems);
        this.cdr.detectChanges();
      }

    }

Legend
Html element
Component
Html element with directive

# results matching ""

# No results matching ""