import {Component, EventEmitter, TemplateRef, ContentChild, ViewChild} from '@angular/core'; import {OnChanges, SimpleChange, ChangeDetectorRef, AfterViewInit} from '@angular/core'; import {CORE_DIRECTIVES} from '@angular/common'; import * as _ from 'lodash'; import {BdSelect} from '../Select/select'; import {BdIcon} from '../Icon/icon'; import {BdChipItem} from './chipItem'; import {BdChip} from '../Chip/chip'; import {BdMultiSelectOptionTemplate} from './multiSelectOptionTemplate'; import {BdMultiSelectChipTemplate} from './multiSelectChipTemplate'; @Component({ selector: 'bd-multi-select', inputs: ['value', 'options', 'itemKey', 'placeholder', 'selected'], outputs: ['selectedChange'], directives: [CORE_DIRECTIVES, BdSelect, BdChip, BdChipItem, BdIcon, BdMultiSelectOptionTemplate], styles: [require('./multiSelect.scss')], template: `
close
` }) export class BdMultiSelect implements OnChanges, AfterViewInit { public selectedChange: EventEmitter; public selected: Array; public options: Array; public itemKey: string; public itemText: string; public placeholder: string; public template: TemplateRef; public chipTemplate: TemplateRef; private initialOptions: Array; @ContentChild(BdMultiSelectOptionTemplate) private bdMultiSelectOptionTemplate: BdMultiSelectOptionTemplate; @ContentChild(BdMultiSelectChipTemplate) private bdMultiSelectChipTemplate: BdMultiSelectChipTemplate; @ViewChild(BdSelect) private bdSelect: BdSelect; constructor(private changeDetector: ChangeDetectorRef) { this.options = []; this.selected = []; this.selectedChange = new EventEmitter(); } public ngAfterViewInit() { if (this.bdMultiSelectOptionTemplate) { this.bdSelect.optionTemplate = this.bdMultiSelectOptionTemplate.getTemplate(); } if (this.bdMultiSelectChipTemplate) { this.chipTemplate = this.bdMultiSelectChipTemplate.getTemplate(); } this.closeSelect(); this.changeDetector.detectChanges(); } public ngOnChanges(changes: { [key: string]: SimpleChange }) { if (changes['options'] && changes['options'].currentValue) { this.initialOptions = _.uniqWith(this.options, _.isEqual); } if (changes['selected'] && changes['selected'].currentValue) { this.options = _.differenceWith(this.initialOptions, this.selected, _.isEqual); } if (changes['itemKey'] && changes['itemKey'].currentValue) { this.itemText = `$item.${this.itemKey}`; } } public optionSelectionChanged(option: any) { this.bdSelect.selectedOptionText = ''; this.selected = _.xorWith(this.selected, [option], _.isEqual); this.selectedChange.emit(this.selected); this.closeSelect(); } public onSelectFocusLost() { setTimeout(() => { this.bdSelect.isVisible = this.bdSelect.isPopupOpen = false; }, 100); } public toggleSelect(event: Event) { if (!this.bdSelect.isVisible && _.isEmpty(this.options)) { return; } this.bdSelect.isVisible = !this.bdSelect.isVisible; this.bdSelect.isPopupOpen = this.bdSelect.isVisible; event.stopPropagation(); } private closeSelect() { this.bdSelect.isVisible = this.bdSelect.isPopupOpen = false; } }