Skip to main content

Protocol Event Handlers

Key Terms

Table 43. 

Term

Definition

onChange

User-defined JavaScript function that is triggered when a given value in a LIMS Worksheet changes.

onRender

User-defined JavaScript function that is triggered when a Protocol is rendered in a LIMS Worksheet.



Comparison Operators

Table 44. 

Operator

Description

==

Equal to

===

Equal value and equal type

!=

Not equal to

!===

Not equal value or not equal type

>

Greater than

<

Less than

>=

Greater than or equal to

<=

Less than or equal to



Logical Operators

Table 45. 

Operator

Description

&&

And

||

Or

!

Not



When developing content in L7|ESP, there are front-end utility functions that can be used in onRender or onChange functions. These utility functions provide an easy way to interact with the LIMS Worksheet.

Common Event Handler Functions used in L7|ESP

getDataAt(rowIndexOrSampleName, columnIndexOrHeaderName)

Retrieve a value from a LIMS cell for a given row in the Worksheet.

Parameters:

  • rowIndexOrSampleName (str|num) - the index or Entity name of the desired row.

  • columnIndexOrHeaderName (str|num) - the index or header name of the desired column.

Examples:

# Retrieve the value for "Input Mass" for a single row in the Worksheet.
# This only works for onChange functions. OnRender functions are evaluated before
# the End User interacts with the Worksheet, and must evaluate a specific row (0)
# or each row in the Worksheet. 
let vol = api.getDataAt(row, 'Input Mass')
...

# Retrieve the value for "Input Mass" for the first row in the Worksheet.
# This should be used when grouping by ALL Entities in the Worksheet. 
let vol = api.getDataAt(0, 'Input Mass')
...

# Retrieve the value for "Input Mass" for each row in the Worksheet.
for(var i=0; i<api.getSampleCount(); i++) {
  let vol = api.getDataAt(i, 'Input Mass')
  ...
}

This function can also be used to determine if a field has a value.

if(!api.getDataAt(row, 'Field Name')){
...
}
if(!api.getDataAt(0, 'Field Name')){
...
}
if(!api.getDataAt(i, 'Field Name')){
...
}

Note

api.getDataAt is used to retrieve data from another field in the same Protocol.

Conditions should use newValue to reference the value of the current field.

Boolean (checkbox) values need to be converted to strings.

let dry_ice = api.getDataAt(row, 'Dry Ice').toString().toLowerCase()
if (dry_ice === 'true') {
...
}

Note

toLowerCase ensures the compared values are in the same case.

Note

When a checkbox does not have a default value, the value for the checkbox when the Worksheet renders is null, not false.

If you need to evaluate a checkbox without a default value, first evaluate that the field has a value.

let apprvd = api.getDataAt(row, 'Approved')
if (apprvd && apprvd.toString().toLowerCase() === "true") {
...
}

For mathematical operations, parameters need to be converted to numeric values.

let mass = api.getDataAt(row, 'Input Mass')
let conc = api.getDataAt(row, 'Sample Concentration (ng/uL)')
let sam_vol = api.getDataAt(row, 'Sample Volume (uL)')
let dil_vol = parseFloat(mass) / parseFloat(conc)
let wat_vol = 56 - parseFloat(dil_vol)
api.setDataAt(row, 'Sample Input Volume (uL)', dil_vol.toFixed(1))
api.setDataAt(row, 'Water Volume (uL)', wat_vol.toFixed(1))

Note

parseFloat parses an argument (converting it to a string first if needed) and returns a floating point number. toFixed() sets the number of decimal places.

setDataAt(rowIndexOrSampleName, columnIndexOrHeaderName, value)

Set a value for a LIMS cell for a given row in the Worksheet.

Parameters:

  • rowIndexOrSampleName (str|num) - the index or Entity name of the desired row.

  • columnIndexOrHeaderName (str|num) - the index or header name of the desired column.

  • value - the value to set.

Examples:

# Set the value for "Molecular Weight (g)" for a single row in the Worksheet.
# This only works for onChange functions. OnRender functions are evaluated before
# the End User interacts with the Worksheet, and must evaluate a specific row (0)
# or each row in the Worksheet.
api.setDataAt(row, 'Molecular Weight (g)', '0')

