_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 ```js 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: ```js 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: ```js const formId = 123; const field = JetFormBuilder[formId].getInput( 'field_name' ); field.value.current = 'updated value'; ``` For checkbox and multiple select: ```js 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: ```js // 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: ```js 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](https://user-images.githubusercontent.com/46720998/195395870-845cec9d-301e-458a-92de-f6557c4a430f.png) If you try to substitute another value, it will work as we expect. ![image](https://user-images.githubusercontent.com/46720998/195396057-d303e7c2-8848-4821-aee7-54610a3f4c4c.png) --- If your logic needs to remove the watcher in some circumstances, here is an example how to do it ```js 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 [:small_orange_diamond: View source of current page](https://raw.githubusercontent.com/wiki/Crocoblock/jetformbuilder/Understanding-reactivity.md)