Ng bootstrap typeahead

Ng bootstrap typeahead DEFAULT
import { Component } from'@angular/core';  
import { TypeaheadMatch } from'ngx-bootstrap/typeahead/typeahead-match.class';  
 selector: 'app-ngx-bootstrap-typeahead',  
 templateUrl: './ngx-bootstrap-typeahead.component.html'  
exportclassNgxBootstrapTypeaheadComponent {  
 selectedValue: string;  
 selectedOption: any;  
 countries: any[] = [  
     "name": "Afghanistan",  
     "phoneCode": "+93",  
     "alpha2code": "AF",  
     "alpha3code": "AFG"  
     "name": "Albania",  
     "phoneCode": "+355",  
     "alpha2code": "AL",  
     "alpha3code": "ALB"  
     "name": "Algeria",  
     "phoneCode": "+213",  
     "alpha2code": "DZ",  
     "alpha3code": "DZA"  
     "name": "Montserrat",  
     "phoneCode": "+1",  
     "alpha2code": "MS",  
     "alpha3code": "MSR"  
     "name": "Morocco",  
     "phoneCode": "+212",  
     "alpha2code": "MA",  
     "alpha3code": "MAR"  
     "name": "Mozambique",  
     "phoneCode": "+258",  
     "alpha2code": "MZ",  
     "alpha3code": "MOZ"  
     "name": "Namibia",  
     "phoneCode": "+264",  
     "alpha2code": "NA",  
     "alpha3code": "NAM"  
     "name": "Nauru",  
     "phoneCode": "+674",  
     "alpha2code": "NR",  
     "alpha3code": "NRU"  
     "name": "Nepal",  
     "phoneCode": "+977",  
     "alpha2code": "NP",  
     "alpha3code": "NPL"  
     "name": "Netherlands",  
     "phoneCode": "+31",  
     "alpha2code": "NL",  
     "alpha3code": "NLD"  
     "name": "Netherlands Antilles",  
     "phoneCode": "+599",  
     "alpha2code": "AN",  
     "alpha3code": "ANT"  
     "name": "New Caledonia",  
     "phoneCode": "+687",  
     "alpha2code": "NC",  
     "alpha3code": "NCL"  
     "name": "New Zealand",  
     "phoneCode": "+64",  
     "alpha2code": "NZ",  
     "alpha3code": "NZL"  
     "name": "North Korea",  
     "phoneCode": "+850",  
     "alpha2code": "KP",  
     "alpha3code": "PRK"  
     "name": "Northern Mariana Islands",  
     "phoneCode": "+1",  
     "alpha2code": "MP",  
     "alpha3code": "MNP"  
     "name": "Norway",  
     "phoneCode": "+47",  
     "alpha2code": "NO",  
     "alpha3code": "NOR"  
     "name": "Oman",  
     "phoneCode": "+968",  
     "alpha2code": "OM",  
     "alpha3code": "OMN"  
  },    
 onSelect(event: TypeaheadMatch): void {  
   this.selectedOption=event.item;  
Sours: https://dzone.com/articles/use-of-ngx-bootstrap-typehead-in-angular-8

npm

Add bootstrap typeahead control to NgxForm

Install

Install package

Import module

import{NgxFormTypeaheadModule}from'@ngxform/ng-bootstrap-typeahead'; ... @NgModule({ ... imports: [FormsModule,ReactiveFormsModule,NgxFormModule,NgxFormTypeaheadModule],})

Input Option

interfaceNgxBootstrapTypeaheadOptionextendsNgxFormControlOption{defaultValue?: any;hostClass?: any;ngClass?: any;options?: any[];ngbTypeahead?: (text: Observable<string>)=>Observable<readonlyany[]>;resultTemplate?: TemplateRef<ResultTemplateContext>;windowTemplate?: TemplateRef<WindowTemplateContext>;inputFormatter?: (item: any)=>string;openOnFocus?: boolean;focus?: boolean | Subject<boolean>;disabled?: boolean;fullWithWindow?: boolean;}

Usage

Simple typeahead

simple-typeahead.component.html

<form[formGroup]="demoForm" (ngSubmit)="onSubmit()"><ng-templatengxFormAnchor[controls]="demoForm.controls"></ng-template><buttontype="submit" class="btn btn-primary">Submit</button></form>

simple-typeahead.component.ts

import{NgxBootstrapTypeaheadControl}from'@ngxform/ng-bootstrap-typeahead';import{Component,OnInit}from'@angular/core';import{NgxFormGroup}from'@ngxform/platform';import{Validators}from'@angular/forms'; @Component({selector: 'app-basic',templateUrl: './basic.component.html',styleUrls: ['./basic.component.scss']})exportclassSimpleTypeaheadComponentimplementsOnInit{publicdemoForm: NgxFormGroup;ngOnInit(): void{consttypeaheadOptions: {name: string; flag: string}[]=[{name: 'Alabama',flag: '5/5c/Flag_of_Alabama.svg/45px-Flag_of_Alabama.svg.png'},{name: 'Alaska',flag: 'e/e6/Flag_of_Alaska.svg/43px-Flag_of_Alaska.svg.png'},{name: 'Arizona',flag: '9/9d/Flag_of_Arizona.svg/45px-Flag_of_Arizona.svg.png'},{name: 'Arkansas',flag: '9/9d/Flag_of_Arkansas.svg/45px-Flag_of_Arkansas.svg.png'},{name: 'California',flag: '0/01/Flag_of_California.svg/45px-Flag_of_California.svg.png'},{name: 'Colorado',flag: '4/46/Flag_of_Colorado.svg/45px-Flag_of_Colorado.svg.png'},{name: 'Connecticut',flag: '9/96/Flag_of_Connecticut.svg/39px-Flag_of_Connecticut.svg.png'},{name: 'Delaware',flag: 'c/c6/Flag_of_Delaware.svg/45px-Flag_of_Delaware.svg.png'},{name: 'Florida',flag: 'f/f7/Flag_of_Florida.svg/45px-Flag_of_Florida.svg.png'}];this.demoForm=newNgxFormGroup({typeahead: newNgxBootstrapTypeaheadControl('',[Validators.required,Validators.email,Validators.minLength(3)],[],{label: 'NgBootstrap Typeahead',controlClass: ['form-control'],ngClass: 'd-flex flex-column form-group',options: typeaheadOptions,inputFormatter: (item: any)=>item.name,openOnFocus: true,errorMessages: [{key: 'required',message: 'This field is required'},]})});}onSubmit(): void{ this.demoForm.submitted=true;console.log(this.demoForm.value);}}

Custom template

Custom Result Template

custom-result-template.component.html

<ng-template#resultTemplatelet-r="result" let-t="term"><img[src]="'https://upload.wikimedia.org/wikipedia/commons/thumb/' + r['flag']" class="mr-1" style="width: 16px"> {{r.name}} </ng-template><form[formGroup]="demoForm" (ngSubmit)="onSubmit()"><ng-templatengxFormAnchor[controls]="demoForm.controls"></ng-template><buttontype="submit" class="btn btn-primary">Submit</button></form>

custom-result-template.component.ts

import{NgxBootstrapTypeaheadControl,ResultTemplateContext}from'@ngxform/ng-bootstrap-typeahead';import{Component,OnInit,TemplateRef,ViewChild}from'@angular/core';import{NgxFormGroup}from'@ngxform/platform';import{Validators}from'@angular/forms'; @Component({selector: 'app-basic',templateUrl: './basic.component.html',styleUrls: ['./basic.component.scss']})exportclassCustomResultTemplateComponentimplementsOnInit{publicdemoForm: NgxFormGroup; @ViewChild('resultTemplate',{static: true})resultTemplate: TemplateRef<ResultTemplateContext>;ngOnInit(): void{consttypeaheadOptions: {name: string; flag: string}[]=[{name: 'Alabama',flag: '5/5c/Flag_of_Alabama.svg/45px-Flag_of_Alabama.svg.png'},{name: 'Alaska',flag: 'e/e6/Flag_of_Alaska.svg/43px-Flag_of_Alaska.svg.png'},{name: 'Arizona',flag: '9/9d/Flag_of_Arizona.svg/45px-Flag_of_Arizona.svg.png'},{name: 'Arkansas',flag: '9/9d/Flag_of_Arkansas.svg/45px-Flag_of_Arkansas.svg.png'},{name: 'California',flag: '0/01/Flag_of_California.svg/45px-Flag_of_California.svg.png'},{name: 'Colorado',flag: '4/46/Flag_of_Colorado.svg/45px-Flag_of_Colorado.svg.png'},{name: 'Connecticut',flag: '9/96/Flag_of_Connecticut.svg/39px-Flag_of_Connecticut.svg.png'},{name: 'Delaware',flag: 'c/c6/Flag_of_Delaware.svg/45px-Flag_of_Delaware.svg.png'},{name: 'Florida',flag: 'f/f7/Flag_of_Florida.svg/45px-Flag_of_Florida.svg.png'}];this.demoForm=newNgxFormGroup({typeahead: newNgxBootstrapTypeaheadControl('',[Validators.required,Validators.email,Validators.minLength(3)],[],{label: 'NgBootstrap Typeahead',controlClass: ['form-control'],ngClass: 'd-flex flex-column form-group',options: typeaheadOptions,resultTemplate: this.resultTemplate,inputFormatter: (item: any)=>item.name,openOnFocus: true,errorMessages: [{key: 'required',message: 'This field is required'},]})});}onSubmit(): void{ this.demoForm.submitted=true;console.log(this.demoForm.value);}}

Custom Window Template

custom-window-template.component.html

<ng-template#windowTemplatelet-results="results" let-term="term" let-formatter="formatter" let-markActive="markActive" let-select="select" let-activeIdx="activeIdx"><ng-template#rtlet-r="result" let-t="term"><img[src]="'https://upload.wikimedia.org/wikipedia/commons/thumb/' + r['flag']" class="mr-1" style="width: 16px" /> {{ r.name }} </ng-template><ng-templatengFor[ngForOf]="results" let-resultlet-idx="index"><buttontype="button" class="dropdown-item" role="option" [id]="id + '-' + idx" [class.active]="idx === activeIdx" (mouseenter)="markActive(idx)" (click)="select(result)"><ng-template[ngTemplateOutlet]="resultTemplate || rt" [ngTemplateOutletContext]="{ result: result, term: term, formatter: formatter }"></ng-template></button></ng-template></ng-template><form[formGroup]="demoForm" (ngSubmit)="onSubmit()"><ng-templatengxFormAnchor[controls]="demoForm.controls"></ng-template><buttontype="submit" class="btn btn-primary">Submit</button></form>

custom-window-template.component.ts

import{NgxBootstrapTypeaheadControl,WindowTemplateContext}from'@ngxform/ng-bootstrap-typeahead';import{Component,OnInit,TemplateRef,ViewChild}from'@angular/core';import{NgxFormGroup}from'@ngxform/platform';import{Validators}from'@angular/forms'; @Component({selector: 'app-basic',templateUrl: './basic.component.html',styleUrls: ['./basic.component.scss']})exportclassCustomWindowTemplateComponentimplementsOnInit{publicdemoForm: NgxFormGroup; @ViewChild('windowTemplate',{static: true})windowTemplate: TemplateRef<WindowTemplateContext>;ngOnInit(): void{consttypeaheadOptions: {name: string; flag: string}[]=[{name: 'Alabama',flag: '5/5c/Flag_of_Alabama.svg/45px-Flag_of_Alabama.svg.png'},{name: 'Alaska',flag: 'e/e6/Flag_of_Alaska.svg/43px-Flag_of_Alaska.svg.png'},{name: 'Arizona',flag: '9/9d/Flag_of_Arizona.svg/45px-Flag_of_Arizona.svg.png'},{name: 'Arkansas',flag: '9/9d/Flag_of_Arkansas.svg/45px-Flag_of_Arkansas.svg.png'},{name: 'California',flag: '0/01/Flag_of_California.svg/45px-Flag_of_California.svg.png'},{name: 'Colorado',flag: '4/46/Flag_of_Colorado.svg/45px-Flag_of_Colorado.svg.png'},{name: 'Connecticut',flag: '9/96/Flag_of_Connecticut.svg/39px-Flag_of_Connecticut.svg.png'},{name: 'Delaware',flag: 'c/c6/Flag_of_Delaware.svg/45px-Flag_of_Delaware.svg.png'},{name: 'Florida',flag: 'f/f7/Flag_of_Florida.svg/45px-Flag_of_Florida.svg.png'}];this.demoForm=newNgxFormGroup({typeahead: newNgxBootstrapTypeaheadControl('',[Validators.required,Validators.email,Validators.minLength(3)],[],{label: 'NgBootstrap Typeahead',controlClass: ['form-control'],ngClass: 'd-flex flex-column form-group',options: typeaheadOptions,inputFormatter: (item: any)=>item.name,openOnFocus: true,errorMessages: [{key: 'required',message: 'This field is required'},{key: 'email',message: 'Email is invalid'},{key: 'minlength',message: 'Min length is 3'}]})});}onSubmit(): void{ this.demoForm.submitted=true;console.log(this.demoForm.value);}}

Dynamic data

dynamic.component.html

<form[formGroup]="demoForm" (ngSubmit)="onSubmit()"><ng-templatengxFormAnchor[controls]="demoForm.controls"></ng-template><buttontype="submit" class="btn btn-primary">Submit</button></form>

dynamic.component.ts

import{Component,OnInit,TemplateRef,ViewChild}from'@angular/core';import{NgxFormGroup}from'@ngxform/platform';import{Validators}from'@angular/forms';import{catchError,debounceTime,distinctUntilChanged,map,switchMap}from'rxjs/operators';import{Observable}from'rxjs';import{HttpClient}from'@angular/common/http';import{NgxBootstrapTypeaheadControl,WindowTemplateContext}from'@ngxform/ng-bootstrap-typeahead'; @Component({selector: 'app-dynamic',templateUrl: './dynamic.component.html',styleUrls: ['./dynamic.component.scss']})exportclassDynamicComponentimplementsOnInit{publicdemoForm: NgxFormGroup; @ViewChild('windowTemplate',{static: true})windowTemplate: TemplateRef<WindowTemplateContext>;constructor(privatehttp: HttpClient){}ngOnInit(): void{constsearch=(text$: Observable<string>)=>text$.pipe(debounceTime(200),distinctUntilChanged(),switchMap((term)=>{if(term !== undefined&&term !== ''){returnthis.http.get(`https://restcountries.eu/rest/v2/name/${term.toLowerCase()}`).pipe(catchError((error)=>error));}else{returnthis.http.get('https://restcountries.eu/rest/v2/all').pipe(catchError((error)=>error));}}),map((data: any[])=>{returndata.map((item)=>Object.assign(item,{key: item.name}));}));this.demoForm=newNgxFormGroup({typeahead: newNgxBootstrapTypeaheadControl('',[Validators.required,Validators.email,Validators.minLength(3)],[],{label: 'NgBootstrap Typeahead',controlClass: ['form-control'],ngClass: 'd-flex flex-column form-group',inputFormatter: (item: any)=>item.name,ngbTypeahead: search,errorMessages: [{key: 'required',message: 'This field is required'},{key: 'email',message: 'Email is invalid'},{key: 'minlength',message: 'Min length is 3'}]})});}onSubmit(): void{this.demoForm.submitted=true;console.log(this.demoForm.value);}}

Keywords

none

Sours: https://www.npmjs.com/package/@ngxform/ng-bootstrap-typeahead
  1. Quotes for granddaughter
  2. Flower hulu movie
  3. Pink monitor riser

ng-bootstrap typeahead: how to handle Observable<Person[]> rather than Observable<string[]>

I've a newbie Angular/Typescript question.

I followed the Wikipedia example defined in ng-bootstrap typeahead and I decided to replace the Wikipedia call with a custom REST service that provides the following GET call:

and returns a list of persons matching the name, where each person is:

Now from the typescript part and the angular part everything works fine if I map(...) the array of persons to an array of string of names into the _service:

  • [p1, p2, p3] -> [nameP1, nameP2, ...]

But I'd like to don't map that way in the _service and returns the list of persons to allow the user to click on the result in the dropdown and then display the detail of the person without subsequent calls.

So at the moment in my typescript component, the model is:

And the search part is the following:

while the html part is:

How can I show just the names in the dropdown and allow the user to click on the name and show him the corresponding person?

Sours: https://stackoverflow.com/questions/52237768/ng-bootstrap-typeahead-how-to-handle-observableperson-rather-than-observabl
An11 Bo Typeahead001 A0016
import{ChangeDetectorRef,ComponentFactoryResolver,ComponentRef,Directive,ElementRef,EventEmitter,forwardRef,Inject,Injector,Input,NgZone,OnDestroy,OnInit,Output,Renderer2,TemplateRef,ViewContainerRef,ApplicationRef,OnChanges,SimpleChanges}from'@angular/core';import{ControlValueAccessor,NG_VALUE_ACCESSOR}from'@angular/forms';import{DOCUMENT}from'@angular/common';import{BehaviorSubject,fromEvent,Observable,of,OperatorFunction,Subject,Subscription}from'rxjs';import{map,switchMap,tap}from'rxjs/operators';import{Live}from'../util/accessibility/live';import{ngbAutoClose}from'../util/autoclose';import{Key}from'../util/key';import{PopupService}from'../util/popup';import{PlacementArray,positionElements}from'../util/positioning';import{isDefined,toString}from'../util/util';import{NgbTypeaheadConfig}from'./typeahead-config';import{NgbTypeaheadWindow,ResultTemplateContext}from'./typeahead-window';/** * An event emitted right before an item is selected from the result list. */exportinterfaceNgbTypeaheadSelectItemEvent<T=any>{/** * The item from the result list about to be selected. */item: T;/** * Calling this function will prevent item selection from happening. */preventDefault: ()=>void;}letnextWindowId=0;/** * A directive providing a simple way of creating powerful typeaheads from any text input. */@Directive({selector: 'input[ngbTypeahead]',exportAs: 'ngbTypeahead',host: {'(blur)': 'handleBlur()','[class.open]': 'isPopupOpen()','(keydown)': 'handleKeyDown($event)','[autocomplete]': 'autocomplete','autocapitalize': 'off','autocorrect': 'off','role': 'combobox','aria-multiline': 'false','[attr.aria-autocomplete]': 'showHint ? "both" : "list"','[attr.aria-activedescendant]': 'activeDescendant','[attr.aria-owns]': 'isPopupOpen() ? popupId : null','[attr.aria-expanded]': 'isPopupOpen()'},providers: [{provide: NG_VALUE_ACCESSOR,useExisting: forwardRef(()=>NgbTypeahead),multi: true}]})exportclassNgbTypeaheadimplementsControlValueAccessor,OnInit,OnChanges,OnDestroy{private_popupService: PopupService<NgbTypeaheadWindow>;private_subscription: Subscription|null=null;private_closed$=newSubject();private_inputValueBackup: string|null=null;private_valueChanges: Observable<string>;private_resubscribeTypeahead: BehaviorSubject<any>;private_windowRef: ComponentRef<NgbTypeaheadWindow>|null=null;private_zoneSubscription: any;/** * The value for the `autocomplete` attribute for the `<input>` element. * * Defaults to `"off"` to disable the native browser autocomplete, but you can override it if necessary. * * @since 2.1.0 */ @Input()autocomplete='off';/** * A selector specifying the element the typeahead popup will be appended to. * * Currently only supports `"body"`. */ @Input()container: string;/** * If `true`, model values will not be restricted only to items selected from the popup. */ @Input()editable: boolean;/** * If `true`, the first item in the result list will always stay focused while typing. */ @Input()focusFirst: boolean;/** * The function that converts an item from the result list to a `string` to display in the `<input>` field. * * It is called when the user selects something in the popup or the model value changes, so the input needs to * be updated. */ @Input()inputFormatter: (item: any)=>string;/** * The function that converts a stream of text values from the `<input>` element to the stream of the array of items * to display in the typeahead popup. * * If the resulting observable emits a non-empty array - the popup will be shown. If it emits an empty array - the * popup will be closed. * * See the [basic example](#/components/typeahead/examples#basic) for more details. * * Note that the `this` argument is `undefined` so you need to explicitly bind it to a desired "this" target. */ @Input()ngbTypeahead: OperatorFunction<string,readonlyany[]>|null|undefined;/** * The function that converts an item from the result list to a `string` to display in the popup. * * Must be provided, if your `ngbTypeahead` returns something other than `Observable<string[]>`. * * Alternatively for more complex markup in the popup you should use `resultTemplate`. */ @Input()resultFormatter: (item: any)=>string;/** * The template to override the way resulting items are displayed in the popup. * * See the [ResultTemplateContext](#/components/typeahead/api#ResultTemplateContext) for the template context. * * Also see the [template for results demo](#/components/typeahead/examples#template) for more details. */ @Input()resultTemplate: TemplateRef<ResultTemplateContext>;/** * If `true`, will show the hint in the `<input>` when an item in the result list matches. */ @Input()showHint: boolean;/** * The preferred placement of the typeahead. * * Possible values are `"top"`, `"top-left"`, `"top-right"`, `"bottom"`, `"bottom-left"`, * `"bottom-right"`, `"left"`, `"left-top"`, `"left-bottom"`, `"right"`, `"right-top"`, * `"right-bottom"` * * Accepts an array of strings or a string with space separated possible values. * * The default order of preference is `"bottom-left bottom-right top-left top-right"` * * Please see the [positioning overview](#/positioning) for more details. */ @Input()placement: PlacementArray='bottom-left';/** * A custom class to append to the typeahead popup window * * Accepts a string containing CSS class to be applied on the `ngb-typeahead-window`. * * This can be used to provide instance-specific styling, ex. you can override popup window `z-index` * * @since 9.1.0 */ @Input()popupClass: string;/** * An event emitted right before an item is selected from the result list. * * Event payload is of type [`NgbTypeaheadSelectItemEvent`](#/components/typeahead/api#NgbTypeaheadSelectItemEvent). */ @Output()selectItem=newEventEmitter<NgbTypeaheadSelectItemEvent>();activeDescendant: string|null=null;popupId=`ngb-typeahead-${nextWindowId++}`;private_onTouched=()=>{};private_onChange=(_: any)=>{};constructor(private_elementRef: ElementRef<HTMLInputElement>,viewContainerRef: ViewContainerRef,private_renderer: Renderer2,injector: Injector,componentFactoryResolver: ComponentFactoryResolver,config: NgbTypeaheadConfig,ngZone: NgZone,private_live: Live, @Inject(DOCUMENT)private_document: any,private_ngZone: NgZone,private_changeDetector: ChangeDetectorRef,applicationRef: ApplicationRef){this.container=config.container;this.editable=config.editable;this.focusFirst=config.focusFirst;this.showHint=config.showHint;this.placement=config.placement;this._valueChanges=fromEvent<Event>(_elementRef.nativeElement,'input').pipe(map($event=>($event.targetasHTMLInputElement).value));this._resubscribeTypeahead=newBehaviorSubject(null);this._popupService=newPopupService<NgbTypeaheadWindow>(NgbTypeaheadWindow,injector,viewContainerRef,_renderer,this._ngZone,componentFactoryResolver,applicationRef);this._zoneSubscription=ngZone.onStable.subscribe(()=>{if(this.isPopupOpen()){positionElements(this._elementRef.nativeElement,this._windowRef!.location.nativeElement,this.placement,this.container==='body');}});}ngOnInit(): void{this._subscribeToUserInput();}ngOnChanges({ngbTypeahead}: SimpleChanges): void{if(ngbTypeahead&&!ngbTypeahead.firstChange){this._unsubscribeFromUserInput();this._subscribeToUserInput();}}ngOnDestroy(): void{this._closePopup();this._unsubscribeFromUserInput();this._zoneSubscription.unsubscribe();}registerOnChange(fn: (value: any)=>any): void{this._onChange=fn;}registerOnTouched(fn: ()=>any): void{this._onTouched=fn;}writeValue(value){this._writeInputValue(this._formatItemForInput(value));if(this.showHint){this._inputValueBackup=value;}}setDisabledState(isDisabled: boolean): void{this._renderer.setProperty(this._elementRef.nativeElement,'disabled',isDisabled);}/** * Dismisses typeahead popup window */dismissPopup(){if(this.isPopupOpen()){this._resubscribeTypeahead.next(null);this._closePopup();if(this.showHint&&this._inputValueBackup!==null){this._writeInputValue(this._inputValueBackup);}this._changeDetector.markForCheck();}}/** * Returns true if the typeahead popup window is displayed */isPopupOpen(){returnthis._windowRef!=null
Sours: https://github.com/ng-bootstrap/ng-bootstrap/blob/master/src/typeahead/typeahead.ts

Bootstrap typeahead ng

.

Try AngularJS 1.5 - 31 of 33 - UI Bootstrap \u0026 Typeahead

.

Now discussing:

.



1705 1706 1707 1708 1709