Skip to content

Understanding reactivity

Sasha Ivanenko edited this page Jan 19, 2023 · 3 revisions

Here we will talk about the approach to writing custom scripts for JetFormBuilder after version 3.0.

What's the idea?

The idea is to make a universal method to update/read data from form fields.

Why?

For convenience

When you need to change the value in a text field, or format it, we write something like this

const field = document.querySelector( '#field_name' );

field.value = 'updated value';

But if the display of a conditional block depends on this field, then we need to supplement our code as follows:

const field = document.querySelector( '#field_name' );

field.value = 'updated value';

// for conditional blocks & calculated fields
jQuery( field ).trigger( 'change.JetFormBuilderMain' );

Now imagine code that changes a radio, select, or even a WYSIWYG. Each of these fields has a separate path through which you can change the value in the field. And what these three fields have in common is that they accept values of type String. Now we can write like this:

const formId = 123;
const field = JetFormBuilder[formId].getInput( 'field_name' );

field.value.current = 'updated value';

For checkbox and multiple select:

const formId = 123;
const field = JetFormBuilder[formId].getInput( 'field_name' );

// selects only passed items 
field.value.current = [ '34', '564', '22' ];

For reactivity

We don't need to worry about listing Calculated Fields & Conditional Blocks anymore. Formbuilder will take care of it. So we will not need to write something like this:

// deprecated trigger
jQuery( someField ).trigger( 'change.JetFormBuilderMain' );

How does it work?

The mechanism is very simple and reliable. As it was shown above, each field has a value property. This property is a ReactiveVar prototype object (assets/src/frontend/main/reactive/ReactiveVar.js) And when the current property changes in this object, the reactive variable automatically launches its "watchers" (let's call them that).

More details on the example:

let { ReactiveVar } = window.JetFormBuilderAbstract;
let value = new ReactiveVar( null );
value.make();

value.watch( () => {
    console.log( 'You entered: ' + value.current )
} );

value.current = 128;

You can copy the above example into the browser console and get the following result: image

If you try to substitute another value, it will work as we expect. image


If your logic needs to remove the watcher in some circumstances, here is an example how to do it

let { ReactiveVar } = window.JetFormBuilderAbstract;
let value = new ReactiveVar( null );
value.make();

let clearWatcher = value.watch( () => {
    console.log( 'You entered: ' + value.current )
} );

value.current = 128;

clearWatcher();

value.current = 255;

The watch method returns a function to delete this watcher that was added.


This is the main idea on which all reactivity is based. It is used in Calculated Field, in Conditional Block, in multistep logic.

Useful links

🔸 View source of current page