Skip to content

Creating and Using Ruleset Includes

Often, you may want to create common functions and processes that may be used from different rulesets, but only want to code once. For this, you might create a RulesetInclude.

A RulesetInclude is a document that contains JSON javascript to be included into Rulesets, as if it was written there directly. It is similar in concept to the C/C++ usage of the #include directive.

Editing a RulesetInclude

RulesetIncludes can be created from the template with id /form/94869c359bf4131553761097

RuleSetInclude2

Field Description
Name The key and descriptor of the RulesetInclude
Description A fuller description of the RulesetInclude, if required.
RSI Group A group name used to group RulesetIncludes, such as 'your-company-name' or 'system'
Include Script The actual code you wish to create and share to Rulesets.

Structure of a RulesetInclude script

The content of an include script may seem complicated at first, but basically it should follow the format:

object : {
    object-property-1 : value/object/function,
    object-property-2 : value/object/function,
    ...
}

For example, a very simple include might be

widgetFunctions : {

    version : '2018-09-07-B',

    rollDie : function() {
        var dieValue = Math.floor(Math.random() * 6) + 1;
        return dieValue;
    }

}

As for any JSON object, the different elements (value/object/function) on the same sibling level should be separated by comma.

You can define a number of root level objects, if you wish, providing they are separated by commas.

Referencing sibling functions in a RulesetInclude

Often we might want for one function within our RulesetInclude to use another function within the same RulesetInclude object.

Generally we can use the keyword this to reference the parent object, and thus utilise that sibling function.

However, this can sometimes change depending on the context we are in at the time, eg, within a callback function. A more robust method is to preset a variable within the function to be this at the beginning, and to use that as reference to the containing object, eg

insectService : {
    funcA : function() {
        return "caterpillar";
    },

    funcB : function() {
        var includeMain = this;

        return "Green " + includeMain.funcA();
    }
}

BEWARE -- this relies on the final usage referencing the function through the RulesetInclude's root level object; if the function has been assigned to a free floating function variable, neither this or the preset variable will work.

// Using the above myIncludeObject
var grubName = ft3.insectService.funcB();    // Okay - will work


var getGrubName = ft3.insectService.funcB;
var grubName = getGrubName();    // XXX This will fail, eg "includeMain.funcA is not a function"

A robust way of preventing, or highlighting this problem, is to include a self check in your RulesetInclude, ala

insectService : {
    name : 'insectService',      // give the main object a name property

    funcA : function() {
        return "caterpillar";
    },

    funcB : function() {
        var includeMain = this;

        // Do a check to make sure this is being called correctly
        if (!(includeMain.name === 'insectService')) {
            throw 'This function needs to be called as a child of "insectService"';
        }

        return "Green " + includeMain.funcA();
    }
}

Including a RulesetInclude in a Ruleset

To use a RulesetInclude in your Ruleset, simply write a #include line at the beginning of your Ruleset script, after the first open bracket ({). Reference the required RulesetInclude by its name, within double quotes.

Eg:

// RuleSet: MyRuleset
// Updated by: ...
{
#include "Widget Functions JS",
...

The Formbird application will take the content of that RulesetInclude, and copy it into the ruleset at that point where #include was called, at runtime.

Using the included RulesetInclude

To use the functions of your RulesetInclude, under a JayRule ruleset, simply reference the main object of your RulesetInclude via ft3 (= ntf.scope). Eg

var ft3 = ntf.scope; 

var widgetFunctionsVersion = ft3.widgetFunctions.version;

var diceRollNumber = ft3.widgetFunctions.rollDie();

If editing older JSON/Javascript Rulesets, ie those not using JayRule, you would use the main object, (assuming main has been set to this at the beginning of mainRule ).

var main = this;
...

var widgetFunctionsVersion = main.widgetFunctions.version;

var diceRollNumber = main.widgetFunctions.rollDie();

Alternative Usage

It is possible to omit the containing object altogether when creating a RulesetInclude, and just have the functions defined, eg

// RulesetInclude Script

rollDie : function() {
    var dieValue = Math.floor(Math.random() * 6) + 1;
    return dieValue;
}

The RulesetInclude functions can then be used as direct child functions of ft3, eg

var ft3 = ntf.scope; 

var diceRollNumber = ft3.rollDie();

The disadvantage here is that if for some reason other RulesetIncludes have a function of the same name, or a function is declared directly in the ruleset with the same name, one of the function declarations is going to override the other.