import {
Component, ElementRef, TemplateRef, ViewEncapsulation, HostListener
} from '@angular/core';
import { isBs3 } from '../utils/ng2-bootstrap-config';
import { TypeaheadDirective } from './typeahead.directive';
import { TypeaheadMatch } from './typeahead-match.class';
import { latinize } from './typeahead-utils';
@Component({
selector: 'typeahead-container',
// tslint:disable-next-line
template: `
`,
// tslint:disable
host: {
'class': 'dropdown open',
'[class.dropdown-menu]':'isBs4',
'[class.dropup]':'dropup',
style: 'position: absolute;display: block;'
},
// tslint: enable
encapsulation: ViewEncapsulation.None
})
export class TypeaheadContainerComponent {
public parent: TypeaheadDirective;
public query: any;
public element: ElementRef;
public isFocused: boolean = false;
public top: string;
public left: string;
public display: string;
public placement: string;
public dropup: boolean;
public get isBs4():boolean {
return !isBs3();
}
protected _active: TypeaheadMatch;
protected _matches: TypeaheadMatch[] = [];
public constructor(element: ElementRef) {
this.element = element;
}
public get active(): TypeaheadMatch {
return this._active;
}
public get matches(): TypeaheadMatch[] {
return this._matches;
}
public set matches(value: TypeaheadMatch[]) {
this._matches = value;
if (this._matches.length > 0) {
this._active = this._matches[0];
if (this._active.isHeader()) {
this.nextActiveMatch();
}
}
}
public get optionsListTemplate(): TemplateRef {
return this.parent ? this.parent.optionsListTemplate : undefined;
}
public get itemTemplate(): TemplateRef {
return this.parent ? this.parent.typeaheadItemTemplate : undefined;
}
public selectActiveMatch(): void {
this.selectMatch(this._active);
}
public prevActiveMatch(): void {
let index = this.matches.indexOf(this._active);
this._active = this.matches[index - 1 < 0
? this.matches.length - 1
: index - 1];
if (this._active.isHeader()) {
this.prevActiveMatch();
}
}
public nextActiveMatch(): void {
let index = this.matches.indexOf(this._active);
this._active = this.matches[index + 1 > this.matches.length - 1
? 0
: index + 1];
if (this._active.isHeader()) {
this.nextActiveMatch();
}
}
public selectActive(value: TypeaheadMatch): void {
this.isFocused = true;
this._active = value;
}
public hightlight(match: TypeaheadMatch, query: any): string {
let itemStr: string = match.value;
let itemStrHelper: string = (this.parent && this.parent.typeaheadLatinize
? latinize(itemStr)
: itemStr).toLowerCase();
let startIdx: number;
let tokenLen: number;
// Replaces the capture string with the same string inside of a "strong" tag
if (typeof query === 'object') {
let queryLen: number = query.length;
for (let i = 0; i < queryLen; i += 1) {
// query[i] is already latinized and lower case
startIdx = itemStrHelper.indexOf(query[i]);
tokenLen = query[i].length;
if (startIdx >= 0 && tokenLen > 0) {
itemStr = itemStr.substring(0, startIdx) + '' + itemStr.substring(startIdx, startIdx + tokenLen) + '' + itemStr.substring(startIdx + tokenLen);
itemStrHelper = itemStrHelper.substring(0, startIdx) + ' ' + ' '.repeat(tokenLen) + ' ' + itemStrHelper.substring(startIdx + tokenLen);
}
}
} else if (query) {
// query is already latinized and lower case
startIdx = itemStrHelper.indexOf(query);
tokenLen = query.length;
if (startIdx >= 0 && tokenLen > 0) {
itemStr = itemStr.substring(0, startIdx) + '' + itemStr.substring(startIdx, startIdx + tokenLen) + '' + itemStr.substring(startIdx + tokenLen);
}
}
return itemStr;
}
@HostListener('mouseleave')
@HostListener('blur')
public focusLost(): void {
this.isFocused = false;
}
public isActive(value: TypeaheadMatch): boolean {
return this._active === value;
}
public selectMatch(value: TypeaheadMatch, e: Event = void 0): boolean {
if (e) {
e.stopPropagation();
e.preventDefault();
}
this.parent.changeModel(value);
setTimeout(() =>
this.parent.typeaheadOnSelect.emit(value), 0
);
return false;
}
}