Component Rules
There might be situations where you want to optionally show or hide some components depending on the input in other components. This is what component rules are for.
Adding rules to a component
When defining your components you can add a list of rules that needs to be fulfilled in order for the component to be visible:
- Code
- Example
import * as React from "react";
import {
textField,
integerField,
booleanField,
equals,
max,
createForm,
StatefulFormView,
} from "@fab4m/fab4m";
const form = createForm({
city: textField({ label: "City" }),
inCityCenter: booleanField({ label: "Do you live in the city center?" }),
streetCars: booleanField({
label: "Do you use street cars?",
rules: [
["city", equals("Gothenburg")],
["inCityCenter", equals(true)],
],
}),
subway: booleanField({
label: "Do you use the subway?",
rules: [["city", equals("Stockholm")]],
}),
usage: integerField({
label: "How may times do you use public transport per week?",
}),
expensive: booleanField({
label: "Do you think public transport is too expensive?",
rules: [["usage", max(3)]],
}),
});
export default function BasicRules() {
return <StatefulFormView form={form} hideSubmit={true} />;
}
Rule groups
By default, rules are logically ANDed together.
You can use logical groups to override this.
- Code
- Example
import React from "react";
import {
textField,
integerField,
booleanField,
equals,
max,
createForm,
StatefulFormView,
or,
} from "@fab4m/fab4m";
const form = createForm({
city: textField({ label: "City" }),
usage: integerField({
label: "How may times do you use public transport per week?",
}),
expensive: booleanField({
label: "Do you think public transport is too expensive?",
rules: [
or([
["city", equals("Gothenburg")],
["usage", max(5)],
]),
],
}),
});
export default function BasicRules() {
return <StatefulFormView form={form} hideSubmit={true} />;
}
Rule functions can also be nested:
expensive: booleanField({
title: "Do you think public transport is too expensive?",
rules: [or([equals("city", "Gothenburg"), and([greaterThan("usage", 5), lessThan(10)]))],
}),
Custom rules
You can use the callback rule to provide any logic you want for your form.
Rules and JSON Schema
Due to the potential complexity of rules in forms, we generate a unique JSON schema depending on the state of the data to keep the schema simple. for example:
- Code
- Example
import * as React from "react";
import * as beautify from "json-beautify";
import {
textField,
equals,
StatefulFormView,
generateSchema,
createForm,
booleanField,
} from "@fab4m/fab4m";
const form = createForm({
city: textField({ label: "City" }),
streetCars: booleanField({
label: "Do you use street cars?",
required: true,
rules: [["city", equals("Gothenburg")]],
}),
});
export default function RuleSchema() {
const [schema, changeSchema] = React.useState(generateSchema(form));
form.onDataChange((data) => {
changeSchema(generateSchema(form, data));
});
return (
<div>
<StatefulFormView form={form} hideSubmit={true} />
<h4>Here's the schema:</h4>
<pre>{beautify.default(schema, null, 2, 80)}</pre>
</div>
);
}
Check out the rule library
Fab4m comes with several rules, check them out in the Rule reference. Also, check the extension guide on how to create your own widgets.