Skip to main content

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:

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.

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:

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.