Skip to content

Ruleset Functions

Formbird Application Functions are those functions made available to rulesets from the Formbird application, and are used to interact with the Formbird document and data.

These functions are provided through the object ntf which is passed to all rulesets. They are provided in its property object scope. By convention, we assign ft3 to this object, so as to make later coding briefer.

By convention, we assign ft3 to ntf.scope early in a block of script,

var ft3 = ntf.scope;

ft3.enableField('customerName', false);

so we might use its member functions with the shorthand "ft3.function-name", rather than typing "ntf.scope.function-name". It would be quite valid to do away with ft3 and just use ntf.scope everywhere in your script; in this documentation though, we will be using ft3 by convention, so at least be aware of where it comes from.

ft3 can be considered the general portable toolbox that contains these functions (and others) we use in rules.

The following chapters describe each of those functions in full.

  • checkChecklistItem
  • createDocumentFromTemplate
  • enableField
  • findDocumentsByElastic
  • getConfiguration
  • getFilter
  • mandateField
  • openNewDocument
  • scheduleNewSystemAction
  • sendSMS
  • setFilter
  • showField
  • showNotification
  • updateDocument

There are also "library" or third party objects available from ft3: Later -- a date time handling library ModalService -- a modal dialog library * moment -- a date-time handling library


checkChecklistItem

Sets a checklist field item to checked or unchecked on the document. (client-side function)

Syntax

*ft3.checkChecklistItem('field-name', 'option-name', 'state'*);

Part Description
field-name name of the field on the document
option-name name of the checklist option to change
state values: true/false

Example

    ft3.checkChecklistItem('wingColours', 'blue', true);
    ft3.checkChecklistItem('wingColours', 'red', false);

createDocumentFromTemplate

(Applies to both client-side + server-side function)

Creates a new document according to a given template.

Syntax

*ft3.createDocumentFromTemplate(doc-info, templateID, userID, function(err,doc*) { ... });

Part Description
doc-info JSON object of the properties to write to the new document.
nb - do not include systemHeader information. This will be catered for by use of the templateID.
templateID the ID of the template to use to create the document.
userID the User ID to use for creation.
err error returned by process -- null if successful
doc the created document

Example

    var newDocInfo = {
            "name": "Jennifer",
            "age" : 23,
            "description" : "Here lies the messenger." 
            };
    var templateID = '5511e701d1e0d8d0a7cc5414';

    ft3.createDocumentFromTemplate(newDocInfo, templateID, ntf.user.documentId,
    function(err, doc) {
        if (err) {
            ntf.logger.error('Error creating document: ' + err);
        }
        else {
            ntf.logger.info('Document created: ' + doc.documentId);
        }
    });

See also

Function openNewDocument


enableField

(Applies to client-side rulesets)

Sets the enablement of a field on the document.

Syntax:

*ft3.enableField(field-name, state*)

Part Description
field-name name of the field on the document
state values: true, false

Example

ft3.enableField('establishmentDate', false);

// Disable field if document is closed
var flag = !(ntf.document.status === 'Closed');
ft3.enableField('status', flag);

Note

To enable fields on a parent document in the case that a child document is open, precede the field-name with "parentDoc", eg "parentDoc.lastName".

To enable fields on a child document in the case that a child document is open, precede the field-name with "childDoc", eg "childDoc.lastName".


findDocumentsByElastic

(Applies to server-side and client-side rulesets)

Function to make a query (ElasticSearch) and retrieve a "resultset" of documents.

Syntax

ft3.findDocumentsByElastic( query* , user-id , [options,] function( err , result ) { *

...

})

Part Description
query a structured ElasticSearch query
user-id documentId of the user, to enforce security of data visibility
options (optional); an object containing options; see below
err if an error occurred, contains the error
result an object containing the full ElasticSearch result structure.

options

The optional argument options can contain alternative options/switches to change the mode of the query.

Option Description
includeAllVersions Fetches all versions of the document.
Normally, only the current version of a document is fetched.
Value: true | false (default false)
includeDeleted Fetches deleted documents as well as undeleted ones.
Value: true
searchOfflineOnly (unverified)

ElasticSearch result size

This method has a default results limit of 50 documents.

The result returned will contain the full number of matching documents, (result.data.hits.total), but the actual returned documents will only number 50.

To change this, add a "size": n element to the ElasticSearch query. This will override the default size added by the appserver (see example).

