UNPKG

angular6-json-schema-form

Version:
774 lines 103 kB
import * as tslib_1 from "tslib"; import cloneDeep from 'lodash-es/cloneDeep'; import isEqual from 'lodash-es/isEqual'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, forwardRef, Input, Output } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { convertSchemaToDraft6 } from './shared/convert-schema-to-draft6.function'; import { DomSanitizer } from '@angular/platform-browser'; import { forEach, hasOwn } from './shared/utility.functions'; import { FrameworkLibraryService } from './framework-library/framework-library.service'; import { hasValue, inArray, isArray, isEmpty, isObject } from './shared/validator.functions'; import { JsonPointer } from './shared/jsonpointer.functions'; import { JsonSchemaFormService } from './json-schema-form.service'; import { resolveSchemaReferences } from './shared/json-schema.functions'; import { WidgetLibraryService } from './widget-library/widget-library.service'; export const JSON_SCHEMA_FORM_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => JsonSchemaFormComponent), multi: true, }; /** * @module 'JsonSchemaFormComponent' - Angular JSON Schema Form * * Root module of the Angular JSON Schema Form client-side library, * an Angular library which generates an HTML form from a JSON schema * structured data model and/or a JSON Schema Form layout description. * * This library also validates input data by the user, using both validators on * individual controls to provide real-time feedback while the user is filling * out the form, and then validating the entire input against the schema when * the form is submitted to make sure the returned JSON data object is valid. * * This library is similar to, and mostly API compatible with: * * - JSON Schema Form's Angular Schema Form library for AngularJs * http://schemaform.io * http://schemaform.io/examples/bootstrap-example.html (examples) * * - Mozilla's react-jsonschema-form library for React * https://github.com/mozilla-services/react-jsonschema-form * https://mozilla-services.github.io/react-jsonschema-form (examples) * * - Joshfire's JSON Form library for jQuery * https://github.com/joshfire/jsonform * http://ulion.github.io/jsonform/playground (examples) * * This library depends on: * - Angular (obviously) https://angular.io * - lodash, JavaScript utility library https://github.com/lodash/lodash * - ajv, Another JSON Schema validator https://github.com/epoberezkin/ajv * * In addition, the Example Playground also depends on: * - brace, Browserified Ace editor http://thlorenz.github.io/brace */ let JsonSchemaFormComponent = class JsonSchemaFormComponent { constructor(changeDetector, frameworkLibrary, widgetLibrary, jsf, sanitizer) { this.changeDetector = changeDetector; this.frameworkLibrary = frameworkLibrary; this.widgetLibrary = widgetLibrary; this.jsf = jsf; this.sanitizer = sanitizer; this.formValueSubscription = null; this.formInitialized = false; this.objectWrap = false; // Is non-object input schema wrapped in an object? this.previousInputs = { schema: null, layout: null, data: null, options: null, framework: null, widgets: null, form: null, model: null, JSONSchema: null, UISchema: null, formData: null, loadExternalAssets: null, debug: null, }; // Outputs // tslint:disable-next-line:no-output-on-prefix this.onChanges = new EventEmitter(); // Live unvalidated internal form data // tslint:disable-next-line:no-output-on-prefix this.onSubmit = new EventEmitter(); // Complete validated form data this.isValid = new EventEmitter(); // Is current data valid? this.validationErrors = new EventEmitter(); // Validation errors (if any) this.formSchema = new EventEmitter(); // Final schema used to create form this.formLayout = new EventEmitter(); // Final layout used to create form // Outputs for possible 2-way data binding // Only the one input providing the initial form data will be bound. // If there is no inital data, input '{}' to activate 2-way data binding. // There is no 2-way binding if inital data is combined inside the 'form' input. this.dataChange = new EventEmitter(); this.modelChange = new EventEmitter(); this.formDataChange = new EventEmitter(); this.ngModelChange = new EventEmitter(); } get value() { return this.objectWrap ? this.jsf.data['1'] : this.jsf.data; } set value(value) { this.setFormValues(value, false); } get stylesheets() { const stylesheets = this.frameworkLibrary.getFrameworkStylesheets(); const load = this.sanitizer.bypassSecurityTrustResourceUrl; return stylesheets.map(stylesheet => load(stylesheet)); } get scripts() { const scripts = this.frameworkLibrary.getFrameworkScripts(); const load = this.sanitizer.bypassSecurityTrustResourceUrl; return scripts.map(script => load(script)); } ngOnInit() { this.updateForm(); } ngOnChanges() { this.updateForm(); } writeValue(value) { this.setFormValues(value, false); if (!this.formValuesInput) { this.formValuesInput = 'ngModel'; } } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } setDisabledState(isDisabled) { if (this.jsf.formOptions.formDisabled !== !!isDisabled) { this.jsf.formOptions.formDisabled = !!isDisabled; this.initializeForm(); } } updateForm() { if (!this.formInitialized || !this.formValuesInput || (this.language && this.language !== this.jsf.language)) { this.initializeForm(); } else { if (this.language && this.language !== this.jsf.language) { this.jsf.setLanguage(this.language); } // Get names of changed inputs let changedInput = Object.keys(this.previousInputs) .filter(input => this.previousInputs[input] !== this[input]); let resetFirst = true; if (changedInput.length === 1 && changedInput[0] === 'form' && this.formValuesInput.startsWith('form.')) { // If only 'form' input changed, get names of changed keys changedInput = Object.keys(this.previousInputs.form || {}) .filter(key => !isEqual(this.previousInputs.form[key], this.form[key])) .map(key => `form.${key}`); resetFirst = false; } // If only input values have changed, update the form values if (changedInput.length === 1 && changedInput[0] === this.formValuesInput) { if (this.formValuesInput.indexOf('.') === -1) { this.setFormValues(this[this.formValuesInput], resetFirst); } else { const [input, key] = this.formValuesInput.split('.'); this.setFormValues(this[input][key], resetFirst); } // If anything else has changed, re-render the entire form } else if (changedInput.length) { this.initializeForm(); if (this.onChange) { this.onChange(this.jsf.formValues); } if (this.onTouched) { this.onTouched(this.jsf.formValues); } } // Update previous inputs Object.keys(this.previousInputs) .filter(input => this.previousInputs[input] !== this[input]) .forEach(input => this.previousInputs[input] = this[input]); } } setFormValues(formValues, resetFirst = true) { if (formValues) { const newFormValues = this.objectWrap ? formValues['1'] : formValues; if (!this.jsf.formGroup) { this.jsf.formValues = formValues; this.activateForm(); } else if (resetFirst) { this.jsf.formGroup.reset(); } if (this.jsf.formGroup) { this.jsf.formGroup.patchValue(newFormValues); } if (this.onChange) { this.onChange(newFormValues); } if (this.onTouched) { this.onTouched(newFormValues); } } else { this.jsf.formGroup.reset(); } } submitForm() { const validData = this.jsf.validData; this.onSubmit.emit(this.objectWrap ? validData['1'] : validData); } /** * 'initializeForm' function * * - Update 'schema', 'layout', and 'formValues', from inputs. * * - Create 'schemaRefLibrary' and 'schemaRecursiveRefMap' * to resolve schema $ref links, including recursive $ref links. * * - Create 'dataRecursiveRefMap' to resolve recursive links in data * and corectly set output formats for recursively nested values. * * - Create 'layoutRefLibrary' and 'templateRefLibrary' to store * new layout nodes and formGroup elements to use when dynamically * adding form components to arrays and recursive $ref points. * * - Create 'dataMap' to map the data to the schema and template. * * - Create the master 'formGroupTemplate' then from it 'formGroup' * the Angular formGroup used to control the reactive form. */ initializeForm() { if (this.schema || this.layout || this.data || this.form || this.model || this.JSONSchema || this.UISchema || this.formData || this.ngModel || this.jsf.data) { this.jsf.resetAllValues(); // Reset all form values to defaults this.initializeOptions(); // Update options this.initializeSchema(); // Update schema, schemaRefLibrary, // schemaRecursiveRefMap, & dataRecursiveRefMap this.initializeLayout(); // Update layout, layoutRefLibrary, this.initializeData(); // Update formValues this.activateForm(); // Update dataMap, templateRefLibrary, // formGroupTemplate, formGroup // Uncomment individual lines to output debugging information to console: // (These always work.) // console.log('loading form...'); // console.log('schema', this.jsf.schema); // console.log('layout', this.jsf.layout); // console.log('options', this.options); // console.log('formValues', this.jsf.formValues); // console.log('formGroupTemplate', this.jsf.formGroupTemplate); // console.log('formGroup', this.jsf.formGroup); // console.log('formGroup.value', this.jsf.formGroup.value); // console.log('schemaRefLibrary', this.jsf.schemaRefLibrary); // console.log('layoutRefLibrary', this.jsf.layoutRefLibrary); // console.log('templateRefLibrary', this.jsf.templateRefLibrary); // console.log('dataMap', this.jsf.dataMap); // console.log('arrayMap', this.jsf.arrayMap); // console.log('schemaRecursiveRefMap', this.jsf.schemaRecursiveRefMap); // console.log('dataRecursiveRefMap', this.jsf.dataRecursiveRefMap); // Uncomment individual lines to output debugging information to browser: // (These only work if the 'debug' option has also been set to 'true'.) if (this.debug || this.jsf.formOptions.debug) { const vars = []; // vars.push(this.jsf.schema); // vars.push(this.jsf.layout); // vars.push(this.options); // vars.push(this.jsf.formValues); // vars.push(this.jsf.formGroup.value); // vars.push(this.jsf.formGroupTemplate); // vars.push(this.jsf.formGroup); // vars.push(this.jsf.schemaRefLibrary); // vars.push(this.jsf.layoutRefLibrary); // vars.push(this.jsf.templateRefLibrary); // vars.push(this.jsf.dataMap); // vars.push(this.jsf.arrayMap); // vars.push(this.jsf.schemaRecursiveRefMap); // vars.push(this.jsf.dataRecursiveRefMap); this.debugOutput = vars.map(v => JSON.stringify(v, null, 2)).join('\n'); } this.formInitialized = true; } } /** * 'initializeOptions' function * * Initialize 'options' (global form options) and set framework * Combine available inputs: * 1. options - recommended * 2. form.options - Single input style */ initializeOptions() { if (this.language && this.language !== this.jsf.language) { this.jsf.setLanguage(this.language); } this.jsf.setOptions({ debug: !!this.debug }); let loadExternalAssets = this.loadExternalAssets || false; let framework = this.framework || 'default'; if (isObject(this.options)) { this.jsf.setOptions(this.options); loadExternalAssets = this.options.loadExternalAssets || loadExternalAssets; framework = this.options.framework || framework; } if (isObject(this.form) && isObject(this.form.options)) { this.jsf.setOptions(this.form.options); loadExternalAssets = this.form.options.loadExternalAssets || loadExternalAssets; framework = this.form.options.framework || framework; } if (isObject(this.widgets)) { this.jsf.setOptions({ widgets: this.widgets }); } this.frameworkLibrary.setLoadExternalAssets(loadExternalAssets); this.frameworkLibrary.setFramework(framework); this.jsf.framework = this.frameworkLibrary.getFramework(); if (isObject(this.jsf.formOptions.widgets)) { for (const widget of Object.keys(this.jsf.formOptions.widgets)) { this.widgetLibrary.registerWidget(widget, this.jsf.formOptions.widgets[widget]); } } if (isObject(this.form) && isObject(this.form.tpldata)) { this.jsf.setTpldata(this.form.tpldata); } } /** * 'initializeSchema' function * * Initialize 'schema' * Use first available input: * 1. schema - recommended / Angular Schema Form style * 2. form.schema - Single input / JSON Form style * 3. JSONSchema - React JSON Schema Form style * 4. form.JSONSchema - For testing single input React JSON Schema Forms * 5. form - For testing single schema-only inputs * * ... if no schema input found, the 'activateForm' function, below, * will make two additional attempts to build a schema * 6. If layout input - build schema from layout * 7. If data input - build schema from data */ initializeSchema() { // TODO: update to allow non-object schemas if (isObject(this.schema)) { this.jsf.AngularSchemaFormCompatibility = true; this.jsf.schema = cloneDeep(this.schema); } else if (hasOwn(this.form, 'schema') && isObject(this.form.schema)) { this.jsf.schema = cloneDeep(this.form.schema); } else if (isObject(this.JSONSchema)) { this.jsf.ReactJsonSchemaFormCompatibility = true; this.jsf.schema = cloneDeep(this.JSONSchema); } else if (hasOwn(this.form, 'JSONSchema') && isObject(this.form.JSONSchema)) { this.jsf.ReactJsonSchemaFormCompatibility = true; this.jsf.schema = cloneDeep(this.form.JSONSchema); } else if (hasOwn(this.form, 'properties') && isObject(this.form.properties)) { this.jsf.schema = cloneDeep(this.form); } else if (isObject(this.form)) { // TODO: Handle other types of form input } if (!isEmpty(this.jsf.schema)) { // If other types also allowed, render schema as an object if (inArray('object', this.jsf.schema.type)) { this.jsf.schema.type = 'object'; } // Wrap non-object schemas in object. if (hasOwn(this.jsf.schema, 'type') && this.jsf.schema.type !== 'object') { this.jsf.schema = { 'type': 'object', 'properties': { 1: this.jsf.schema } }; this.objectWrap = true; } else if (!hasOwn(this.jsf.schema, 'type')) { // Add type = 'object' if missing if (isObject(this.jsf.schema.properties) || isObject(this.jsf.schema.patternProperties) || isObject(this.jsf.schema.additionalProperties)) { this.jsf.schema.type = 'object'; // Fix JSON schema shorthand (JSON Form style) } else { this.jsf.JsonFormCompatibility = true; this.jsf.schema = { 'type': 'object', 'properties': this.jsf.schema }; } } // If needed, update JSON Schema to draft 6 format, including // draft 3 (JSON Form style) and draft 4 (Angular Schema Form style) this.jsf.schema = convertSchemaToDraft6(this.jsf.schema); // Initialize ajv and compile schema this.jsf.compileAjvSchema(); // Create schemaRefLibrary, schemaRecursiveRefMap, dataRecursiveRefMap, & arrayMap this.jsf.schema = resolveSchemaReferences(this.jsf.schema, this.jsf.schemaRefLibrary, this.jsf.schemaRecursiveRefMap, this.jsf.dataRecursiveRefMap, this.jsf.arrayMap); if (hasOwn(this.jsf.schemaRefLibrary, '')) { this.jsf.hasRootReference = true; } // TODO: (?) Resolve external $ref links // // Create schemaRefLibrary & schemaRecursiveRefMap // this.parser.bundle(this.schema) // .then(schema => this.schema = resolveSchemaReferences( // schema, this.jsf.schemaRefLibrary, // this.jsf.schemaRecursiveRefMap, this.jsf.dataRecursiveRefMap // )); } } /** * 'initializeData' function * * Initialize 'formValues' * defulat or previously submitted values used to populate form * Use first available input: * 1. data - recommended * 2. model - Angular Schema Form style * 3. form.value - JSON Form style * 4. form.data - Single input style * 5. formData - React JSON Schema Form style * 6. form.formData - For easier testing of React JSON Schema Forms * 7. (none) no data - initialize data from schema and layout defaults only */ initializeData() { if (hasValue(this.data)) { this.jsf.formValues = cloneDeep(this.data); this.formValuesInput = 'data'; } else if (hasValue(this.model)) { this.jsf.AngularSchemaFormCompatibility = true; this.jsf.formValues = cloneDeep(this.model); this.formValuesInput = 'model'; } else if (hasValue(this.ngModel)) { this.jsf.AngularSchemaFormCompatibility = true; this.jsf.formValues = cloneDeep(this.ngModel); this.formValuesInput = 'ngModel'; } else if (isObject(this.form) && hasValue(this.form.value)) { this.jsf.JsonFormCompatibility = true; this.jsf.formValues = cloneDeep(this.form.value); this.formValuesInput = 'form.value'; } else if (isObject(this.form) && hasValue(this.form.data)) { this.jsf.formValues = cloneDeep(this.form.data); this.formValuesInput = 'form.data'; } else if (hasValue(this.formData)) { this.jsf.ReactJsonSchemaFormCompatibility = true; this.formValuesInput = 'formData'; } else if (hasOwn(this.form, 'formData') && hasValue(this.form.formData)) { this.jsf.ReactJsonSchemaFormCompatibility = true; this.jsf.formValues = cloneDeep(this.form.formData); this.formValuesInput = 'form.formData'; } else { this.formValuesInput = null; } } /** * 'initializeLayout' function * * Initialize 'layout' * Use first available array input: * 1. layout - recommended * 2. form - Angular Schema Form style * 3. form.form - JSON Form style * 4. form.layout - Single input style * 5. (none) no layout - set default layout instead * (full layout will be built later from the schema) * * Also, if alternate layout formats are available, * import from 'UISchema' or 'customFormItems' * used for React JSON Schema Form and JSON Form API compatibility * Use first available input: * 1. UISchema - React JSON Schema Form style * 2. form.UISchema - For testing single input React JSON Schema Forms * 2. form.customFormItems - JSON Form style * 3. (none) no input - don't import */ initializeLayout() { // Rename JSON Form-style 'options' lists to // Angular Schema Form-style 'titleMap' lists. const fixJsonFormOptions = (layout) => { if (isObject(layout) || isArray(layout)) { forEach(layout, (value, key) => { if (hasOwn(value, 'options') && isObject(value.options)) { value.titleMap = value.options; delete value.options; } }, 'top-down'); } return layout; }; // Check for layout inputs and, if found, initialize form layout if (isArray(this.layout)) { this.jsf.layout = cloneDeep(this.layout); } else if (isArray(this.form)) { this.jsf.AngularSchemaFormCompatibility = true; this.jsf.layout = cloneDeep(this.form); } else if (this.form && isArray(this.form.form)) { this.jsf.JsonFormCompatibility = true; this.jsf.layout = fixJsonFormOptions(cloneDeep(this.form.form)); } else if (this.form && isArray(this.form.layout)) { this.jsf.layout = cloneDeep(this.form.layout); } else { this.jsf.layout = ['*']; } // Check for alternate layout inputs let alternateLayout = null; if (isObject(this.UISchema)) { this.jsf.ReactJsonSchemaFormCompatibility = true; alternateLayout = cloneDeep(this.UISchema); } else if (hasOwn(this.form, 'UISchema')) { this.jsf.ReactJsonSchemaFormCompatibility = true; alternateLayout = cloneDeep(this.form.UISchema); } else if (hasOwn(this.form, 'uiSchema')) { this.jsf.ReactJsonSchemaFormCompatibility = true; alternateLayout = cloneDeep(this.form.uiSchema); } else if (hasOwn(this.form, 'customFormItems')) { this.jsf.JsonFormCompatibility = true; alternateLayout = fixJsonFormOptions(cloneDeep(this.form.customFormItems)); } // if alternate layout found, copy alternate layout options into schema if (alternateLayout) { JsonPointer.forEachDeep(alternateLayout, (value, pointer) => { const schemaPointer = pointer .replace(/\//g, '/properties/') .replace(/\/properties\/items\/properties\//g, '/items/properties/') .replace(/\/properties\/titleMap\/properties\//g, '/titleMap/properties/'); if (hasValue(value) && hasValue(pointer)) { let key = JsonPointer.toKey(pointer); const groupPointer = (JsonPointer.parse(schemaPointer) || []).slice(0, -2); let itemPointer; // If 'ui:order' object found, copy into object schema root if (key.toLowerCase() === 'ui:order') { itemPointer = [...groupPointer, 'ui:order']; // Copy other alternate layout options to schema 'x-schema-form', // (like Angular Schema Form options) and remove any 'ui:' prefixes } else { if (key.slice(0, 3).toLowerCase() === 'ui:') { key = key.slice(3); } itemPointer = [...groupPointer, 'x-schema-form', key]; } if (JsonPointer.has(this.jsf.schema, groupPointer) && !JsonPointer.has(this.jsf.schema, itemPointer)) { JsonPointer.set(this.jsf.schema, itemPointer, value); } } }); } } /** * 'activateForm' function * * ...continued from 'initializeSchema' function, above * If 'schema' has not been initialized (i.e. no schema input found) * 6. If layout input - build schema from layout input * 7. If data input - build schema from data input * * Create final layout, * build the FormGroup template and the Angular FormGroup, * subscribe to changes, * and activate the form. */ activateForm() { // If 'schema' not initialized if (isEmpty(this.jsf.schema)) { // TODO: If full layout input (with no '*'), build schema from layout // if (!this.jsf.layout.includes('*')) { // this.jsf.buildSchemaFromLayout(); // } else // If data input, build schema from data if (!isEmpty(this.jsf.formValues)) { this.jsf.buildSchemaFromData(); } } if (!isEmpty(this.jsf.schema)) { // If not already initialized, initialize ajv and compile schema this.jsf.compileAjvSchema(); // Update all layout elements, add values, widgets, and validators, // replace any '*' with a layout built from all schema elements, // and update the FormGroup template with any new validators this.jsf.buildLayout(this.widgetLibrary); // Build the Angular FormGroup template from the schema this.jsf.buildFormGroupTemplate(this.jsf.formValues); // Build the real Angular FormGroup from the FormGroup template this.jsf.buildFormGroup(); } if (this.jsf.formGroup) { // Reset initial form values if (!isEmpty(this.jsf.formValues) && this.jsf.formOptions.setSchemaDefaults !== true && this.jsf.formOptions.setLayoutDefaults !== true) { this.setFormValues(this.jsf.formValues); } // TODO: Figure out how to display calculated values without changing object data // See http://ulion.github.io/jsonform/playground/?example=templating-values // Calculate references to other fields // if (!isEmpty(this.jsf.formGroup.value)) { // forEach(this.jsf.formGroup.value, (value, key, object, rootObject) => { // if (typeof value === 'string') { // object[key] = this.jsf.parseText(value, value, rootObject, key); // } // }, 'top-down'); // } // Subscribe to form changes to output live data, validation, and errors this.jsf.dataChanges.subscribe(data => { this.onChanges.emit(this.objectWrap ? data['1'] : data); if (this.formValuesInput && this.formValuesInput.indexOf('.') === -1) { this[`${this.formValuesInput}Change`].emit(this.objectWrap ? data['1'] : data); } }); // Trigger change detection on statusChanges to show updated errors this.jsf.formGroup.statusChanges.subscribe(() => this.changeDetector.markForCheck()); this.jsf.isValidChanges.subscribe(isValid => this.isValid.emit(isValid)); this.jsf.validationErrorChanges.subscribe(err => this.validationErrors.emit(err)); // Output final schema, final layout, and initial data this.formSchema.emit(this.jsf.schema); this.formLayout.emit(this.jsf.layout); this.onChanges.emit(this.objectWrap ? this.jsf.data['1'] : this.jsf.data); // If validateOnRender, output initial validation and any errors const validateOnRender = JsonPointer.get(this.jsf, '/formOptions/validateOnRender'); if (validateOnRender) { // validateOnRender === 'auto' || true const touchAll = (control) => { if (validateOnRender === true || hasValue(control.value)) { control.markAsTouched(); } Object.keys(control.controls || {}) .forEach(key => touchAll(control.controls[key])); }; touchAll(this.jsf.formGroup); this.isValid.emit(this.jsf.isValid); this.validationErrors.emit(this.jsf.ajvErrors); } } } }; tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "schema", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Array) ], JsonSchemaFormComponent.prototype, "layout", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "data", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "options", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "framework", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "widgets", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "form", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "model", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "JSONSchema", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "UISchema", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "formData", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "ngModel", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", String) ], JsonSchemaFormComponent.prototype, "language", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Boolean) ], JsonSchemaFormComponent.prototype, "loadExternalAssets", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Boolean) ], JsonSchemaFormComponent.prototype, "debug", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object), tslib_1.__metadata("design:paramtypes", [Object]) ], JsonSchemaFormComponent.prototype, "value", null); tslib_1.__decorate([ Output(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "onChanges", void 0); tslib_1.__decorate([ Output(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "onSubmit", void 0); tslib_1.__decorate([ Output(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "isValid", void 0); tslib_1.__decorate([ Output(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "validationErrors", void 0); tslib_1.__decorate([ Output(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "formSchema", void 0); tslib_1.__decorate([ Output(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "formLayout", void 0); tslib_1.__decorate([ Output(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "dataChange", void 0); tslib_1.__decorate([ Output(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "modelChange", void 0); tslib_1.__decorate([ Output(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "formDataChange", void 0); tslib_1.__decorate([ Output(), tslib_1.__metadata("design:type", Object) ], JsonSchemaFormComponent.prototype, "ngModelChange", void 0); JsonSchemaFormComponent = tslib_1.__decorate([ Component({ // tslint:disable-next-line:component-selector selector: 'json-schema-form', template: ` <div *ngFor="let stylesheet of stylesheets"> <link rel="stylesheet" [href]="stylesheet"> </div> <div *ngFor="let script of scripts"> <script type="text/javascript" [src]="script"></script> </div> <form [autocomplete]="jsf?.formOptions?.autocomplete ? 'on' : 'off'" class="json-schema-form" (ngSubmit)="submitForm()"> <root-widget [layout]="jsf?.layout"></root-widget> </form> <div *ngIf="debug || jsf?.formOptions?.debug"> Debug output: <pre>{{debugOutput}}</pre> </div>`, changeDetection: ChangeDetectionStrategy.OnPush, // Adding 'JsonSchemaFormService' here, instead of in the module, // creates a separate instance of the service for each component providers: [JsonSchemaFormService, JSON_SCHEMA_FORM_VALUE_ACCESSOR] }), tslib_1.__metadata("design:paramtypes", [ChangeDetectorRef, FrameworkLibraryService, WidgetLibraryService, JsonSchemaFormService, DomSanitizer]) ], JsonSchemaFormComponent); export { JsonSchemaFormComponent }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi1zY2hlbWEtZm9ybS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9hbmd1bGFyNi1qc29uLXNjaGVtYS1mb3JtLyIsInNvdXJjZXMiOlsibGliL2pzb24tc2NoZW1hLWZvcm0uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLFNBQVMsTUFBTSxxQkFBcUIsQ0FBQztBQUM1QyxPQUFPLE9BQU8sTUFBTSxtQkFBbUIsQ0FBQztBQUV4QyxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsWUFBWSxFQUNaLFVBQVUsRUFDVixLQUFLLEVBR0wsTUFBTSxFQUNMLE1BQU0sZUFBZSxDQUFDO0FBQ3pCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUNuRixPQUFPLEVBQUUsWUFBWSxFQUFtQixNQUFNLDJCQUEyQixDQUFDO0FBQzFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDN0QsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sK0NBQStDLENBQUM7QUFDeEYsT0FBTyxFQUNMLFFBQVEsRUFDUixPQUFPLEVBQ1AsT0FBTyxFQUNQLE9BQU8sRUFDUCxRQUFRLEVBQ1AsTUFBTSw4QkFBOEIsQ0FBQztBQUN4QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDN0QsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDbkUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDekUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFJL0UsTUFBTSxDQUFDLE1BQU0sK0JBQStCLEdBQVE7SUFDbEQsT0FBTyxFQUFFLGlCQUFpQjtJQUMxQixX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