Scripting & More Tab - Formula

  • If you have selected formula as your question type, you will enter your formula in the "Formula" field, located in the Scripting and More tab of the eForm Editor.
  • Formulas are especially useful in scored forms, where the final score for the form is the sum, average, etc. of the points accrued while the patient is completing the form.

Generating a total score:

The GAD-7 is a good example of this functionality. It contains all of the clinical scoring questions in a section named 'gad7Qs' and then uses the following formula in a hidden formula item to calculate the sum of all of the scores of that section:

ScriptUtil.sum(gad7Qs)
Copy Rule

Note: The formula item containing the script above must be located outside of the section that is being summed, to prevent the formula from summing itself.

Displaying a formula result:

If you would like to display the value calculated by your formula you can do so by adding "$$" to the "Caption" field (in the General tab). You can also use the "$$" in the "Custom Note" field (in the Note Formatting tab) if you don't want to display the value to the  patient but would like to capture it in the patient chart.

Example: GAD-7 eForm

The GAD-7 Ocean eForm is a good example of generating a total score and displaying the result:

  • The GAD-7 questionnaire contains seven questions to be scored. These questions are placed within a single section of the eForm named 'gad7Qs'.
  • Each of the seven questions are configured with pre-defined responses for the patient to choose from, and each response value is associated with a different point value.
  • In this case, we can see that the response of "Not at all" is associated with a point value of "0", while the response value of "Several days" is associated with a point value of "1".
  • A hidden formula item exists near the end of the form containing the "ScriptUtil.sum(gad7Qs)" script to calculate the sum of all of the point values for the seven questions.
  • In this case, we can see that two responses of "Several days" have been input, and since each of those responses are worth a point value of "1", the sum of all points in the section is "2".
  • The hidden formula item in the GAD-7 form has also been configured to generate a note of the total score using the "$$" symbol. The "$$" symbol is replaced with the output value of the formula script.
  • In this case, we can see that "$$" symbol is replaced with the sum value of "2".

More resources:

To learn how to round your formula answers to the nearest digit, please refer to: "Limiting the Number of Decimal Places in Formula Calculations".

For more examples of possible score calculations and more advanced scripting articles, please refer to:


Scripting & More Tab - Show this field if

  • The "Show this field if" field in the Scripting and More tab of the eForm Editor can be used to show or hide items (or make a clinical note), depending on answers to previous questions or other patient information.
  • Below you will find some examples of what types of scripts can go into this field.

Hide an item:

To hide items (eg formulas) so that they do not appear to patients, select the item in the eForm editor and in the Scripting & More tab, in the "Show this field if:" field, enter false.

Display a question, based on demographics:

If you are creating a general health assessment form and you want to ask about the possibility of pregnancy, you can choose to only show this field if the patient is female by entering the following into the "Show this field if" field:

pt.isFemale()
Copy Rule

For a full list of available patient-related functions, please refer to: "ScriptPatient ("Pt") Functions".

Display a question, based on how the patient responds to a Yes/No item type:

  1. Create your first question

    • First, create an item for the initial question asked to the patient. In the Scripting & More tab, ensure you give it an Item Reference.

       

      In our example, we first ask the patient if they smoke, in order to determine whether or not to offer smoking cessation counselling. Our first question "Do you smoke?" will be a Yes/No item type and have the item reference: "smoking".

  2. Create a hidden question

    • Next, create a second item. This question will be hidden, depending on how the patient answers the initial question. In the Scripting & More tab, use the "Show this field if" field to reference the answer that should make the second question appear. The item will appear dark grey with (hidden) underneath to show that it is hidden from patients until the appropriate answer is provided.

       

      In our example, if the patient answers yes, we want to show them a second yes/no question "Would you be interested in smoking cessation counselling?".

      smoking.r == 'Y'
      Copy Rule

Note: .r refers to that item’s response choice (e.g. “N” for no, “Y” for yes).

Display a question based on a patient's text response:

  1. Create your first question

    • First, create an item for the initial question asked to the patient. In the Scripting & More tab, ensure you give it an Item Reference.

       

      In our example, our first question is a menu item type with a caption: "What is your first language?" We provide a menu with the options English, French or Other. We gave this item reference: "language".

  2. Create a hidden question

    • Next, create a second item. This question will be hidden, depending on how the patient answers the initial question. In the Scripting & More tab, use the "Show this field if" field to reference the answer that should make the second question appear. The item will appear dark grey with (hidden) underneath to show that it is hidden from patients until the appropriate answer is provided.

       

      In our example, if the patient answers "Other" we want to show them an additional question "Please specify:" and collect their response using a Text Field item type. Since our menu choice for "Other" has a point value of 3, we can use the following JavaScript expression in the "Show this field if" field:

      language.p == 3
      Copy Rule
    • If your first question is a menu choice allowing multiple selections, use the following ".r" value in combination with Javascript's String.indexOf() function in the "Show this field if" field:

      In our example, if the patient answers "Other" we want to show them an additional question "Please specify:" and collect their response using a Text Field item type. Since our first question is a menu choice allowing multiple selections, we can use the following JavaScript expression in the "Show this field if" field:

      language.r.indexOf("Other") >= 0
      Copy Rule

      Note: In the above example, "Other" is the specific menu choice that you wish to unhide the second question.


