diff --git a/src/lib/src/framework-library/no-framework/no-framework.component.ts b/src/lib/src/framework-library/no-framework/no-framework.component.ts index 28a4a963..b825df4e 100755 --- a/src/lib/src/framework-library/no-framework/no-framework.component.ts +++ b/src/lib/src/framework-library/no-framework/no-framework.component.ts @@ -1,15 +1,62 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; +import * as _ from 'lodash'; +import { JsonSchemaFormService } from '../../json-schema-form.service'; @Component({ selector: 'no-framework', template: ` + `, + [layoutNode]="layoutNode"> + `, }) -export class NoFrameworkComponent { +export class NoFrameworkComponent implements OnInit { + + options: any; // Options used in this framework + parentArray: any = null; + isOrderable = false; + @Input() layoutNode: any; @Input() layoutIndex: number[]; @Input() dataIndex: number[]; + + constructor( + public jsf: JsonSchemaFormService + ) { } + + ngOnInit() { + this.options = _.cloneDeep(this.layoutNode.options); + if (this.layoutNode.arrayItem && this.layoutNode.type !== '$ref') { + this.parentArray = this.jsf.getParentNode(this); + if (this.parentArray) { + this.isOrderable = this.layoutNode.arrayItemType === 'list' && + !this.options.readonly && this.parentArray.options.orderable; + } + } + } + + + get showRemoveButton(): boolean { + if (!this.options.removable || this.options.readonly || + this.layoutNode.type === '$ref' + ) { return false; } + if (this.layoutNode.recursiveReference) { return true; } + if (!this.layoutNode.arrayItem || !this.parentArray) { return false; } + // If array length <= minItems, don't allow removing any items + return this.parentArray.items.length - 1 <= this.parentArray.options.minItems ? false : + // For removable list items, allow removing any item + this.layoutNode.arrayItemType === 'list' ? true : + // For removable tuple items, only allow removing last item in list + this.layoutIndex[this.layoutIndex.length - 1] === this.parentArray.items.length - 2; + } + + removeItem() { + this.jsf.removeItem(this); + } } diff --git a/src/lib/src/shared/jsonpointer.functions.ts b/src/lib/src/shared/jsonpointer.functions.ts index e6075228..cbe1336b 100755 --- a/src/lib/src/shared/jsonpointer.functions.ts +++ b/src/lib/src/shared/jsonpointer.functions.ts @@ -392,7 +392,10 @@ export class JsonPointer { console.error(`forEachDeep error: Iterator is not a function:`, fn); return; } + const firstPointerPart = pointer.split('/')[1]; + if (firstPointerPart && rootObject.hasOwnProperty(firstPointerPart)) { if (!bottomUp) { fn(object, pointer, rootObject); } + } if (isObject(object) || isArray(object)) { for (let key of Object.keys(object)) { const newPointer = pointer + '/' + this.escape(key);