svogv
Version:
A decorator based approach for model driven forms, including an advanced DataGrid and a TreeView component.
93 lines • 13 kB
JavaScript
import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
/**
* This component creates a complete editor from a viewmodel. The viewmodel should have
* decorators to control the form's behavior. The form can be styled an supports validation.
* It creates one field for each property not decorated with {@link Hidden}decorator.
*
* Example of usage:
* <example-url>/#/editor</example-url>
*/
export class AutoFormComponent {
constructor() {
/**
* Ungrouped element will appear at the end, after all groupes.
* If there are no groups this will be ignored. Optional.
*/
this.ungroupedAfter = true;
this.editors = new Array();
this.groups = new Array();
}
ngOnInit() {
// take all controls as is
const hasDecorators = this.formGroup.__editorModel__;
// loop through all fields
for (const controlName in this.formGroup.controls) {
if (!this.formGroup.controls.hasOwnProperty(controlName)) {
continue;
}
let displayOrder = 0;
let groupOrder = 0;
let groupName;
let groupDesc;
let isInGroup = false;
if (hasDecorators) {
displayOrder = this.formGroup.__editorModel__[`__displayOrder__${controlName}`];
isInGroup = !!this.formGroup.__editorModel__[`__isGrouped__${controlName}`];
if (isInGroup) {
groupName = this.formGroup.__editorModel__[`__groupName__${controlName}`];
groupOrder = this.formGroup.__editorModel__[`__groupOrder__${controlName}`];
groupDesc = this.formGroup.__editorModel__[`__groupDesc__${controlName}`];
}
}
if (!isInGroup) {
// if not part of any group just push to main group
this.editors.push({
key: displayOrder,
editor: controlName
});
}
else {
// check if group already exists
const existingGroupArray = this.groups.filter((g) => g.name === groupName);
const groupExists = existingGroupArray.length === 1;
if (!groupExists) {
this.groups.push({
key: groupOrder,
name: groupName,
desc: groupDesc,
editors: new Array()
});
}
// add field to existing group (assume that here the group always exists)
const existingGroup = this.groups.filter((g) => g.name === groupName)[0];
// and store
existingGroup.editors.push({
key: displayOrder,
editor: controlName
});
}
}
// check the display decorator and sort
this.editors.sort((e, n) => e.key - n.key);
// sort groups
this.groups.sort((e, n) => e.key - n.key);
}
grouped() {
return this.groups && this.groups.length > 0;
}
}
AutoFormComponent.decorators = [
{ type: Component, args: [{
selector: 'ac-autoform',
template: "<ng-content></ng-content>\n<ng-container *ngIf=\"!ungroupedAfter\">\n <ac-editor *ngFor=\"let editor of editors\" [name]=\"editor.editor\" [formGroup]=\"formGroup\"></ac-editor>\n</ng-container>\n<ng-container *ngIf=\"grouped()\">\n <fieldset *ngFor=\"let group of groups\">\n <legend [attr.title]=\"group.desc\" *ngIf=\"group.name\">{{ group.name }}</legend>\n <ac-editor *ngFor=\"let editor of group.editors\" [name]=\"editor.editor\" [formGroup]=\"formGroup\"></ac-editor>\n </fieldset>\n</ng-container>\n<ng-container *ngIf=\"ungroupedAfter\">\n <ac-editor *ngFor=\"let editor of editors\" [name]=\"editor.editor\" [formGroup]=\"formGroup\"></ac-editor>\n</ng-container>\n",
styles: ['fieldset { border-top: 1px silver solid; padding: 10px; }',
'legend { width: auto; padding-left: 10px; padding-right: 10px; font-size: 1em;}']
},] }
];
AutoFormComponent.ctorParameters = () => [];
AutoFormComponent.propDecorators = {
formGroup: [{ type: Input }],
ungroupedAfter: [{ type: Input }]
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0b2Zvcm0uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Ii4uLy4uLy4uL3Byb2plY3RzL3N2b2d2L3NyYy8iLCJzb3VyY2VzIjpbImxpYi93aWRnZXRzL2VkaXRvcnMvYXV0b2Zvcm0vYXV0b2Zvcm0uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ3pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQzs7Ozs7OztHQU9HO0FBU0gsTUFBTSxPQUFPLGlCQUFpQjtJQXFCNUI7UUFmQTs7O1dBR0c7UUFFSSxtQkFBYyxHQUFHLElBQUksQ0FBQztRQVczQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksS0FBSyxFQUFtQyxDQUFDO1FBQzVELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxLQUFLLEVBS25CLENBQUM7SUFDUCxDQUFDO0lBRU0sUUFBUTtRQUNiLDBCQUEwQjtRQUMxQixNQUFNLGFBQWEsR0FBYSxJQUFJLENBQUMsU0FBaUIsQ0FBQyxlQUFlLENBQUM7UUFDdkUsMEJBQTBCO1FBQzFCLEtBQUssTUFBTSxXQUFXLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUU7WUFDakQsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsRUFBRTtnQkFDeEQsU0FBUzthQUNWO1lBQ0QsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztZQUNuQixJQUFJLFNBQWlCLENBQUM7WUFDdEIsSUFBSSxTQUFpQixDQUFDO1lBQ3RCLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQztZQUN0QixJQUFJLGFBQWEsRUFBRTtnQkFDakIsWUFBWSxHQUFLLElBQUksQ0FBQyxTQUFpQixDQUFDLGVBQWUsQ0FDckQsbUJBQW1CLFdBQVcsRUFBRSxDQUNqQyxDQUFDO2dCQUNGLFNBQVMsR0FBRyxDQUFDLENBQUcsSUFBSSxDQUFDLFNBQWlCLENBQUMsZUFBZSxDQUNwRCxnQkFBZ0IsV0FBVyxFQUFFLENBQzlCLENBQUM7Z0JBQ0YsSUFBSSxTQUFTLEVBQUU7b0JBQ2IsU0FBUyxHQUFLLElBQUksQ0FBQyxTQUFpQixDQUFDLGVBQWUsQ0FDbEQsZ0JBQWdCLFdBQVcsRUFBRSxDQUM5QixDQUFDO29CQUNGLFVBQVUsR0FBSyxJQUFJLENBQUMsU0FBaUIsQ0FBQyxlQUFlLENBQ25ELGlCQUFpQixXQUFXLEVBQUUsQ0FDL0IsQ0FBQztvQkFDRixTQUFTLEdBQUssSUFBSSxDQUFDLFNBQWlCLENBQUMsZUFBZSxDQUNsRCxnQkFBZ0IsV0FBVyxFQUFFLENBQzlCLENBQUM7aUJBQ0g7YUFDRjtZQUNELElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQ2QsbURBQW1EO2dCQUNuRCxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztvQkFDaEIsR0FBRyxFQUFFLFlBQVk7b0JBQ2pCLE1BQU0sRUFBRSxXQUFXO2lCQUNwQixDQUFDLENBQUM7YUFDSjtpQkFBTTtnQkFDTCxnQ0FBZ0M7Z0JBQ2hDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDLENBQUM7Z0JBQzNFLE1BQU0sV0FBVyxHQUFHLGtCQUFrQixDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7Z0JBQ3BELElBQUksQ0FBQyxXQUFXLEVBQUU7b0JBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO3dCQUNmLEdBQUcsRUFBRSxVQUFVO3dCQUNmLElBQUksRUFBRSxTQUFTO3dCQUNmLElBQUksRUFBRSxTQUFTO3dCQUNmLE9BQU8sRUFBRSxJQUFJLEtBQUssRUFBbUM7cUJBQ3RELENBQUMsQ0FBQztpQkFDSjtnQkFDRCx5RUFBeUU7Z0JBQ3pFLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN6RSxZQUFZO2dCQUNaLGFBQWEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO29CQUN6QixHQUFHLEVBQUUsWUFBWTtvQkFDakIsTUFBTSxFQUFFLFdBQVc7aUJBQ3BCLENBQUMsQ0FBQzthQUNKO1NBQ0Y7UUFDRCx1Q0FBdUM7UUFDdkMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMzQyxjQUFjO1FBQ2QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRU0sT0FBTztRQUNaLE9BQU8sSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDL0MsQ0FBQzs7O1lBMUdGLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsYUFBYTtnQkFLdkIsMHJCQUF3Qzt5QkFIdEMsMkRBQTJEO29CQUMzRCxpRkFBaUY7YUFHcEY7Ozs7d0JBS0UsS0FBSzs2QkFNTCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbi8qKlxuICogVGhpcyBjb21wb25lbnQgY3JlYXRlcyBhIGNvbXBsZXRlIGVkaXRvciBmcm9tIGEgdmlld21vZGVsLiBUaGUgdmlld21vZGVsIHNob3VsZCBoYXZlXG4gKiBkZWNvcmF0b3JzIHRvIGNvbnRyb2wgdGhlIGZvcm0ncyBiZWhhdmlvci4gVGhlIGZvcm0gY2FuIGJlIHN0eWxlZCBhbiBzdXBwb3J0cyB2YWxpZGF0aW9uLlxuICogSXQgY3JlYXRlcyBvbmUgZmllbGQgZm9yIGVhY2ggcHJvcGVydHkgbm90IGRlY29yYXRlZCB3aXRoIHtAbGluayBIaWRkZW59ZGVjb3JhdG9yLlxuICpcbiAqIEV4YW1wbGUgb2YgdXNhZ2U6XG4gKiA8ZXhhbXBsZS11cmw+LyMvZWRpdG9yPC9leGFtcGxlLXVybD5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYWMtYXV0b2Zvcm0nLFxuICBzdHlsZXM6IFtcbiAgICAnZmllbGRzZXQgeyBib3JkZXItdG9wOiAxcHggc2lsdmVyIHNvbGlkOyBwYWRkaW5nOiAxMHB4OyB9JyxcbiAgICAnbGVnZW5kIHsgd2lkdGg6IGF1dG87IHBhZGRpbmctbGVmdDogMTBweDsgcGFkZGluZy1yaWdodDogMTBweDsgZm9udC1zaXplOiAxZW07fSdcbiAgXSxcbiAgdGVtcGxhdGVVcmw6ICcuL2F1dG9mb3JtLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBBdXRvRm9ybUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIC8qKlxuICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgZm9ybS4gUmVxdWlyZWQuXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgZm9ybUdyb3VwOiBGb3JtR3JvdXA7XG4gIC8qKlxuICAgKiBVbmdyb3VwZWQgZWxlbWVudCB3aWxsIGFwcGVhciBhdCB0aGUgZW5kLCBhZnRlciBhbGwgZ3JvdXBlcy5cbiAgICogSWYgdGhlcmUgYXJlIG5vIGdyb3VwcyB0aGlzIHdpbGwgYmUgaWdub3JlZC4gT3B0aW9uYWwuXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgdW5ncm91cGVkQWZ0ZXIgPSB0cnVlO1xuXG4gIHB1YmxpYyBlZGl0b3JzOiB7IGtleTogbnVtYmVyOyBlZGl0b3I6IHN0cmluZyB9W107XG4gIHB1YmxpYyBncm91cHM6IHtcbiAgICBrZXk6IG51bWJlcjtcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgZGVzYzogc3RyaW5nO1xuICAgIGVkaXRvcnM6IHsga2V5OiBudW1iZXI7IGVkaXRvcjogc3RyaW5nIH1bXTtcbiAgfVtdO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuZWRpdG9ycyA9IG5ldyBBcnJheTx7IGtleTogbnVtYmVyOyBlZGl0b3I6IHN0cmluZyB9PigpO1xuICAgIHRoaXMuZ3JvdXBzID0gbmV3IEFycmF5PHtcbiAgICAgIGtleTogbnVtYmVyO1xuICAgICAgbmFtZTogc3RyaW5nO1xuICAgICAgZGVzYzogc3RyaW5nO1xuICAgICAgZWRpdG9yczogeyBrZXk6IG51bWJlcjsgZWRpdG9yOiBzdHJpbmcgfVtdO1xuICAgIH0+KCk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgLy8gdGFrZSBhbGwgY29udHJvbHMgYXMgaXNcbiAgICBjb25zdCBoYXNEZWNvcmF0b3JzOiBib29sZWFuID0gKHRoaXMuZm9ybUdyb3VwIGFzIGFueSkuX19lZGl0b3JNb2RlbF9fO1xuICAgIC8vIGxvb3AgdGhyb3VnaCBhbGwgZmllbGRzXG4gICAgZm9yIChjb25zdCBjb250cm9sTmFtZSBpbiB0aGlzLmZvcm1Hcm91cC5jb250cm9scykge1xuICAgICAgaWYgKCF0aGlzLmZvcm1Hcm91cC5jb250cm9scy5oYXNPd25Qcm9wZXJ0eShjb250cm9sTmFtZSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBsZXQgZGlzcGxheU9yZGVyID0gMDtcbiAgICAgIGxldCBncm91cE9yZGVyID0gMDtcbiAgICAgIGxldCBncm91cE5hbWU6IHN0cmluZztcbiAgICAgIGxldCBncm91cERlc2M6IHN0cmluZztcbiAgICAgIGxldCBpc0luR3JvdXAgPSBmYWxzZTtcbiAgICAgIGlmIChoYXNEZWNvcmF0b3JzKSB7XG4gICAgICAgIGRpc3BsYXlPcmRlciA9ICggdGhpcy5mb3JtR3JvdXAgYXMgYW55KS5fX2VkaXRvck1vZGVsX19bXG4gICAgICAgICAgYF9fZGlzcGxheU9yZGVyX18ke2NvbnRyb2xOYW1lfWBcbiAgICAgICAgXTtcbiAgICAgICAgaXNJbkdyb3VwID0gISEoIHRoaXMuZm9ybUdyb3VwIGFzIGFueSkuX19lZGl0b3JNb2RlbF9fW1xuICAgICAgICAgIGBfX2lzR3JvdXBlZF9fJHtjb250cm9sTmFtZX1gXG4gICAgICAgIF07XG4gICAgICAgIGlmIChpc0luR3JvdXApIHtcbiAgICAgICAgICBncm91cE5hbWUgPSAoIHRoaXMuZm9ybUdyb3VwIGFzIGFueSkuX19lZGl0b3JNb2RlbF9fW1xuICAgICAgICAgICAgYF9fZ3JvdXBOYW1lX18ke2NvbnRyb2xOYW1lfWBcbiAgICAgICAgICBdO1xuICAgICAgICAgIGdyb3VwT3JkZXIgPSAoIHRoaXMuZm9ybUdyb3VwIGFzIGFueSkuX19lZGl0b3JNb2RlbF9fW1xuICAgICAgICAgICAgYF9fZ3JvdXBPcmRlcl9fJHtjb250cm9sTmFtZX1gXG4gICAgICAgICAgXTtcbiAgICAgICAgICBncm91cERlc2MgPSAoIHRoaXMuZm9ybUdyb3VwIGFzIGFueSkuX19lZGl0b3JNb2RlbF9fW1xuICAgICAgICAgICAgYF9fZ3JvdXBEZXNjX18ke2NvbnRyb2xOYW1lfWBcbiAgICAgICAgICBdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIWlzSW5Hcm91cCkge1xuICAgICAgICAvLyBpZiBub3QgcGFydCBvZiBhbnkgZ3JvdXAganVzdCBwdXNoIHRvIG1haW4gZ3JvdXBcbiAgICAgICAgdGhpcy5lZGl0b3JzLnB1c2goe1xuICAgICAgICAgIGtleTogZGlzcGxheU9yZGVyLFxuICAgICAgICAgIGVkaXRvcjogY29udHJvbE5hbWVcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBjaGVjayBpZiBncm91cCBhbHJlYWR5IGV4aXN0c1xuICAgICAgICBjb25zdCBleGlzdGluZ0dyb3VwQXJyYXkgPSB0aGlzLmdyb3Vwcy5maWx0ZXIoKGcpID0+IGcubmFtZSA9PT0gZ3JvdXBOYW1lKTtcbiAgICAgICAgY29uc3QgZ3JvdXBFeGlzdHMgPSBleGlzdGluZ0dyb3VwQXJyYXkubGVuZ3RoID09PSAxO1xuICAgICAgICBpZiAoIWdyb3VwRXhpc3RzKSB7XG4gICAgICAgICAgdGhpcy5ncm91cHMucHVzaCh7XG4gICAgICAgICAgICBrZXk6IGdyb3VwT3JkZXIsXG4gICAgICAgICAgICBuYW1lOiBncm91cE5hbWUsXG4gICAgICAgICAgICBkZXNjOiBncm91cERlc2MsXG4gICAgICAgICAgICBlZGl0b3JzOiBuZXcgQXJyYXk8eyBrZXk6IG51bWJlcjsgZWRpdG9yOiBzdHJpbmcgfT4oKVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIGFkZCBmaWVsZCB0byBleGlzdGluZyBncm91cCAoYXNzdW1lIHRoYXQgaGVyZSB0aGUgZ3JvdXAgYWx3YXlzIGV4aXN0cylcbiAgICAgICAgY29uc3QgZXhpc3RpbmdHcm91cCA9IHRoaXMuZ3JvdXBzLmZpbHRlcigoZykgPT4gZy5uYW1lID09PSBncm91cE5hbWUpWzBdO1xuICAgICAgICAvLyBhbmQgc3RvcmVcbiAgICAgICAgZXhpc3RpbmdHcm91cC5lZGl0b3JzLnB1c2goe1xuICAgICAgICAgIGtleTogZGlzcGxheU9yZGVyLFxuICAgICAgICAgIGVkaXRvcjogY29udHJvbE5hbWVcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIGNoZWNrIHRoZSBkaXNwbGF5IGRlY29yYXRvciBhbmQgc29ydFxuICAgIHRoaXMuZWRpdG9ycy5zb3J0KChlLCBuKSA9PiBlLmtleSAtIG4ua2V5KTtcbiAgICAvLyBzb3J0IGdyb3Vwc1xuICAgIHRoaXMuZ3JvdXBzLnNvcnQoKGUsIG4pID0+IGUua2V5IC0gbi5rZXkpO1xuICB9XG5cbiAgcHVibGljIGdyb3VwZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ3JvdXBzICYmIHRoaXMuZ3JvdXBzLmxlbmd0aCA+IDA7XG4gIH1cbn1cbiJdfQ==