Basics of JavaScript

Basic Code

Symbol Meaning
== equals
!= not equals
|| or
&& and
> greater than
>= greater than or equal to
< less than
<= less than or equal to
() brackets control order of execution
. a period indicates a property of something
Case JavaScript is case-sensitive (i.e. capitalization matters!)

Answer Variable

Any item that's been completed by a patient has 2 useful properties:

  1. Response value ("r")
  2. Point value ("p")

Accessing an Item's own Response Value

An item's own response value can be inserted into the caption or custom note of an item by using the string "$$". This is particularly useful when working with formula fields.

Examples:

myPainScale, a numeric scale with point values from 0-5.

myPainScale.r
Returns the value associated with the patient's choice (always in standard language, i.e. English)
myPainScale.p
Returns the point value as a number
$$
Returns the response value of that item when used in its own "Caption" or "Custom Note" fields (example caption field: "My Pain Scale Score: $$")

Script Variables

Variable Description Example Expressions
pt The ScriptPatient object with age, sex, etc.
pt.isMale() && pt.getAge() >= 55

Refer to "ScriptPatient Functions" for more details about more "pt." expressions.

daysSinceLastCompleted The number of day since the patient last complete this form
daysSinceLastCompleted > 365
firstTime Whether or not the patient has ever completed this form
firstTime
lastCompletedTag A string “remembered” by the form last time it was completed
lastCompletedTag.indexOf('myString') != -1

ScriptUtil Functions

ScriptUtil provides miscellaneous functions that allow you to simplify your scripts and support special use-cases. ScriptUtil is bound to all script session contexts, so you can use these functions in tablet rules or within eForms (show if, make note if, etc.)

Please refer to "ScriptUtil Functions" for examples of common ScriptUtil functions.


ScriptPatient ("pt") Functions

The ScriptPatient functions are available on the "pt" object in any script context, such as a tablet rule or within an eForm Action script.

Function Description Example Expression (Boolean)
getAge() Returns age in years
pt.getAge() > 40
getAgeInMonths() Returns age in months
pt.getAgeInMonths() > 18
getAgeInWeeks() Returns age in weeks
pt.getAgeInWeeks() > 6
isFemale() Returns true if female, false if not
pt.isFemale()
isMale() Returns true if male, false if not
pt.isMale()
getReasonForVisit() Returns the patient's reason for visit (not supported for all EMRs)
pt.getReasonForVisit() == 'PHE'
getCppItemKeys(cppListKey) Returns a string array of the patient profile items. Available keys will vary by EMR. See Medication Reconciliation eForm for an example of Rx profile item.
pt.getCppItemKeys('rx').length > 0
getCppItemData(cppListKey) Returns a key-value table for a CPP item with a specified list key and item key.
pt.getCppItemData("immu", "influenza virus vaccine")

 


ScriptUtil Functions

ScriptUtil provides miscellaneous functions that allow you to simplify your scripts and support special use-cases. ScriptUtil is bound to all script session contexts, so you can use these functions in tablet rules or within eForms (show if, make note if, etc.).

Variable(s) Description & Example Expression

sum, max, min

Returns the sum/max/min of point values in the section

ScriptUtil.sum(section1Ref) > 10
Copy Example

countAnswersMatching, countAnswersWithPointsEqualTo

The number of answers matching the value or point value in the specified section

ScriptUtil.countAnswersMatching(mySection,'other') > 0
Copy Example

percentComplete

Returns a number between 0 and 100 representing the number of completed items in a section (including nested sections)

ScriptUtil.percentComplete('nutriSTEPQs') == 100
Copy Example

getKeyword

Provides access to any keyword. Used for CPP access and a ‘catch-all’ for access to patient information.

ScriptUtil.getKeyword('@providerName') == 'John Smith'
Copy Example

getResponse

Provides access to an answer provided on a previous EForm in the same session.

ScriptUtil.getResponse('mySmokingScreenForm','isCurrentSmoker') == 'Y'
Copy Example

queueContains

(supported on Ocean Tablet only)

Returns true if the form queue (or completed forms) contains the ref passed in.

