1 import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
2 import { FormControl, ValidatorFn } from '@angular/forms';
4 import { I18n } from '@ngx-translate/i18n-polyfill';
5 import * as _ from 'lodash';
7 import { Icons } from '../../../shared/enum/icons.enum';
8 import { CdFormGroup } from '../../forms/cd-form-group';
9 import { SelectMessages } from './select-messages.model';
10 import { SelectOption } from './select-option.model';
13 selector: 'cd-select',
14 templateUrl: './select.component.html',
15 styleUrls: ['./select.component.scss']
17 export class SelectComponent implements OnInit, OnChanges {
21 data: Array<string> = [];
23 options: Array<SelectOption> = [];
25 messages = new SelectMessages({}, this.i18n);
27 selectionLimit: number;
31 customBadgeValidators: ValidatorFn[] = [];
34 selection = new EventEmitter();
39 filteredOptions: Array<SelectOption> = [];
42 constructor(private i18n: I18n) {}
46 if (this.data.length > 0) {
47 this.initMissingOptions();
49 this.options = _.sortBy(this.options, ['name']);
53 private initFilter() {
54 this.filter = new FormControl('', { validators: this.customBadgeValidators });
55 this.form = new CdFormGroup({ filter: this.filter });
56 this.filteredOptions = [...(this.options || [])];
59 private initMissingOptions() {
60 const options = this.options.map((option) => option.name);
61 const needToCreate = this.data.filter((option) => options.indexOf(option) === -1);
62 needToCreate.forEach((option) => this.addOption(option));
63 this.forceOptionsToReflectData();
66 private addOption(name: string) {
67 this.options.push(new SelectOption(false, name, ''));
68 this.options = _.sortBy(this.options, ['name']);
69 this.triggerSelection(this.options.find((option) => option.name === name));
72 triggerSelection(option: SelectOption) {
75 (this.selectionLimit && !option.selected && this.data.length >= this.selectionLimit)
79 option.selected = !option.selected;
81 this.selection.emit({ option: option });
84 private updateOptions() {
85 this.data.splice(0, this.data.length);
86 this.options.forEach((option: SelectOption) => {
87 if (option.selected) {
88 this.data.push(option.name);
95 this.filteredOptions = this.options.filter((option) => option.name.includes(this.filter.value));
98 private forceOptionsToReflectData() {
99 this.options.forEach((option) => {
100 if (this.data.indexOf(option.name) !== -1) {
101 option.selected = true;
110 if (!this.options || !this.data || this.data.length === 0) {
113 this.forceOptionsToReflectData();
117 if (this.filteredOptions.length === 0) {
118 this.addCustomOption();
120 this.triggerSelection(this.filteredOptions[0]);
126 if (!this.isCreatable()) {
129 this.addOption(this.filter.value);
137 this.filter.value.length > 0 &&
138 this.filteredOptions.every((option) => option.name !== this.filter.value)
142 private resetFilter() {
143 this.filter.setValue('');
147 removeItem(item: string) {
148 this.triggerSelection(
149 this.options.find((option: SelectOption) => option.name === item && option.selected)