import {ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, OnInit, Output, ViewChild} from '@angular/core';
import * as _ from 'lodash';
@Component({
selector: 'dc-search-select',
template: `
0" class="dc-select-container"
[ngClass]="{'disable':disable}" [class.dc-invalid]="required && !firstLoad && (!currentValue || currentValue.length == 0)"
[style.width]="width" [class.new-select]="newStyle">
-
{{list[nameKey]}}
No Data.
`,
styles: [`
ul, ol, li {
list-style: none;
margin: 0;
padding: 0;
}
.dc-select-container {
width: 160px;
height: 30px;
font-size: 12px;
color: #333;
background: #fff;
/*border: solid 1px #ccc;*/
/*border-radius: 3px;*/
margin: 0 10px;
padding: 0;
display: inline-block;
position: relative
}
.new-select.dc-select-container,.new-select .dc-select-input,.new-select .dc-select-input > .dc-select-current,.new-select .clear-input-value,.new-select .dc-select-btn{
height: 40px !important;
}
.new-select .dc-select-input > .dc-select-current{
line-height: 38px;
}
.new-select .dc-select-btn{
padding-top:16px;
}
.new-select .dc-select-drop{
top: 40px;
}
.clear-input-value {
position: absolute;
right: 20px;
top: 0;
cursor: pointer;
width: 12px;
height: 30px;
z-index: 2;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAABS2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzggNzkuMTU5ODI0LCAyMDE2LzA5LzE0LTAxOjA5OjAxICAgICAgICAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+IEmuOgAAAOVJREFUKJF90DFKA1EQBuAvj2Cu8MBqe8FokedeQb2A6WzU0uN4gxTbxkM8CKKSfqvAXsAi2lj4dlkh5Icp5p9/Zv6ZSdM0Ck7whDucFW6LFV7wDdNSOMUac/9xVeIet9iFMvmQeIw5XjELeOzFdV2LMQ6qGKO6rvv0HA8By55p21ZKSYxRjFFKSdu2403LKS77rOs6OWcpJZBz1nXduOEiHPF9CD8Bb2PPKSU552HT+CZsg78/g6qqBhu9vaqqxg2rSdM0M+TyhWP4xCJgjxu8HxF/4Br7/ugdEp6xwVeJTeEWReMX1Y9FK/4RDOgAAAAASUVORK5CYII=) no-repeat center center transparent;
}
.clear-input-value:hover {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAABS2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzggNzkuMTU5ODI0LCAyMDE2LzA5LzE0LTAxOjA5OjAxICAgICAgICAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+IEmuOgAAAOtJREFUKJF90b1NAzEcBfBfriCVm2vR3S2ABFXYAViADACUjMMGWQCGQIoQWJngrLTXWBSBIhRxooBCnuTCz++9/4dHMUYFJ3jALc4Kt8AMT/iCUTGc4hkXDuMdN1hWJfmYWHl7wbjC/VbcdZ0Qwk4VQtB13fZ6jrsK0y0zDIO2bYUQhBA0TWMYhv1K01GMcVXa2qW2bWu9XkspyTnvG1bVkb4P4bvC29/0vu+llDRN82smLCqbPYO6rvV9L+cs5yylpK7rfcNsFGMc47Vs4RgiJhVWuLb5nP/wgSt7Qy9xiUfM8VnOvHCTovEDCGVJpA/ldQoAAAAASUVORK5CYII=) no-repeat center center transparent;
}
.dc-select-input {
padding: 0 10px;
width: 100%;
height: 30px;
line-height: 30px;
position: relative;
border-radius: 4px;
border: 1px solid #ccc;
font-size: 14px;
color: #333;
box-shadow: none;
}
.dc-select-input.dc-valid {
border-color: #3FB992;
}
.dc-select-input.dc-invalid {
border-color: #FF3B3B;
}
.dc-select-input.focus {
border-radius: 4px;
border-color: #2BB1FF;
transition: none;
background: none;
outline: none;
}
.dc-select-container.disable {
background: #f5f5f5;
border-color: #ccc;
color: #999
}
.dc-select-input > .dc-select-current {
width: calc(100% - 35px);
background: none;
position: relative;
z-index: 1;
cursor: default;
display: flex;
height: 30px;
}
.dc-select-input > .dc-select-current li {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
margin-right: 10px;
}
.dc-select-input > .dc-select-current li span {
margin-right: 10px;
}
.dc-select-btn {
width: 0;
height: 30px;
position: absolute;
right: 0;
top: 0;
padding: 12px 15px 0 5px;
cursor: pointer;
}
.dc-select-container.disable .dc-select-btn {
cursor: default;
}
.dc-select-arrow {
border: solid 4px transparent;
border-top-width: 6px;
border-top-color: #333;
width: 0;
height: 0;
}
.dc-select-container.disable .dc-select-arrow {
border-top-color: #ccc;
}
.dc-select-drop {
position: absolute;
top: 30px;
left: -1px;
width: calc(100% + 2px);
box-shadow: 0 0 10px 2px rgba(0, 0, 0, .2);
background: #fff;
list-style: none;
border-radius: 3px;
z-index: 1000;
padding: 10px 0;
}
.dc-select-drop > ul {
margin: 0;
overflow-y: auto;
overflow-x: hidden;
}
.dc-select-drop > ul > li {
width: 100%;
height: 30px;
line-height: 26px;
cursor: pointer;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding: 3px 10px;
user-select: none;
}
.dc-select-drop > ul > li.radioLi {
display: flex;
flex-direction: row;
}
.dc-select-drop > ul > li:hover,
.dc-select-drop > ul > li.checked {
color: #333333;
background: #edf0f5;
}
.dc-search-select-text {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.noChecked,.invalid{
color: #bbbbbb;
}
.dc-select-drop > ul > li.noChecked:hover,.dc-select-drop > ul > li.invalid:hover{
color: #bbbbbb;
background: #fff;
cursor: auto;
}
:host /deep/ .noChecked .dc-checkbox-text:hover{
background-color: transparent !important;
}
:host /deep/ .invalid .dc-checkbox-text:hover{
background-color: transparent !important;
}
`]
})
export class SearchSelectComponent implements OnInit {
firstLoad = true;
showDropFlag: boolean;
keyword: string;
@Input() disable: boolean;
@Input() width: string;
@Input() maxHeight: string;
@Input() fieldKey: string;
@Input() nameKey: string;
@Input() currentValue: any;
@Input() multiple: boolean;
@Input() noSearch: boolean;
@Input() required: boolean;
@Input() newStyle: boolean;
/**
* [{id,name,checked}]
*/
_source: any;
@Input() set source(v: any) {
if (!v) {
this._source = [];
}
for (let i = 0; i < v.length; i++) {
let vi = v[i];
vi.checkModel = {
checked: false,
index: i,
field: vi[this.fieldKey]
};
if (this.currentValue && this.currentValue.length > 0) {
for (let j = 0; j < this.currentValue.length; j++) {
const cj = this.currentValue[j];
if (vi[this.fieldKey] == cj[this.fieldKey]) {
vi.checkModel.checked = true;
}
}
} else {
this.currentValue = [];
}
}
this._source = _.cloneDeep(v);
}
@Output() checkEvent = new EventEmitter();
get source() {
return this._source;
}
@ViewChild('dropList') dropList: ElementRef;
@ViewChild('selectContainer') selectContainer: ElementRef;
checkOptions: any;
constructor(private changeDetectorRef: ChangeDetectorRef) {
this.maxHeight = this.maxHeight || '300px';
this.width = this.width || '150px';
this.nameKey = this.nameKey || 'name';
this.fieldKey = this.fieldKey || 'id';
this.checkOptions = {
key: 'checked',
};
}
ngOnInit() {
}
@HostListener('document:click', ['$event'])
onDocumentClick(ev: any) {
if (this.showDropFlag && !this.selectContainer.nativeElement.contains(ev.target)) {
this.showDropFlag = false;
this.keyword = '';
}
}
searchMe(ev: any) {
this.keyword = ev;
}
showCurrentTitle() {
if (this.currentValue) {
let res: Array = [];
for (let i = 0; i < this.currentValue.length; i++) {
res.push(this.currentValue[i][this.nameKey]);
}
return res.join(', ');
}
return '';
}
selectList(ev: any, list: any) {
if (this.multiple) {// 复选
ev.stopPropagation();
if (list.checkModel.checked) {
list.checkModel.checked = false;
} else {
list.checkModel.checked = true;
}
this.checkboxChangeEvent(list.checkModel);
} else {// 单选
this.currentValue = [];
for (let i = 0; i < this.source.length; i++) {
this.source[i].checkModel.checked = false;
}
if (this.currentValue[this.fieldKey] == list[this.fieldKey]) {
list.checkModel.checked = false;
return;
} else {
list.checkModel.checked = true;
this.currentValue.push(list);
}
this.checkEvent.emit(this.currentValue);
this.showDropFlag = false;
this.keyword = '';
}
}
checkboxChangeEvent(ev: any) {
let listItem = _.find(this.source, (item) => {
return item[this.fieldKey] == ev.field;
});
if (ev.checked) {
let index = _.findIndex(this.currentValue, (o: any) => {
return o[this.fieldKey] == ev.field;
});
if (index == -1) {
this.currentValue.push(listItem);
}
} else {
for (let i = 0; i < this.currentValue.length; i++) {
if (this.currentValue[i][this.fieldKey] == ev.field) {
this.currentValue.splice(i, 1);
break;
}
}
}
this.checkEvent.emit(this.currentValue);
}
showDropList(ev: any) {
this.firstLoad = false;
if (this.showDropFlag) {
this.showDropFlag = false;
this.keyword = '';
} else {
setTimeout(() => {
this.showDropFlag = true;
}, 10);
}
}
getCurrentVal() {
return this.currentValue;
}
filter(data: any, keyword: string) {
if (keyword) {
return data.filter((item: any) => item[this.nameKey].indexOf(keyword) > -1);
} else {
return data || [];
}
}
clearValue(ev: any) {
this.firstLoad = false;
this.currentValue = [];
for (let i = 0; i < this.source.length; i++) {
this.source[i].checkModel.checked = false;
}
this.checkEvent.emit(null);
this.showDropFlag = true;
}
}