Configure Specimen Collection Page (nth Step)
Got feedback or spotted a mistake?

Leave a comment at the end of this page or email contact@krishagni.com

Configure Specimen Collection Page (nth Step)

Introduction

OpenSpecimen allows specimens to be collected as per a specific event calendar for clinical trial-based protocols. This will enable you to pre-define specimens in CP and collect planned specimens as shown below:

This page is configurable from version 8.1 onwards. Please refer to the wiki page https://openspecimen.atlassian.net/l/cp/Pd1eaN2c for more details. Using the CP workflows configuration, you can configure additional fields to be captured after this step. You can configure any visit/specimen default and custom fields to capture value for them. Refer to the 'Collection Protocol Level Configuration' section to add a workflow at the CP level.

The nth step works as an update option. The specimens are collected at the specimen collection page and only the values for the fields are updated in the nth step.

Sections and properties used in Nth step: 

Section in Nth step:

Section

Details

Section

Details

visitFields

If visit fields need to be displayed on the nth step, this section must be added. There will be only one section of this displaying one row for a visit being collected.

fields

All fields to be displayed in a table format within the 'fields' section of JSON. 

title

Title of each section/table in the nth step.

fieldGroups

If fields need to be displayed in separate sections or tables, multiple sections can be within fieldGroups.

For example: 'Primary Specimen details', 'Aliquot details' etc. Each section can have a title, criteria, and set of fields.

criteria

This defines conditions for displaying fields in each section. For example 'Centrifuge event details' section can be displayed only for 'Whole Blood' & 'Primary' specimens.

Properties used within Sections:

  1. Specimen Collection properties:

Property

Description

Property

Description

name

Identifies the section as specimenCollection. This tells OpenSpecimen that this JSON block handles Nth step.

view

Optional. Specifies a custom HTML or component view if you want to override the default table-based layout. Usually set to null.

ctrl

Optional. Defines a custom Angular controller if additional logic is required. Usually set to null.

data

Main configuration object containing all parameters for specimen collection — visit details, specimen fields, criteria, and display logic.

  1. Data Section:

Property

Description

Property

Description

showVisitDetails

If true, visit-related fields (like Visit Name, Visit Status) are displayed at the top of the step.(Deprecated from v11.x)

showCollectionEvent

Displays specimen collection event fields such as collection date, time, and collector.(Deprecated from v11.x)

showReceivedEvent

Displays received event fields such as received time and received quality.(Deprecated from v11.x)

defCollectionDate

Sets the default collection date field (commonly "visit_date" to use the visit’s date).(Deprecated from v11.x)

hideCopyFirstToAll

If false, users can copy the first specimen’s field values to all other specimens in the table for faster data entry.

(Deprecated from v11.x)

enableCofrc

Used for collapse mode. (Deprecated from v11.x)

visitFields

Defines the configuration of visit-related fields (see separate table below). (Deprecated from v11.x)

fieldGroups

Contains one or more specimen field tables (each representing a section like Whole Blood, Plasma, PBMC, etc.).

showCollectionTree

If false, it skip the collection page and directly navigate to Nth step. (Deprecated from v11.x)

Visit Field Section (Deprecated from v11.x, it is handle through the system workflow):

Property

Description

Property

Description

title

Title of the visit section displayed on the UI (e.g., “Visit Details”).

criteria

Optional. Defines logical conditions for displaying this section. Leave blank ("") to always display.

fields

Defining fields for the each section for data entry on fields.

Field Group Section:

Property

Description

Property

Description

title

Title for each specimen section/table (e.g., “Whole Blood Collection Details”, “Plasma Collection Details”).

criteria

Logical condition used to decide when this section appears. Defines specimen attributes like type, lineage, or status required to show this group.

fields

List of specimen field configurations to display in the table for this group. Each object represents one column.

Criteria:

Property

Description

Property

Description

op

Logical operator — can be "AND" or "OR" to combine multiple rules.

rules

Array of conditions (rules) to match specimen attributes. Each rule has a field, operator, and value.

Rules (Inside criteria):

Property

Description

