The Javascript Point allows you to add Javascript code to your sessions which can be executed when a user clicks a button or when one of the Session Lifecycle callbacks has occurred. With a basic understanding of the Javascript programming language, this point can be used to perform advanced calculations or other pre-processing changes to your session data.
Javascript is an easy-to-learn programming language and there is a helpful and active online community that can help you to get started with learning the language or jumping straight in with working samples of code. Here are some links that may help you get started:
In order to write Javascript, we recommend that you write your javascript code using one of the following tools. The basic editors should be enough for simple javascript but if you would like more advanced features then the advanced editors might be more suitable.
The javascript point can be configured in the Mobile Data Anywhere Designer to specify the display mode, button title and the javascript code to be executed. Below is an example of the properties window for a Javascript point, opened in the Mobile Data Anywhere Designer.
The Display Mode for a Javascript Point can be one of two options; No Interface or Just a Button. When No Interface is selected, the javascript point won’t be appear in the session on the mobile application. The javascript will be executed using the session lifecycle and point callbacks. When Just a Button is selected, the javascript point will appear as a button in the session. The button title setting will be used to customise the text that is displayed on this button.
The Javascript Code section is where you can add javascript code. You can import javascript from an existing javascript file using the Import .js file button.
In order to improve and add new functionality to the Javascript point, certain callbacks, parameters and other features will be introduced in new versions of the javascript implementation. These changes will only be available on devices that have installed a Mobile Data Anywhere app with the required javascript version. The table below shows which app version is required in order to use the features of a particular javascript version.
To determine which version of the app you have installed on a device, please refer to the guide on Installing Updates via The Settings Page .
Javascript Version | Apple iOS devices | Google Android devices |
---|---|---|
1.2 | Mobile Data Anywhere 1.1.44+ | Mobile Data Anywhere 1.1.55+ |
1.1 | Mobile Data Anywhere 1.1.41+ | Mobile Data Anywhere 1.1.43+ |
1.0 | All prior versions | All prior versions |
Javascript Version | Changes |
---|---|
1.2 |
|
1.1 |
|
If you want to use a feature from a new javascript version but still want to support previous javascript versions then you will need to use javascript version checking. See below for an example or download the Javascript Device Information sample project .
The example below shows how to check if the device supports javascript 1.1 or greater
x={
onSessionStart: function() {
var changes = {};
if (typeof javascriptVersion !== "undefined" && javascriptVersion >= 1.1) {
// Compatible javascriptVersion
changes["supportedVersion"] = 1;
printObject(deviceInformation); // Requires javascriptVersion 1.1+
} else {
// Legacy javascriptVersion
changes["supportedVersion"] = 0;
return changes;
}
// Requires javascriptVersion 1.1+
changes["javascriptVersion"] = javascriptVersion.toString();
changes["systemPlatform"] = systemPlatform;
changes["app"] = deviceInformation["app"];
changes["appName"] = deviceInformation["appName"];
changes["appVersion"] = deviceInformation["appVersion"];
changes["appBuild"] = deviceInformation["appBuild"];
changes["deviceModel"] = deviceInformation["deviceModel"];
changes["deviceSystem"] = deviceInformation["deviceSystem"];
changes["deviceVersion"] = deviceInformation["deviceVersion"];
return changes;
}
}
Javascript alert and confirm dialogs can be displayed on a device to provide the user with a simple message or to present a question and wait for a response.
There are two implementations available for javascript dialogs however the legacy dialogs are no longer supported and can cause issues for Apple devices running iOS 11 or greater. If you wish to use the app on iOS 11+ devices, please ensure the app is updated to the latest version and that the javascript uses the new javascript dialogs.
The new javascript dialogs are only available in recent versions of the Mobile Data Anywhere app. If you are unable to update to the latest version of the app or require a period to transition then you can use javascript compatibility checking to use the legacy dialogs for older version. Please see the Javascript Versions and Availability for more details.
An alert dialog allows you to display a message to the user with a single 'OK' button that can be pressed to dismiss the message.
Description:
The example below shows how an alert dialog can be used to display a message, wait for the user to close the alert and then save changes back to the session. This uses the onButtonPress callback to execute the javascript that displays the dialog and then it uses the onAlertClosed callback to handle the user's response to the alert dialog. |
x={
onButtonPress: function() {
var changes = { "alternativeAlertStatus": "Waiting for user to close alert." };
this.alertDialog('A message displayed using alertDialog()');
// NOTE: Unlike legacy javascript dialogs, the new dialogs do not pause javascript execution.
// Any code after calling this.alertDialog will continue to be executed.
// This example demonstrates how you can save a value to the session while waiting for the
// user to finish responsding to the dialog.
return changes;
},
onAlertClosed: function() {
// This will execute after the user has pressed the OK button to dismiss the alert.
var changes = { "alternativeAlertStatus": "Alert has closed." };
return changes;
}
}
Legacy Javascript Dialogs are not supported on recent Apple iOS versions (iOS 11+). Please use the new Javascript Dialogs if you wish to deploy projects to devices running iOS 11 or greater.
x={
onButtonPress: function() {
var changes = { "standardAlertStatus": "Waiting for user to close alert." };
alert('A message displayed using legacy alert()');
// NOTE: This will not execute until the user has dismissed the displayed alert.
changes["standardAlertStatus"] = "Alert was closed";
return changes;
}
}
The new javascript alert dialog has an optional parameter for you to pass in a dictionary of custom parameters. This can be useful for passing in data which can then be retrieved in the onAlertClosed callback . You can then continue processing the data with the user's response to the alert and then save any changes back to the session. This functionality is only available in the New Javascript Dialogs and is not available in the Legacy Javascript Dialogs.
This example is also available in the Javascript Sample Dialogs project which can be downloaded or imported into your account at the bottom of this page .
Description:
This example shows how custom parameters can be passed into an alert dialog and then retrieved in
the
onAlertClosed callback
.
The javascript is triggered when the
Selection Point
with ID
This example demonstrates two ways of retrieving the value of the point that changed. The
onPointValueChanged callback
was updated to provide the
|
x={
onPointValueChanged: function(pointId, pointValue) {
if(pointId == "onetwothree") {
var isLegacyVersion = false;
if(typeof javascriptVersion === "undefined" || javascriptVersion < 1.1) {
// Legacy support
// Version 1.1 added the pointValue parameter to the onPointValueChanged callback.
// If using an older version of the app with an older javascript version, retreive
// the pointValue the another way.
isLegacyVersion = true;
pointValue = this.project.session['onetwothree'];
}
if (!pointValue) {
// If the value is empty, undefined, null, untruthy... don't show an alert.
return { "alertWithIdentifierStatus": "Deselected.", "alertIdentifier": "" };
}
var customParameters = { "myAlertId": pointValue };
if (isLegacyVersion) {
return { "alertWithIdentifierStatus":"Update the Mobile Data Anywhere app to use the new javascript alerts."};
} else {
this.alertDialog("Alert with ID:" + pointValue, customParameters);
}
return;
}
},
onAlertClosed: function(customParameters) {
var thisAlertId = customParameters["myAlertId"];
return { "alertWithIdentifierStatus": "The alert with id " + thisAlertId + " has closed.", "alertIdentifier":thisAlertId };
}
}
A confirm dialog can be used to present a question to the user with two responses; OK and Cancel.
Description:
The example below shows how a confirm dialog can be used to display a question, wait for the user to press OK or Cancel and then save changes back to the session. This example uses the onButtonPress callback to execute the javascript that displays the dialog and then it uses the onConfirmClosed callback to handle the user's response to the confirm dialog. |
x={
onButtonPress: function() {
var changes = { "alternativeConfirmStatus": "Waiting for user to close confirm dialog." };
this.confirmDialog('A question displayed using a confirmDialog().Do you want to confirm or cancel?');
// NOTE: Unlike standard javascript dialogs, the alternative dialogs do not pause javascript execution.
// Any code after calling this.alertDialog will continue to be executed.
// This example demonstrates how you can save a value to the session while waiting for the
// user to finish responsding to the dialog.
return changes;
},
onConfirmClosed: function(response) {
// This will execute after the user has pressed either confirm/cancel on the confirm dialog.
if (response) {
return { "alternativeConfirmStatus": "OK was pressed." };
} else {
return { "alternativeConfirmStatus": "Cancel was pressed." };
}
}
}
Legacy Javascript Dialogs are not supported on recent Apple iOS versions (iOS 11+). Please use the new Javascript Dialogs if you wish to deploy projects to devices running iOS 11 or greater.
x={
onButtonPress: function() {
var changes = { "standardConfirmStatus": "Waiting for user to close confirm dialog." };
if (confirm('A question displayed using legacy confirm().Do you want to confirm or cancel?')) {
changes = { "standardConfirmStatus": "OK was pressed." };
} else {
changes = { "standardConfirmStatus": "Cancel was pressed." };
}
// NOTE: Standard javascript dialogs will pause javascript execution.
// Any code after calling alert() or confirm() will only continue after the user has responded.
return changes;
}
}
The new javascript confirm dialog has an optional parameter for you to pass in a dictionary of custom parameters. This can be useful for passing in data which can then be retrieved in the onConfirmClosed callback . You can then continue processing the data with the user's response to the confirm and then save any changes back to the session. This functionality is only available in the New Javascript Dialogs and is not available in the Legacy Javascript Dialogs.
This example is also available in the Javascript Sample Dialogs project which can be downloaded or imported into your account at the bottom of this page .
Description:
This example shows how custom parameters can be passed into a confirm dialog and then retrieved in
the
onAlertClosed callback
. If the OK button is pressed, the confirm ID that is passed in as a custom parameter will be saved
to the edit point called
This example demonstrates two ways of retrieving the value of the point that changed. The
onPointValueChanged callback
was updated to provide the
|
x={
onPointValueChanged: function(pointId, pointValue) {
if(pointId == "fourfivesix") {
var isLegacyVersion = false;
if(typeof javascriptVersion === "undefined" || javascriptVersion < 1.1) {
// Legacy support
// Version 1.1 added the pointValue parameter to the onPointValueChanged callback.
// If using an older version of the app with an older javascript version, retreive
// the pointValue the another way.
isLegacyVersion = true;
pointValue = this.project.session['fourfivesix'];
}
if (!pointValue) {
// If the value is empty, undefined, null, untruthy... don't show an alert.
return { "confirmWithIdentifierStatus": "Deselected.", "confirmIdentifier": "" };
}
var customParameters = { "myConfirmId": pointValue };
if (isLegacyVersion) {
return { "confirmWithIdentifierStatus":"Update the Mobile Data Anywhere app to use the new javascript alerts."};
} else {
this.confirmDialog("Confirm with ID:" + pointValue, customParameters);
}
return;
}
},
onConfirmClosed: function(response, customParameters) {
var thisConfirmId = customParameters["myConfirmId"];
if (response) {
return {
"confirmWithIdentifierStatus": "Confirmed id: " + thisConfirmId,
"confirmIdentifier":thisConfirmId
};
} else {
return { "confirmWithIdentifierStatus": "Cancelled id: " + thisConfirmId };
}
}
}
Javascript code can be executed by implementing a javascript callback within a Javascript point. The callbacks are triggered under various scenarios such as when a session is started or finished. The following callbacks are available. Please note that some callbacks and some callback parameters are only available on the most recent version of the Mobile Data Anywhere app. If you are unable to ensure all your devices are running the latest version of the app, please see the Javascript Versions and Availability section.
Callback | Usage | Availability |
---|---|---|
onButtonPress |
onButtonPress()
|
1.0 |
onSessionStart |
onSessionStart()
|
1.0 |
onSessionFinish |
onSessionFinish()
|
1.0 |
onProjectDatabaseChanged |
onProjectDatabaseChanged(project)
|
1.0 |
onPointValueChanged |
onPointValueChanged(pointId)
|
1.0 |
onPointValueChanged(pointId, pointValue)
|
1.1 | |
onAlertClosed |
onAlertClosed(customParameters)
|
1.1 |
onConfirmClosed |
onConfirmClosed(response, customParameters)
|
1.1 |
The onButtonPress function will only be executed if the javascript point’s display mode is set to Just a Button which will display a button on the screen, on the mobile application. When this button is pressed, the onButtonPress function will be executed.
Usage | Availability |
---|---|
onButtonPress()
|
1.0 |
x={
onButtonPress: function()
{
var changes = {};
// Setup a variable to store the number of times the
// button is pressed.
if (window.pressedCount == null) {
window.pressedCount = 0;
}
// Each time this button is pressed, we increment the count by one.
window.pressedCount = window.pressedCount + 1;
// Update EditPoint1's value with a message.
changes['EditPoint1'] = "Pressed " + window.pressedCount + " times.";
return changes;
}
}
This function will be executed when a project’s session list has changed. This includes changes such as a new session being finished or a session being sent, duplicated or deleted. This function has a parameter called project which will be the name of the project that was changed. This could be the currently open project or could be another project such as a sub project. The project parameter can be used to handle the event for specific projects.
Usage | Availability |
---|---|
onProjectDatabaseChanged(project)
|
1.0 |
Parameter | Type | Description | Availability |
---|---|---|---|
project | string | The filename of the project that was updated. | 1.0 |
x={
onProjectDatabaseChanged: function(project)
{
var changes = {};
changes['EditPoint1'] = "Project " + project + " was updated!";
return changes;
}
}
This function will be executed when any point’s value is updated. This function has a parameter key which will be the ID of the point that changed. This parameter can be used to handle the event for specific points.
Usage | Availability |
---|---|
onPointValueChanged(pointId)
|
1.0 |
onPointValueChanged(pointId, pointValue)
|
1.1 |
Parameter | Type | Description | Availability |
---|---|---|---|
pointId | string | The ID of the point that was updated. | 1.0 |
pointValue | string | The new value of the point that was updated. | 1.1 |
x={
onPointValueChanged: function(pointId, pointValue) {
if(typeof javascriptVersion === "undefined" || javascriptVersion < 1.1) {
// Legacy support: pointValue will be undefined for javascript versions prior to 1.1
pointValue = this.project.session[pointId];
}
var newValueForEditPoint1 = "Point " + pointId + " has been updated with new value: " + pointValue;
return { 'EditPoint1': newValueForEditPoint1 };
}
}
This function will execute when an alert dialog is closed. This will not occur if using the legacy javascript alert dialogs which are no longer supported.
Usage | Availability |
---|---|
onAlertClosed(customParameters)
|
1.1 |
onAlertClosed: function(customParameters) {
var aCustomParameter = customParameters["aCustomParameter"];
var changes = {};
changes['EditPoint1'] = "An alert closed with custom parameter " + aCustomParameter;
return changes;
}
This function will execute when a confirm dialog is closed. This will not occur if using the legacy javascript confirm dialogs which are no longer supported.
Usage | Availability |
---|---|
onConfirmClosed(response, customParameters)
|
1.1 |
onConfirmClosed: function(response, customParameters) {
var aCustomParameter = customParameters["aCustomParameter"];
var changes = {};
if (response) {
changes['EditPoint1'] = "An alert closed with custom parameter " + aCustomParameter;
} else {
// User cancelled the dialog so don't make any changes to the session.
}
return changes;
}
A session summary is stored for each session on the device and can be retrieved from within javascript code. This process starts by getting a reference to the project, using the project's full file name, and then retrieving the summaries from the project.
Session summaries do not contain all custom point values, as this would cause performance issues on most mobile devices. Instead, the summary contains a set of base data as well as values for each point that has been specified in the project's session list columns.
x={
onButtonPress: function()
{
// Get the guid of the currently open session.
var sessionGuid = this.project.session.__guid__;
// Get a list of session summaries from the sub project.
var childProject = projects['JavascriptPushDataChild.ppc'];
var summaries = childProject.summaries;
// ... use session summaries
}
}
x={
onButtonPress: function() {
var childProject = projects['JSLastChildSubproject.ppc'];
var summaries = childProject.summaries;
var sessionGuid = this.project.session.__guid__;
var sortedChildren = '';
// Filter to non-deleted, related child sessions
summaries = summaries.filter(function(el) {
return (el.parent_guid)
&& (el.parent_guid.toUpperCase() == sessionGuid.toUpperCase())
&& (el.status != 2);
});
// Sorting
var sortedChildSessions = summaries.sort(function(a, b) {
if(a.saved_timestamp === b.saved_timestamp) {
return a;
} else {
return b.saved_timestamp - a.saved_timestamp; // Descending
}
});
var lastChildGuid = sortedChildSessions[0].guid; // Most recent
for(childSession in sortedChildSessions) {
var summary = sortedChildSessions[childSession];
var childGuid = summary.guid;
var savedDate = summary.saved;
var guidPrefix = childGuid.substring(0,8);
sortedChildren += savedDate + ": " + guidPrefix + "";
}
return {
'sorted_children': sortedChildren,
'most_recent_child': lastChildGuid
};
}
}
x={
onButtonPress: function() {
var childProject = projects['JSLastChildSubproject.ppc'];
var summaries = childProject.summaries;
var sessionGuid = this.project.session.__guid__;
var sortedChildren = '';
// Filter to non-deleted, related child sessions
summaries = summaries.filter(function(el) {
return (el.parent_guid)
&& (el.parent_guid.toUpperCase() == sessionGuid.toUpperCase())
&& (el.status != 2);
});
// Sorting
var sortedChildSessions = summaries.sort(function(a, b) {
if(a.saved_timestamp === b.saved_timestamp) {
return a;
} else {
return a.saved_timestamp - b.saved_timestamp; // Ascending
}
});
var lastChildGuid = sortedChildSessions[sortedChildSessions.length - 1].guid; // Most Recent
for(childSession in sortedChildSessions) {
var summary = sortedChildSessions[childSession];
var childGuid = summary.guid;
var savedDate = summary.saved;
var guidPrefix = childGuid.substring(0,8);
sortedChildren += savedDate + ": " + guidPrefix + "";
}
return {
'sorted_children': sortedChildren,
'most_recent_child': lastChildGuid
};
}
}
Javascript callbacks can be used to save changes to the currently open session and since javascript version 1.2, changes can be persisted to any session on the device.
When a callback is executed and a dictionary (hash table) is returned, the keys will be used to find points within the currently open session. If a point is found then the value for the matching key will be saved to the session. See below for an example:
x={
onButtonPress: function()
{
var changes = {};
// This will save the value 'Example' to the point named 'EditPoint1'
changes['EditPoint1'] = "Example";
// This will save the value 45.32 to the point named 'NumpadPoint1'
changes['NumpadPoint1'] = 45.32;
return changes;
}
}
Or more concisely:
x={
onButtonPress: function()
{
return {
'EditPoint1': 'Example',
'NumpadPoint1': 45.32
};
}
}
Javascript version 1.2 introduced the ability update multiple sessions, including session from other projects. This can be done by returning an array that contains a dictionary (hash table) per project.
x={
onButtonPress: function()
{
return [
{
'project.path': 'JavascriptPushDataChild.ppc',
'sessions': {
'ff7f9262-4d55-42a1-8113-573f0d937ace': {
'EditPoint1': 'Example'
'NumpadPoint1': 45.32
},
'4ded65b0-5b9e-43f1-ba4f-e836e904b40b': {
'EditPoint1': 'Example',
'NumpadPoint1': 45.32
},
}
},
{
'project.path': 'JavascriptPushDataParent.ppc',
'sessions': {
'5f423a2f-6c94-4aa9-b749-beb9538f819b': {
'EditPoint1': 'Example'
'NumpadPoint1': 45.32
},
}
}
];
}
}
x={
onButtonPress: function()
{
// Get the guid of the currently open parent session.
var sessionGuid = this.project.session.__guid__;
// Get a list of session summaries from the sub project.
var childProject = projects['JavascriptPushDataChild.ppc'];
var summaries = childProject.summaries;
// Filter the sub sessions to only include sessions that are related to the open parent session.
// This is determined by comparing each sub session's 'parent_guid' with the guid of the opened
// session.
// This will also filter out any deleted sessions by ensuring each sub session does not have
// a deleted status (status of 2).
var childSessions = summaries.filter(function(el) {
return (el.parent_guid)
&& (el.parent_guid.toUpperCase() == sessionGuid.toUpperCase())
&& (el.status != 2);
});
// Loop through the related sub sessions and prepare a dictionary containing the changes to
// be applied.
var childSessionsData = {};
for(childSession in childSessions) {
var childGuid = childSessions[childSession].guid;
childSessionsData[childGuid] = { 'parent_data': 'Data from parent session ' + sessionGuid };
}
// Prepare a dictionary to define the sub project and the sessions to update.
var childProjectChanges = {
'project.path': 'JavascriptPushDataChild.ppc',
'sessions': childSessionsData
}
// Prepare a dictionary to define the parent project and the session to update.
var statusMessage = new Date().toLocaleString() + ': Pushed to ' + childSessions.length + ' children.';
var parentProjectChanges = {
'project.path': 'JavascriptPushDataParent.ppc',
'sessions': {
[sessionGuid]: { 'status': statusMessage }
}
}
// Returning an array, containing a dictionary per project.
return [ childProjectChanges, parentProjectChanges ];
}
}
Similar to the Logic point , javascript is able to show and hide points in the current session. This can help improve the maintainability of large projects where Logic points are used extensively to show and hide points. Instead, this can now be maintained in a single Javascript point.
If both a Logic point and a Javascript point are used to show/hide the same point, whichever is evaluated last will determine the outcome. It is recommended to use one or the other to avoid any confusion when maintaining your project.
Most points can be shown/hidden using a reference to the point's name. However, the Layout point does not have a point name and instead can be referenced using the text content.
x={
onButtonPress: function() {
this.showPoints(['Edit', 'This layout will appear/disappear.', 'boolean']);
}
}
x={
onButtonPress: function() {
this.hidePoints(['Edit', 'This layout will appear/disappear.', 'boolean']);
}
}
There are several functions and variables that are available within javascript that can be used to process session data and assist with debugging issues with your javascript code.
Function | Description | Availability |
---|---|---|
printObject(object)
|
Can be used to print an object's properties to console log where the standard console log for a cyclic object would otherwise fail. | 1.1 |
The following samples demonstrate how the Javascript Point can be used in several different ways, in your projects. Please start by downloading the project files and the javascript files that are used in these samples.
This sample demonstrates how javascript code can be executed using the Button interface from a Javascript Point. Each time the button is pressed, a value is incremented and saved to an edit point.
The project contains an edit point, EditPoint1 , and has a javascript point called JavascriptPoint which has been configured with the properties seen below:
The Display Mode option has been set to Just a Button which will display a button within the session when used on a mobile device. The button will display the text “Press Me”.
The Javascript Code contains a function callback for onButtonPress which is executed when the javascript point’s button is pressed.
Each time the button is pressed, the javascript will increment a number and store this number as the pressedCount . By storing this value in window.pressedCount , this value is shared with all other projects and sessions. This function contains a dictionary called changes which is used to set a value for the edit point, EditPoint1.
var changes = {};
...
changes['EditPoint1'] = "The button has been pressed " + window.pressedCount + " times.";
return changes;
This sample demonstrates how javascript code can be executed using the various javascript callbacks that are available including; onPointValueChanged, onSessionStart, onSessionFinish, onProjectDatabaseChanged.
In the Javascript Sample project there is a javascript point called JavascriptCallbacks on page 2. This javascript point has been configured with the properties seen in the screenshot below and is described in more detail in the following section. The javascript code that is used for this point is included with the sample projects in a file, javascript_sample_2_callbacks.js .
The onSessionStart callback is executed whenever a session is started which includes starting a new session and starting an existing session.
onSessionStart: function() {
// Ensure project storage has been initialised.
if (window.projectstorage == null) {
window.projectstorage = {};
}
var changes = {};
// This is how you can determine if the session has just been created or if
// the session is an existing session.
if (this.project.session.__new__) {
changes['onSessionStartNew'] = 'True'; // New session
} else {
changes['onSessionStartExisting'] = 'True'; // Existing session
}
return changes;
}
This callback is important as it is the first callback to be executed when opening a session and can be used to prepare anything that needs to be used in other callbacks. For example, in the sample this method prepares a dictionary window.projectstorage which will be used to store session-specific data.
// Ensure project storage has been initialised.
if (window.projectstorage == null) {
window.projectstorage = {};
}
Javascript code can be used to determine the difference between starting a new session and an existing session using:
// This is how you can determine if the session has just been created or if
// the session is an existing session.
if (this.project.session.__new__) {
changes['onSessionStartNew'] = 'True'; // New session
} else {
changes['onSessionStartExisting'] = 'True'; // Existing session
}
The function onSessionFinish is executed whenever a session is finished. In this sample, this function is used to increment a count of the times that the session has been finished. This sample demonstrates several important features of the Javascript Point including how to store data specifically for each session and how to create custom functions.
onSessionFinish: function() {
var changes = {};
// Increment and store the finishedCount.
var finishedCount = this.getValueForKey('finishedCount');
finishedCount += 1;
this.storeValueForKey('finishedCount', finishedCount);
changes['onSessionFinish'] = finishedCount + ' times';
return changes;
},
storeValueForKey: function(key, value) {
var project = getProject('javascript_sample_2_callbacks.ppc');
var sessionGuid = project.session.__guid__;
// Ensure this session's storage has been initialised.
if (window.projectstorage[sessionGuid] == null) {
window.projectstorage[sessionGuid] = {};
}
window.projectstorage[sessionGuid][key] = value;
},
getValueForKey: function(key) {
var project = getProject('javascript_sample_2_callbacks.ppc');
var sessionGuid = project.session.__guid__;
if (window.projectstorage != null) {
if (window.projectstorage[sessionGuid] != null) {
return window.projectstorage[sessionGuid][key];
}
}
return null;
}
This function is used is useful when used in conjunction with a SubProject Point as this function will execute when a sub project’s database has been updated. This function is useful in doing calculations or post processing for the parent session, whenever a change is detected in the sub project. A sub project is updated when a session is created, sent, duplicated or deleted. It will also be triggered when the sub project’s session list is viewed.
onProjectDatabaseChanged: function(project) {
var changes = {};
changes['onProjectDatabaseChanged'] = 'True';
return changes;
}
This function in the javascript code, onPointValueChanged , is executed whenever a point is updated within a session. Javascript code can be used to filter this action so that it only makes changes to your data when specific conditions are met.
onPointValueChanged: function(key) {
var changes = {};
// These changes will be applied when any point has changed value.
changes['onPointValueChangedForAnyPoint'] = 'True';
// Only update the display if the point that changed is not onPointValueChangedName.
if (key != 'onpointvaluechangedname') {
changes['onPointValueChangedName'] = key;
}
// Filter this function to only update the session when the point ChangeMe changes.
if (this.project.session.changeme.length > 0) {
changes['onPointValueChanged'] = 'True';
changes['onPointValueChangedName'] = key;
}
return changes;
}
This sample demonstrates how a Javascript point can be used to extract session values from a project and
how to sort the session data. See the provided sample project,
javascript_sample_session_data.ppc
, for a full example.
In order for a Javascript point to have access to session point values, each of the points need to be added
to the project's Session List Columns. This can be configured in the designer by going to
Project properties
->
Options
->
Session List Columns
.
Once the points have been added to the Session List Columns, they become accessible in the project's list of session summaries.
var sessionSummaries = this.project.summaries;
var otherProjectFileName = 'other test project.ppc';
var otherProject = getProject(otherProjectFileName);
var otherSessionSummaries = this.project.summaries;
Example below is when the project contains one session:
[
{
"status":0,
"values":{"selection1":"C", "startdate":"2021-01-05 10:11:22", "selection2":"X"},
"parent_guid":null,
"saved":"05-01-2021",
"created":"05-01-2021",
"guid":B4FF1D5C-A971-4FA5-9ED5-EB11C5FBC6F1",
"saved_timestamp":1612498314,
"created_timestamp":1612498307
},
... additional sessions ...
]
x = {
onSessionStart: function()
{
var summaryPropertyName = 'saved';
var sortByAscending = true;
this.sortOnStringProperty(this.project.summaries, sortingPointName, sortByAscending);
// ...
// this.project.summaries is now sorted
// ...
},
sortOnStringProperty(arr, property, asc = true) {
arr.sort(function (a,b) {
if(asc){
return a[property].localeCompare(b[property]);
}else{
return b[property].localeCompare(a[property]);
}
});
},
}
Sorting using a summary's value property:
x = {
onSessionStart: function()
{
var sessionPointName = 'selection1';
var sortByAscending = true;
this.sortOnStringValueProperty(this.project.summaries, sortingPointName, sortByAscending);
// ...
// this.project.summaries is now sorted
// ...
},
sortOnStringProperty(arr, property, asc = true) {
arr.sort(function (a,b) {
if(asc){
return a[property].localeCompare(b[property]);
}else{
return b[property].localeCompare(a[property]);
}
});
},
}
See the sample project,
javascript_sample_session_data.ppc
, for a full example.