calcapp-iframe.js

Overview

The calcapp-iframe.js JavaScript library enables host pages to interact with embedded Calcapp apps. Use the library to:

Target audience

This library is designed for developers with JavaScript experience who need to integrate Calcapp apps into existing web applications. Most Calcapp authors won’t need this library, as Calcapp’s primary appeal is requiring only formula knowledge rather than traditional programming skills.

If you’re a programmer looking to integrate Calcapp apps with your company’s services, or if you know JavaScript and want to create more sophisticated integrations, this library provides the tools you need.

Getting started

Loading the library

Load the library from one of these URLs:

Important: Don’t self-host the library. We may update it as Calcapp evolves. Add the defer attribute to prevent the script from blocking page load:

<script src="https://connect.calcapp.net/calcapp-iframe.min.js"
        defer>
</script>

Browser compatibility

The library uses modern JavaScript features and requires a current web browser. We don’t support Internet Explorer.

Library initialization

The library sets window.calcappIframe as the main entry point. Use this object to retrieve values from embedded apps and manage iframe dimensions.

Quick example

To print the value of field named Field1, part of a screen named MainScreen, to your JavaScript console:

// Using async/await (recommended)
try {
  const value = await calcappIframe.getValue("MainScreen", "Field1");
  console.log("Value: ", value);
} catch (error) {
  console.error("Error: ", error);
}

// Using promises
calcappIframe.getValue("MainScreen", "Field1")
  .then(value => console.log("Value: ", value))
  .catch(error => console.error("Error: ", error));

API reference

The calcappIframe object provides these functions:

calcappIframe.getValue

Retrieves a single value from an embedded Calcapp app.

try {
  const value = await calcappIframe.getValue("MainScreen", "Field1");
  console.log("Value: ", value);
} catch (error) {
  console.error("Error: ", error);
}

Use getValues to retrieve multiple values efficiently.

Understanding Calcapp’s data structure

Apps store data in properties that belong to variables or calculations:

Variables include fields, text boxes, groups, buttons and navigators. Fields have a default property (their value) plus additional properties:

Number fields, text fields, switch fields and date and time fields support additional properties specific to their types. Similarly, navigators, text boxes and groups support their distinctive properties.

Calculations include all screens, which have properties like:

Top-level calculation (usually named App) includes properties like:

All properties are documented in our properties reference.

Important: Property names must start with a lowercase letter when used with this library. Use visible, not Visible.

Data type mapping

Calcapp data types map to JavaScript as follows:

Promise-based API

All functions return JavaScript Promise objects because communication with embedded apps is asynchronous. Apps run in iframe elements and the only way for a page embedding such apps to communicate with them is through message passing. Values cannot be returned directly (synchronously) and are only available at some unspecified point in the future.

The returned promise is resolved when the value becomes available, at which point your code can run. Handle success and errors like this:

try {
  const value = await calcappIframe.getValue("SomeScreen", "SomeField");
  console.log("Value: ", value);
} catch (error) {
  console.error("Error: ", error);
}

Examples

Get a field value:

try {
  const value = await calcappIframe.getValue("MainScreen", "Field1");
  console.log("Value: ", value);
} catch (error) {
  console.error("Error: ", error);
}

Check field visibility:

try {
  const isVisible = await calcappIframe.getValue("MainScreen",
                                                 "Field1",
                                                 "visible");
  console.log("Field visible: ", isVisible);
} catch (error) {
  console.error("Error: ", error);
}

Target specific app (when multiple apps are embedded):

If there are multiple apps embedded in a single page, you must identify which app to target. You can pass:

Example using an app alias:

try {
  const value = await calcappIframe.getValue("MainScreen",
                                             "Field1",
                                             null,
                                             "abc123");
  console.log("Value: ", value);
} catch (error) {
  console.error("Error: ", error);
}

Get user email from private app:

try {
  const email = await calcappIframe.getValue("App", null, "userEmailAddress");
  console.log("User email: ", email);
} catch (error) {
  console.error("Error: ", error);
}

Parameters

calcappIframe.getValue(calculationName,
                       variableName,
                       propertyName,
                       app)