Property

Description

field

Field name to be evaluated (e.g., specimen.type, specimen.status).

op

Comparison operator — e.g., ==, !=, >, <.

value

Expected value to match against. String values must be enclosed in single quotes (e.g., 'Whole Blood').

Field properties used in field group:

Property

Description

Property

Description

name

Name for the field, typically matches baseField.

baseField

Actual backend field name (e.g., specimen.initialQty, specimen.storageLocation).

caption

Optional. Custom label shown as column header in the UI.

type

Type of specimen field. Common type: span (read-only), text, number, pv (dropdown), date, toggle-checkbox.

icon

Optional. Display icon for the field like checkbox.

width

Optional. Defines the column width (e.g., "30px").

defaultValue

Default value assigned to the field (e.g., false for checkbox field).

optional

If false, field become mandatory.

 

Example 1: Display Anatomic Site, Laterality, Collection Container and Spun Event for Whole Blood Specimens

 

Configuration:

{ "name": "specimenCollection", "data": { "fieldGroups": [ { "title": "Anatomic Site", "criteria": { "op" : "AND", "rules": [ { "field": "specimen.lineage", "op": "==", "value": "'New'" } ] }, "fields": [ { "name": "specimen.label", "baseField": "specimen.label", "type": "span" }, { "name": "specimen.anatomicSite", "baseField": "specimen.anatomicSite" }, { "name": "specimen.laterality", "baseField": "specimen.laterality" }, { "name": "specimen.pathology", "baseField": "specimen.pathology" }, { "name" : "specimen.collectionContainer", "baseField" : "specimen.collectionContainer", "caption": "SR Container", "type": "span" } ] }, { "title": "Spun Event for Blood Specimens", "criteria": { "op": "AND", "rules": [ { "field": "specimen.type", "op": "==", "value": "'Whole Blood'" }, { "field": "specimen.lineage", "op": "==", "value": "'New'" } ] }, "fields": [ { "name": "specimen.label", "baseField": "specimen.label", "type": "span" }, { "name": "events.SpecimenSpunEvent.user", "baseField": "specimen.events.SpecimenSpunEvent.user" }, { "name": "events.SpecimenSpunEvent.time", "baseField": "specimen.events.SpecimenSpunEvent.time" }, { "name": "events.SpecimenSpunEvent.gForce", "baseField": "specimen.events.SpecimenSpunEvent.gForce" }, { "name": "events.SpecimenSpunEvent.duration", "baseField": "specimen.events.SpecimenSpunEvent.duration" }, { "name": "events.SpecimenSpunEvent.comments", "baseField": "specimen.events.SpecimenSpunEvent.comments" } ] }, { "title": "Events for Frozen Tissue", "criteria": { "op": "AND", "rules": [ { "field": "specimen.lineage", "op": "==", "value": "'New'" }, { "field": "specimen.type", "op": "==", "value": "'Frozen Tissue'" } ] }, "fields": [ { "name": "specimen.label", "baseField": "specimen.label", "type": "span" }, { "name": "events.SpecimenCheckInCheckOutEvent.status", "baseField": "specimen.events.SpecimenCheckInCheckOutEvent.status" }, { "name": "events.SpecimenCheckInCheckOutEvent.user", "baseField": "specimen.events.SpecimenCheckInCheckOutEvent.user" }, { "name": "events.SpecimenCheckInCheckOutEvent.time", "baseField": "specimen.events.SpecimenCheckInCheckOutEvent.time" }, { "name": "events.SpecimenFrozenEvent.time", "baseField": "specimen.events.SpecimenFrozenEvent.time" }, { "name": "events.SpecimenFrozenEvent.user", "baseField": "specimen.events.SpecimenFrozenEvent.user" }, { "name": "events.SpecimenFrozenEvent.frozenMethod", "baseField": "specimen.events.SpecimenFrozenEvent.frozenMethod" } ] }, { "title" : "Specimen viability", "criteria": { "op": "AND", "rules" : [ { "field" : "specimen.lineage", "op" : "==", "value" : "'Derived'" }, { "field" : "['Serum', 'Plasma'].indexOf(specimen.type)", "op" : "!=", "value" : "-1" } ] }, "enableCofrc" : true, "fields" : [ { "name" : "specimen.label", "baseField" : "specimen.label", "type" : "span" }, { "name" : "specimen.type", "baseField" : "specimen.type", "type" : "span" }, { "name" : "specimen.extensionDetail.attrsMap.ST4", "baseField" : "specimen.extensionDetail.attrsMap.ST4" } ] } ] } }

