NgAutoComplete / Example

Light-weight autocomplete component for Angular.

https://github.com/sengirab/ngAutocomplete

Installation

npm i ng-auto-complete --save

Styling !Important

First thing to note, i've created this package to be as simple as possible. That's why i don't include any styling, this is so you could style it the way you want it.

If you like the styling i did for the example .gif shown above, you can copy it from here.

Classes

.ng-autocomplete-dropdown (.open .is-loading .is-async)

.ng-autocomplete-inputs

.ng-autocomplete-input

.ng-autocomplete-placeholder

.ng-autocomplete-dropdown-icon (.open)

.ng-dropdown (.open .is-initial-empty)

.dropdown-item (.active)

Responses !Important

Response when selected

" {group: AutocompleteGroup, item: AutocompleteItem} "

Response when cleared

" {group: AutocompleteGroup, item: null} "

Note that when calling completer.ResetInput('completer'), this will clear the input. This means that the completer will emit {group: AutocompleteGroup, item: null} . If your listening to this within your component keep in mind that each clear the item will be null

The input will also emit "null" when the input reaches a length of <= 0 .

Usage

import { BrowserModule } from " @angular/platform-browser " ; import { NgModule } from " @angular/core " ; import { FormsModule } from " @angular/forms " ; import { HttpModule } from " @angular/http " ; import { AppComponent } from " ./app.component " ; import { NgAutoCompleteModule } from " ng-auto-complete " ; @ NgModule ( ) export class AppModule { }

import { Component , ViewChild } from " @angular/core " ; import { CreateNewAutocompleteGroup , SelectedAutocompleteItem , NgAutoCompleteComponent } from " ng-auto-complete " ; @ Component ( ) export class AppComponent { @ ViewChild ( NgAutoCompleteComponent ) public ; public ; constructor { } Selected { console . log ( item ) ; } }

< ng-autocomplete ( selected )= " Selected($event) " [ classes ]= " [''] " [ group ]= " group " > < / ng-autocomplete >

Remove selected values

public selected : any [ ] = [ ] ; Selected ( item : SelectedAutocompleteItem ) { this . selected . push ( item . item ) ; this . completer . RemovableValues ( ' completer ' , this . selected ) }

Turn off completion

In some cases you may want to disable auto completion. e.g you want a html select element.

Example

Usage

public group = [ CreateNewAutocompleteGroup ( ' Search / choose in / from list ' , ' completer ' , [ , , , , , ] , , ' ' , false ) ] ;

With children

Usage

public group = [ CreateNewAutocompleteGroup ( ' Search / choose in / from list ' , ' completer_one ' , [ , , , ] , , ' ' ) , CreateNewAutocompleteGroup ( ' Search / choose in / from list ' , ' completer_two ' , [ , , , , , , ] , , ' completer_one ' ) ] ;

Within a form

import { Component , OnInit , ViewChild } from " @angular/core " ; import { FormArray , FormBuilder , FormGroup } from " @angular/forms " ; import { CreateNewAutocompleteGroup , SelectedAutocompleteItem , NgAutoCompleteComponent } from " ng-auto-complete " ; @ Component ( ) export class AppComponent implements OnInit { @ ViewChild ( NgAutoCompleteComponent ) public ; public ; public ; constructor { } ngOnInit { this . form = this . _fb . group ( ) ; } Selected { this . form . controls [ ' items ' ] = this . _fb . array ( [ ... this . form . controls [ ' items ' ] . value , item . original ] ) ; console . log ( item ) ; } }

Changelog - (Read before updating.)

Internal fixes & performance improvements.

I.E fixes

New functions SetEnable(key: string) SetDisable(key: string)



ExpressionChangedAfterItHasBeenCheckedError Fixed this error in a previous version, this ends up in propagating the error, this isn't user friendly. Since i must check something in the ngAfterViewChecked there is no escaping this error unless setTimeout is used (which i did now).



Internal changes The way how the first value was selected is changed. Package used to wait until view was checked, this was checked periodically via a interval. Now a subject has been created to emit this value to all their subscribers.

BREAKING: FindInput function has been removed.



Updates regarding angular 7

Important. Breaking changes!

NgAutocompleteComponent renamed to NgAutoCompleteComponent

Very big changes internally. Stopped using rollup to create my npm package. Using angular libraries now instead.



Updated to newest version of angular.

Fixed an maximum callstack exceeded bug.

Added searchLength to options when create an autocomplete group, it configures when to fire a search. The number given is the amount of characters in the input.

Removed dropdown it's own comparison when using Async. Assuming the user will probably filter the results.

Added new classes to wrong element.

Changes to behaviour of the dropdown (mainly for async). Dropdown now only opens when there's a default value at start. It will stay closed until it has a list to show. -- Represented by the class: is-initial-empty. Dropdown now has a loading class; is-loading. Internal changes to keep the new code compatible with new behaviour.



New Functionality.

Support for async functions. Useful for when you want to use your own API to return results. @ ViewChild ( NgAutoCompleteComponent ) public completer : NgAutoCompleteComponent ; ; this . completer . SetAsync ( ' completer ' , async ) ;



New Functionality.