Example

    ft3 = ntf.scope;
    ...

    var eqry = {
        'size' : 1000,
        'query': {'bool': {'filter' : [
            {'term': {'type' : 'insect'}},
            {'term': {'color' : 'blue'}}
        ]}}
    };

    // Modify from, size dynamically after the eqry statement
    eqry.from = 100;
    eqry.size = 500;
    eqry.sort = [{'commonName':'asc'}];

    ft3.findDocumentsByElastic(eqry, ntf.user.documentId, function(err, result) {
        if (err) {
            ntf.logger.info('Error: ' + err.message);
        } 
        else {
            var i;
            ntf.logger.info('# Total Matches in DB: ' + result.data.hits.total);
            ntf.logger.info('# Returned Results: ' + result.data.hits.hits.length);
            for (i=0;i < result.data.hits.hits.length;i++) {
                var doc = result.data.hits.hits[i]._source;
                ntf.logger.info('Blue Insect [' + i + ']: ' + doc.name);
            }
        }
    });
    return;

Tip

Use the javascript map function for arrays to convert an ElasticSearch result to an array of documents:

var docs = result.data.hits.hits.map(function(hit) { return hit._source });

Result topology

The result object returned by this function is a full ElasticSearch result structure, so may be quite arcane to dissect. The following properties are the most useful ones for our purposes.

Property Description
result.data.hits.total Number - The full count of matching documents in the database.
This is not the same as the count of documents returned, which may be limited by the size property of the submitted query.
result.data.hits.hits Array of objects representing each fetched document.
result.data.hits.hits[n]._source The full document found on the nth hit of the hits array

Sample ElasticSearch result

{
  "statusCode": 200,
  "data": {
    "took": 2,
    "timed_out": false,
    "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
    },
    "hits": {
      "total": 1,
      "max_score": 0,
      "hits": [
        {
          "_index": "gobble",
          "_type": "documents",
          "_id": "584f25cf22478a32c64c440e",
          "_score": 0,
          "_source": {
            "event": "OnLoad",
            "systemHeader": {
              "summaryName": "Dexwise Spider - OnLoad",
              "serverUpdatedDate": "2017-12-19T04:14:14.207000+00:00",
              "systemType": "document",
              "excludeGeneralSearch": false,
              "templateId": "224bc62858d73ce57a9cb85e",
              "serverDate": "2017-03-07T05:28:24.514Z",
              "currentVersion": true,
              "versionId": "12e837f0-e473-11e7-a189-39e2cecb7850",
              "createdWith": "224bc62858d73ce57a9cb85e",
              "summaryDescription": "RuleSet for processing of template Spider (et al), OnLoad event.",
              "createdBy": "5476946bb671fc07650beed1",
              "createdDate": "2017-12-19T04:14:14.767000+00:00",
              "serverCreatedDate": "2017-12-19T04:14:14.207000+00:00",
              "previousVersionId": "91c0bd80-e46f-11e7-a189-39e2cecb7850"
            },
            "businessType": "RuleSet",
            "flagInPreSave": true,
            "syncTemplateRule": true,
            "versionTag": "20171018A",
            "ruleSetGroup": "dexwise",
            "addSecurityKeys": [
              {
                "name": "DA-Dexwise-Rulesets",
                "documentId": "b8d9eeb0-02f6-11e7-965b-4799f2a39188"
              }
            ],
            "objectEventDescriptor": "Dexwise Spider - OnLoad",
            "template": [
              {
                "name": "Spider",
                "documentId": "c6a8eb50-c029-11e6-9eea-13b66331d97f"
              }
            ],
            "vtn": "system.ruleset",
            "appTags": [
              "system",
              "ruleset"
            ],
            "documentId": "abbff110-c0b7-11e6-9eea-13b66331d97f"
          }
        }
      ]
    }
  },
  "filter": false
}

findVersionDocument

(server-side)

Retrieves a version of a document by its versionId.

Syntax

*ft3.findVersionDocument(versionId, userId, function(err, document*) {
    ...
})

Part Description
versionDoc The document object returned from the function.
versionId The versionId of the document to retrieve.
userId The user id to pass. Should be ntf.user.documentId
err Error object returned from the function if it fails.
document The document object returned from the function.

Example

    ntf.logger.info('Running findVersionDocument');
    ft3.findVersionDocument('3624da40-fd08-11e7-b927-e74a925fc9ea', ntf.user.documentId, function(err, document) {
        if (err) {
            ntf.logger.error(err);
        }
        else {
            ntf.logger.info('Retrieved document version: ' + document.systemHeader.versionId); 
            ntf.logger.info('_id: ' + document._id);
        }
        callbackContinue(ntf);
    });

getConfiguration

(server-side function)

Function to get configuration entries, either from the configuration document in the database, or from Config.js in the file system for fieldtec-web.

(nb - scope of fetchable configuration may have changed since this document)

Syntax