calculationName
string
The name of the calculation which the identified variable or property belongs to. Screens are calculations.
variableName
string
(optional)
The name of the variable which the identified property belongs to. Fields, text boxes, buttons, groups and navigators are all variables. If this parameter is left undefined, the identified property is expected to reference a calculation property as opposed to a variable property.
propertyName
string
(optional)
The name of the property whose value should be retrieved. If this parameter is left undefined, the value of the default property is returned instead. For fields, the default property is the value of the field. The first character of a property name must be lower-case.
app
HTMLIFrameElement
or string
or number

(optional)
The app the value should be retrieved from. If this parameter represents an iframe element, the value is retrieved from the app hosted by said element. If this parameter represents the number n, the value is retrieved from the app hosted by the n-th iframe element in the document hosting an app written with Calcapp, in depth-first traversal order. If this parameter represents a string, this string is expected to be an alias of an app written with Calcapp, and the value is retrieved from the app hosted by an iframe element in the document referencing the app with the given alias. If this parameter is undefined and there is only a single iframe element in the document hosting an app written with Calcapp, the value is retrieved from this app. If this parameter is undefined and there are multiple iframe elements hosting apps written with Calcapp, an exception is thrown.
Returns
Promise
A promise which is resolved with the sought value or is rejected with an error message if there is a problem.
Throws
Error
  • If there are no iframe elements in the document hosting apps written with Calcapp.
  • If the given app parameter is a number and said number is greater than or equal to the number of iframe elements in the document hosting apps written with Calcapp.
  • If the given app parameter is a string and there is no iframe element in the document which hosts an app with an alias equal to the given parameter.
  • If the given app parameter is defined but is neither a number, nor a string, nor an HTMLIFrameElement element.

calcappIframe.getValues

Retrieves multiple values from an embedded Calcapp app in a single call. This is much more efficient than calling getValue multiple times.

try {
  const values = await calcappIframe.getValues([{
    calculationName: "MainScreen",
    variableName: "Field1"
  }, {
    calculationName: "MainScreen",
    variableName: "Field1",
    propertyName: "visible"
  }]);
  console.log("Field value: ", values[0]);
  console.log("Field visible: ", values[1]);
} catch (error) {
  console.error("Error: ", error);
}

This library communicates through message passing with the app hosted by an iframe element. As such, retrieving multiple values through this function is far more efficient than repeatedly invoking the getValue function.

Each array element specifies a value to retrieve using the same parameters as getValue. See the getValue documentation for details on Calcapp’s data structure.

Parameters

calcappIframe.getValues(soughtValues, app)
soughtValues
Array
An array of objects which hold information on a sought value. This object must contain a property named calculationName and can optionally contain properties named variableName and propertyName. These properties are identical to the calculationName, variableName and propertyName parameters given to the getValue function; refer to its documentation for more information. The resolved value of the returned promise corresponds to the array given here; refer to the documentation for the return value for more information.
app
HTMLIFrameElement
or string
or number

(optional)
The app the values should be retrieved from. If this parameter represents an iframe element, the values are retrieved from the app hosted by said element. If this parameter represents the number n, the values are retrieved from the app hosted by the n-th iframe element in the document hosting an app written with Calcapp, in depth-first traversal order. If this parameter represents a string, this string is expected to be an alias of an app written with Calcapp, and the values are retrieved from the app hosted by an iframe element in the document referencing the app with the given alias. If this parameter is undefined and there is only a single iframe element in the document hosting an app written with Calcapp, the values are retrieved from this app. If this parameter is undefined and there are multiple iframe elements hosting apps written with Calcapp, an exception is thrown.
Returns
Promise
A promise which is resolved with an array of the sought values or is rejected with an error message if there is a problem. The element at index n of the resolved array corresponds to the element at index n of the array given as the soughtValues parameter.
Throws
Error
  • If there are no iframe elements in the document hosting apps written with Calcapp.
  • If the given app parameter is a number and said number is greater than or equal to the number of iframe elements in the document hosting apps written with Calcapp.
  • If the given app parameter is a string and there is no iframe element in the document which hosts an app with an alias equal to the given parameter.
  • If the given app parameter is defined but is neither a number, nor a string, nor an HTMLIFrameElement element.

calcappIframe.subscribeToNewHeight

Subscribes to height change events from an embedded Calcapp app. Returns a function that, when called, cancels the subscription.

Height changes occur when:

For automatic iframe resizing, use manageHeight instead.

Example

const unsubscribe = calcappIframe.subscribeToNewHeight((newHeight,
                                                        iframe) => {
  console.log("New height: ", newHeight);
});

// Later, to stop listening:
unsubscribe();

