ngx-dynamic-json-schema-form v1.2.0
ngx-dynamic-json-schema-form
The goal of this library is to provide a highly adjustable solution, to render forms based on JSON schemas. By this approach translations and custom css and components are feasible. The price of this is a more boilerplate heavy approach.
This library is still in an early stage of development and currently is only tested with JSON Schema 04. Any opinions and requests are welcome!
Usage
Having a look at the example application really helps with understanding the usage of this library :)
In the first step you'll have to create components to display the different types of forms. Have them extend the according classes, provided by this module.
For example a StringForm
:
@Component({
selector: 'app-my-string-form',
styleUrls: ['./my-string-form.component.scss'],
template: `
<input (input)="update.next($event.target.value)" [value]="initial || ''" />
`,
})
export class MyStringFormComponent extends StringForm {
constructor() {
super();
}
}
Inside your template you access the different attributes, made available by the according FormClass. Use them to implement your form! Also to enable the use of (output)
and (errors)
you'll have to call update.next()
.
After adding all necessary Components assign them inside a wrapping component to a variable with the type DynamicJsonSchemaForm
. Here a snippet from the example application:
export class AppComponent {
form: DynamicJsonSchemaForm = {
string: MyStringFormComponent,
array: MyArrayFormComponent,
boolean: MyBooleanFormComponent,
number: MyNumberFormComponent,
wrapper: MyWrapperComponent,
};
..
}
You can now create a NgxDynamicJsonSchemaFormComponent
and provide the schema for the generation. The (output)
provides you an EventEmitter
which listens to data changes inside the form.
<ngx-dynamic-json-schema-form
[form]="form"
[schema]="schema"
[initial]="{ name: 'Already filled!' }"
(output)="result = $event"
(errors)="errors = $event"
(valid)="invalid = !$event"
></ngx-dynamic-json-schema-form>
<hr />
<small>Result: {{ result | json }}</small>
<hr />
<small>Errors: {{ errors | json }}</small>
<hr />
<small>Invalid: {{ invalid | json }}</small>
<hr />
Error Handling
The errors inside each FormComponent
are provided by a error$
Observable of the type ValidationError[]
. Currently the following errors are supported, you can also simply look them up in the types.ts
:
export enum ValidationError {
MULTIPLE_OF = 'MULTIPLE_OF',
MIN_LENGTH = 'MIN_LENGTH',
MAX_LENGTH = 'MAX_LENGTH',
MAXIMUM = 'MAXIMUM',
MINIMUM = 'MINIMUM',
PATTERN = 'PATTERN',
MIN_ITEMS = 'MIN_ITEMS',
MAX_ITEMS = 'MAX_ITEMS',
UNIQUE_ITEMS = 'UNIQUE_ITEMS',
MIN_PROPERTIES = 'MIN_PROPERTIES',
MAX_PROPERTIES = 'MAX_PROPERTIES',
REQUIRED = 'REQUIRED',
}
You're also able to listen to all upcoming errors at the <ngx-dynamic-json-schema-form>
component. Just listen to the (error)
EventEmitter
.
WrapperForm
The WrapperForm
is a special case inside this project. It can contain all forms (even itself!) and therefore needs a marked entrypoint for the insertion. Due to the current implementation you'll need to provide a <ng-template #content></ng-template>
. The children of this wrapper will be placed next to it. An example implementation, which also shows the title
above the content could look like this:
<h1>{{ title }}</h1>
<div>
<ng-template #content></ng-template>
</div>
Another special functionality the WrapperForm
provides is a level
attribute indicating how many layers deep your into the form. The base level is 0
and increases with each additional layer. This can be used to apply styling based on the layer:
<h1 *ngIf="level === 0">{{ title }}</h1>
<h3 *ngIf="level > 0">{{ title }}</h3>
<div>
<ng-template #content></ng-template>
</div>