value = *ft3.getConfiguration(key*)

Part Description
value the variable to receive the value
key the key of the configuration item to fetch

Example

    // Get configuration from main configuration document
    var templateId = ft3.getConfiguration("clientConfiguration.ruleSetIncludeTemplateId");

    ntf.logger.info('Env = ' + env1 );
    ntf.logger.info('RSInc TID = ' + templateId);

getFilter

Function to return the ElasticSearch query filter used by an instance of a grid or related field component.

(client-side function)

Syntax

*ft3.getFilter(field-name*)

Part Description
field-name the name of the field to interrogate, single-quoted

Example

    var oldFilter = ft3.getFilter('gridWidgets');

See Also

setFilter (link tba)


mandateField

Makes a field on the document mandatory or not mandatory. When mandatory, the field must have a non-blank value for the document to be saved.

(client-side function)

Syntax

ft3.mandateField( field-name* , state )*

Part Description
field-name name of the field on the document
state whether to make the field mandatory, values true, false

Example

ft3.mandateField('status', true);
ft3.mandateField('widgetColor', false);

Note

To mandate fields on a parent document in the case that a child document is open, precede the field-name with "parentDoc", eg "parentDoc.lastName".

To mandate fields on a child document in the case that a child document is open, precede the field-name with "childDoc", eg "childDoc.lastName".


ModalService (object)

A function Object for presenting message dialogs to the user.

(client-side function)

Warning
The following may have minor inaccuracies, due to the underlying 3rd party library changes

Syntax

*ft3.ModalService.openModal(args*)

ft3.ModalService.openModal(options)*
.then(
    
function confirmFunction() { .... }
    
function dismissFunction(dismissType) { ... }
*
)

ft3.ModalService.swal(args) !!! AVOID USING IN NEW RULESETS

Part Description
args Arguments for the openModal function
options An object containing options for the dialog
confirmFunction The function to occur on the user clicking OK button.
dismissFunction The function to occur on the user dismissing or cancelling the dialog.
dismissType Whether the dialog was dismissed by clicking cancel, clicking outside the dialog, or escaping
Values: 'cancel', 'overlay','close','timer'

Options

(From SweetAlert documentation - some discrepancies may occur)

Options marked "Definite" are envisaged to be supported for the full term of the component development in future. Others may also be continued on, and this table is subject to change re those.

Option Definite Default value Description
title x null The title of the modal, as HTML. It can either be added to the object under the key "title" or passed as the first parameter of the function.
titleText x null The title of the modal, as text. Useful to avoid HTML injection.
text x null A description for the modal. It can either be added to the object under the key "text" or passed as the second parameter of the function.
html x null A HTML description for the modal. If "text" and "html" parameters are provided in the same time, "text" will be used.
type x null The type of the modal. SweetAlert2 comes with 5 built-in types which will show a corresponding icon animation: warning, error, success, info and question. It can either be put in the array under the key "type" or passed as the third parameter of the function.
input x null Input field type, can be text, email, password, number, tel, range, textarea, select, radio, checkbox, file and url.
width x '500px' Modal window width, including paddings (box-sizing: border-box). Can be in px or %.
padding x 20 Modal window padding.
background x '#fff' Modal window background (CSS background property).
customClass null A custom CSS class for the modal.
timer x null Auto close timer of the modal. Set in ms (milliseconds).
animation true If set to false, modal CSS animation will be disabled.
allowOutsideClick x true If set to false, the user can't dismiss the modal by clicking outside it.
allowEscapeKey x true If set to false, the user can't dismiss the modal by pressing the Escape key.
allowEnterKey x true If set to false, the user can't confirm the modal by pressing the Enter or Space keys, unless they manually focus the confirm button.
showConfirmButton x true If set to false, a "Confirm"-button will not be shown. It can be useful when you're using custom HTML description.
showCancelButton x false If set to true, a "Cancel"-button will be shown, which the user can click on to dismiss the modal.
confirmButtonText x 'OK' Use this to change the text on the "Confirm"-button.
cancelButtonText x 'Cancel' Use this to change the text on the "Cancel"-button.
confirmButtonColor x '#3085d6' Use this to change the background color of the "Confirm"-button (must be a HEX value).
cancelButtonColor x '#aaa' Use this to change the background color of the "Cancel"-button (must be a HEX value).
confirmButtonClass null A custom CSS class for the "Confirm"-button.
cancelButtonClass null A custom CSS class for the "Cancel"-button.
closeOnConfirm x true Whether to close the dialog on clicking "Confirm"-button.
closeOnCancel x true Whether to close the dialog on clicking "Cancel"-button
reverseButtons x false Set to true if you want to invert default buttons positions ("Confirm"-button on the right side).
focusCancel false Set to true if you want to focus the "Cancel"-button by default.
showCloseButton false Set to true to show close button in top right corner of the modal.
showLoaderOnConfirm false Set to true to disable buttons and show that something is loading. Useful for AJAX requests.
preConfirm null Function to execute before confirm, should return Promise, see usage example.
imageUrl x null Add a customized icon for the modal. Should contain a string with the path or URL to the image.
imageWidth x null If imageUrl is set, you can specify imageWidth to describes image width in px.
imageHeight x null Custom image height in px.
imageClass x null A custom CSS class for the customized icon.
inputPlaceholder x '' Input field placeholder.
inputValue x '' Input field initial value.
inputOptions {} or Promise If input parameter is set to "select" or "radio", you can provide options. Object keys will represent options values, object values will represent options text values.
inputAutoTrim x true Automatically remove whitespaces from both ends of a result string. Set this parameter to false to disable auto-trimming.
inputAttributes {} HTML input attributes (e.g. min, max, autocomplete, accept), that are added to the input field. Object keys will represent attributes names, object values will represent attributes values.
inputValidator null Validator for input field, should return Promise, see usage example.
inputClass null A custom CSS class for the input field.
progressSteps [] Progress steps, useful for modal queues, see usage example.
currentProgressStep null Current active progress step. The default is swal.getQueueStep()
progressStepsDistance '40px' Distance between progress steps.
onOpen null Function to run when modal opens, provides modal DOM element as the first argument.
onClose null Function to run when modal closes, provides modal DOM element as the first argument.