# Set the value for "Molecular Weight (g)" for the first row in the Worksheet.
# This should be used when grouping by ALL Entities in the Worksheet.
api.setDataAt(0, 'Molecular Weight (g)', '0')

# Set the value for "Molecular Weight (g)" for each row in the Worksheet.
api.setDataAt(i, 'Molecular Weight (g)', '0')

Note

onChange functions: if setting a field back to its default value (e.g., setting the complete field to false), you do not want the function to continue evaluating when there is no newValue.

if (newValue.toString().toLowerCase()==='false') {
  return
}
...

showColumns(headerNamesOrIndices)

Set the given columns as visible in the Worksheet.

Parameters:

  • headerNamesOrIndices (array<str>|array<num>) - an array of column identifiers (header names or indices) to show.

Example:

api.showColumns(['Molecular Weight (g)'])

# Comma-separate a list of fields.
api.showColumns(['Field 1', ‘Field 2’, ‘Field 3’])

hideColumns(headerNamesOrIndices)

Set the given columns as hidden in the Worksheet.

Parameters:

  • headerNamesOrIndices (array<str>|array<num>) - an array of column identifiers (header names or indices) to hide.

Example:

api.hideColumns(['Molecular Weight (g)'])

# Comma-separate a list of fields.
api.hideColumns(['Field 1', ‘Field 2’, ‘Field 3’])

Note

Use switch statements for multiple if/else statements.

The objective of a switch statement is to give an expression to evaluate and several different statements to execute based on the value of the expression. The interpreter checks each case against the value of the expression until a match is found. If nothing matches, a default condition will be used.

switch (expression) {
   case 1: 
      statement(s)
      break; 
   case 2: 
      statement(s)
      break;
   ...
   case n: 
      statement(s)
      break; 
   default: 
      statement(s)
}

The break statements indicate the end of a particular case. If they were omitted, the interpreter would continue executing each statement in each of the following cases.

For example, if each option in a picklist should hide and display different fields in the Protocol:

let nuc_acid = api.getDataAt(0, 'Nucleic Acid')
switch(nuc_acid) {
        case 'DNA':
        api.hideColumns(['RNA Concentration'])
        api.showColumns(['DNA Concentration'])
        break;
    case 'RNA':
        api.hideColumns(['DNA Concentration'])
        api.showColumns(['RNA Concentration'])
        break;
    case 'TNA':
        api.showColumns(['DNA Concentration', 'RNA Concentration'])
        break;
    default:
        api.hideColumns(['DNA Concentration', 'RNA Concentration'])
}

showNotification(message, category, title)

Show a toast notification.

Parameters:

  • message (str) - the message in the toast notification.

  • category (str) - error, warning, success, or information.

  • title (str) - the title of the toast notification.

Example:

if (!newValue) {
  return
}
let dry_ice = api.getDataAt(row, 'Dry Ice').toString().toLowerCase()
if (dry_ice === "false") {
  if (newValue !== null && newValue !== '') { 
    if (row===0) {
      api.showNotification('Dry Ice must be selected!', 'error')
    }
  api.setDataAt(row, 'Dry Ice Weight (kg)', '')
  }
}

Note

If grouping by all Entities in the Worksheet, add a condition for the first row (0) in the Worksheet so that one toast notification is triggered for all Entities in the sheet.

addProtocolLink(name, target, url)

Add a link to the Worksheet action area.

Parameters:

  • name (str) - the name of the link.

  • target (str) - '_blank' opens the link in a new web browser tab.

  • url (str) - the url for the link.

Example:

api.addProtocolLink({
  name: 'L7|ESP',
  target: '_blank',
  url: 'https://l7informatics.com/esp'
})

addChainButton(label)

Add a “Send Samples to Next Workflow” button to the Worksheet action area.

Parameters:

  • label (str) - the text to display on the button.

Example:

api.addChainButton('Route Samples')

Note

This function will only work in Workflow Chain Experiments, and is not needed after version 3.0 unless you want to customize the label.