mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
#976 dynamically resolve form primitives
This commit is contained in:
committed by
Mario Romano
parent
7ff6fd7150
commit
3092cfddaa
@@ -25,11 +25,8 @@
|
||||
<div *ngSwitchCase="'dynamic-table'">
|
||||
<dynamic-table-widget [content]="field"></dynamic-table-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'readonly'">
|
||||
<display-value-widget [field]="field.field" (fieldChanged)="checkVisibility($event)"></display-value-widget>
|
||||
</div>
|
||||
<div *ngSwitchDefault>
|
||||
<span>UNKNOWN WIDGET TYPE: {{field.type}}</span>
|
||||
<form-field [field]="field.field"></form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -48,7 +48,7 @@ export class FormFieldComponent implements OnInit {
|
||||
|
||||
ngOnInit() {
|
||||
if (this.field) {
|
||||
let componentType = this.formRenderingService.getComponentType(this.field.type);
|
||||
let componentType = this.formRenderingService.resolveComponentType(this.field);
|
||||
if (componentType) {
|
||||
let factory = this.componentFactoryResolver.resolveComponentFactory(componentType);
|
||||
this.componentRef = this.container.createComponent(factory/*, 0, this.injector*/);
|
||||
|
@@ -15,57 +15,7 @@
|
||||
<div *ngFor="let col of content.columns" class="mdl-cell mdl-cell--{{col.size}}-col">
|
||||
<div class="mdl-grid" *ngIf="col.hasFields()">
|
||||
<div *ngFor="let field of col.fields" class="mdl-cell mdl-cell--12-col">
|
||||
<div [ngSwitch]="field.type" [hidden]="!field.isVisible">
|
||||
<div *ngSwitchCase="'integer'">
|
||||
<number-widget [field]="field" (fieldChanged)="fieldChanged($event);"></number-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'text'">
|
||||
<form-field [field]="field"></form-field>
|
||||
</div>
|
||||
<div *ngSwitchCase="'multi-line-text'">
|
||||
<multiline-text-widget [field]="field" (fieldChanged)="fieldChanged($event);"></multiline-text-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'boolean'">
|
||||
<checkbox-widget [field]="field" (fieldChanged)="fieldChanged($event);"></checkbox-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'dropdown'">
|
||||
<dropdown-widget [field]="field" (fieldChanged)="fieldChanged($event);"></dropdown-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'hyperlink'">
|
||||
<hyperlink-widget [field]="field" (fieldChanged)="fieldChanged($event);"></hyperlink-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'radio-buttons'">
|
||||
<radio-buttons-widget [field]="field" (fieldChanged)="fieldChanged($event);"></radio-buttons-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'readonly'">
|
||||
<display-value-widget [field]="field" (fieldChanged)="fieldChanged($event);"></display-value-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'readonly-text'">
|
||||
<display-text-widget [field]="field" (fieldChanged)="fieldChanged($event);"></display-text-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'upload'">
|
||||
<upload-widget *ngIf="!field.params.link" [field]="field" (fieldChanged)="fieldChanged($event);"></upload-widget>
|
||||
<attach-widget *ngIf="field.params.link" [field]="field" (fieldChanged)="fieldChanged($event);"></attach-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'typeahead'">
|
||||
<typeahead-widget [field]="field" (fieldChanged)="fieldChanged($event);"></typeahead-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'functional-group'">
|
||||
<functional-group-widget [field]="field" (fieldChanged)="fieldChanged($event);"></functional-group-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'people'">
|
||||
<people-widget [field]="field" (fieldChanged)="fieldChanged($event);"></people-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'date'">
|
||||
<date-widget [field]="field" (fieldChanged)="fieldChanged($event);"></date-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'amount'">
|
||||
<amount-widget [field]="field" (fieldChanged)="fieldChanged($event);"></amount-widget>
|
||||
</div>
|
||||
<div *ngSwitchDefault>
|
||||
<span>UNKNOWN WIDGET TYPE: {{field.type}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<form-field [field]="field" [hidden]="!field.isVisible"></form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -15,6 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { UnknownWidget } from './unknown/unknown.widget';
|
||||
import { TabsWidget } from './tabs/tabs.widget';
|
||||
import { ContainerWidget } from './container/container.widget';
|
||||
|
||||
@@ -50,6 +51,7 @@ export * from './tabs/tabs.widget';
|
||||
export * from './container/container.widget';
|
||||
|
||||
// primitives
|
||||
export * from './unknown/unknown.widget';
|
||||
export * from './text/text.widget';
|
||||
export * from './number/number.widget';
|
||||
export * from './checkbox/checkbox.widget';
|
||||
@@ -76,6 +78,7 @@ export * from './dynamic-table/editors/boolean/boolean.editor';
|
||||
export * from './dynamic-table/editors/text/text.editor';
|
||||
|
||||
export const WIDGET_DIRECTIVES: any[] = [
|
||||
UnknownWidget,
|
||||
TabsWidget,
|
||||
ContainerWidget,
|
||||
TextWidget,
|
||||
|
@@ -23,11 +23,8 @@
|
||||
<div *ngSwitchCase="'dynamic-table'">
|
||||
<dynamic-table-widget [content]="field"></dynamic-table-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'readonly'">
|
||||
<display-value-widget [field]="field.field" (fieldChanged)="tabChanged($event);"></display-value-widget>
|
||||
</div>
|
||||
<div *ngSwitchDefault>
|
||||
<span>UNKNOWN WIDGET TYPE: {{field.type}}</span>
|
||||
<form-field [field]="field.field"></form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -0,0 +1,31 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { WidgetComponent } from './../widget.component';
|
||||
|
||||
@Component({
|
||||
selector: 'unknown-widget',
|
||||
template: `
|
||||
<div>
|
||||
<i class="material-icons">error_outline</i>
|
||||
<span style="color: red">Unknown type: {{field.type}}</span>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
export class UnknownWidget extends WidgetComponent {
|
||||
}
|
@@ -17,41 +17,104 @@
|
||||
|
||||
import { Injectable, Type } from '@angular/core';
|
||||
|
||||
import { TextWidget } from './../components/widgets/text/text.widget';
|
||||
import {
|
||||
FormFieldModel,
|
||||
UnknownWidget,
|
||||
TextWidget,
|
||||
MultilineTextWidget,
|
||||
NumberWidget,
|
||||
CheckboxWidget,
|
||||
DropdownWidget,
|
||||
DateWidget,
|
||||
AmountWidget,
|
||||
RadioButtonsWidget,
|
||||
HyperlinkWidget,
|
||||
DisplayValueWidget,
|
||||
DisplayTextWidget,
|
||||
TypeaheadWidget,
|
||||
PeopleWidget,
|
||||
FunctionalGroupWidget,
|
||||
DynamicTableWidget,
|
||||
AttachWidget,
|
||||
UploadWidget
|
||||
} from './../components/widgets/index';
|
||||
|
||||
@Injectable()
|
||||
export class FormRenderingService {
|
||||
|
||||
private types: { [key: string]: Type<{}> } = {
|
||||
'text': TextWidget
|
||||
private types: { [key: string]: ComponentTypeResolver } = {
|
||||
'text': DefaultTypeResolver.fromType(TextWidget),
|
||||
'integer': DefaultTypeResolver.fromType(NumberWidget),
|
||||
'multi-line-text': DefaultTypeResolver.fromType(MultilineTextWidget),
|
||||
'boolean': DefaultTypeResolver.fromType(CheckboxWidget),
|
||||
'dropdown': DefaultTypeResolver.fromType(DropdownWidget),
|
||||
'date': DefaultTypeResolver.fromType(DateWidget),
|
||||
'amount': DefaultTypeResolver.fromType(AmountWidget),
|
||||
'radio-buttons': DefaultTypeResolver.fromType(RadioButtonsWidget),
|
||||
'hyperlink': DefaultTypeResolver.fromType(HyperlinkWidget),
|
||||
'readonly': DefaultTypeResolver.fromType(DisplayValueWidget),
|
||||
'readonly-text': DefaultTypeResolver.fromType(DisplayTextWidget),
|
||||
'typeahead': DefaultTypeResolver.fromType(TypeaheadWidget),
|
||||
'people': DefaultTypeResolver.fromType(PeopleWidget),
|
||||
'functional-group': DefaultTypeResolver.fromType(FunctionalGroupWidget),
|
||||
'dynamic-table': DefaultTypeResolver.fromType(DynamicTableWidget)
|
||||
};
|
||||
|
||||
getComponentType(fieldType: string): Type<{}> {
|
||||
if (fieldType) {
|
||||
return this.types[fieldType] || null;
|
||||
}
|
||||
return null;
|
||||
constructor() {
|
||||
this.types['upload'] = (field: FormFieldModel): Type<{}> => {
|
||||
if (field) {
|
||||
let params = field.params;
|
||||
if (params && params.link) {
|
||||
return AttachWidget;
|
||||
}
|
||||
return UploadWidget;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
setComponentType(fieldType: string, componentType: Type<{}>, override: boolean = false) {
|
||||
getComponentTypeResolver(fieldType: string, defaultValue: Type<{}> = UnknownWidget): ComponentTypeResolver {
|
||||
if (fieldType) {
|
||||
return this.types[fieldType] || DefaultTypeResolver.fromType(defaultValue);
|
||||
}
|
||||
return DefaultTypeResolver.fromType(defaultValue);
|
||||
}
|
||||
|
||||
setComponentTypeResolver(fieldType: string, resolver: ComponentTypeResolver, override: boolean = false) {
|
||||
if (!fieldType) {
|
||||
throw new Error(`fieldType is null or not defined`);
|
||||
}
|
||||
|
||||
if (!componentType) {
|
||||
throw new Error(`componentType is null or not defined`);
|
||||
if (!resolver) {
|
||||
throw new Error(`resolver is null or not defined`);
|
||||
}
|
||||
|
||||
let existing = this.types[fieldType];
|
||||
if (existing && !override) {
|
||||
throw new Error(`componentType is already mapped, use override option if you intend replacing existing mapping.`);
|
||||
throw new Error(`already mapped, use override option if you intend replacing existing mapping.`);
|
||||
}
|
||||
|
||||
this.types[fieldType] = componentType;
|
||||
this.types[fieldType] = resolver;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.setComponentType('xx', TextWidget);
|
||||
resolveComponentType(field: FormFieldModel, defaultValue: Type<{}> = UnknownWidget): Type<{}> {
|
||||
if (field) {
|
||||
let resolver = this.getComponentTypeResolver(field.type, defaultValue);
|
||||
return resolver(field);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export interface ComponentTypeResolver {
|
||||
(field: FormFieldModel): Type<{}>;
|
||||
}
|
||||
|
||||
export class DefaultTypeResolver {
|
||||
static fromType(type: Type<{}>): ComponentTypeResolver {
|
||||
return (field: FormFieldModel) => {
|
||||
return type;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user