Example 1

    ft3.ModalService.openModal('Test Message Title', 'This is a test of the button functionality in ruleset script.', 'success');

Example2

    ft3.ModalService.openModal({
      title: 'Are you sure?',
      text: "You won't be able to revert this!",
      type: 'warning',
      showCancelButton: true,
      confirmButtonColor: '#3085d6',
      cancelButtonColor: '#d33',
      confirmButtonText: 'Yes, delete it!',
      cancelButtonText: 'No, cancel!'
    })
    .then(
        function confirmFunction () {
          ft3.ModalService.openModal(
            'Deleted!',
            'Your imaginary file has been deleted.',
            'success'
          );
        }, 
        function dismissFunction(dismiss) {
          // dismiss can be 'cancel', 'overlay',
          // 'close', and 'timer'
          if (dismiss === 'cancel') {
            ft3.ModalService.openModal(
              'Cancelled',
              'Your imaginary file is safe :)',
              'error'
            );
          }
        }
    );

Example 3 (old style using .swal)

ft3.ModalService.swal(
    {
        title:'Confirm Work Order Cancellation',
        type:'warning',
        showCancelButton:true,
        confirmButtonColor:'#DD6B55',
        confrmButtonText:'OK',
        cancelButtonText:'Cancel',
        closeOnConfirm:true,
        closeOnCancel:true
    },
    function(confirmed) {
        if (confirmed) {
            ntf.logger.info('Work Order cancelled. ' + confirmed);
        }
        else  {
            ntf.logger.info('Cancellation cancelled :/ ' + confirmed);
            ntf.document.cancelled = false;
        }
    }

Note

ModalService.openModal is based on the third party library SweetAlert.


openNewDocument

Opens a new document of a given template, in the current or a new window.

(client-side function)

Syntax

ft3.openNewDocument( template-id* , initial-values , new-window , callback(err) )*;

where |Part|Description| |---|---| |template-id |id of the template to open| |initial-values |JSON structure of initial field values| |new-window |indicates whether to use a new window, or the current one| || values: true for new window/tab; false for current window| |callback |function to call when operation has completed|

Example

       var TPL_ID = 'b62410d1e601a95aacdb9c6f';
       var initialValues = {
            'genus'   : 'Cicadidae',
            'species' : 'Exuviae',
            'commonName' : 'Cicada'
       };

       ft3.openNewDocument(TPL_ID, initialValues, 'yes', function(err){
            if (err) {
                ntf.logger.info('Error opening new document: ' + err.message);
            }
            else {
                ntf.logger.info("New document opened.");            
            }
       });

Note

For a server side version, see createDocumentFromTemplate.


scheduleNewSystemAction

Schedules a System Action to occur in the future, which runs a RuleSet.

(server-side function)

Syntax

ft3. scheduleNewSystemAction( document , checkDate , objectEventDescriptor , ​ user , function( systemActionDocument , err ))

Part Description
document the document object being processed
checkDate the date-time the system action should run
objectEventDescriptor the Object Event Descriptor of the ruleset
user the user to use for the system action
systemActionDocument the newly created system action document
err any error that occurred; null if successful

Example

        var nbrMinutesToWait = 15;
        var checkDate = new Date();
        var templateId = '944e24fb8cf0a381942b3e77';

        checkDate = ft3.moment().add(nbrMinutesToWait, 'minute');

        // Create a stripped down version of the document to pass
        var docToPass = {
            documentId : ntf.document.documentId,
            note : 'document truncated - query for current'
        };

        ft3.scheduleNewSystemAction(docToPass, checkDate, 'Task-Direct-LoneOvertime',
                ntf.user, function(err, doc) {
            if (err) {
                ntf.logger.info(err.message);
            }
            else if (doc) {
                logger.info('New system action created: ' + doc.documentId);
            }
            ...
        });
        return;

Tip

When passing the document to this method, remove most of the document content and leave just the documentId. It is most probably important for the target ruleset to query for the current document from the database anyway, using documentId.

This will avoid any issues with using an out of date version of the document in the target ruleset, as ntf.document received by the ruleset will be as was passed when this function was called, not automatically what is current in the database.

var docToPass = {
  documentId : ntf.document.documentId,
  note : 'This document is truncated to just the documentId -- query for current.'
};

ft3.scheduleNewSystemAction(docToPass, checkDate, 'Task-Direct-LoneOvertime', ntf.user, function(err, doc) { ...

sendSMS

Function to send an SMS message.

Requires that SMS service has been configured on the target environment's server.

(server-side function)

Syntax

ft3.sendSMS( target-number* , message , function( err , result ) { ... })*

Part Description
target-number mobile number to send to
message text to send
err if an error occurred, contains the error message
result if successful, result of the sending (details tba)

Example

        if (
            !ntf.hasRun.smsOwner    
        ) {
            ft3.sendSMS('0477003434', 'Spider ' + ntf.document.commonName + ' changed', 
            function(err, result) {
                if (err) {
                    ntf.logger.error('Error on sendSMS: ' + err);
                }
                else {
                    ntf.logger.info('SMS sent');
                }
            });
            ntf.hasRun.smsDexter = true;
        }

setFilter

Sets the ElasticSearch query filter on an instance of ft-grid, ft-related-document, and other field types.

(client-side function)

Syntax

ft3.setFilter( field-name* , new-filter )*

Part Description
field-name the name of the field whose filter is to set
new-filter a string or JSON object containing a new elasticsearch query

Applies to

The setFilter function applies to:

  • ft-grid, or similar custom grid components
  • ft-related-document
  • ft-address-map

Example

    var oldFilter = ft3.getFilter('gridWidgets');

    var newFilter = {'query':{'bool':{'filter':[{'match':{'color':'turquoise'}}]}}}; 

    ft3.setFilter('gridWidgets', newFilter);

See Also

getFilter


showField

Shows or hides a field on the document.

(client-side function)

Syntax

ft3.showField( field-name* , state )*;

Part Description
field-name name of the field on the document
state whether to show the field, values: true, false

Note

To show/hide fields on a parent document in the case that a child document is open, precede the field-name with "parentDoc", eg parentDoc.lastName.

To show/hide fields on a child document in the case that a child document is open, precede the field-name with "childDoc", eg childDoc.lastName.


showNotification

Shows a notification message that displays in the top right corner of the page.

(client-side function)

Syntax

ft3.showNotification( message* , status )*;

Part Description
message text to display
status mode/state of the notification
values: 'error', 'info', 'success', "warning', 'forbidden'

updateDocument

Function to update a document.

(client & server-side function)

Syntax

ft3.updateDocument( doc-id* , change , *user-id, function( err* , doc* ) {...});

Part Description
doc-id documentId of the document to update
change JSON of the change to perform
user-id documentId of the user
err if an error occurred, contains the error message
doc if successful, the final document

WARNING

Using updateDocument within a PostSave ruleset on the same document can result in a runaway process where the document keeps saving over and over ad infinitum.

Preferably, move any such changes to PreSaveServer where the ntf.document object can still be modified normally, without needing to call updateDocument.

If it is necessary to still use it in PostSave, then use the PostSaveLoopPrevention method to update the document.

See Preventing PostSave Looping (link tba)

Example

    var change = {
        'saDateMark' : new Date()
    };

    ft3.updateDocument(ntf.document.documentId, change, ntf.user.documentId, 
    function(err, doc) {
        if (err) {
            ntf.logger.error('Error in updateDocument: ' + err);
        }
        else {
            ntf.logger.info('Document updated successfully.');
        }
        ntf.hasRun.updateDateMark = true;
        callback();
    });
    return;