ScriptUtil.queueContains('phq9')
Copy Example

queueSize

(supported on Ocean Tablet only)

Returns the number of forms in the queue plus any forms that have already been completed.

ScriptUtil.queueSize() == 0
Copy Example

parseDate

Accepts a date string in "yyyy-mm-dd" format and returns a Javascript Date (tablet v127+)

ScriptUtil.parseDate("2015-3-5")
Copy Example

webQ

Displays sections or items for web questionnaires only, not tablets.

ScriptUtil.isWebQ()
Copy Example

walkIn

Returns true for walk-in patients (tablet v178+).

ScriptUtil.isWalkIn()
Copy Example

 


Orientation to Ocean Note Flags

Ocean's Note Flagging feature allows an eForm to tag a patient's response with a coloured "flag". These flags are intended to assist clinicians and their administrators with rapid triaging of responses.

The flags appear in the following three areas:

  • 1. The subject of the provider's notification email as a suffix (e.g., "Ocean Online Questionnaire Complete - Red"),
  • 2. The body of the provider's notification email ( e.g. "The response has been flagged as  Red ."),
  • 3. The status column in the Patients tab as a coloured asterisk icon (*)

Flag Types

The flags' meanings are intentionally left to the end-users to define. Below are a list of supported flag types and general meanings (in accordance with clinical documentation guidelines):

Flag types General meanings (in accordance with clinical documentation guidelines)
RED Red indicates an urgent or serious concern (e.g., suicidal ideation)
ORANGE Orange indicates a potentially urgent or serious concern (e.g., fever in an otherwise low-risk context)
YELLOW Yellow indicates something or concern without a specific urgency
GREEN Green indicates something reassuring (such as a negative COVID-19 screen)
BLUE Blue indicates something of general interest
PURPLE Purple also indicates something of general interest

Configuration