Example 2: Display ‘Processed By' and ‘Processed Time’ fields only for 'PBMC’ and 'Plasma' samples

Configuration:

[ { "name" : "specimenCollection", "view" : null, "ctrl" : null, "data" : { "fieldGroups" : [ { "title" : "Processing Details", "criteria" : { "op" : "AND", "rules" : [ { "field" : "specimen.lineage", "op" : "!=", "value" : "'New'" },{ "field" : "['PBMC', 'Plasma'].indexOf(specimen.type)", "op" : "!=", "value" : "-1" } ] }, "enableCofrc" : true, "fields" : [ { "name" : "specimen.label", "baseField" : "specimen.label", "type" : "span" }, { "name" : "specimen.type", "baseField" : "specimen.type", "type" : "span" }, { "name" : "specimen.createdBy", "baseField" : "specimen.createdBy", "caption" : "Processed By User" }, { "name" : "specimen.createdOn", "baseField" : "specimen.createdOn", "caption" : "Processed Time" } ] } ] } } ]

 

 

Example 3: Display Concentration for Derived Specimens.

{ "name" : "specimenCollection", "view" : null, "ctrl" : null, "data" : { "defCollectionDate" : "current_date", "fieldGroups" : [ { "title" : "Derived Level", "criteria" : { "op" : "AND", "rules" : [ { "field" : "specimen.lineage", "op" : "==", "value" : "'Derived'" }] }, "fields" : [ { "name" : "specimen.label", "baseField" : "specimen.label", "type" : "span" }, { "name" : "specimen.type", "baseField" : "specimen.type", "type" : "span" }, { "name" : "specimen.concentration", "baseField" : "specimen.concentration", "caption" : "Concentration" }] } ] } }

 

 

Example 4: Display Specimen Requirement Label

{ "name" : "specimen.reqLabel", "baseField" : "specimen.reqLabel", "caption" : "Specimen Requirement Name" }

Example JSON to configure the setup that is shown in the above screenshot:

You need to add ‘specimen.reqLabel’ in the dictionary section as well before adding the field in the Nth step.

Example 5: Display Specimen Custom Fields on the nth step.

 

{ "name" : "specimenCollection", "view" : null, "ctrl" : null, "data" : { "fieldGroups" : [ { "title" : "Surepath Solution Remarks", "criteria" : { "op" : "OR", "rules" : [ { "field" : "specimen.lineage", "op" : "==", "value" : "'New'" } ] }, "fields" : [ { "name" : "specimen.label", "baseField" : "specimen.label", "type" : "span" }, { "name" : "specimen.extensionDetail.attrsMap.surepath_solution_remarks", "baseField" : "specimen.extensionDetail.attrsMap.surepath_solution_remarks" } ] } ] } }

NOTE

  • The subform field is not supported in the nth step. This is because the sub-form is a 1:many relation with the main form, and it is not possible to display the 1:many field in the nth step.

  • A radio button is not supported on the nth step before v11.

  • Once the workflow is uploaded, refresh your browser page once and then collect samples.

  • The nth step page will appear after the default specimen collection page.

 

Example 5: Display Specimen Custom Fields with selectively defaulted values

 

