import {Component, ElementRef, OnInit, EventEmitter} from '@angular/core';
import {NgClass} from '@angular/common';
import {BdChip, BdInputContainer} from 'angular2materialize';
const KEY_LEFT = 37;
const KEY_RIGHT = 39;
const KEY_ENTER = 13;
const KEY_BACKSPACE = 8;
@Component({
selector: 'bd-tags',
directives: [BdChip, BdInputContainer, NgClass],
inputs: ['tags', 'label', 'errorMessage', 'isInvalid'],
outputs: ['tagsChange'],
template: `
<${BdChip} *ngFor="#tag of tags | slice: 0: pointer + 1; #i = index">
{{tag}}
close
${BdChip}>
<${BdChip} *ngFor="#tag of tags | slice: pointer+1: tags.length; #i = index">
{{tag}}
close
${BdChip}>
`
})
export class BdTags implements OnInit {
private tags:string[];
private label:string;
private current:string = '';
private errorMessage = '';
private isInvalid = false;
private pointer:number;
private elementRef:ElementRef;
private tagsChange: EventEmitter = new EventEmitter();
constructor(elementRef:ElementRef) {
this.elementRef = elementRef;
}
public ngOnInit() {
this.pointer = this.tags.length - 1
}
private onKey(event:any) {
switch (event.keyCode) {
case KEY_ENTER:
this.addTag(this.current);
break;
case KEY_LEFT:
this.changePointer(this.pointer - 1);
break;
case KEY_RIGHT:
this.changePointer(this.pointer + 1);
break;
case KEY_BACKSPACE:
if(this.current.length > 0) {
return;
}
this.removeTag();
break;
}
}
private onBlur(): void {
this.addTag(this.current);
}
private onRemove(index: number, pointer: number): void {
const tagIndex = index + pointer;
this.setTags(this.removeFromArrayBeforeIndex(this.tags, tagIndex));
}
private addTag(tag:string): void {
if (!tag || this.tags.indexOf(tag) >= 0) {
this.current = '';
return;
}
this.setTags(this.addToArrayAfterIndex(this.tags, this.pointer, tag.trim()));
this.current = '';
this.changePointer(this.pointer + 1);
}
private removeTag(): void {
if(this.pointer < 0) {
return;
}
this.setTags(this.removeFromArrayBeforeIndex(this.tags, this.pointer));
this.changePointer(this.pointer - 1);
}
private removeFromArrayBeforeIndex(array: string[], index: number): string[] {
const firstPart = array.slice(0, index);
const secondPart = array.slice(index + 1, array.length);
return [...firstPart, ...secondPart];
}
private changePointer(newValue): void {
if (this.current) {
return;
}
this.pointer = this.resolveToBoundryIndex(newValue);
}
private addToArrayAfterIndex(array: string[], index: number, item: string): string[] {
const firstPart = array.slice(0, index+1);
const secondPart = array.slice(index+1, array.length);
return [...firstPart, item, ...secondPart];
}
private resolveToBoundryIndex(index:number): number {
return Math.min(
this.tags.length - 1,
Math.max(-1, index)
);
}
private setTags(tags: string[]) {
this.tags = tags;
this.tagsChange.emit(tags);
}
}