Created new functions to add custom ng-templates. Every ng template receives a context that's equal to an AutocompleteItem type. Except for the dropdownValue, this receives a hightlight too. see example template parameter must be of type: dropdownValue | placeholderValue | noResults @ ViewChild ( NgAutoCompleteComponent ) public completer : NgAutoCompleteComponent ; @ ViewChild ( ' dropdownValue ' ) dropdownValue : TemplateRef < any > ; @ ViewChild ( ' placeholderValue ' ) placeholderValue : TemplateRef < any > ; @ ViewChild ( ' noResults ' ) noResults : TemplateRef < any > ; this . completer . SetTemplate ( ' completer ' , ' dropdownValue ' , this . dropdownValue ) ; this . completer . SetTemplate ( ' completer ' , ' noResults ' , this . noResults ) ; this . completer . SetTemplate ( ' completer ' , ' placeholderValue ' , this . placeholderValue ) ; < ng-template # dropdownValue let-value let-hightlight = " highlight " > < div [ innerHTML ]= " hightlight " > < / div > </ ng-template > < ng-template # placeholderValue let-value > {{value.title}} </ ng-template > < ng-template # noResults let-value > Hey, you searched for: {{value}}. But there are no results! </ ng-template >



Big performance refactor. Instead of using arrays, now uses objects. Search by object key.

New @output, (no-results) emits GroupNoResult.

A lot of internal changes & bugfixes.

In some cases when the a view has a hidden ng-content, that shows if an expression evaluates to true and a completer function has been used e.g( SelectItem('completer', 5) ) it would give an error; completer view is not initialized. Functions that are called before the completer view has been initialized are now queued to be fired when the view is actually initialized.

) it would give an error; completer view is not initialized.

Added tab to submit events. (not preventing default, so still goes to the next input, if there's one).

Added better support for navigating with arrows. Dropdown list now navigates to the selected item if the items exceed the dropdown its given height.

Internal code cleanup.

Mobile update: Remove mouseover when mobile. This prevents the user from needing to double tap the options.

Styling

Some internal styling has changed. When completer is turned of, input used to be disabled. This doesn't work on all browsers. Input now get pointer-events: none;

Browser compatibility.

Fixes

Value has to be set on input (equal to ngModel). This created an issue on safari, when an item was selected, the placeholder didn't go away.



Styling

There's a new element span.ng-autocomplete-dropdown-icon this replaces the dropdown icon i did with css only.

Other changes

Increase of internal performance.

Had some issues with Element refs. #fixed.

New Functionality.

It's now possible to instantiate CreateNewAutocompleteGroup with an empty array and set its value later. This can be useful when you're waiting for an async task to complete. const component = NgAutoCompleteComponent.FindCompleter('completer', this.completers); component.SetValues( 'late', // <-- NOTE: this is the key of the input. You can call this what you want. [ {title: 'Option 4', id: '1'}, {title: 'Option 5', id: '2'}, {title: 'Option 6', id: '3'}, {title: 'Option 7', id: '4'}, {title: 'Option 8', id: '5'}, {title: 'Option 9', id: '6'}, ] )

Created new pipe to highlight search query. class dropdown-item-highlight

Changes

CreateNewAutocompleteGroup now accepts {id:string|number}, before only {id:string}

Some small changes.

KeyEvents now preventDefault

Close dropdown on tab.

Open dropdown on focus - was only on click.

Updated README.md.

Maintain active option when input is blurred - also for disabled completion inputs now.

Updated README.md.

Maintain active option when input is blurred.

Updated README.md.

Updated README.md.

Fixed an issue; when selecting a option from a completer that is parent, active child option didn't reset.

Updated README.md.

New Functionality.

SelectItem(key: string, id: string) NgAutoCompleteComponent function - Set value manual, by id. This can be useful when the list is loaded but there's a value set in the database. When the data is fetched from server, this method can be used. @ ViewChild ( NgAutoCompleteComponent ) public completer : NgAutoCompleteComponent ; this . completer . SelectItem ( ' completer ' , ' 1 ' ) ; ### Or if multiple completers in component. @ ViewChildren ( NgAutoCompleteComponent ) public completers : QueryList < NgAutoCompleteComponent > ; ; completer . SelectItem ( ' completer ' , ' 1 ' ) ;



Only groups with parents did a reset when the input reached a length <= 0. Now all inputs do, input with parents still get set to initial value.

[1.0.0] - 2017-07-11. Releasing since it's being used.

Renamed Functions.

ResetCompleters to ResetInputs.

ResetCompleter to ResetInput.

FindCompleter to FindInput.

TriggerChangeCompleters to TriggerChange.

New Functionality.

<ng-autocomplete [key]="'group1'"> - Added key on component.

static FindCompleter usage (NgAutoCompleteComponent.FindCompleter()) (not to be confused with the old FindCompleter, now FindInput) (key: string, list: QueryList): NgAutoCompleteComponent. This can be useful when you have multiple ng-autocomplete components in one component. Note that this can only be used when the view has been init.



NgAutoCompleteComponent Functions

I have made all NgAutoCompleteComponent and CompleterComponent functions public, so you could do a lot more than i'll show you

I've documented the functions of which i think their useful:

Usage

@ ViewChild ( NgAutoCompleteComponent ) public completer : NgAutoCompleteComponent ;

Function Description FindCompleter((key: string, list: QueryList)) (Static function) Finds completer ResetInputs() Resets all rendered completer inputs FindInput(key: string) Find completer input by assigned key RemovableValues(key: string, list: {id: string or number, [value: string]: any}[]) Remove options from rendered list (by id) SelectItem(key: string, id: string or number) e.g set an initial value on the completers input SetValues(key: string, {id: string or number, [value: string]: any}[]) Sets values for the input. Useful in async situations.

CompleterComponent Functions

Usage

@ ViewChild ( NgAutoCompleteComponent ) public completer : NgAutoCompleteComponent ; public input = this . completer . FindInput ( ' completer ' ) ;

Function Description ClearValue() Clears found completer's input.

Contributing

Do you like to code?

Fork & clone

npm install

ng serve

git checkout -b my-new-feature

component lives in src/app/ng-autocomplete/*

Submit a pull request

Do you like organizing?