{ "name" : "specimenCollection", "view" : null, "ctrl" : null, "data" : { "showCollectionEvent" : false, "showReceivedEvent" : false, "defCollectionDate" : "current_date", "fieldGroups" : [ { "title" : "PB - Cryopreserved Cells", "criteria" : { "op" : "AND", "rules" : [ { "field" : "specimen.lineage", "op" : "==", "value" : "'Aliquot'" }, { "field" : "specimen.parentLabel", "op" : ".indexOf('BCC') == ", "value" : "0" } ] }, "enableCofrc" : false, "fields" : [ { "name" : "specimen.label", "baseField" : "specimen.label", "type" : "span" }, { "name" : "specimen.parentLabel", "baseField" : "specimen.parentLabel", "type" : "span" }, { "name" : "specimen.type", "baseField" : "specimen.type", "type" : "span" }, { "name" : "specimen.extensionDetail.attrsMap.cell_count", "baseField" : "specimen.extensionDetail.attrsMap.cell_count", "caption" : "Cell Count", "defaultValue": "10.00" } ] }, { "title" : "PB - Cell Pellet", "criteria" : { "op" : "AND", "rules" : [ { "field" : "specimen.lineage", "op" : "==", "value" : "'Aliquot'" }, { "field" : "specimen.parentLabel", "op" : ".indexOf('BCP') == ", "value" : "0" } ] }, "enableCofrc" : false, "fields" : [ { "name" : "specimen.label", "baseField" : "specimen.label", "type" : "span" }, { "name" : "specimen.parentLabel", "baseField" : "specimen.parentLabel", "type" : "span" }, { "name" : "specimen.type", "baseField" : "specimen.type", "type" : "span" }, { "name" : "specimen.extensionDetail.attrsMap.cell_count", "baseField" : "specimen.extensionDetail.attrsMap.cell_count", "caption" : "Cell Count" } ] } }
The Nth Step for child specimen

 

Example 6: Display Specimen Custom Fields based for specific Specimen Types

{ "name" : "specimenCollection", "view" : null, "ctrl" : null, "data" : { "showCollectionEvent" : false, "showReceivedEvent" : false, "defCollectionDate" : "current_date", "treeColumns" : [ { "fields" : [ { "name" : "description", "width" : 35 }, { "name" : "label", "width" : 15 }, { "name" : "quantity", "width" : 15 }, { "name" : "container", "width" : 30 }, { "name" : "position", "width" : 30 }, { "name" : "status", "width" : 15 } ] } ], "fieldGroups" : [ { "title" : "WBC count and Suspension Volume", "criteria" : { "op" : "AND", "rules" : [ { "field" : "specimen.lineage", "op" : "==", "value" : "'New'" }, { "field" : "['Peripheral Blood', 'Bone Marrow'].indexOf(specimen.type)", "op" : "!=", "value" : "-1" }, { "field" : "specimen.collectionEvent.container", "op" : "!=", "value" : "'Serum Separator Vacutainer'" } ] }, "enableCofrc" : false, "fields" : [ { "name" : "specimen.label", "baseField" : "specimen.label", "type" : "span" }, { "name" : "specimen.type", "baseField" : "specimen.type", "type" : "span" }, { "name" : "specimen.extensionDetail.attrsMap.wbc", "baseField" : "specimen.extensionDetail.attrsMap.wbc", "caption" : "WBC Count (10^6 / ml)" }, { "name" : "specimen.extensionDetail.attrsMap.volsus", "baseField" : "specimen.extensionDetail.attrsMap.volsus", "caption" : "Suspension Volume (ml)" } ] }

 

Example 7: Close Parent Specimen on the nth step

{ "name" : "specimenCollection", "view" : null, "ctrl" : null, "data" : { "fieldGroups" : [{ "title" : "Whole Blood Details", "criteria" : { "op" : "AND", "rules" : [ { "field" : "specimen.specimenClass", "op" : "!=", "value" : "'Tissue'" }, { "field" : "specimen.lineage", "op" : "==", "value" : "'New'" } ] }, "enableCofrc" : true, "fields" : [ { "name" : "specimen.label", "baseField" : "specimen.label", "type" : "span" }, { "name" : "specimen.type", "baseField" : "specimen.type", "type" : "span" }, { "name" : "specimen.closeAfterChildrenCreation", "caption" : "Close Specimen", "type" : "toggle-checkbox", "defaultValue" : true, "values" : { "trueValue" : "true", "falseValue" : "false" } } ] } ] } }

Example 8: Display fields based on the specimen requirement code

{ "name" : "specimenCollection", "view" : null, "ctrl" : null, "data" : { "showCollectionEvent" : false, "showReceivedEvent" : false, "defCollectionDate" : "current_date", "fieldGroups" : [ { "title" : "PB - Cryopreserved Cells", "criteria" : { "op" : "AND", "rules" : [ { "field" : "specimen.lineage", "op" : "==", "value" : "'New'" }, { "field" : "specimen.reqCode", "op" : "==", "value" : "PBC" } ] }, "enableCofrc" : false, "fields" : [ { "name" : "specimen.label", "baseField" : "specimen.label", "type" : "span" }, { "name" : "specimen.type", "baseField" : "specimen.type", "type" : "span" }, { "name" : "specimen.extensionDetail.attrsMap.cell_count", "baseField" : "specimen.extensionDetail.attrsMap.cell_count", "caption" : "Cell Count", "defaultValue": "10.00" } ] }] } }

Configure Visit Fields on the nth Step

This configuration is deprecated in v11 because, starting from v11, visit fields (both default and custom) are automatically pulled from the dictionary.

The visit fields - 'Clinical Diagnoses', 'Clinical Status', 'Surgical Pathology Number' etc. are not displayed on the specimen collection page when collecting planned samples. The specimen collection page is currently not configurable to add visit level fields. These fields can be configured on the nth step and will be displayed only for planned specimens.

'visitFields' section is used to add visit fields on the nth step. You need to add the dictionary section as well before adding the fields in the Nth step.

{ "name": "specimenCollection", "data": { "visitFields": { "title": "Visit Details", "fields": [ [ { "name" : "visit.status", "baseField" : "visit.status" }, { "name": "visit.name", "baseField": "visit.name", "type": "span", "width": "150px" }, { "name": "visit.clinicalDiagnoses", "baseField": "visit.clinicalDiagnoses", "width": "200px" }, { "name": "visit.comments", "baseField": "visit.comments", "width": "200px" } ] ] }, "fieldGroups": [ { "title": "Frozen Event", "criteria": { "rules": [ { "field": "specimen.specimenClass", "op": "==", "value": "'Tissue'" } ] }, "fields": [ { "name": "specimen.label", "baseField": "specimen.label", "type": "span" }, { "name": "specimen.type", "baseField": "specimen.type", "type": "span" }, { "name": "events.SpecimenFrozenEvent.time", "baseField": "specimen.events.SpecimenFrozenEvent.time" }, { "name": "events.SpecimenFrozenEvent.user", "baseField": "specimen.events.SpecimenFrozenEvent.user" }, { "name": "events.SpecimenFrozenEvent.frozenMethod", "baseField": "specimen.events.SpecimenFrozenEvent.frozenMethod" } ] } ] } }

Hide Fields/Table on Specimen Collection Page (v7.1)

This configuration is deprecated in v11 but users can hide the fields through the custom workflow.

The idea is to allow CP admins to hide the columns/tables whose values are derived from the other field values displayed on the screen and submit them to the backend/API.

Hide table code snippet

{ "title": "Aliquots: Processing Details", "criteria": { "rules": { ... } }, "enableCofrc": false, "hideTable": true, // To hide the specimen collection page "fields": [ ... ] }

Hide column code snippet

{ "title": "Frozen Details", "criteria": { "rules": { ... } }, "enableCofrc": false, "fields": [ { "name" : "events.SpecimenFrozenEvent.frozenMethod", "baseField" : "specimen.events.SpecimenFrozenEvent.frozenMethod", "caption" : "Frozen Method", "defaultValue" : "Not Specified", "hideColumn" : true // To hide the frozen method column at the nth step }, ... ] }

Example: Processing event information for child specimens needs to be derived from its parent specimen automatically

Previously, to achieve that, you would have to show that fields/table in the step. As a resolution, now you will be able to hide the fields and tables on the step.

Before hiding the 'Aliquot: Processing Details' section on the specimen collection page:

After hiding the 'Aliquot: Processing Details':

Example JSON to configure the setup that is shown in the above screenshot:

Show/Hide Visit, Collection, and Received Event Fields (v7.1)

In v11, this isn't supported as the specimen collection page was deprecated. However, it can be achieved through custom workflows.

Use-Cases

  1. Sometimes specimens are collected in the clinic but not yet received by the biobank when the clinic staff enters the details. So the received event is not needed on the specimen collection page.

  2. Collection times are different for each primary specimen. So instead of collecting one time for all, you will collect different times in the nth step.

The options are to be added in the “specimenCollection” section of the workflows JSON as illustrated below:

{ "name": "specimenCollection", "data": { "showVisitDetails": false, "showCollectionEvent": false, "showReceivedEvent": true, "defReceiveQuality": "To be Received", //defaults received qualtity to 'To be Received' "defCollectionStatus" : "Collected", //defaults collection status to 'Collected' "defCollectionDate" : "current_date", // (v8.1) defaults collection and received dates to current date. The supported values are none, current_date and visit_date. ... } }

The above configuration hides visit fields, collection event fields, and displays the received event fields. When the above configuration is not present, all the fields are displayed by default.

From v8.1, the collection and receive dates would be blank by default. You can set the collection and receive dates as below:

Code

Description

Code

Description

defCollectionDate = 'visit_date'

The common collection and receive dates will be the same as whatever is populated in the visit date field.

defCollectionDate = 'current_date'

The collection and receive dates will be the current/present date/time.

defCollectionDate = 'none'

You are forced to select a date for collection and received fields.

 

Screenshot before configuration:

Screenshot after configuration:

Example JSON to configure the setup that is shown in the above screenshot:

 

Remove the default visit date(v10.0)

This configuration is deprecated in v11 but can be achieved through custom workflows.

{ "name": "specimenCollection", "data": { "defVisitDate": "none" } }

Once you added the above code "defVisitDate": "none" in the "specimenCollection section”, you can see the visit date field empty. OpenSpecimen will ask the user to enter the date to proceed further.

Disable visit autofill (v11.0)

The defaulted values on events or workflows configuration are autofilled in both cases.

{ "name" : "specimenCollection", "view" : null, "ctrl" : null, "data" : { "autoInitVisit" : false } }

#1 Autofill Enabled:

USE-CASE

Result

USE-CASE

Result

Create a new visit (no visits exist for that participant)

Visit fields (default and custom) is empty expect defaulted values.

Create a new visit under same event (visit exisit for participant for this event)

Visit fields (default and custom) values is autopopulate from old visits expect below fields.

  • Visit Date is defaulted to current date.

  • Surg Path Number is empty.

  • Status is defaulted to Complete.

Create a new visit under different event (visit doesn’t exisit for participant for this event)

Visit fields (default) values is autopopulate from old visits from different event expect below fields.

  • Visit Date is defaulted to current date.

  • Surg Path Number, Cohort, Comments and all custom fields is empty.

  • Status is defaulted to Complete.

  • Clinical Status is defaulted to “Not Specified”

  • Clinical Diagnosis should be pulled from last visit from different event.

Edit the existing visit

Visit fields (default and custom) values are shown AS-IS.

 #2 Autofill Disabled:

USE-CASE

Result

USE-CASE

Result

Create a new visit (no visits exist for that participant)

Visit fields (default and custom) is empty expect defaulted values.

Create a new visit under same event (visit exisit for participant for this event)

Visit fields (default and custom) are empty expect defaulted values.

Create a new visit under different event (visit doesn’t exisit for participant for this event)

Visit fields (default and custom) is empty expect defaulted values.

Edit the existing visit

Visit fields (default and custom) values are shown AS-IS.

 

Display Specimen Events at the nth Step

You can display specimen events at the nth step like frozen event, fixed event, spun event, etc at the nth step.

Example: Display Frozen Event for Whole Blood Specimens

Example JSON to configure the setup that is shown in the above screenshot:

 

Got feedback or spotted a mistake?

Leave a comment at the end of this page or email contact@krishagni.com