import {Component, EventEmitter, Optional } from '@angular/core'; import { AfterViewInit, Output, Input, ChangeDetectionStrategy } from '@angular/core'; import {NgControl, ControlValueAccessor, } from '@angular/forms'; import {Http} from '@angular/http'; import {Verify} from '../../../services/validation/Verify'; import {ApiRoot} from 'dotcms-js/dotcms-js'; import {Observable} from 'rxjs'; import * as _ from 'lodash'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'cw-input-rest-dropdown', template: ` `, }) export class RestDropdown implements AfterViewInit, ControlValueAccessor { @Input() placeholder: string; @Input() allowAdditions: boolean; @Input() minSelections: number; @Input() maxSelections: number; @Input() optionUrl: string; @Input() optionValueField: string; @Input() optionLabelField: string; @Input() value: string; @Output() change: EventEmitter = new EventEmitter(); @Output() touch: EventEmitter = new EventEmitter(); private _modelValue: string; private _options: Observable; onChange: Function = ( ) => { }; onTouched: Function = ( ) => { }; constructor(private _http: Http, private _apiRoot: ApiRoot, @Optional() public control: NgControl) { if (control) { control.valueAccessor = this; } this.placeholder = ''; this.optionValueField = 'key'; this.optionLabelField = 'value'; this.allowAdditions = false; this.minSelections = 0; this.maxSelections = 1; } ngAfterViewInit(): void { } writeValue(value: any): void { if (value && value.indexOf(',') > -1) { this._modelValue = value.split(','); } else { this._modelValue = _.isEmpty(value) ? '' : value; } } registerOnChange(fn): void { this.onChange = fn; } registerOnTouched(fn): void { this.onTouched = fn; } fireChange($event): void { this.change.emit($event); this.onChange($event); } fireTouch($event): void { this.touch.emit($event); this.onTouched($event); } ngOnChanges(change): void { if (change.optionUrl) { const requestOptionArgs = this._apiRoot.getDefaultRequestOptions(); this._options = this._http.get(change.optionUrl.currentValue, requestOptionArgs) .map((res: any) => this.jsonEntriesToOptions(res)); } if (change.value && change.value.currentValue && change.value.currentValue.indexOf(',') > -1) { this._modelValue = change.value.currentValue.split(','); } } private jsonEntriesToOptions(res: any): any { const valuesJson = res.json(); let ary = []; if (Verify.isArray(valuesJson)) { ary = valuesJson.map(valueJson => this.jsonEntryToOption(valueJson)); } else { ary = Object.keys(valuesJson).map((key) => { return this.jsonEntryToOption(valuesJson[key], key); }); } return ary; } private jsonEntryToOption(json: any, key: string = null): {value: string, label: string} { const opt = {value: null, label: null}; if (!json[this.optionValueField] && this.optionValueField === 'key' && key != null) { opt.value = key; } else { opt.value = json[this.optionValueField]; } opt.label = json[this.optionLabelField]; return opt; } }