2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 import * as _ from "lodash";
22 import { Component, Compiler, EventEmitter, ViewContainerRef, ViewChild, Input, Output, ElementRef, ComponentRef, ComponentFactoryResolver } from '@angular/core'
23 import {ValidationConfiguration} from "app/models";
24 import {IUiElementChangeEvent} from "../form-components/ui-element-base.component";
25 import {UiElementInputComponent} from "../form-components/input/ui-element-input.component";
26 import {UiElementPopoverInputComponent} from "../form-components/popover-input/ui-element-popover-input.component";
27 import {UiElementIntegerInputComponent} from "../form-components/integer-input/ui-element-integer-input.component";
28 import {UiElementDropDownComponent, DropdownValue} from "../form-components/dropdown/ui-element-dropdown.component";
29 import {PROPERTY_DATA} from "../../../../utils/constants";
31 enum DynamicElementComponentCreatorIdentifier {
41 selector: 'dynamic-element',
42 template: `<div #target></div>`,
43 styleUrls: ['./dynamic-element.component.less'],
45 UiElementInputComponent,
46 UiElementDropDownComponent,
47 UiElementPopoverInputComponent,
48 UiElementIntegerInputComponent
51 export class DynamicElementComponent {
53 @ViewChild('target', { read: ViewContainerRef }) target: any;
55 @Input() name: string;
56 @Input() readonly:boolean;
57 @Input() path:string;//optional param. used only for for subnetpoolid type
60 @Output() valueChange: EventEmitter<any> = new EventEmitter<any>();
61 @Output('elementChanged') emitter: EventEmitter<IUiElementChangeEvent> = new EventEmitter<IUiElementChangeEvent>();
63 cmpRef: ComponentRef<any>;
64 private isViewInitialized: boolean = false;
65 private elementCreatorIdentifier: DynamicElementComponentCreatorIdentifier;
66 validation = ValidationConfiguration.validation;
69 private componentFactoryResolver: ComponentFactoryResolver,
70 private compiler: Compiler,
71 private el: ElementRef) {
75 if (!this.isViewInitialized) {
79 // Factory to create component based on type or other property attributes.
80 const prevElementCreatorIdentifier: DynamicElementComponentCreatorIdentifier = this.elementCreatorIdentifier;
82 case this.path && this.path.toUpperCase().indexOf("SUBNETPOOLID") !== -1:
83 this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.SUBNETPOOLID;
85 case this.type === 'integer':
86 this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.INTEGER;
88 case this.type === 'float':
89 this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.FLOAT;
91 case PROPERTY_DATA.SCALAR_TYPES.indexOf(this.type) > -1:
92 case this.type === 'string':
93 this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.STRING;
95 case this.type === 'boolean':
96 this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.BOOLEAN;
99 this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.DEFAULT;
102 // In case the dynamic element creator is changed, then destroy old and build new.
103 if (this.elementCreatorIdentifier !== prevElementCreatorIdentifier) {
105 this.cmpRef.destroy();
107 this.createComponentByIdentifier();
110 // Update attributes in base element class
112 this.cmpRef.instance.name = this.name;
113 this.cmpRef.instance.type = this.type;
114 this.cmpRef.instance.value = this.value;
115 this.cmpRef.instance.readonly = this.readonly;
119 createComponentByIdentifier() {
120 switch(this.elementCreatorIdentifier) {
121 case DynamicElementComponentCreatorIdentifier.SUBNETPOOLID:
122 if(this.name.toUpperCase().indexOf("SUBNETPOOLID") == -1){//if it's an item of subnetpoolid list get the parent name
123 let pathArray = this.path.split("#");
124 this.name = pathArray[pathArray.length - 2];
126 this.createComponent(UiElementPopoverInputComponent);
129 case DynamicElementComponentCreatorIdentifier.INTEGER:
130 this.createComponent(UiElementIntegerInputComponent);
131 this.cmpRef.instance.pattern = this.validation.validationPatterns.integer;
134 case DynamicElementComponentCreatorIdentifier.FLOAT:
135 this.createComponent(UiElementIntegerInputComponent);
136 this.cmpRef.instance.pattern = /^[-+]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?$/;
139 case DynamicElementComponentCreatorIdentifier.STRING:
140 this.createComponent(UiElementInputComponent);
143 case DynamicElementComponentCreatorIdentifier.BOOLEAN:
144 this.createComponent(UiElementDropDownComponent);
146 // Build drop down values
148 tmp.push(new DropdownValue(true,'TRUE'));
149 tmp.push(new DropdownValue(false,'FALSE'));
150 this.cmpRef.instance.values = tmp;
151 if(!_.isUndefined(this.value)){//contains the real value (and not a string)
152 this.value = JSON.parse(this.value);
156 case DynamicElementComponentCreatorIdentifier.DEFAULT:
158 this.createComponent(UiElementInputComponent);
159 console.log("ERROR: No ui component to handle type: " + this.type);
162 // Subscribe to change event of of ui-element-basic and fire event to change the value
163 this.cmpRef.instance.baseEmitter.subscribe((event) => { this.emitter.emit(event); });
164 this.cmpRef.instance.valueChange.subscribe((event) => { this.valueChange.emit(event); });
167 createComponent(ComponentToCreate:any):void {
168 let factory = this.componentFactoryResolver.resolveComponentFactory(ComponentToCreate);
169 this.cmpRef = this.target.createComponent(factory);
173 this.updateComponent();
176 ngAfterContentInit() {
177 this.isViewInitialized = true;
178 this.updateComponent();
183 this.cmpRef.destroy();