Skip to content

4.25 Script

4.25.1 Definition of JavaScript Code

The Formulario allows executing JavaScript code in two places:

  • In JavaScript actions, indicated by a parameter with the value "method."
  • In the onBeforeRender/onAfterRender attributes.

In both cases, the field can reference JavaScript in two ways:

  • Indicating a function name, which should be defined in a "script" tag on the same page or in an attached file, referenced with the src attribute of the script tag. The path in this case can be absolute or relative to the "forms" directory of the project.
  • Indicating a JavaScript script that will run in the context of the page.

With script tag on the same page:

<edit>
    <script>
        function method1() {
            ...
        }
        function method2() {
            ...
        }
        function method3() {
            ...
        }
    </script>
    <form>
        <input id="myInput" onBeforeRender="method2" onAfterRender="method3"/>
        ...
        <action type="js method="method1"/>
        ...
        <action method="vh.setWidgetValue('myInput',123.5);console.log(vh.widget('myInput'))"
        type="js" />
        ...
    </form>
</edit>

...
<edit>
    <script src="scripts/test.js"/>
    <form>
        <input id="myInput" onBeforeRender="method2" onAfterRender="method3"/>
        ...
        <action type="js method="method1"/>
        ...
        <action method="vh.setWidgetValue('myInput',123.5);console.log(vh.widget('myInput'))"
        type="js" />
        ...
    </form>
</edit>

In the file test.js:

function method1() {
    ...

function method2() {
    ...
}
function method3() {
    ...
}

4.25.2 Objects Available in the JavaScript Context

When entering a screen, a context is created for that page. All calls to functions and scripts share this context and are not eliminated until a new navigation is made.

Objects available in the JavaScript context:

  • console: access to the DevConsole.
  • ctx: instance of GlobalContext.
  • renderEnv: instance of RenderinEnvironment.
  • vh: instance of ScriptViewHelper.
  • eh: instance of ScriptEntityHelper, utility for handling entity data.
  • session: instance of HashMap that allows exchanging values between screens.

For example, this function lists the elements of the prueba table and modifies the description with the text "d_prueba" concatenated with the entity id.

function listTests(){
    console.log("listTests");

    var testRepo = ctx.get("repos").get("testRepo");
    var lstTest = testRepo.listAll();
    var i = 0;
    while(i != lstTest.size()){
        var entityTest = lstTest.get(i);
        entityTest.set("d_test","d_test_"+entityTest.get("test_id"));
        testRepo.save(entityTest);
        i++
    }
}

4.25.2.1 ScriptViewHelper (vh)

Provides quick access methods for objects in the rendering environment. Objects returned as collections are ScriptableList objects that allow applying functions to all elements with apply() and filter().

For example, in this function, we access the elements of a datalistitem by searching for them in the list of viewHolders, obtaining the ViewContext of each one, and making a "set" to modify the view value.

function printValues() { 
    // obtain all context holders from the view
    var viewContexts = vh.viewHolders();

    // filter to keep only datalistitems
    lst = viewContexts.filter(obj => obj.holderId.startsWith('datalistitemSampleUnit'));

    // obtain the view contexts ('view')
    lst = lst.apply(obj => obj.widgetContext.viewContext);

    // set in all contexts
    lst.apply(obj => obj.set('num_sample_unit','33'));
}

The ScriptViewHelper implements shortcuts to obtain different objects from the interface:

  • viewHolders(): list of WidgetContextHolders of the current view.
  • viewContexts(): list of ViewContexts of the current view.
  • viewContext(componentId): returns the ViewContext associated with the indicated component.
  • widgets(): complete list of statefulWidgets that can be found in the interface.
  • widget(componentId): returns the first widget found with the componentId
  • entities(): list of entities accessible from ContextHolders.

All these methods return lists of type ScriptableList, which include methods to implement the filter-map-reduce pattern: filter, filterFirst, map, flatMap, reduce, reduceSum, reduceCount, apply

widgets().filter(o => o.componentId.startsWith(‘sample_transect’) && o.getValue() != null ).map( w => w.getValue()).reduceSum()

4.25.3 Updating Widget Data

From JavaScript, you can modify view data directly by accessing the widget and invoking the setValue() method:

var widget= vh.widget(idcomponent); widget.setValue(123.0);

Or in one line with the shortcut:

vh.setWidgetValue(123.0);

But when accessing the widget, we have the option to modify the Android view properties from JavaScript.

widget.setBackgroundColor(color.red)

These operations do not require a screen refresh because we are modifying the component directly. However, if there is a case where we modify the object on which the component's data depends, for example, we modify the data in session or the data in the entity, and we want the view value to be re-rendered to update the component value, we can use the updateWidget('componentId') method;

For example, in this case, we have a button that will add 1 to a property stored in the session, and we want that updating the value will also update the displayed value in the field: