import {Component, ElementRef, HostListener, Input, OnInit, ViewChild} from '@angular/core'; import * as _ from 'lodash'; import {DcTagsOptions} from './tags.option.type'; @Component({ selector: 'dc-tags-input', template: `
`, styles: [` ul, li { list-style: none; margin: 0; padding: 0; } .clearFix { zoom: 1; } .clearFix:after { clear: both; height: 0; width: 100%; overflow: hidden; visibility: hidden; display: block; content: '.'; } .tags-input-box { border: 1px solid #ccc; padding: 15px; position: relative; } .tags-input-show-list { display: inline-block; max-width: 150px; padding-right: 30px; overflow: hidden; text-overflow: ellipsis; position: relative; height: 30px; line-height: 30px; padding-left: 10px; border: 1px solid #ccc; margin-right: 15px; } .tags-input-content{ position: relative; } .tags-input-text{ height: 30px; line-height: 30px; width: 100%; } .tag-remove{ margin: 0; padding: 0; border: none; width: 14px; height: 14px; overflow: hidden; cursor: pointer; position: absolute; right: 5px; top: 8px; } .tags-input-drop{ position: absolute; left: 0; top: 29px; width: 100%; height: auto; max-height: 200px; overflow: auto; border: 1px solid #ccc; background: #fff; } .tags-input-drop-list { cursor: pointer; width: 100%; height: 30px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 30px; text-indent: 10px; } .tags-input-drop-list:hover { color: #fff; background-color: #0081cc; } `] }) export class TagsInputComponent implements OnInit { dropList: any = []; showList: any = []; showDropFlag: boolean = false; inputValue: string; defaultNameKey: string = 'name'; defaultCheckedKey: string = 'checked'; hideDropListTimer: any; @Input() options: DcTagsOptions; _tagDatas: any; @Input() set tagDatas(v) { const temp: any[] = _.cloneDeep(v || []); let tempShowList: any[] = []; let tempDropList: any[] = []; for (let i = 0; i < temp.length; i++) { let checkKey = 'checked'; if (this.options && this.options.checkKey) { checkKey = this.options.checkKey; } if (temp[i][checkKey]) { tempShowList.push(temp[i]); } else { tempDropList.push(temp[i]); } } this.dropList = tempDropList; this.showList = tempShowList; this._tagDatas = temp; } get tagDatas() { return this._tagDatas; } @ViewChild('tagsInput') tagsInput: ElementRef; constructor() { } ngOnInit() { if (this.options && this.options.nameKey) { this.defaultNameKey = this.options.nameKey; } if (this.options && this.options.checkKey) { this.defaultCheckedKey = this.options.checkKey; } } tagsInputFocus(ev: any) { this.tagsInput.nativeElement.focus(); ev.stopPropagation(); } tagInputChange() { this.showDropFlag = true; } removeTag(item: any, index: number) { item[this.defaultCheckedKey] = false; const temp = this.showList.splice(index, 1)[0]; if (temp.type != 'add') { this.dropList.push(temp); } } // input点回车/下拉点击列表,插入到show中 addTag(selectItem?: any) { this.showDropFlag = false; let val = _.trim((selectItem && selectItem[this.defaultNameKey]) || this.inputValue); if (!val) { this.inputValue = ''; return; } const dropIndex = _.findIndex(this.dropList, (item: any) => { return _.trim(item[this.defaultNameKey]) === val; }); const showIndex = _.findIndex(this.showList, (item: any) => { return _.trim(item[this.defaultNameKey]) === val; }); let item: any = {}; // 在下拉列表中,不在showlist中,则将下拉的移入到showlist中 if (dropIndex != -1 && showIndex == -1) { item = this.dropList.splice(dropIndex, 1)[0]; item[this.defaultCheckedKey] = true; this.showList.push(item); } else if (dropIndex != -1 && showIndex != -1) { // 在下拉列表中,也在showlist中,则移除下拉列表的数据,不插入 this.dropList.splice(dropIndex, 1); } else if (dropIndex == -1 && showIndex == -1) { // 不在下拉列表中,也不在showlist中,则插入数据到showlist中,无ID item[this.defaultNameKey] = val; item[this.defaultCheckedKey] = true; item['type'] = 'add'; this.showList.push(item); } this.inputValue = ''; } showDropList(ev: any) { if (this.hideDropListTimer) { clearTimeout(this.hideDropListTimer); this.hideDropListTimer = null; } ev.stopPropagation(); this.showDropFlag = true; } hideDropList() { if (this.hideDropListTimer) { clearTimeout(this.hideDropListTimer); this.hideDropListTimer = null; } this.hideDropListTimer = setTimeout(() => { this.showDropFlag = false; }, 300); } @HostListener('document:click', ['$event']) onDocumentClick(ev: any) { this.hideDropList(); } public getCheckedTags(){ return this.showList; } }