To create a noteFlag in a specific form and have it appear in an email notification:

  1. Edit the eForm

    • Locate the eForm that you would like to generate the flag in the eForms tab and open the editor.
    •  
    • Look for an existing inactive "noteFlag" item in case one already exists (e.g., the PHQ-9 has one but it is left inactive).
    •  
    • If there is no "noteFlag" item, add a new item type "Formula".
    •  
    • Set the caption to "noteFlag: $$" (this isn't strictly necessary, but makes it easier to troubleshoot).
    • In the item's Note Formatting tab, set "Create a note for this item" to "never" and set the "Populate answer for EMR Field" to "noteFlag".
    • In the item's Scripting and More tab, set the "Show this field if:" to "false" (to hide the field from patients). Set the formula to a script that reflects how you want the note flag to behave.
      • For example, in this PHQ-9 form, the flag is 'RED' if the suicidal ideation question is 'Y' and blank ('') otherwise. The formula should evaluate to either blank or one of the colour options listed above.
      • The exact expression for convenient copy-pasting of this example is provided below:
  2. Set "Notify me when viewed" when emailing the form

    • If you would like note flags with the notification emails, ensure that your email template is configured to send this notification email by checking the "Notify me when complete" checkbox
    • Note flags can still be useful without email notifications. For example, kiosk and tablet screening forms or Ocean Reminders will also generate note flags and display them in the Patients tab and the Daysheet as shown above.

Clinical Considerations when using Note Flags for Triaging Urgent Responses

Disclaimer:

Since the note flagging feature relies on ordinary email for notifications, it cannot be relied upon as the only means of providing a safe response for patients with worrisome symptoms. It should NOT be considered a substitute for in-person triaging, or direct instructions for patients. Clinical judgment is required to ensure safety when designing a triaging protocol and its associated eForm.

For example, a form that triggers a "RED" note flag for an acute risk for suicidal ideation should also clearly and unequivocally direct the patient to the emergency department.

Nonetheless, despite this important constraint, the note flagging feature can be a useful adjunct to improve the timeliness and quality of patient care when used appropriately.

Email Notification Management

Thanks to the intelligent filtering, rule evaluation, and triggering capabilities of modern web-based email platforms like Gmail, you may find it helpful to configure a rule to assist with advanced notifications involving note flags.

For example, using Gmail, you can create a filter to look for the " - RED" email subject and subsequently trigger a unique chime on a clinician smart phone for such events. Please refer to your email client's and smart phone's documentation for instructions on how to do this. Here are some sample articles that describe this process:

 


Using Formula Scripting to Calculate an Average

A hidden formula item can be added to an eForm to calculate the average of certain values collected from the eForm questions.

Simple Averages

Generating a simple average is straightforward if you can always assume a fixed number of answered questions (i.e. if you require a response to all questions).

Simple Average = Total Value of Responses / Number of Questions
Example:

If you have five questions with refs 'q1', 'q2', 'q3', 'q4', and 'q5', your formula would look like this:

(q1.p + q2.p + q3.p + q4.p + q5.p) / 5
Copy Rule

Averages of Answered Questions

However, it gets a bit trickier if you only want to count a question when it’s answered. The main difference is that you need to calculate the number of questions that are answered for the denominator.

Average Answer = Total Value of Responses / Number of Questions Answered

You can check if a question has been answered by looking at its literal response (.r).

q1.r == ''
means the answer is blank
q1.r == 'N'
means the answer is "No"
q1.r == 'Y'
means the answer is "Yes"

The following is JavaScript shorthand for saying "use 1 if q1.r isn’t empty; otherwise use 0"

(q1.r != '' ? 1 : 0)
Copy Rule
Example:

Using the previous example, if "q3" was left blank, you would only want to divide by 4 when generating the average. That means you need to calculate the denominator by adding 1 for each answered question.

This is what your new formula would look like:

(q1.p + q2.p + q3.p + q4.p + q5.p) / ((q1.r != '' ? 1 : 0) + (q2.r != '' ? 1 : 0) + (q3.r != '' ? 1 : 0) + (q4.r != '' ? 1 : 0) + (q5.r != '' ? 1 : 0))
Copy Rule

Limiting the Number of Decimal Places in Formula Calculations

When developing complex formulas in Ocean eForms, you may find yourself with a large number of decimal places (e.g., 2.342456677543). In order to limit the number of decimal places, simply add ".toFixed(#)" to the end of your formula, where # is the desired number of decimal places.

For example:

Original formula:
(( (6 - q1.p) + (6 - q2.p) + (q3.p) ) / 3)
Copy Formula

This formula would result in an answer such a 2.666667

Revised formula:
(( (6 - q1.p) + (6 - q2.p) + (q3.p) ) / 3).toFixed(2)
Copy Formula

This formula would result in an answer such as 2.67


Advanced JavaScript in Forms ("Fancy Stuff")

Inline Functions

Sometimes, you want a "formula" or "show if" expression to do really fancy stuff. Perhaps you want to do an "if/then/else" type of expression to decide whether a section of questions resolves to level 1 or level 2. It could be a lot more complicated than that (see the probability of readmission score for an example).

You will find that adding a simple if (x) { return y; } won't work. For example, the following will not work:

(ScriptUtil.sum(mySection) > 5) return 2; else return 1;

The trick is that you need to define and execute a function inline, like this:

(function() { if (ScriptUtil.sum(mySection) > 5) return 2; else return 1; })() 
Copy Rule

Technical Details

To break this this down, this part defines the function: (function() { if (ScriptUtil.sum(mySection) > 5) return 2; else return 1;}) and the () at the end simply runs the newly defined function.

Date Manipulations

You can create a new Date in Javascript using the new Date() call, which returns the current date/time instant. You can use new Date(2020,2,10) to create a date for March 10, 2020 (yes, March; the month is confusingly 0-indexed, so January is month 0).

You can call new Date().getMonth() to get the current month (0-indexed again, so March is month 2).

To compare dates, simply subtract them to obtain the number of milliseconds in between, then divide that difference by 1000*60*60*24 to get the difference in days.

Google "Javascript date reference" for more information.

Advanced Javascript

As long your script evaluates to a single expression, you can do pretty much anything that you can do with Javascript. Some advanced scripting functionality uses an inline function as described above to have a complicated multi-line algorithm wrapped in a single expression.

You can learn more about Javascript using Google (e.g. "how do I compare dates in Javascript?") or by reading a good reference book (e.g. "Javascript: The Good Parts").


Reverse Coding in Ocean eForms

Occasionally, when developing scales using Likert-type questions, you will find yourself needing to reverse code some of the items.

For example, an item such as "I don't like working with computers" scored from 1-5 (where 1 is "strongly disagree" and 5 is "strongly agree"), should be re-coded so that the negative answer is associated with the lower score. Re-coding is especially important if the item is being used in a formula to compute a scale score.

In Ocean, your reverse coding formula would be as follows:

New score = (max + min) - response
Example:

You have provided your patient with a 3-question survey scored on a 5 point-scale. Questions 1 and 2 are reverse coded. You would like to calculate a mean score for the survey.

Survey Fesponses:
  • Question 1 (q1.p) = 5
  • Question 2 (q2.p) = 4
  • Question 3 (q3.p) = 1
Ocean Formula:
((6 - q1.p) + (6 - q2.p) + (q3.p)) / 3
Copy Rule
Mean Score:
( ( 6 - 5 ) + ( 6 - 4 ) + 1 ) / 3 = 1.33
Copy Rule