Parameters

        calcappIframe.subscribeToNewHeight(listener, app)
listener
Function
A function which is invoked with the new height, in pixels, passed as its first parameter. The iframe element hosting the app written with Calcapp is passed as the second parameter.
app
HTMLIFrameElement
or string
or number

(optional)
The app whose events should be subscribed to. If this parameter represents an iframe element, the app hosted by this element is used as the subscription target. If this parameter represents the number n, the app hosted by the n-th iframe element in the document hosting an app written with Calcapp, in depth-first traversal order, is used as the subscription target. If this parameter represents a string, this string is expected to be an alias of an app written with Calcapp, and the app hosted by an iframe element in the document referencing the app with the given alias is used as the subscription target. If this parameter is undefined and there is only a single iframe element in the document hosting an app written with Calcapp, this app is used as the subscription target. If this parameter is undefined and there are multiple iframe elements hosting apps written with Calcapp, an exception is thrown.
Returns
Function
A function which, when invoked, ends the subscription.
Throws
Error
  • If there are no iframe elements in the document hosting apps written with Calcapp.
  • If the given app parameter is a number and said number is greater than or equal to the number of iframe elements in the document hosting apps written with Calcapp.
  • If the given app parameter is a string and there is no iframe element in the document which hosts an app with an alias equal to the given parameter.
  • If the given app parameter is defined but is neither a number, nor a string, nor an HTMLIFrameElement element.

calcappIframe.manageHeight

Automatically adjusts the iframe height to match the embedded app’s height. Returns a function that stops the automatic management when called.

The app typically changes its height in response to the user navigating to a new screen or entering a value in a field such that a different field is made visible.

This function uses a mutation observer to automatically stop watching the height of an app when the iframe element hosting it is removed.

Options

Configure behavior with an options object:

About extraHeight: Embedded apps and host pages communicate asynchronously. When the height of an app changes using an animation, this library animates the iframe element to match the app height. When the app becomes larger, the iframe element may lag behind the embedded app and momentarily not be large enough to fully contain it. As a result, a scrollbar may appear, only to disappear a split second later when the iframe element is properly sized.

To prevent this, iframe elements should be a number of pixels taller than the app. The extraHeight property adds these pixels to the app’s height. The default value is 16 pixels, which is appropriate for most apps. For a perfectly snug fit, set this value to zero.

Declarative usage

Add attributes to the iframe element for automatic setup:

<iframe src="..."
        calcapp-managed-height
        calcapp-managed-height-minimum="200"
        calcapp-managed-height-maximum="800"
        calcapp-managed-height-extra="20"></iframe>

Use these attributes for the corresponding options:

Use data- prefixes if needed: data-calcapp-managed-height, etc.

Note: When used declaratively, this function is called by this library in response to the DOMContentLoaded event firing on the window object. As such, declarative usage only works for iframe elements present when the page is initially loaded.

Example

const stopManaging = calcappIframe.manageHeight("abc123", {
  minimumHeight: 200,
  maximumHeight: 400,
  extraHeight: 50
});

// Later, to stop automatic height management:
stopManaging();

Parameters

calcappIframe.manageHeight(app, options)
app
HTMLIFrameElement
or string
or number

(optional)
The app whose events should be subscribed to. If this parameter represents an iframe element, the app hosted by this element is used as the subscription target. If this parameter represents the number n, the app hosted by the n-th iframe element in the document hosting an app written with Calcapp, in depth-first traversal order, is used as the subscription target. If this parameter represents a string, this string is expected to be an alias of an app written with Calcapp, and the app hosted by an iframe element in the document referencing the app with the given alias is used as the subscription target. If this parameter is undefined and there is only a single iframe element in the document hosting an app written with Calcapp, this app is used as the subscription target. If this parameter is undefined and there are multiple iframe elements hosting apps written with Calcapp, an exception is thrown.
options
Object
An object containing various options for this function, as described above.
Returns
Function
A function which, when invoked, stops watching the height.
Throws
Error
  • If there are no iframe elements in the document hosting apps written with Calcapp.
  • If the given app parameter is a number and said number is greater than or equal to the number of iframe elements in the document hosting apps written with Calcapp.
  • If the given app parameter is a string and there is no iframe element in the document which hosts an app with an alias equal to the given parameter.
  • If the given app parameter is defined but is neither a number, nor a string, nor an HTMLIFrameElement element.