Lowdefy
v3.23.3/Operators/_js/

_js

SECURITY WARNING: The _js operator executes JavaScript inside your Lowdefy app. Insecure code can expose your app or data. Since Lowdefy doesn't validate your JavaScript, make sure that you only load trusted code.
Environment: Client Only
(args: any[]): any

The _js operator executes a JavaScript function when the operator is evaluated. If used in a block, this function is called every time the Lowdefy engine checks if any block on the page should be updated. This function must be synchronous, and it is highly recommended that it is a pure function (it always returns the same result for the same input, and does not have side effects). Since it is called often it should also execute quickly, a slow operator will slow down the entire app. The JsAction action can be used to execute asynchronous code when an event is triggered.

To use the _js operator the following is needed:

  • Load the custom JavaScript into the app head tag. See the Custom Code section for more details.
  • In the custom JavaScript, pass the JavaScript operator function to the app using the window.lowdefy.registerJsOperator(name: string, operatorFunction: function) method.
  • A list of arguments can be passed to the JavaScript function which will be spread as function parameters.
  • The returned value of the custom JavaScript function will be the operator result.

Operator methods:

_js.{{ method_name }}

(args?: any[]): any

The _js.{{ method_name }} method evaluates the JavaScript function as registered using window.lowdefy.registerJsOperator(method_name: string, method: function). When passing a list of arguments to the JavaScript function, then list of arguments will be spread as function parameters.

The loaded JavaScript function must be a synchronous pure function. See the Custom JavaScript section for more detail on how to load custom JavaScript operators.

Examples

A custom JavaScript operator to calculate primes:
# lowdefy.yaml
name: make-me-primes
lowdefy: '3.23.3'
app:
  html:
    # This HTML will be appended to the head HTML tag in the Lowdefy app
    appendHead: |
      <script type="text/javascript">
        // Define the JavaScript function.
        function makePrimes(to) {
          return [...Array((to || 1)-1).keys()].map(i=>i+2).filter(n =>
          [...Array(n-2).keys()].map(i=>i+2).reduce((acc,x)=> acc && n % x !== 0, true));
        }
        // Register the JavaScript operator function.
        window.lowdefy.registerJsOperator('makePrimes', makePrimes);
      </script>
pages:
  - id: home
    type: PageHeaderMenu
    blocks:
      - id: num_of_primes
        type: NumberInput
        properties:
          title: Give me all the primes below?
      - id: primes
        type: Markdown
        properties:
          content:
            _nunjucks:
              template: |
                All primes below {{ num_of_primes }} is: {{ primes }}
              on:
                num_of_primes:
                  _state: num_of_primes
                primes:
                  # Use the custom JavaScript operator.
                  _js.makePrimes:
                    - _state: num_of_primes
_js.function to create a label.formatter function for an EChart block:

Create a JavaScript file which are hosted publicly. The public folder in your Lowdefy app makes this easy. Also check to register the custom operator using window.lowdefy.registerJsOperator.

// file: /public/getLabel.js
const getLabel = (levelTwo, levelThree, levelFour) => (param) => {
  var depth = param.treePathInfo.length;
  if (depth === 2) {
      return levelTwo;
  }
  else if (depth === 3) {
      return levelThree;
  }
  else if (depth === 4) {
      return levelFour;
  }
}
window.lowdefy.registerJsOperator('getLabel', getLabel);

Load the JavaScript by referencing it into the Lowdefy application HTML head tag.

// file: imports.html
<script type="text/javascript" src="/public/getLabel.js"></script>

Use the _js.getLabel operator

# file: lowdefy.yaml
name: my-chart
lowdefy: '3.23.3'
app:
  html:
    appendHead:
      _ref: imports.html # Loading html content into the application head tag.
pages:
  - id: home
    type: PageHeaderMenu
    blocks:
      - id: chart
        type: EChart
        properties:
          height: 600
          option:
            series:
              - radius:
                  - '15%'
                  - '80%'
                type: 'sunburst'
                sort: null
                emphasis:
                  focus: 'ancestor'
                data:
                  - value: 8,
                    children:
                      - value: 4,
                        children:
                          - value: 2
                          - value: 1
                          - value: 1
                          - value: 0.5
                      - value: 2
                  - value: 4
                    children:
                      - children:
                          - value: 2
                  - value: 4
                    children:
                      - children:
                          - value: 2
                  - value: 3
                    children:
                      - children:
                          - value: 1
                label:
                  color: '#000'
                  textBorderColor: '#fff'
                  textBorderWidth: 2
                  formatter:
                    _js.getLabel: # Use the getLabel function
                      - 'radial'
                      - 'tangential'
                      - 'other'
                levels:
                  - {}
                  - itemStyle:
                      color: '#CD4949'
                    label:
                      rotate: 'radial'
                  - itemStyle:
                      color: '#F47251'
                    label:
                      rotate: 'tangential'
                  - itemStyle:
                      color: '#FFC75F'
                    label:
                      rotate: 0