ngx-schema-form
ngx-schema-form copied to clipboard
Conditional logic
Hey,
I want to extend this project with conditional logic, which allow to have more complicated logic expressed and controlled with JSON schema. For the logic rules I will use the json-rules-engine.
Example: what am I trying to accomplish?
- Listen to form data changes
- Run rules when the form data has changed
- Rules can change the form schema
- Render the form with new schema
Problems? I think it creates a new subscription each time the schema has changed. https://github.com/makinacorpus/angular2-schema-form/blob/b59cf8568f446820dee301ba9d310695a751905c/src/form.component.ts#L98
Question Do you have any idea what is the best way to accomplish this?
// Template
<sf-form
[schema]="schema"
[model]="model"
[actions]="actions"
(onChange)="onChange($event)"
(isValid)="isValidEvent($event)"
(onErrorChange)="onErrorChangeEvent"
(onErrorsChange)="onErrorsChangeEvent">
</sf-form>
public rules;
public schema: any;
public model: any;
private runRules;
private updateBusy: boolean = false;
constructor() {
this.rules = [
{
conditions: {
email: "empty"
},
event: {
type: "required",
params: {
field: "password"
},
}
}
];
this.schema = {
properties: {
email: {
type: "string",
description: "email",
format: "email"
},
password: {
type: "string",
description: "Password"
},
rememberMe: {
type: "boolean",
default: false,
description: "Remember me"
}
},
required: ["email", "rememberMe"],
buttons: [{
id: "submit",
label: "verzenden"
}]
};
this.runRules = rulesRunner(this.schema, this.rules, Engine, actions);
}
// Listen to the onChange event
public onChange($event): void {
const formData: any = $event.value;
if (formData && !this.updateBusy && !equals(this.model, formData)) {
this.updateBusy = true;
this.runRules(formData)
.then((conf) => {
if (!equals(this.schema, conf.schema)) {
this.schema = conf.schema;
this.model = formData;
}
this.updateBusy = false;
}).bind(this));
}
}
// This function will be called after the required event was fired
function required(params: Requiredparams, schema): void {
cont { field } = params;
if (schema.properties[field] === undefined) {
console.error("field is missing from the schema and can't be required");
}
const fieldIsCurrentlyRequired = ~schema.required.indexOf(field);
if (!fieldIsCurrentlyRequired) {
schema.required.push(field);
}
}
kind regards,