Form.io Core Data Processing Engine
This library is the core data processing engine behind the Form.io platform. It is a set of isomorphic APIs that allow for complex orchestration (e.g. calculated values, conditionally hidden components, complex logic, etc.) of JSON form and submission definitions.
Usage
@formio/core is available as an npm package. You can install it using the package manager of your choice:
npm install --save @formio/core
yarn add @formio/core
Development
Processing form and submission data efficiently has two distinct requirements:
- A form- and data-aware traversal of the form JSON; and
- A set of processing functions to derive (and occasionally mutate) form state.
The first requirement is accomplished via the eachComponentData
and eachComponentDataAsync
functions, which traverse each form component JSON and provide a callback parameter by which to interact with the component and it's corresponding submission data parameter(s).
The second requirement is accomplished via "processors" (e.g. calculate
, validate
, or hideChildren
) which are functions that, given an evaluation context
, operate on, derive state from, and occasionally mutate the form state and submission values depending on the internal form logic, resulting in a scope
object that contains the results of each processor keyed by component path.
To run a suite of processor functions on a form and a submission, the process
family of functions take a form JSON definition, a submission JSON definition, and an array of processor function as an arguments (encapsulated as a context
object which is passed through to each callback processor function).
import { processSync } from '@formio/core';
const form = {
display: 'form',
components: [
{
type: 'textfield',
key: 'firstName',
label: 'First Name',
input: true,
},
{
type: 'textfield',
key: 'lastName',
label: 'Last Name',
input: true,
},
{
type: 'button',
key: 'submit',
action: 'submit',
label: 'Submit',
},
],
};
const submission = {
data: {
firstName: 'John',
lastName: 'Doe',
},
};
const addExclamationSync = (context) => {
const { component, data, scope, path, value } = context;
if (!scope.addExclamation) scope.addExclamation = {};
let newValue = `${value}!`;
scope.addExclamation[path] = true;
_.set(data, path, newValue);
return;
};
const context = {
components: form.components,
data: submission.data,
processors: [{ processSync: addExclamationSync }],
scope: {},
};
const resultScope = processSync(context);
console.assert(resultScope['addExclamation']?.firstName === true);
console.assert(resultScope['addExclamation']?.lastName === true);
console.assert(submission.data.firstName === 'John!');
console.assert(submission.data.lastName === 'Doe!');
Debugging
Debugging the Form.io Enterprise Server can be challenging because of the added complexity of the @formio/vm library (which sandboxes the @formio/core processors for safe execution of untrusted JavaScript on the server). Instructions on how to debug can be found here.
Experimental
This library contains experimental code (found in the src/experimental
directory or via an import, e.g. import { Components } from @formio/core/experimental
) that was designed to update and replace the core rendering engine behind the Form.io platform. It is a tiny (12k gzipped) rendering framework that allows for the rendering of complex components as well as managing the data models controlled by each component.
Usage
To use this experimental framework, you will first need to install the parent library into your application.
npm install --save @formio/core
yarn add @formio/core
Next, you can create a new component as follows.
import { Components } from '@formio/core/experimental';
Components.addComponent({
type: 'h3',
template: (ctx) => `<h3>${ctx.component.header}</h3>`,
});
And now this component will render using the following.
const header = Components.createComponent({
type: 'h3',
header: 'This is a test',
});
console.log(header.render());
You can also use this library by including it in your webpage scripts by including the following.
<script src="https://cdn.jsdelivr.net/npm/@formio/base@latest/dist/formio.core.min.js"></script>
After you do this, you can then do the following to create a Data Table in your website.
FormioCore.render(
document.getElementById('data-table'),
{
type: 'datatable',
key: 'customers',
components: [
{
type: 'datavalue',
key: 'firstName',
label: 'First Name',
},
{
type: 'datavalue',
key: 'lastName',
label: 'First Name',
},
],
},
{},
{
customers: [
{ firstName: 'Joe', lastName: 'Smith' },
{ firstName: 'Sally', lastName: 'Thompson' },
{ firstName: 'Mary', lastName: 'Bono' },
],
},
);